11use clippy_utils:: diagnostics:: span_lint_and_then;
22use clippy_utils:: qpath_generic_tys;
3- use clippy_utils:: res:: { MaybeDef , MaybeResPath } ;
3+ use clippy_utils:: res:: MaybeResPath ;
44use clippy_utils:: source:: snippet_with_applicability;
55use rustc_errors:: Applicability ;
66use rustc_hir:: def_id:: DefId ;
77use rustc_hir:: { self as hir, QPath , TyKind } ;
88use rustc_lint:: LateContext ;
99use rustc_span:: symbol:: sym;
10+ use std:: borrow:: Cow ;
1011
1112use super :: RC_BUFFER ;
1213
1314pub ( super ) fn check ( cx : & LateContext < ' _ > , hir_ty : & hir:: Ty < ' _ > , qpath : & QPath < ' _ > , def_id : DefId ) -> bool {
14- let app = Applicability :: Unspecified ;
15+ let mut app = Applicability :: Unspecified ;
1516 let name = cx. tcx . get_diagnostic_name ( def_id) ;
1617 if name == Some ( sym:: Rc ) {
17- if let Some ( alternate) = match_buffer_type ( cx, qpath) {
18+ if let Some ( alternate) = match_buffer_type ( cx, qpath, & mut app ) {
1819 #[ expect( clippy:: collapsible_span_lint_calls, reason = "rust-clippy#7797" ) ]
1920 span_lint_and_then (
2021 cx,
@@ -27,39 +28,10 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
2728 ) ;
2829 true
2930 } else {
30- let Some ( ty) = qpath_generic_tys ( qpath) . next ( ) else {
31- return false ;
32- } ;
33- if !ty. basic_res ( ) . is_diag_item ( cx, sym:: Vec ) {
34- return false ;
35- }
36- let TyKind :: Path ( qpath) = & ty. kind else { return false } ;
37- let inner_span = match qpath_generic_tys ( qpath) . next ( ) {
38- Some ( ty) => ty. span ,
39- None => return false ,
40- } ;
41- span_lint_and_then (
42- cx,
43- RC_BUFFER ,
44- hir_ty. span ,
45- "usage of `Rc<T>` when `T` is a buffer type" ,
46- |diag| {
47- let mut applicability = app;
48- diag. span_suggestion (
49- hir_ty. span ,
50- "try" ,
51- format ! (
52- "Rc<[{}]>" ,
53- snippet_with_applicability( cx, inner_span, ".." , & mut applicability)
54- ) ,
55- app,
56- ) ;
57- } ,
58- ) ;
59- true
31+ false
6032 }
6133 } else if name == Some ( sym:: Arc ) {
62- if let Some ( alternate) = match_buffer_type ( cx, qpath) {
34+ if let Some ( alternate) = match_buffer_type ( cx, qpath, & mut app ) {
6335 #[ expect( clippy:: collapsible_span_lint_calls, reason = "rust-clippy#7797" ) ]
6436 span_lint_and_then (
6537 cx,
@@ -71,34 +43,6 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
7143 } ,
7244 ) ;
7345 true
74- } else if let Some ( ty) = qpath_generic_tys ( qpath) . next ( ) {
75- if !ty. basic_res ( ) . is_diag_item ( cx, sym:: Vec ) {
76- return false ;
77- }
78- let TyKind :: Path ( qpath) = & ty. kind else { return false } ;
79- let inner_span = match qpath_generic_tys ( qpath) . next ( ) {
80- Some ( ty) => ty. span ,
81- None => return false ,
82- } ;
83- span_lint_and_then (
84- cx,
85- RC_BUFFER ,
86- hir_ty. span ,
87- "usage of `Arc<T>` when `T` is a buffer type" ,
88- |diag| {
89- let mut applicability = app;
90- diag. span_suggestion (
91- hir_ty. span ,
92- "try" ,
93- format ! (
94- "Arc<[{}]>" ,
95- snippet_with_applicability( cx, inner_span, ".." , & mut applicability)
96- ) ,
97- app,
98- ) ;
99- } ,
100- ) ;
101- true
10246 } else {
10347 false
10448 }
@@ -107,13 +51,25 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
10751 }
10852}
10953
110- fn match_buffer_type ( cx : & LateContext < ' _ > , qpath : & QPath < ' _ > ) -> Option < & ' static str > {
54+ fn match_buffer_type (
55+ cx : & LateContext < ' _ > ,
56+ qpath : & QPath < ' _ > ,
57+ applicability : & mut Applicability ,
58+ ) -> Option < Cow < ' static , str > > {
11159 let ty = qpath_generic_tys ( qpath) . next ( ) ?;
11260 let id = ty. basic_res ( ) . opt_def_id ( ) ?;
11361 let path = match cx. tcx . get_diagnostic_name ( id) {
114- Some ( sym:: OsString ) => "std::ffi::OsStr" ,
115- Some ( sym:: PathBuf ) => "std::path::Path" ,
116- _ if Some ( id) == cx. tcx . lang_items ( ) . string ( ) => "str" ,
62+ Some ( sym:: OsString ) => "std::ffi::OsStr" . into ( ) ,
63+ Some ( sym:: PathBuf ) => "std::path::Path" . into ( ) ,
64+ Some ( sym:: Vec ) => {
65+ let TyKind :: Path ( vec_qpath) = & ty. kind else {
66+ return None ;
67+ } ;
68+ let vec_generic_ty = qpath_generic_tys ( vec_qpath) . next ( ) ?;
69+ let snippet = snippet_with_applicability ( cx, vec_generic_ty. span , "_" , applicability) ;
70+ format ! ( "[{snippet}]" ) . into ( )
71+ } ,
72+ _ if Some ( id) == cx. tcx . lang_items ( ) . string ( ) => "str" . into ( ) ,
11773 _ => return None ,
11874 } ;
11975 Some ( path)
0 commit comments