@@ -14,7 +14,7 @@ use rustc_infer::infer::{self, TyCtxtInferExt};
14
14
use rustc_infer:: traits;
15
15
use rustc_middle:: lint:: in_external_macro;
16
16
use rustc_middle:: ty:: { self , Binder , IsSuggestable , Subst , ToPredicate , Ty } ;
17
- use rustc_span:: symbol:: sym;
17
+ use rustc_span:: symbol:: { sym, Ident } ;
18
18
use rustc_span:: Span ;
19
19
use rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt ;
20
20
@@ -187,55 +187,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
187
187
err. span_label ( self . tcx . def_span ( def_id) , & format ! ( "{} defined here" , found) ) ;
188
188
}
189
189
} else if !self . check_for_cast ( err, expr, found, expected, expected_ty_expr) {
190
- let is_struct_pat_shorthand_field =
191
- self . maybe_get_struct_pattern_shorthand_field ( expr) . is_some ( ) ;
190
+ let struct_pat_shorthand_field = self . maybe_get_struct_pattern_shorthand_field ( expr) ;
192
191
let methods = self . get_conversion_methods ( expr. span , expected, found, expr. hir_id ) ;
193
192
if !methods. is_empty ( ) {
194
- if let Ok ( expr_text) = self . sess ( ) . source_map ( ) . span_to_snippet ( expr. span ) {
195
- let mut suggestions = iter:: zip ( iter:: repeat ( & expr_text) , & methods)
196
- . filter_map ( |( receiver, method) | {
197
- let method_call = format ! ( ".{}()" , method. name) ;
198
- if receiver. ends_with ( & method_call) {
199
- None // do not suggest code that is already there (#53348)
193
+ let mut suggestions = iter:: zip ( iter:: repeat ( & expr) , & methods)
194
+ . filter_map ( |( receiver_expr, method) | {
195
+ let method_call = format ! ( ".{}()" , method. name) ;
196
+ fn method_ident ( expr : & hir:: Expr < ' _ > ) -> Option < Ident > {
197
+ match expr. kind {
198
+ ExprKind :: MethodCall ( receiver_method, ..) => Some ( receiver_method. ident ) ,
199
+ ExprKind :: Unary ( _, expr) | ExprKind :: AddrOf ( .., expr) => method_ident ( expr) ,
200
+ _ => None
201
+ }
202
+ }
203
+ let method_ident = method_ident ( & receiver_expr) ;
204
+ if let Some ( method_ident) = method_ident
205
+ && method_ident. name == method. name
206
+ {
207
+ None // do not suggest code that is already there (#53348)
208
+ } else {
209
+ let method_call_list = [ ".to_vec()" , ".to_string()" ] ;
210
+ let mut sugg = if let ExprKind :: MethodCall ( receiver_method, ..) = receiver_expr. kind
211
+ && receiver_method. ident . name == sym:: clone
212
+ && method_call_list. contains ( & method_call. as_str ( ) )
213
+ {
214
+ vec ! [ (
215
+ receiver_method. ident. span,
216
+ method. name. to_string( )
217
+ ) ]
200
218
} else {
201
- let method_call_list = [ ".to_vec()" , ".to_string()" ] ;
202
- let mut sugg = if receiver. ends_with ( ".clone()" )
203
- && method_call_list. contains ( & method_call. as_str ( ) )
219
+ if expr. precedence ( ) . order ( )
220
+ < ExprPrecedence :: MethodCall . order ( )
204
221
{
205
- let max_len = receiver. rfind ( '.' ) . unwrap ( ) ;
206
- vec ! [ (
207
- expr. span,
208
- format!( "{}{}" , & receiver[ ..max_len] , method_call) ,
209
- ) ]
222
+ vec ! [
223
+ ( expr. span. shrink_to_lo( ) , "(" . to_string( ) ) ,
224
+ ( expr. span. shrink_to_hi( ) , format!( "){}" , method_call) ) ,
225
+ ]
210
226
} else {
211
- if expr. precedence ( ) . order ( )
212
- < ExprPrecedence :: MethodCall . order ( )
213
- {
214
- vec ! [
215
- ( expr. span. shrink_to_lo( ) , "(" . to_string( ) ) ,
216
- ( expr. span. shrink_to_hi( ) , format!( "){}" , method_call) ) ,
217
- ]
218
- } else {
219
- vec ! [ ( expr. span. shrink_to_hi( ) , method_call) ]
220
- }
221
- } ;
222
- if is_struct_pat_shorthand_field {
223
- sugg. insert (
224
- 0 ,
225
- ( expr. span . shrink_to_lo ( ) , format ! ( "{}: " , receiver) ) ,
226
- ) ;
227
+ vec ! [ ( expr. span. shrink_to_hi( ) , method_call) ]
227
228
}
228
- Some ( sugg)
229
+ } ;
230
+ if let Some ( name) = struct_pat_shorthand_field {
231
+ sugg. insert (
232
+ 0 ,
233
+ ( expr. span . shrink_to_lo ( ) , format ! ( "{}: " , name) ) ,
234
+ ) ;
229
235
}
230
- } )
231
- . peekable ( ) ;
232
- if suggestions. peek ( ) . is_some ( ) {
233
- err. multipart_suggestions (
234
- "try using a conversion method" ,
235
- suggestions,
236
- Applicability :: MaybeIncorrect ,
237
- ) ;
238
- }
236
+ Some ( sugg)
237
+ }
238
+ } )
239
+ . peekable ( ) ;
240
+ if suggestions. peek ( ) . is_some ( ) {
241
+ err. multipart_suggestions (
242
+ "try using a conversion method" ,
243
+ suggestions,
244
+ Applicability :: MaybeIncorrect ,
245
+ ) ;
239
246
}
240
247
} else if let ty:: Adt ( found_adt, found_substs) = found. kind ( )
241
248
&& self . tcx . is_diagnostic_item ( sym:: Option , found_adt. did ( ) )
0 commit comments