|
1 | 1 | use clippy_utils::diagnostics::span_lint_and_sugg; |
2 | 2 | use clippy_utils::source::snippet_with_applicability; |
3 | | -use rustc_ast::ast::{BindingMode, ByRef, Lifetime, Mutability, Param, PatKind, Path, TyKind}; |
| 3 | +use rustc_ast::ast::{BindingMode, ByRef, Lifetime, Mutability, Param, PatKind, TyKind}; |
4 | 4 | use rustc_errors::Applicability; |
5 | 5 | use rustc_lint::{EarlyContext, EarlyLintPass}; |
6 | 6 | use rustc_session::declare_lint_pass; |
7 | | -use rustc_span::Span; |
8 | 7 | use rustc_span::symbol::kw; |
9 | 8 |
|
10 | 9 | declare_clippy_lint! { |
@@ -65,73 +64,69 @@ enum Mode { |
65 | 64 | Value, |
66 | 65 | } |
67 | 66 |
|
68 | | -fn check_param_inner(cx: &EarlyContext<'_>, path: &Path, span: Span, binding_mode: &Mode, mutbl: Mutability) { |
69 | | - if let [segment] = &path.segments[..] |
70 | | - && segment.ident.name == kw::SelfUpper |
71 | | - { |
72 | | - // In case we have a named lifetime, we check if the name comes from expansion. |
73 | | - // If it does, at this point we know the rest of the parameter was written by the user, |
74 | | - // so let them decide what the name of the lifetime should be. |
75 | | - // See #6089 for more details. |
76 | | - let mut applicability = Applicability::MachineApplicable; |
77 | | - let self_param = match (binding_mode, mutbl) { |
78 | | - (Mode::Ref(None), Mutability::Mut) => "&mut self".to_string(), |
79 | | - (Mode::Ref(Some(lifetime)), Mutability::Mut) => { |
80 | | - if lifetime.ident.span.from_expansion() { |
81 | | - applicability = Applicability::HasPlaceholders; |
82 | | - "&'_ mut self".to_string() |
83 | | - } else { |
84 | | - let lt_name = snippet_with_applicability(cx, lifetime.ident.span, "..", &mut applicability); |
85 | | - format!("&{lt_name} mut self") |
86 | | - } |
87 | | - }, |
88 | | - (Mode::Ref(None), Mutability::Not) => "&self".to_string(), |
89 | | - (Mode::Ref(Some(lifetime)), Mutability::Not) => { |
90 | | - if lifetime.ident.span.from_expansion() { |
91 | | - applicability = Applicability::HasPlaceholders; |
92 | | - "&'_ self".to_string() |
93 | | - } else { |
94 | | - let lt_name = snippet_with_applicability(cx, lifetime.ident.span, "..", &mut applicability); |
95 | | - format!("&{lt_name} self") |
96 | | - } |
97 | | - }, |
98 | | - (Mode::Value, Mutability::Mut) => "mut self".to_string(), |
99 | | - (Mode::Value, Mutability::Not) => "self".to_string(), |
100 | | - }; |
101 | | - |
102 | | - span_lint_and_sugg( |
103 | | - cx, |
104 | | - NEEDLESS_ARBITRARY_SELF_TYPE, |
105 | | - span, |
106 | | - "the type of the `self` parameter does not need to be arbitrary", |
107 | | - "consider to change this parameter to", |
108 | | - self_param, |
109 | | - applicability, |
110 | | - ); |
111 | | - } |
112 | | -} |
113 | | - |
114 | 67 | impl EarlyLintPass for NeedlessArbitrarySelfType { |
115 | 68 | fn check_param(&mut self, cx: &EarlyContext<'_>, p: &Param) { |
116 | 69 | // Bail out if the parameter it's not a receiver or was not written by the user |
117 | 70 | if !p.is_self() || p.span.from_expansion() { |
118 | 71 | return; |
119 | 72 | } |
120 | 73 |
|
121 | | - match &p.ty.kind { |
122 | | - TyKind::Path(None, path) => { |
123 | | - if let PatKind::Ident(BindingMode(ByRef::No, mutbl), _, _) = p.pat.kind { |
124 | | - check_param_inner(cx, path, p.span.to(p.ty.span), &Mode::Value, mutbl); |
125 | | - } |
| 74 | + let (path, binding_mode, mutbl) = match &p.ty.kind { |
| 75 | + TyKind::Path(None, path) if let PatKind::Ident(BindingMode(ByRef::No, mutbl), _, _) = p.pat.kind => { |
| 76 | + (path, Mode::Value, mutbl) |
126 | 77 | }, |
127 | | - TyKind::Ref(lifetime, mut_ty) => { |
| 78 | + TyKind::Ref(lifetime, mut_ty) |
128 | 79 | if let TyKind::Path(None, path) = &mut_ty.ty.kind |
129 | | - && let PatKind::Ident(BindingMode::NONE, _, _) = p.pat.kind |
130 | | - { |
131 | | - check_param_inner(cx, path, p.span.to(p.ty.span), &Mode::Ref(*lifetime), mut_ty.mutbl); |
132 | | - } |
| 80 | + && let PatKind::Ident(BindingMode::NONE, _, _) = p.pat.kind => |
| 81 | + { |
| 82 | + (path, Mode::Ref(*lifetime), mut_ty.mutbl) |
133 | 83 | }, |
134 | | - _ => {}, |
| 84 | + _ => return, |
| 85 | + }; |
| 86 | + |
| 87 | + let span = p.span.to(p.ty.span); |
| 88 | + if let [segment] = &path.segments[..] |
| 89 | + && segment.ident.name == kw::SelfUpper |
| 90 | + { |
| 91 | + // In case we have a named lifetime, we check if the name comes from expansion. |
| 92 | + // If it does, at this point we know the rest of the parameter was written by the user, |
| 93 | + // so let them decide what the name of the lifetime should be. |
| 94 | + // See #6089 for more details. |
| 95 | + let mut applicability = Applicability::MachineApplicable; |
| 96 | + let self_param = match (binding_mode, mutbl) { |
| 97 | + (Mode::Ref(None), Mutability::Mut) => "&mut self".to_string(), |
| 98 | + (Mode::Ref(Some(lifetime)), Mutability::Mut) => { |
| 99 | + if lifetime.ident.span.from_expansion() { |
| 100 | + applicability = Applicability::HasPlaceholders; |
| 101 | + "&'_ mut self".to_string() |
| 102 | + } else { |
| 103 | + let lt_name = snippet_with_applicability(cx, lifetime.ident.span, "'_", &mut applicability); |
| 104 | + format!("&{lt_name} mut self") |
| 105 | + } |
| 106 | + }, |
| 107 | + (Mode::Ref(None), Mutability::Not) => "&self".to_string(), |
| 108 | + (Mode::Ref(Some(lifetime)), Mutability::Not) => { |
| 109 | + if lifetime.ident.span.from_expansion() { |
| 110 | + applicability = Applicability::HasPlaceholders; |
| 111 | + "&'_ self".to_string() |
| 112 | + } else { |
| 113 | + let lt_name = snippet_with_applicability(cx, lifetime.ident.span, "'_", &mut applicability); |
| 114 | + format!("&{lt_name} self") |
| 115 | + } |
| 116 | + }, |
| 117 | + (Mode::Value, Mutability::Mut) => "mut self".to_string(), |
| 118 | + (Mode::Value, Mutability::Not) => "self".to_string(), |
| 119 | + }; |
| 120 | + |
| 121 | + span_lint_and_sugg( |
| 122 | + cx, |
| 123 | + NEEDLESS_ARBITRARY_SELF_TYPE, |
| 124 | + span, |
| 125 | + "the type of the `self` parameter does not need to be arbitrary", |
| 126 | + "consider to change this parameter to", |
| 127 | + self_param, |
| 128 | + applicability, |
| 129 | + ); |
135 | 130 | } |
136 | 131 | } |
137 | 132 | } |
0 commit comments