Skip to content

Commit 56cee2b

Browse files
committed
fix: make the suggestion apply only to the inner type
Now we don't touch, and thus don't break, whatever path `Rc`/`Arc` was specified with
1 parent 6d60568 commit 56cee2b

File tree

7 files changed

+167
-26
lines changed

7 files changed

+167
-26
lines changed

clippy_lints/src/types/rc_buffer.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,46 @@ use clippy_utils::source::snippet_with_applicability;
33
use clippy_utils::{path_def_id, qpath_generic_tys};
44
use rustc_errors::Applicability;
55
use rustc_hir::def_id::DefId;
6-
use rustc_hir::{self as hir, QPath, TyKind};
6+
use rustc_hir::{QPath, Ty, TyKind};
77
use rustc_lint::LateContext;
88
use rustc_span::symbol::sym;
99
use std::borrow::Cow;
1010

1111
use super::RC_BUFFER;
1212

13-
pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool {
13+
pub(super) fn check(cx: &LateContext<'_>, hir_ty: &Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool {
1414
let mut app = Applicability::Unspecified;
1515
let name = cx.tcx.get_diagnostic_name(def_id);
1616
if name == Some(sym::Rc) {
17-
if let Some(alternate) = match_buffer_type(cx, qpath, &mut app) {
17+
if let Some(ty) = qpath_generic_tys(qpath).next()
18+
&& let Some(alternate) = match_buffer_type(cx, ty, &mut app)
19+
{
1820
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
1921
span_lint_and_then(
2022
cx,
2123
RC_BUFFER,
2224
hir_ty.span,
2325
"usage of `Rc<T>` when `T` is a buffer type",
2426
|diag| {
25-
diag.span_suggestion(hir_ty.span, "try", format!("Rc<{alternate}>"), app);
27+
diag.span_suggestion_verbose(ty.span, "try", alternate, app);
2628
},
2729
);
2830
true
2931
} else {
3032
false
3133
}
3234
} else if name == Some(sym::Arc) {
33-
if let Some(alternate) = match_buffer_type(cx, qpath, &mut app) {
35+
if let Some(ty) = qpath_generic_tys(qpath).next()
36+
&& let Some(alternate) = match_buffer_type(cx, ty, &mut app)
37+
{
3438
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
3539
span_lint_and_then(
3640
cx,
3741
RC_BUFFER,
3842
hir_ty.span,
3943
"usage of `Arc<T>` when `T` is a buffer type",
4044
|diag| {
41-
diag.span_suggestion(hir_ty.span, "try", format!("Arc<{alternate}>"), app);
45+
diag.span_suggestion_verbose(ty.span, "try", alternate, app);
4246
},
4347
);
4448
true
@@ -52,10 +56,9 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
5256

5357
fn match_buffer_type(
5458
cx: &LateContext<'_>,
55-
qpath: &QPath<'_>,
59+
ty: &Ty<'_>,
5660
applicability: &mut Applicability,
5761
) -> Option<Cow<'static, str>> {
58-
let ty = qpath_generic_tys(qpath).next()?;
5962
let id = path_def_id(cx, ty)?;
6063
let path = match cx.tcx.get_diagnostic_name(id) {
6164
Some(sym::OsString) => "std::ffi::OsStr".into(),

tests/ui/rc_buffer.fixed

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,9 @@ fn func_bad4(_: Rc<std::ffi::OsStr>) {}
3131
// does not trigger lint
3232
fn func_good1(_: Rc<RefCell<String>>) {}
3333

34+
mod issue_15802 {
35+
fn foo(_: std::rc::Rc<[u8]>) {}
36+
//~^ rc_buffer
37+
}
38+
3439
fn main() {}

tests/ui/rc_buffer.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,9 @@ fn func_bad4(_: Rc<OsString>) {}
3131
// does not trigger lint
3232
fn func_good1(_: Rc<RefCell<String>>) {}
3333

34+
mod issue_15802 {
35+
fn foo(_: std::rc::Rc<Vec<u8>>) {}
36+
//~^ rc_buffer
37+
}
38+
3439
fn main() {}

tests/ui/rc_buffer.stderr

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,52 +2,111 @@ error: usage of `Rc<T>` when `T` is a buffer type
22
--> tests/ui/rc_buffer.rs:10:11
33
|
44
LL | bad1: Rc<String>,
5-
| ^^^^^^^^^^ help: try: `Rc<str>`
5+
| ^^^^^^^^^^
66
|
77
= note: `-D clippy::rc-buffer` implied by `-D warnings`
88
= help: to override `-D warnings` add `#[allow(clippy::rc_buffer)]`
9+
help: try
10+
|
11+
LL - bad1: Rc<String>,
12+
LL + bad1: Rc<str>,
13+
|
914

1015
error: usage of `Rc<T>` when `T` is a buffer type
1116
--> tests/ui/rc_buffer.rs:12:11
1217
|
1318
LL | bad2: Rc<PathBuf>,
14-
| ^^^^^^^^^^^ help: try: `Rc<std::path::Path>`
19+
| ^^^^^^^^^^^
20+
|
21+
help: try
22+
|
23+
LL - bad2: Rc<PathBuf>,
24+
LL + bad2: Rc<std::path::Path>,
25+
|
1526

1627
error: usage of `Rc<T>` when `T` is a buffer type
1728
--> tests/ui/rc_buffer.rs:14:11
1829
|
1930
LL | bad3: Rc<Vec<u8>>,
20-
| ^^^^^^^^^^^ help: try: `Rc<[u8]>`
31+
| ^^^^^^^^^^^
32+
|
33+
help: try
34+
|
35+
LL - bad3: Rc<Vec<u8>>,
36+
LL + bad3: Rc<[u8]>,
37+
|
2138

2239
error: usage of `Rc<T>` when `T` is a buffer type
2340
--> tests/ui/rc_buffer.rs:16:11
2441
|
2542
LL | bad4: Rc<OsString>,
26-
| ^^^^^^^^^^^^ help: try: `Rc<std::ffi::OsStr>`
43+
| ^^^^^^^^^^^^
44+
|
45+
help: try
46+
|
47+
LL - bad4: Rc<OsString>,
48+
LL + bad4: Rc<std::ffi::OsStr>,
49+
|
2750

2851
error: usage of `Rc<T>` when `T` is a buffer type
2952
--> tests/ui/rc_buffer.rs:23:17
3053
|
3154
LL | fn func_bad1(_: Rc<String>) {}
32-
| ^^^^^^^^^^ help: try: `Rc<str>`
55+
| ^^^^^^^^^^
56+
|
57+
help: try
58+
|
59+
LL - fn func_bad1(_: Rc<String>) {}
60+
LL + fn func_bad1(_: Rc<str>) {}
61+
|
3362

3463
error: usage of `Rc<T>` when `T` is a buffer type
3564
--> tests/ui/rc_buffer.rs:25:17
3665
|
3766
LL | fn func_bad2(_: Rc<PathBuf>) {}
38-
| ^^^^^^^^^^^ help: try: `Rc<std::path::Path>`
67+
| ^^^^^^^^^^^
68+
|
69+
help: try
70+
|
71+
LL - fn func_bad2(_: Rc<PathBuf>) {}
72+
LL + fn func_bad2(_: Rc<std::path::Path>) {}
73+
|
3974

4075
error: usage of `Rc<T>` when `T` is a buffer type
4176
--> tests/ui/rc_buffer.rs:27:17
4277
|
4378
LL | fn func_bad3(_: Rc<Vec<u8>>) {}
44-
| ^^^^^^^^^^^ help: try: `Rc<[u8]>`
79+
| ^^^^^^^^^^^
80+
|
81+
help: try
82+
|
83+
LL - fn func_bad3(_: Rc<Vec<u8>>) {}
84+
LL + fn func_bad3(_: Rc<[u8]>) {}
85+
|
4586

4687
error: usage of `Rc<T>` when `T` is a buffer type
4788
--> tests/ui/rc_buffer.rs:29:17
4889
|
4990
LL | fn func_bad4(_: Rc<OsString>) {}
50-
| ^^^^^^^^^^^^ help: try: `Rc<std::ffi::OsStr>`
91+
| ^^^^^^^^^^^^
92+
|
93+
help: try
94+
|
95+
LL - fn func_bad4(_: Rc<OsString>) {}
96+
LL + fn func_bad4(_: Rc<std::ffi::OsStr>) {}
97+
|
98+
99+
error: usage of `Rc<T>` when `T` is a buffer type
100+
--> tests/ui/rc_buffer.rs:35:15
101+
|
102+
LL | fn foo(_: std::rc::Rc<Vec<u8>>) {}
103+
| ^^^^^^^^^^^^^^^^^^^^
104+
|
105+
help: try
106+
|
107+
LL - fn foo(_: std::rc::Rc<Vec<u8>>) {}
108+
LL + fn foo(_: std::rc::Rc<[u8]>) {}
109+
|
51110

52-
error: aborting due to 8 previous errors
111+
error: aborting due to 9 previous errors
53112

tests/ui/rc_buffer_arc.fixed

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,9 @@ fn func_bad4(_: Arc<std::ffi::OsStr>) {}
3030
// does not trigger lint
3131
fn func_good1(_: Arc<Mutex<String>>) {}
3232

33+
mod issue_15802 {
34+
fn foo(_: std::sync::Arc<[u8]>) {}
35+
//~^ rc_buffer
36+
}
37+
3338
fn main() {}

tests/ui/rc_buffer_arc.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,9 @@ fn func_bad4(_: Arc<OsString>) {}
3030
// does not trigger lint
3131
fn func_good1(_: Arc<Mutex<String>>) {}
3232

33+
mod issue_15802 {
34+
fn foo(_: std::sync::Arc<Vec<u8>>) {}
35+
//~^ rc_buffer
36+
}
37+
3338
fn main() {}

tests/ui/rc_buffer_arc.stderr

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,52 +2,111 @@ error: usage of `Arc<T>` when `T` is a buffer type
22
--> tests/ui/rc_buffer_arc.rs:9:11
33
|
44
LL | bad1: Arc<String>,
5-
| ^^^^^^^^^^^ help: try: `Arc<str>`
5+
| ^^^^^^^^^^^
66
|
77
= note: `-D clippy::rc-buffer` implied by `-D warnings`
88
= help: to override `-D warnings` add `#[allow(clippy::rc_buffer)]`
9+
help: try
10+
|
11+
LL - bad1: Arc<String>,
12+
LL + bad1: Arc<str>,
13+
|
914

1015
error: usage of `Arc<T>` when `T` is a buffer type
1116
--> tests/ui/rc_buffer_arc.rs:11:11
1217
|
1318
LL | bad2: Arc<PathBuf>,
14-
| ^^^^^^^^^^^^ help: try: `Arc<std::path::Path>`
19+
| ^^^^^^^^^^^^
20+
|
21+
help: try
22+
|
23+
LL - bad2: Arc<PathBuf>,
24+
LL + bad2: Arc<std::path::Path>,
25+
|
1526

1627
error: usage of `Arc<T>` when `T` is a buffer type
1728
--> tests/ui/rc_buffer_arc.rs:13:11
1829
|
1930
LL | bad3: Arc<Vec<u8>>,
20-
| ^^^^^^^^^^^^ help: try: `Arc<[u8]>`
31+
| ^^^^^^^^^^^^
32+
|
33+
help: try
34+
|
35+
LL - bad3: Arc<Vec<u8>>,
36+
LL + bad3: Arc<[u8]>,
37+
|
2138

2239
error: usage of `Arc<T>` when `T` is a buffer type
2340
--> tests/ui/rc_buffer_arc.rs:15:11
2441
|
2542
LL | bad4: Arc<OsString>,
26-
| ^^^^^^^^^^^^^ help: try: `Arc<std::ffi::OsStr>`
43+
| ^^^^^^^^^^^^^
44+
|
45+
help: try
46+
|
47+
LL - bad4: Arc<OsString>,
48+
LL + bad4: Arc<std::ffi::OsStr>,
49+
|
2750

2851
error: usage of `Arc<T>` when `T` is a buffer type
2952
--> tests/ui/rc_buffer_arc.rs:22:17
3053
|
3154
LL | fn func_bad1(_: Arc<String>) {}
32-
| ^^^^^^^^^^^ help: try: `Arc<str>`
55+
| ^^^^^^^^^^^
56+
|
57+
help: try
58+
|
59+
LL - fn func_bad1(_: Arc<String>) {}
60+
LL + fn func_bad1(_: Arc<str>) {}
61+
|
3362

3463
error: usage of `Arc<T>` when `T` is a buffer type
3564
--> tests/ui/rc_buffer_arc.rs:24:17
3665
|
3766
LL | fn func_bad2(_: Arc<PathBuf>) {}
38-
| ^^^^^^^^^^^^ help: try: `Arc<std::path::Path>`
67+
| ^^^^^^^^^^^^
68+
|
69+
help: try
70+
|
71+
LL - fn func_bad2(_: Arc<PathBuf>) {}
72+
LL + fn func_bad2(_: Arc<std::path::Path>) {}
73+
|
3974

4075
error: usage of `Arc<T>` when `T` is a buffer type
4176
--> tests/ui/rc_buffer_arc.rs:26:17
4277
|
4378
LL | fn func_bad3(_: Arc<Vec<u8>>) {}
44-
| ^^^^^^^^^^^^ help: try: `Arc<[u8]>`
79+
| ^^^^^^^^^^^^
80+
|
81+
help: try
82+
|
83+
LL - fn func_bad3(_: Arc<Vec<u8>>) {}
84+
LL + fn func_bad3(_: Arc<[u8]>) {}
85+
|
4586

4687
error: usage of `Arc<T>` when `T` is a buffer type
4788
--> tests/ui/rc_buffer_arc.rs:28:17
4889
|
4990
LL | fn func_bad4(_: Arc<OsString>) {}
50-
| ^^^^^^^^^^^^^ help: try: `Arc<std::ffi::OsStr>`
91+
| ^^^^^^^^^^^^^
92+
|
93+
help: try
94+
|
95+
LL - fn func_bad4(_: Arc<OsString>) {}
96+
LL + fn func_bad4(_: Arc<std::ffi::OsStr>) {}
97+
|
98+
99+
error: usage of `Arc<T>` when `T` is a buffer type
100+
--> tests/ui/rc_buffer_arc.rs:34:15
101+
|
102+
LL | fn foo(_: std::sync::Arc<Vec<u8>>) {}
103+
| ^^^^^^^^^^^^^^^^^^^^^^^
104+
|
105+
help: try
106+
|
107+
LL - fn foo(_: std::sync::Arc<Vec<u8>>) {}
108+
LL + fn foo(_: std::sync::Arc<[u8]>) {}
109+
|
51110

52-
error: aborting due to 8 previous errors
111+
error: aborting due to 9 previous errors
53112

0 commit comments

Comments
 (0)