@@ -10,7 +10,7 @@ use rustc_hir::GenericArg;
10
10
use rustc_session:: lint:: builtin:: ELIDED_LIFETIMES_IN_PATHS ;
11
11
use rustc_session:: lint:: BuiltinLintDiagnostics ;
12
12
use rustc_span:: symbol:: Ident ;
13
- use rustc_span:: Span ;
13
+ use rustc_span:: { BytePos , Span , DUMMY_SP } ;
14
14
15
15
use smallvec:: smallvec;
16
16
use tracing:: debug;
@@ -267,23 +267,34 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
267
267
} ,
268
268
}
269
269
} else {
270
- self . lower_angle_bracketed_parameter_data ( & Default :: default ( ) , param_mode, itctx)
270
+ (
271
+ GenericArgsCtor {
272
+ args : Default :: default ( ) ,
273
+ bindings : & [ ] ,
274
+ parenthesized : false ,
275
+ span : path_span. shrink_to_hi ( ) ,
276
+ } ,
277
+ param_mode == ParamMode :: Optional ,
278
+ )
271
279
} ;
272
280
273
281
let has_lifetimes =
274
282
generic_args. args . iter ( ) . any ( |arg| matches ! ( arg, GenericArg :: Lifetime ( _) ) ) ;
275
- let first_generic_span = generic_args
276
- . args
277
- . iter ( )
278
- . map ( |a| a. span ( ) )
279
- . chain ( generic_args. bindings . iter ( ) . map ( |b| b. span ) )
280
- . next ( ) ;
281
283
if !generic_args. parenthesized && !has_lifetimes {
284
+ // Note: these spans are used for diagnostics when they can't be inferred.
285
+ // See rustc_resolve::late::lifetimes::LifetimeContext::add_missing_lifetime_specifiers_label
286
+ let elided_lifetime_span = if generic_args. span . is_empty ( ) {
287
+ // If there are no brackets, use the identifier span.
288
+ segment. ident . span
289
+ } else if generic_args. is_empty ( ) {
290
+ // If there are brackets, but not generic arguments, then use the opening bracket
291
+ generic_args. span . with_hi ( generic_args. span . lo ( ) + BytePos ( 1 ) )
292
+ } else {
293
+ // Else use an empty span right after the opening bracket.
294
+ generic_args. span . with_lo ( generic_args. span . lo ( ) + BytePos ( 1 ) ) . shrink_to_lo ( )
295
+ } ;
282
296
generic_args. args = self
283
- . elided_path_lifetimes (
284
- first_generic_span. map_or ( segment. ident . span , |s| s. shrink_to_lo ( ) ) ,
285
- expected_lifetimes,
286
- )
297
+ . elided_path_lifetimes ( elided_lifetime_span, expected_lifetimes)
287
298
. map ( GenericArg :: Lifetime )
288
299
. chain ( generic_args. args . into_iter ( ) )
289
300
. collect ( ) ;
@@ -292,15 +303,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
292
303
let no_non_lt_args = generic_args. args . len ( ) == expected_lifetimes;
293
304
let no_bindings = generic_args. bindings . is_empty ( ) ;
294
305
let ( incl_angl_brckt, insertion_sp, suggestion) = if no_non_lt_args && no_bindings {
295
- // If there are no (non-implicit) generic args or associated type
296
- // bindings, our suggestion includes the angle brackets.
306
+ // If there are no generic args, our suggestion can include the angle brackets.
297
307
( true , path_span. shrink_to_hi ( ) , format ! ( "<{}>" , anon_lt_suggestion) )
298
308
} else {
299
- // Otherwise (sorry, this is kind of gross) we need to infer the
300
- // place to splice in the `'_, ` from the generics that do exist.
301
- let first_generic_span = first_generic_span
302
- . expect ( "already checked that non-lifetime args or bindings exist" ) ;
303
- ( false , first_generic_span. shrink_to_lo ( ) , format ! ( "{}, " , anon_lt_suggestion) )
309
+ // Otherwise we'll insert a `'_, ` right after the opening bracket.
310
+ let span = generic_args
311
+ . span
312
+ . with_lo ( generic_args. span . lo ( ) + BytePos ( 1 ) )
313
+ . shrink_to_lo ( ) ;
314
+ ( false , span, format ! ( "{}, " , anon_lt_suggestion) )
304
315
} ;
305
316
match self . anonymous_lifetime_mode {
306
317
// In create-parameter mode we error here because we don't want to support
@@ -362,7 +373,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
362
373
hir_id : Some ( id) ,
363
374
res : Some ( self . lower_res ( res) ) ,
364
375
infer_args,
365
- args : if generic_args. is_empty ( ) {
376
+ args : if generic_args. is_empty ( ) && generic_args . span . is_empty ( ) {
366
377
None
367
378
} else {
368
379
Some ( self . arena . alloc ( generic_args. into_generic_args ( self . arena ) ) )
@@ -395,7 +406,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
395
406
}
396
407
AngleBracketedArg :: Arg ( _) => None ,
397
408
} ) ) ;
398
- let ctor = GenericArgsCtor { args, bindings, parenthesized : false } ;
409
+ let ctor = GenericArgsCtor { args, bindings, parenthesized : false , span : data . span } ;
399
410
( ctor, !has_non_lt_args && param_mode == ParamMode :: Optional )
400
411
}
401
412
@@ -420,7 +431,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
420
431
let args = smallvec ! [ GenericArg :: Type ( this. ty_tup( * inputs_span, inputs) ) ] ;
421
432
let binding = this. output_ty_binding ( output_ty. span , output_ty) ;
422
433
(
423
- GenericArgsCtor { args, bindings : arena_vec ! [ this; binding] , parenthesized : true } ,
434
+ GenericArgsCtor {
435
+ args,
436
+ bindings : arena_vec ! [ this; binding] ,
437
+ parenthesized : true ,
438
+ span : data. inputs_span ,
439
+ } ,
424
440
false ,
425
441
)
426
442
} )
@@ -436,7 +452,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
436
452
let kind = hir:: TypeBindingKind :: Equality { ty } ;
437
453
let args = arena_vec ! [ self ; ] ;
438
454
let bindings = arena_vec ! [ self ; ] ;
439
- let gen_args = self . arena . alloc ( hir:: GenericArgs { args, bindings, parenthesized : false } ) ;
455
+ let gen_args = self . arena . alloc ( hir:: GenericArgs {
456
+ args,
457
+ bindings,
458
+ parenthesized : false ,
459
+ span_ext : DUMMY_SP ,
460
+ } ) ;
440
461
hir:: TypeBinding { hir_id : self . next_id ( ) , gen_args, span, ident, kind }
441
462
}
442
463
}
0 commit comments