From 5997586e69e44447ada6e4b41ecf38d03ceab869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Aug 2024 18:40:45 +0000 Subject: [PATCH] [Experimental] `>::into` lint Running crater to see how common that pattern is. The Lint would have to be at most warn-by-default because there are a handful of cases detected that are actually perfectly reasonable (`type` aliases with per-platform `cfg`, or macros) which are now at best half-heartedly handled. I've detected a handful of cases where we're calling `.into()` unnecessarily in the `rustc` codebase as well, and changed those. --- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- compiler/rustc_lint/messages.ftl | 2 + compiler/rustc_lint/src/builtin.rs | 105 +++++++++++++++++- compiler/rustc_lint/src/lib.rs | 5 +- compiler/rustc_lint/src/lints.rs | 7 ++ compiler/rustc_lint/src/passes.rs | 12 +- .../src/lint_tail_expr_drop_order.rs | 2 +- compiler/rustc_parse/src/parser/tests.rs | 6 +- compiler/rustc_span/src/symbol.rs | 1 + .../src/traits/const_evaluatable.rs | 4 +- library/alloc/src/rc.rs | 2 +- library/alloc/src/sync.rs | 2 +- library/core/src/convert/mod.rs | 1 + library/std/src/os/fd/owned.rs | 2 +- .../src/sys/pal/unix/process/process_unix.rs | 1 + library/std/src/sys_common/process.rs | 1 + library/std/src/thread/mod.rs | 2 +- .../needless_return_with_question_mark.fixed | 2 +- .../ui/needless_return_with_question_mark.rs | 2 +- .../clippy/tests/ui/useless_conversion.stderr | 74 +++++++++++- .../error-in-impl-trait/realistic-async.rs | 1 + .../issues/issue-83883-describe-lints.stdout | 1 + .../deriving/auxiliary/another-proc-macro.rs | 1 + .../macro-or-patterns-back-compat.fixed | 2 +- .../macros/macro-or-patterns-back-compat.rs | 2 +- .../macro-pat-pattern-followed-by-or.rs | 2 +- 26 files changed, 217 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 81a5e9ee90d72..dd6adb17c5e47 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1120,7 +1120,7 @@ fn check_type_defn<'tcx>( } else { // Evaluate the constant proactively, to emit an error if the constant has // an unconditional error. We only do so if the const has no type params. - let _ = tcx.const_eval_poly(def_id.into()); + let _ = tcx.const_eval_poly(def_id); } } let field_id = field.did.expect_local(); diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 7522e21d0ef09..19a2f989a6c9d 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -740,6 +740,8 @@ lint_reserved_prefix = prefix `{$prefix}` is unknown lint_reserved_string = will be parsed as a guarded string in Rust 2024 .suggestion = insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +lint_self_type_conversion = this conversion is useless `{$source}` to `{$target}` + lint_shadowed_into_iter = this method call resolves to `<&{$target} as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<{$target} as IntoIterator>::into_iter` in Rust {$edition} .use_iter_suggestion = use `.iter()` instead of `.into_iter()` to avoid ambiguity diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index e74fb9d92e9e0..9d675d595395f 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -58,7 +58,7 @@ use crate::lints::{ BuiltinTrivialBounds, BuiltinTypeAliasBounds, BuiltinUngatedAsyncFnTrackCaller, BuiltinUnpermittedTypeInit, BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub, BuiltinUnsafe, BuiltinUnstableFeatures, BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub, - BuiltinWhileTrue, InvalidAsmLabel, + BuiltinWhileTrue, InvalidAsmLabel, SelfTypeConversionDiag, }; use crate::nonstandard_style::{MethodLateContext, method_context}; use crate::{ @@ -1305,7 +1305,7 @@ impl UnreachablePub { effective_vis.at_level(rustc_middle::middle::privacy::Level::Reachable) }) && let parent_parent = cx.tcx.parent_module_from_def_id( - cx.tcx.parent_module_from_def_id(def_id.into()).into(), + cx.tcx.parent_module_from_def_id(def_id).into(), ) && *restricted_did == parent_parent.to_local_def_id() && !restricted_did.to_def_id().is_crate_root() @@ -1589,6 +1589,7 @@ declare_lint_pass!( SoftLints => [ WHILE_TRUE, NON_SHORTHAND_FIELD_PATTERNS, + SELF_TYPE_CONVERSION, UNSAFE_CODE, MISSING_DOCS, MISSING_COPY_IMPLEMENTATIONS, @@ -3063,3 +3064,103 @@ impl EarlyLintPass for SpecialModuleName { } } } + +declare_lint! { + /// The `self_type_conversion` lint detects when a call to `.into()` does not have any effect. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// fn main() { + /// let () = ().into(); + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + pub SELF_TYPE_CONVERSION, + Deny, + "", +} + +pub struct SelfTypeConversion<'tcx> { + ignored_types: Vec>, +} + +impl_lint_pass!(SelfTypeConversion<'_> => [SELF_TYPE_CONVERSION]); + +impl SelfTypeConversion<'_> { + pub fn new() -> Self { + Self { ignored_types: vec![] } + } +} + +impl<'tcx> LateLintPass<'tcx> for SelfTypeConversion<'tcx> { + fn check_item_post(&mut self, cx: &LateContext<'tcx>, item: &hir::Item<'_>) { + let hir::ItemKind::Use(path, kind) = item.kind else { return }; + tracing::info!("{:#?}", item); + tracing::info!(?path, ?kind); + for res in &path.res { + let Res::Def(DefKind::TyAlias, def_id) = res else { continue }; + let ty = cx.tcx.type_of(def_id).instantiate_identity(); + let name = cx.tcx.item_name(*def_id); + // println!("{ty:?} {name:?}"); + tracing::info!("ignoring {ty:?} {name:?}"); + self.ignored_types.push(ty); + for stripped in cx.tcx.stripped_cfg_items(def_id.krate) { + if stripped.name.name == name { + tracing::info!("found stripped {name:#?}"); + } + } + } + // FIXME: also look at conditional cfgd uses so to account for things like + // `use std::io::repr_bitpacked` and `std::io::repr_unpacked`. + } + + fn check_expr_post(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'_>) { + let hir::ExprKind::MethodCall(_segment, rcvr, args, _) = expr.kind else { return }; + if !args.is_empty() { + tracing::info!("non-empty args"); + return; + } + let ty = cx.typeck_results().expr_ty(expr); + let rcvr_ty = cx.typeck_results().expr_ty(rcvr); + tracing::info!(?ty, ?rcvr_ty); + + if ty != rcvr_ty { + tracing::info!("different types"); + return; + } + if self.ignored_types.contains(&rcvr_ty) { + tracing::info!("ignored"); + return; + } + let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) else { + tracing::info!("no type dependent def id"); + return; + }; + tracing::info!(?def_id); + if Some(def_id) != cx.tcx.get_diagnostic_item(sym::into_fn) { + tracing::info!("not into_fn {:?}", cx.tcx.get_diagnostic_item(sym::into_fn)); + return; + } + tracing::info!(?def_id); + tracing::info!(?expr); + if expr.span.macro_backtrace().next().is_some() { + return; + } + if cx.tcx.sess.source_map().span_to_embeddable_string(expr.span).contains("symbolize/gimli") + { + // HACK + return; + } + // println!("{:#?}", self.ignored_types); + cx.emit_span_lint(SELF_TYPE_CONVERSION, expr.span, SelfTypeConversionDiag { + source: rcvr_ty, + target: ty, + }); + // bug!("asdf"); + } +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 1465c2cff7bc1..151ea6def85e2 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -188,7 +188,7 @@ early_lint_methods!( late_lint_methods!( declare_combined_late_lint_pass, [ - BuiltinCombinedModuleLateLintPass, + BuiltinCombinedModuleLateLintPass<'tcx>, [ ForLoopsOverFallibles: ForLoopsOverFallibles, DefaultCouldBeDerived: DefaultCouldBeDerived::default(), @@ -206,6 +206,7 @@ late_lint_methods!( UnitBindings: UnitBindings, NonUpperCaseGlobals: NonUpperCaseGlobals, NonShorthandFieldPatterns: NonShorthandFieldPatterns, + SelfTypeConversion<'tcx>: SelfTypeConversion::new(), UnusedAllocation: UnusedAllocation, // Depends on types used in type definitions MissingCopyImplementations: MissingCopyImplementations, @@ -275,6 +276,7 @@ fn register_builtins(store: &mut LintStore) { store.register_lints(&foreign_modules::get_lints()); store.register_lints(&HardwiredLints::lint_vec()); + store.register_late_pass(move |_tcx| Box::new(SelfTypeConversion::new())); add_lint_group!( "nonstandard_style", NON_CAMEL_CASE_TYPES, @@ -305,6 +307,7 @@ fn register_builtins(store: &mut LintStore) { UNUSED_PARENS, UNUSED_BRACES, REDUNDANT_SEMICOLONS, + // SELF_TYPE_CONVERSION, MAP_UNIT_FN ); diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index ac995b59caff1..77ad525787e97 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -71,6 +71,13 @@ pub(crate) struct BuiltinNonShorthandFieldPatterns { pub prefix: &'static str, } +#[derive(LintDiagnostic)] +#[diag(lint_self_type_conversion)] +pub(crate) struct SelfTypeConversionDiag<'t> { + pub source: Ty<'t>, + pub target: Ty<'t>, +} + #[derive(LintDiagnostic)] pub(crate) enum BuiltinUnsafe { #[diag(lint_builtin_allow_internal_unsafe)] diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index 3a323298bee83..e35349cb7e5b1 100644 --- a/compiler/rustc_lint/src/passes.rs +++ b/compiler/rustc_lint/src/passes.rs @@ -95,13 +95,13 @@ macro_rules! expand_combined_late_lint_pass_methods { /// runtime. #[macro_export] macro_rules! declare_combined_late_lint_pass { - ([$v:vis $name:ident, [$($pass:ident: $constructor:expr,)*]], $methods:tt) => ( + ([$v:vis $name:ident$(<$lt:lifetime>)?, [$($pass:ident$(<$inner_lt:lifetime>)?: $constructor:expr,)*]], $methods:tt) => ( #[allow(non_snake_case)] - $v struct $name { - $($pass: $pass,)* + $v struct $name$(<$lt>)? { + $($pass: $pass$(<$inner_lt>)?,)* } - impl $name { + impl$(<$lt>)? $name$(<$lt>)? { $v fn new() -> Self { Self { $($pass: $constructor,)* @@ -115,12 +115,12 @@ macro_rules! declare_combined_late_lint_pass { } } - impl<'tcx> $crate::LateLintPass<'tcx> for $name { + impl<'tcx> $crate::LateLintPass<'tcx> for $name$(<$lt>)? { $crate::expand_combined_late_lint_pass_methods!([$($pass),*], $methods); } #[allow(rustc::lint_pass_impl_without_macro)] - impl $crate::LintPass for $name { + impl$(<$lt>)? $crate::LintPass for $name$(<$lt>)? { fn name(&self) -> &'static str { panic!() } 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 6590702118c7f..50d10883d2cad 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 @@ -691,7 +691,7 @@ impl Subdiagnostic for LocalLabel<'_> { for dtor in self.destructors { dtor.add_to_diag_with(diag, f); } - let msg = f(diag, crate::fluent_generated::mir_transform_label_local_epilogue.into()); + let msg = f(diag, crate::fluent_generated::mir_transform_label_local_epilogue); diag.span_label(self.span, msg); } } diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs index 3f8d66c2c9580..b810bb4e3bbd9 100644 --- a/compiler/rustc_parse/src/parser/tests.rs +++ b/compiler/rustc_parse/src/parser/tests.rs @@ -2366,8 +2366,7 @@ fn string_to_tts_1() { token::Ident(sym::i32, IdentIsRaw::No), sp(8, 11), ), - ]) - .into(), + ]), ), TokenTree::Delimited( DelimSpan::from_pair(sp(13, 14), sp(18, 19)), @@ -2383,8 +2382,7 @@ fn string_to_tts_1() { ), // `Alone` because the `;` is followed by whitespace. TokenTree::token_alone(token::Semi, sp(16, 17)), - ]) - .into(), + ]), ), ]); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 0dcf38e349365..c830339dcf24f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1119,6 +1119,7 @@ symbols! { integer_: "integer", // underscore to avoid clashing with the function `sym::integer` below integral, into_async_iter_into_iter, + into_fn, into_future, into_iter, intra_doc_pointers, diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 15eb5d74cbfa5..446f9eaa348c0 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -79,7 +79,7 @@ pub fn is_const_evaluatable<'tcx>( Err( EvaluateConstErr::EvaluationFailure(e) | EvaluateConstErr::InvalidConstParamTy(e), - ) => Err(NotConstEvaluatable::Error(e.into())), + ) => Err(NotConstEvaluatable::Error(e)), Ok(_) => Ok(()), } } @@ -140,7 +140,7 @@ pub fn is_const_evaluatable<'tcx>( } Err( EvaluateConstErr::EvaluationFailure(e) | EvaluateConstErr::InvalidConstParamTy(e), - ) => Err(NotConstEvaluatable::Error(e.into())), + ) => Err(NotConstEvaluatable::Error(e)), Ok(_) => Ok(()), } } diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index e014404eff35b..08a7b32579868 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1789,7 +1789,7 @@ impl Rc { /// let x: Rc<&str> = Rc::new("Hello, world!"); /// { /// let s = String::from("Oh, no!"); - /// let mut y: Rc<&str> = x.clone().into(); + /// let mut y: Rc<&str> = x.clone(); /// unsafe { /// // this is Undefined Behavior, because x's inner type /// // is &'long str, not &'short str diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index b34a6d3f660c8..30761739dbff2 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -2468,7 +2468,7 @@ impl Arc { /// let x: Arc<&str> = Arc::new("Hello, world!"); /// { /// let s = String::from("Oh, no!"); - /// let mut y: Arc<&str> = x.clone().into(); + /// let mut y: Arc<&str> = x.clone(); /// unsafe { /// // this is Undefined Behavior, because x's inner type /// // is &'long str, not &'short str diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index e468f4f0f7e66..a995481486040 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -446,6 +446,7 @@ pub trait AsMut { #[doc(search_unbox)] pub trait Into: Sized { /// Converts this type into the (usually inferred) input type. + #[rustc_diagnostic_item = "into_fn"] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn into(self) -> T; diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index abb13b75f5087..fa3f43f659604 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -2,7 +2,7 @@ #![stable(feature = "io_safety", since = "1.63.0")] #![deny(unsafe_op_in_unsafe_fn)] - +#![cfg_attr(not(bootstrap), allow(self_type_conversion))] use super::raw::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; use crate::marker::PhantomData; use crate::mem::ManuallyDrop; 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 ec4965c1d7196..f568d57748677 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -285,6 +285,7 @@ impl Command { // have the drop glue anyway because this code never returns (the // child will either exec() or invoke libc::exit) #[cfg(not(any(target_os = "tvos", target_os = "watchos")))] + #[cfg_attr(not(bootstrap), allow(self_type_conversion))] unsafe fn do_exec( &mut self, stdio: ChildPipes, diff --git a/library/std/src/sys_common/process.rs b/library/std/src/sys_common/process.rs index 9f61d69d85875..9bdbdb450495d 100644 --- a/library/std/src/sys_common/process.rs +++ b/library/std/src/sys_common/process.rs @@ -25,6 +25,7 @@ impl fmt::Debug for CommandEnv { impl CommandEnv { // Capture the current environment with these changes applied + #[cfg_attr(not(bootstrap), allow(self_type_conversion))] pub fn capture(&self) -> BTreeMap { let mut result = BTreeMap::::new(); if !self.clear { diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 85ee369ca2b66..b6ee00a253a95 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -502,7 +502,7 @@ impl Builder { let id = ThreadId::new(); let my_thread = match name { - Some(name) => Thread::new(id, name.into()), + Some(name) => Thread::new(id, name), None => Thread::new_unnamed(id), }; diff --git a/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed b/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed index 9b7da85266316..b8a58f5dc71ca 100644 --- a/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed +++ b/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed @@ -30,7 +30,7 @@ fn main() -> Result<(), ()> { return Ok::<(), ()>(()); Err(())?; Ok::<(), ()>(()); - return Err(().into()); + return Err(()); external! { return Err(())?; } diff --git a/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs b/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs index 68e76d2b6402e..dd5b437aa19af 100644 --- a/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs +++ b/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs @@ -30,7 +30,7 @@ fn main() -> Result<(), ()> { return Ok::<(), ()>(()); Err(())?; Ok::<(), ()>(()); - return Err(().into()); + return Err(()); external! { return Err(())?; } diff --git a/src/tools/clippy/tests/ui/useless_conversion.stderr b/src/tools/clippy/tests/ui/useless_conversion.stderr index 6aeb382902ba1..4cef9d725b9fa 100644 --- a/src/tools/clippy/tests/ui/useless_conversion.stderr +++ b/src/tools/clippy/tests/ui/useless_conversion.stderr @@ -16,12 +16,26 @@ error: useless conversion to the same type: `T` LL | val.into() | ^^^^^^^^^^ help: consider removing `.into()`: `val` +error: this conversion is useless `T` to `T` + --> tests/ui/useless_conversion.rs:10:5 + | +LL | val.into() + | ^^^^^^^^^^ + | + = note: `#[deny(self_type_conversion)]` on by default + error: useless conversion to the same type: `i32` --> tests/ui/useless_conversion.rs:22:22 | LL | let _: i32 = 0i32.into(); | ^^^^^^^^^^^ help: consider removing `.into()`: `0i32` +error: this conversion is useless `i32` to `i32` + --> tests/ui/useless_conversion.rs:22:22 + | +LL | let _: i32 = 0i32.into(); + | ^^^^^^^^^^^ + error: useless conversion to the same type: `std::str::Lines<'_>` --> tests/ui/useless_conversion.rs:52:22 | @@ -58,6 +72,12 @@ error: useless conversion to the same type: `std::string::String` LL | let _: String = "foo".to_string().into(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `"foo".to_string()` +error: this conversion is useless `std::string::String` to `std::string::String` + --> tests/ui/useless_conversion.rs:136:21 + | +LL | let _: String = "foo".to_string().into(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + error: useless conversion to the same type: `std::string::String` --> tests/ui/useless_conversion.rs:137:21 | @@ -94,6 +114,12 @@ error: useless conversion to the same type: `std::string::String` LL | let _: String = format!("Hello {}", "world").into(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `format!("Hello {}", "world")` +error: this conversion is useless `std::string::String` to `std::string::String` + --> tests/ui/useless_conversion.rs:142:21 + | +LL | let _: String = format!("Hello {}", "world").into(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: useless conversion to the same type: `i32` --> tests/ui/useless_conversion.rs:147:13 | @@ -106,6 +132,12 @@ error: useless conversion to the same type: `Foo<'a'>` LL | let _: Foo<'a'> = s2.into(); | ^^^^^^^^^ help: consider removing `.into()`: `s2` +error: this conversion is useless `Foo<'a'>` to `Foo<'a'>` + --> tests/ui/useless_conversion.rs:153:23 + | +LL | let _: Foo<'a'> = s2.into(); + | ^^^^^^^^^ + error: useless conversion to the same type: `Foo<'a'>` --> tests/ui/useless_conversion.rs:155:13 | @@ -274,5 +306,45 @@ error: useless conversion to the same type: `T` LL | x.into_iter().map(Into::into).collect() | ^^^^^^^^^^^^^^^^ help: consider removing -error: aborting due to 36 previous errors +error: this conversion is useless `T` to `T` + --> tests/ui/useless_conversion.rs:10:5 + | +LL | val.into() + | ^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: this conversion is useless `i32` to `i32` + --> tests/ui/useless_conversion.rs:22:22 + | +LL | let _: i32 = 0i32.into(); + | ^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: this conversion is useless `std::string::String` to `std::string::String` + --> tests/ui/useless_conversion.rs:136:21 + | +LL | let _: String = "foo".to_string().into(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: this conversion is useless `std::string::String` to `std::string::String` + --> tests/ui/useless_conversion.rs:142:21 + | +LL | let _: String = format!("Hello {}", "world").into(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: this conversion is useless `Foo<'a'>` to `Foo<'a'>` + --> tests/ui/useless_conversion.rs:153:23 + | +LL | let _: Foo<'a'> = s2.into(); + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 46 previous errors diff --git a/tests/rustdoc-ui/error-in-impl-trait/realistic-async.rs b/tests/rustdoc-ui/error-in-impl-trait/realistic-async.rs index 6c53c2912e1eb..b80ca3d194b64 100644 --- a/tests/rustdoc-ui/error-in-impl-trait/realistic-async.rs +++ b/tests/rustdoc-ui/error-in-impl-trait/realistic-async.rs @@ -23,6 +23,7 @@ mod unix { #[cfg(any(unix, doc))] use unix::*; +#[cfg(not(doc))] // temporary hack in order to run crater with the deny-by-default lint async fn bar() { ().foo() } diff --git a/tests/rustdoc-ui/issues/issue-83883-describe-lints.stdout b/tests/rustdoc-ui/issues/issue-83883-describe-lints.stdout index 6021bce69397b..c28b1202f31e1 100644 --- a/tests/rustdoc-ui/issues/issue-83883-describe-lints.stdout +++ b/tests/rustdoc-ui/issues/issue-83883-describe-lints.stdout @@ -8,6 +8,7 @@ Available lint options: Lint checks provided by rustc: + $NAMES $LEVELS $MEANINGS self-type-conversion deny $NAMES $LEVELS $MEANINGS Lint groups provided by rustc: diff --git a/tests/ui/deriving/auxiliary/another-proc-macro.rs b/tests/ui/deriving/auxiliary/another-proc-macro.rs index 47f3c5b9c4b05..d0169bf51922e 100644 --- a/tests/ui/deriving/auxiliary/another-proc-macro.rs +++ b/tests/ui/deriving/auxiliary/another-proc-macro.rs @@ -1,4 +1,5 @@ #![feature(proc_macro_quote)] +#![allow(self_type_conversion)] extern crate proc_macro; diff --git a/tests/ui/macros/macro-or-patterns-back-compat.fixed b/tests/ui/macros/macro-or-patterns-back-compat.fixed index c16190c399aef..ac541656364fe 100644 --- a/tests/ui/macros/macro-or-patterns-back-compat.fixed +++ b/tests/ui/macros/macro-or-patterns-back-compat.fixed @@ -2,7 +2,7 @@ //@ aux-build:or-pattern.rs #![deny(rust_2021_incompatible_or_patterns)] -#![allow(unused_macros)] +#![allow(unused_macros, self_type_conversion)] #[macro_use] extern crate or_pattern; diff --git a/tests/ui/macros/macro-or-patterns-back-compat.rs b/tests/ui/macros/macro-or-patterns-back-compat.rs index ef0ffb99c1a62..460840d807192 100644 --- a/tests/ui/macros/macro-or-patterns-back-compat.rs +++ b/tests/ui/macros/macro-or-patterns-back-compat.rs @@ -2,7 +2,7 @@ //@ aux-build:or-pattern.rs #![deny(rust_2021_incompatible_or_patterns)] -#![allow(unused_macros)] +#![allow(unused_macros, self_type_conversion)] #[macro_use] extern crate or_pattern; diff --git a/tests/ui/macros/macro-pat-pattern-followed-by-or.rs b/tests/ui/macros/macro-pat-pattern-followed-by-or.rs index d584e919a2a00..76a0241d22069 100644 --- a/tests/ui/macros/macro-pat-pattern-followed-by-or.rs +++ b/tests/ui/macros/macro-pat-pattern-followed-by-or.rs @@ -1,5 +1,5 @@ //@ run-pass -#![allow(unused_macros)] +#![allow(unused_macros, self_type_conversion)] macro_rules! foo { ($x:pat | $y:pat) => {} } // should be ok macro_rules! bar { ($($x:pat)+ | $($y:pat)+) => {} } // should be ok macro_rules! qux { ($x:pat, $y:pat) => {} } // should be ok