|
1 | | -use clippy_utils::diagnostics::span_lint_and_sugg; |
| 1 | +use clippy_utils::diagnostics::span_lint_and_then; |
2 | 2 | use clippy_utils::source::snippet_with_applicability; |
3 | | -use rustc_ast::ast::{BindingMode, ByRef, Lifetime, Mutability, Param, PatKind, TyKind}; |
| 3 | +use rustc_ast::ast::{BindingMode, ByRef, Lifetime, Param, PatKind, TyKind}; |
4 | 4 | use rustc_errors::Applicability; |
5 | 5 | use rustc_lint::{EarlyContext, EarlyLintPass}; |
6 | 6 | use rustc_session::declare_lint_pass; |
@@ -88,44 +88,37 @@ impl EarlyLintPass for NeedlessArbitrarySelfType { |
88 | 88 | if let [segment] = &path.segments[..] |
89 | 89 | && segment.ident.name == kw::SelfUpper |
90 | 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( |
| 91 | + span_lint_and_then( |
122 | 92 | cx, |
123 | 93 | NEEDLESS_ARBITRARY_SELF_TYPE, |
124 | 94 | span, |
125 | 95 | "the type of the `self` parameter does not need to be arbitrary", |
126 | | - "consider to change this parameter to", |
127 | | - self_param, |
128 | | - applicability, |
| 96 | + |diag| { |
| 97 | + let mut applicability = Applicability::MachineApplicable; |
| 98 | + let add = match binding_mode { |
| 99 | + Mode::Value => String::new(), |
| 100 | + Mode::Ref(None) => mutbl.ref_prefix_str().to_string(), |
| 101 | + Mode::Ref(Some(lifetime)) => { |
| 102 | + // In case we have a named lifetime, we check if the name comes from expansion. |
| 103 | + // If it does, at this point we know the rest of the parameter was written by the user, |
| 104 | + // so let them decide what the name of the lifetime should be. |
| 105 | + // See #6089 for more details. |
| 106 | + let lt_name = if lifetime.ident.span.from_expansion() { |
| 107 | + applicability = Applicability::HasPlaceholders; |
| 108 | + "'_".into() |
| 109 | + } else { |
| 110 | + snippet_with_applicability(cx, lifetime.ident.span, "'_", &mut applicability) |
| 111 | + }; |
| 112 | + format!("&{lt_name} {mut_}", mut_ = mutbl.prefix_str()) |
| 113 | + }, |
| 114 | + }; |
| 115 | + |
| 116 | + let mut sugg = vec![(p.ty.span.with_lo(p.span.hi()), String::new())]; |
| 117 | + if !add.is_empty() { |
| 118 | + sugg.push((p.span.shrink_to_lo(), add)); |
| 119 | + } |
| 120 | + diag.multipart_suggestion_verbose("remove the type", sugg, applicability); |
| 121 | + }, |
129 | 122 | ); |
130 | 123 | } |
131 | 124 | } |
|
0 commit comments