@@ -239,47 +239,58 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
239
239
let trait_path = self . trait_path_or_bare_name ( span, expr_id, pick. item . container . id ( ) ) ;
240
240
let trait_generics = self . tcx . generics_of ( pick. item . container . id ( ) ) ;
241
241
242
- let parameter_count = trait_generics. count ( ) - ( trait_generics. has_self as usize ) ;
243
- let trait_name = if parameter_count == 0 {
244
- trait_path
245
- } else {
246
- format ! (
247
- "{}<{}>" ,
248
- trait_path,
249
- std:: iter:: repeat( "_" ) . take( parameter_count) . collect:: <Vec <_>>( ) . join( ", " )
250
- )
251
- } ;
242
+ let trait_name =
243
+ if trait_generics. params . len ( ) <= trait_generics. has_self as usize {
244
+ trait_path
245
+ } else {
246
+ let counts = trait_generics. own_counts ( ) ;
247
+ format ! (
248
+ "{}<{}>" ,
249
+ trait_path,
250
+ std:: iter:: repeat( "'_" )
251
+ . take( counts. lifetimes)
252
+ . chain( std:: iter:: repeat( "_" ) . take(
253
+ counts. types + counts. consts - trait_generics. has_self as usize
254
+ ) )
255
+ . collect:: <Vec <_>>( )
256
+ . join( ", " )
257
+ )
258
+ } ;
252
259
253
260
let mut lint = lint. build ( & format ! (
254
261
"trait-associated function `{}` will become ambiguous in Rust 2021" ,
255
262
method_name. name
256
263
) ) ;
257
264
258
- let self_ty_name = self
265
+ let mut self_ty_name = self
259
266
. sess ( )
260
267
. source_map ( )
261
268
. span_to_snippet ( self_ty_span)
262
269
. unwrap_or_else ( |_| self_ty. to_string ( ) ) ;
263
270
264
- let self_ty_generics_count = match self_ty. kind ( ) {
265
- // Get the number of generics the self type has (if an Adt) unless we can determine that
266
- // the user has written the self type with generics already which we (naively) do by looking
267
- // for a "<" in `self_ty_name`.
268
- Adt ( def, _) if !self_ty_name. contains ( '<' ) => self . tcx . generics_of ( def. did ) . count ( ) ,
269
- _ => 0 ,
270
- } ;
271
- let self_ty_generics = if self_ty_generics_count > 0 {
272
- format ! ( "<{}>" , vec![ "_" ; self_ty_generics_count] . join( ", " ) )
273
- } else {
274
- String :: new ( )
275
- } ;
271
+ // Get the number of generics the self type has (if an Adt) unless we can determine that
272
+ // the user has written the self type with generics already which we (naively) do by looking
273
+ // for a "<" in `self_ty_name`.
274
+ if !self_ty_name. contains ( '<' ) {
275
+ if let Adt ( def, _) = self_ty. kind ( ) {
276
+ let generics = self . tcx . generics_of ( def. did ) ;
277
+ if !generics. params . is_empty ( ) {
278
+ let counts = generics. own_counts ( ) ;
279
+ self_ty_name += & format ! (
280
+ "<{}>" ,
281
+ std:: iter:: repeat( "'_" )
282
+ . take( counts. lifetimes)
283
+ . chain( std:: iter:: repeat( "_" ) . take( counts. types + counts. consts) )
284
+ . collect:: <Vec <_>>( )
285
+ . join( ", " )
286
+ ) ;
287
+ }
288
+ }
289
+ }
276
290
lint. span_suggestion (
277
291
span,
278
292
"disambiguate the associated function" ,
279
- format ! (
280
- "<{}{} as {}>::{}" ,
281
- self_ty_name, self_ty_generics, trait_name, method_name. name,
282
- ) ,
293
+ format ! ( "<{} as {}>::{}" , self_ty_name, trait_name, method_name. name, ) ,
283
294
Applicability :: MachineApplicable ,
284
295
) ;
285
296
0 commit comments