]>
Commit | Line | Data |
---|---|---|
f2b60f7d FG |
1 | use clippy_utils::diagnostics::span_lint_and_sugg; |
2 | use clippy_utils::ty::is_type_diagnostic_item; | |
3 | use if_chain::if_chain; | |
4 | use rustc_ast::ast::LitKind; | |
5 | use rustc_errors::Applicability; | |
6 | use rustc_hir::{Expr, ExprKind}; | |
7 | use rustc_lint::LateContext; | |
8 | use rustc_span::symbol::sym; | |
9 | use std::path::{Component, Path}; | |
10 | ||
11 | use super::PATH_BUF_PUSH_OVERWRITE; | |
12 | ||
13 | pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'tcx Expr<'_>) { | |
14 | if_chain! { | |
15 | if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); | |
16 | if let Some(impl_id) = cx.tcx.impl_of_method(method_id); | |
9ffffee4 | 17 | if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).subst_identity(), sym::PathBuf); |
49aad941 | 18 | if let ExprKind::Lit(lit) = arg.kind; |
f2b60f7d FG |
19 | if let LitKind::Str(ref path_lit, _) = lit.node; |
20 | if let pushed_path = Path::new(path_lit.as_str()); | |
21 | if let Some(pushed_path_lit) = pushed_path.to_str(); | |
22 | if pushed_path.has_root(); | |
23 | if let Some(root) = pushed_path.components().next(); | |
24 | if root == Component::RootDir; | |
25 | then { | |
26 | span_lint_and_sugg( | |
27 | cx, | |
28 | PATH_BUF_PUSH_OVERWRITE, | |
29 | lit.span, | |
30 | "calling `push` with '/' or '\\' (file system root) will overwrite the previous path definition", | |
31 | "try", | |
32 | format!("\"{}\"", pushed_path_lit.trim_start_matches(|c| c == '/' || c == '\\')), | |
33 | Applicability::MachineApplicable, | |
34 | ); | |
35 | } | |
36 | } | |
37 | } |