From e7c55a478fd78cae940b0b43fbdbd4b4c7c6567b Mon Sep 17 00:00:00 2001 From: xFrednet Date: Sat, 25 Jun 2022 14:16:28 +0200 Subject: [PATCH] Fix `#[expect]` for `clippy::ptr_arg` --- clippy_lints/src/ptr.rs | 41 +++++++++++++++++++++++------------------ tests/ui/ptr_arg.rs | 6 ++++++ tests/ui/ptr_arg.stderr | 40 +++++++++++++++++++++++----------------- 3 files changed, 52 insertions(+), 35 deletions(-) diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index b06eba13d2f..8f729feb090 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -1,6 +1,6 @@ //! Checks for usage of `&Vec[_]` and `&String`. -use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then, span_lint_hir_and_then}; use clippy_utils::source::snippet_opt; use clippy_utils::ty::expr_sig; use clippy_utils::visitors::contains_unsafe_block; @@ -166,15 +166,14 @@ impl<'tcx> LateLintPass<'tcx> for Ptr { ) .filter(|arg| arg.mutability() == Mutability::Not) { - span_lint_and_sugg( - cx, - PTR_ARG, - arg.span, - &arg.build_msg(), - "change this to", - format!("{}{}", arg.ref_prefix, arg.deref_ty.display(cx)), - Applicability::Unspecified, - ); + span_lint_hir_and_then(cx, PTR_ARG, arg.emission_id, arg.span, &arg.build_msg(), |diag| { + diag.span_suggestion( + arg.span, + "change this to", + format!("{}{}", arg.ref_prefix, arg.deref_ty.display(cx)), + Applicability::Unspecified, + ); + }); } } } @@ -221,7 +220,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr { let results = check_ptr_arg_usage(cx, body, &lint_args); for (result, args) in results.iter().zip(lint_args.iter()).filter(|(r, _)| !r.skip) { - span_lint_and_then(cx, PTR_ARG, args.span, &args.build_msg(), |diag| { + span_lint_hir_and_then(cx, PTR_ARG, args.emission_id, args.span, &args.build_msg(), |diag| { diag.multipart_suggestion( "change this to", iter::once((args.span, format!("{}{}", args.ref_prefix, args.deref_ty.display(cx)))) @@ -315,6 +314,7 @@ struct PtrArgReplacement { struct PtrArg<'tcx> { idx: usize, + emission_id: hir::HirId, span: Span, ty_did: DefId, ty_name: Symbol, @@ -419,10 +419,8 @@ fn check_fn_args<'cx, 'tcx: 'cx>( if let [.., name] = path.segments; if cx.tcx.item_name(adt.did()) == name.ident.name; - if !is_lint_allowed(cx, PTR_ARG, hir_ty.hir_id); - if params.get(i).map_or(true, |p| !is_lint_allowed(cx, PTR_ARG, p.hir_id)); - then { + let emission_id = params.get(i).map_or(hir_ty.hir_id, |param| param.hir_id); let (method_renames, deref_ty) = match cx.tcx.get_diagnostic_name(adt.did()) { Some(sym::Vec) => ( [("clone", ".to_owned()")].as_slice(), @@ -455,14 +453,20 @@ fn check_fn_args<'cx, 'tcx: 'cx>( }) .and_then(|arg| snippet_opt(cx, arg.span)) .unwrap_or_else(|| substs.type_at(1).to_string()); - span_lint_and_sugg( + span_lint_hir_and_then( cx, PTR_ARG, + emission_id, hir_ty.span, "using a reference to `Cow` is not recommended", - "change this to", - format!("&{}{}", mutability.prefix_str(), ty_name), - Applicability::Unspecified, + |diag| { + diag.span_suggestion( + hir_ty.span, + "change this to", + format!("&{}{}", mutability.prefix_str(), ty_name), + Applicability::Unspecified, + ); + } ); return None; }, @@ -470,6 +474,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>( }; return Some(PtrArg { idx: i, + emission_id: emission_id, span: hir_ty.span, ty_did: adt.did(), ty_name: name.ident.name, diff --git a/tests/ui/ptr_arg.rs b/tests/ui/ptr_arg.rs index 814bbc7af71..fd15001e540 100644 --- a/tests/ui/ptr_arg.rs +++ b/tests/ui/ptr_arg.rs @@ -1,3 +1,4 @@ +#![feature(lint_reasons)] #![allow(unused, clippy::many_single_char_names, clippy::redundant_clone)] #![warn(clippy::ptr_arg)] @@ -109,9 +110,12 @@ mod issue_5644 { #[allow(clippy::ptr_arg)] _s: &String, #[allow(clippy::ptr_arg)] _p: &PathBuf, #[allow(clippy::ptr_arg)] _c: &Cow<[i32]>, + #[expect(clippy::ptr_arg)] _expect: &Cow<[i32]>, ) { } + fn some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec, _s: &String) {} + struct S; impl S { fn allowed( @@ -119,6 +123,7 @@ mod issue_5644 { #[allow(clippy::ptr_arg)] _s: &String, #[allow(clippy::ptr_arg)] _p: &PathBuf, #[allow(clippy::ptr_arg)] _c: &Cow<[i32]>, + #[expect(clippy::ptr_arg)] _expect: &Cow<[i32]>, ) { } } @@ -129,6 +134,7 @@ mod issue_5644 { #[allow(clippy::ptr_arg)] _s: &String, #[allow(clippy::ptr_arg)] _p: &PathBuf, #[allow(clippy::ptr_arg)] _c: &Cow<[i32]>, + #[expect(clippy::ptr_arg)] _expect: &Cow<[i32]>, ) { } } diff --git a/tests/ui/ptr_arg.stderr b/tests/ui/ptr_arg.stderr index a9613daadde..bbf731c6d01 100644 --- a/tests/ui/ptr_arg.stderr +++ b/tests/ui/ptr_arg.stderr @@ -1,5 +1,5 @@ error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:7:14 + --> $DIR/ptr_arg.rs:8:14 | LL | fn do_vec(x: &Vec) { | ^^^^^^^^^ help: change this to: `&[i64]` @@ -7,43 +7,43 @@ LL | fn do_vec(x: &Vec) { = note: `-D clippy::ptr-arg` implied by `-D warnings` error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:11:18 + --> $DIR/ptr_arg.rs:12:18 | LL | fn do_vec_mut(x: &mut Vec) { | ^^^^^^^^^^^^^ help: change this to: `&mut [i64]` error: writing `&String` instead of `&str` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:15:14 + --> $DIR/ptr_arg.rs:16: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 - --> $DIR/ptr_arg.rs:19:18 + --> $DIR/ptr_arg.rs:20: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 - --> $DIR/ptr_arg.rs:23:15 + --> $DIR/ptr_arg.rs:24: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 - --> $DIR/ptr_arg.rs:27:19 + --> $DIR/ptr_arg.rs:28: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 - --> $DIR/ptr_arg.rs:35:18 + --> $DIR/ptr_arg.rs:36: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 - --> $DIR/ptr_arg.rs:48:14 + --> $DIR/ptr_arg.rs:49:14 | LL | fn cloned(x: &Vec) -> Vec { | ^^^^^^^^ @@ -59,7 +59,7 @@ LL | let i = (e).clone(); ... error: writing `&String` instead of `&str` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:57:18 + --> $DIR/ptr_arg.rs:58:18 | LL | fn str_cloned(x: &String) -> String { | ^^^^^^^ @@ -75,7 +75,7 @@ LL ~ x.to_owned() | error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:65:19 + --> $DIR/ptr_arg.rs:66:19 | LL | fn path_cloned(x: &PathBuf) -> PathBuf { | ^^^^^^^^ @@ -91,7 +91,7 @@ LL ~ x.to_path_buf() | error: writing `&String` instead of `&str` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:73:44 + --> $DIR/ptr_arg.rs:74:44 | LL | fn false_positive_capacity(x: &Vec, y: &String) { | ^^^^^^^ @@ -105,13 +105,19 @@ LL ~ let c = y; | error: using a reference to `Cow` is not recommended - --> $DIR/ptr_arg.rs:87:25 + --> $DIR/ptr_arg.rs:88: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 + --> $DIR/ptr_arg.rs:117: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 - --> $DIR/ptr_arg.rs:140:21 + --> $DIR/ptr_arg.rs:146:21 | LL | fn foo_vec(vec: &Vec) { | ^^^^^^^^ @@ -124,7 +130,7 @@ LL ~ let _ = vec.to_owned().clone(); | error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:145:23 + --> $DIR/ptr_arg.rs:151:23 | LL | fn foo_path(path: &PathBuf) { | ^^^^^^^^ @@ -137,7 +143,7 @@ LL ~ let _ = path.to_path_buf().clone(); | error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:150:21 + --> $DIR/ptr_arg.rs:156:21 | LL | fn foo_str(str: &PathBuf) { | ^^^^^^^^ @@ -150,10 +156,10 @@ LL ~ let _ = str.to_path_buf().clone(); | error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:156:29 + --> $DIR/ptr_arg.rs:162:29 | LL | fn mut_vec_slice_methods(v: &mut Vec) { | ^^^^^^^^^^^^^ help: change this to: `&mut [u32]` -error: aborting due to 16 previous errors +error: aborting due to 17 previous errors