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;
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) {
19 "usage of `Rc<T>` when T is a buffer type",
21 format!("Rc<{alternate}>"),
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) {
30 let TyKind::Path(qpath) = &ty.kind else { return false };
31 let inner_span = match qpath_generic_tys(qpath).next() {
35 let mut applicability = app;
40 "usage of `Rc<T>` when T is a buffer type",
44 snippet_with_applicability(cx, inner_span, "..", &mut applicability)
50 } else if cx.tcx.is_diagnostic_item(sym::Arc, def_id) {
51 if let Some(alternate) = match_buffer_type(cx, qpath) {
56 "usage of `Arc<T>` when T is a buffer type",
58 format!("Arc<{alternate}>"),
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) {
66 let TyKind::Path(qpath) = &ty.kind else { return false };
67 let inner_span = match qpath_generic_tys(qpath).next() {
71 let mut applicability = app;
76 "usage of `Arc<T>` when T is a buffer type",
80 snippet_with_applicability(cx, inner_span, "..", &mut applicability)
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)? {
96 sym::OsString => "std::ffi::OsStr",
97 sym::PathBuf => "std::path::Path",