]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/clippy_lints/src/types/rc_buffer.rs
Rollup merge of #103511 - nnethercote:bb-tweaks, r=bjorn3
[rust.git] / src / tools / clippy / clippy_lints / src / types / rc_buffer.rs
1 use clippy_utils::diagnostics::span_lint_and_sugg;
2 use clippy_utils::source::snippet_with_applicability;
3 use clippy_utils::{path_def_id, qpath_generic_tys};
4 use rustc_errors::Applicability;
5 use rustc_hir::{self as hir, def_id::DefId, QPath, TyKind};
6 use rustc_lint::LateContext;
7 use rustc_span::symbol::sym;
8
9 use super::RC_BUFFER;
10
11 pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool {
12     let app = Applicability::Unspecified;
13     if cx.tcx.is_diagnostic_item(sym::Rc, def_id) {
14         if let Some(alternate) = match_buffer_type(cx, qpath) {
15             span_lint_and_sugg(
16                 cx,
17                 RC_BUFFER,
18                 hir_ty.span,
19                 "usage of `Rc<T>` when T is a buffer type",
20                 "try",
21                 format!("Rc<{alternate}>"),
22                 app,
23             );
24         } else {
25             let Some(ty) = qpath_generic_tys(qpath).next() else { return false };
26             let Some(id) = path_def_id(cx, ty) else { return false };
27             if !cx.tcx.is_diagnostic_item(sym::Vec, id) {
28                 return false;
29             }
30             let TyKind::Path(qpath) = &ty.kind else { return false };
31             let inner_span = match qpath_generic_tys(qpath).next() {
32                 Some(ty) => ty.span,
33                 None => return false,
34             };
35             let mut applicability = app;
36             span_lint_and_sugg(
37                 cx,
38                 RC_BUFFER,
39                 hir_ty.span,
40                 "usage of `Rc<T>` when T is a buffer type",
41                 "try",
42                 format!(
43                     "Rc<[{}]>",
44                     snippet_with_applicability(cx, inner_span, "..", &mut applicability)
45                 ),
46                 app,
47             );
48             return true;
49         }
50     } else if cx.tcx.is_diagnostic_item(sym::Arc, def_id) {
51         if let Some(alternate) = match_buffer_type(cx, qpath) {
52             span_lint_and_sugg(
53                 cx,
54                 RC_BUFFER,
55                 hir_ty.span,
56                 "usage of `Arc<T>` when T is a buffer type",
57                 "try",
58                 format!("Arc<{alternate}>"),
59                 app,
60             );
61         } else if let Some(ty) = qpath_generic_tys(qpath).next() {
62             let Some(id) = path_def_id(cx, ty) else { return false };
63             if !cx.tcx.is_diagnostic_item(sym::Vec, id) {
64                 return false;
65             }
66             let TyKind::Path(qpath) = &ty.kind else { return false };
67             let inner_span = match qpath_generic_tys(qpath).next() {
68                 Some(ty) => ty.span,
69                 None => return false,
70             };
71             let mut applicability = app;
72             span_lint_and_sugg(
73                 cx,
74                 RC_BUFFER,
75                 hir_ty.span,
76                 "usage of `Arc<T>` when T is a buffer type",
77                 "try",
78                 format!(
79                     "Arc<[{}]>",
80                     snippet_with_applicability(cx, inner_span, "..", &mut applicability)
81                 ),
82                 app,
83             );
84             return true;
85         }
86     }
87
88     false
89 }
90
91 fn match_buffer_type(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static str> {
92     let ty = qpath_generic_tys(qpath).next()?;
93     let id = path_def_id(cx, ty)?;
94     let path = match cx.tcx.get_diagnostic_name(id)? {
95         sym::String => "str",
96         sym::OsString => "std::ffi::OsStr",
97         sym::PathBuf => "std::path::Path",
98         _ => return None,
99     };
100     Some(path)
101 }