@@ -222,15 +222,12 @@ enum LifetimeRibKind {
222
222
/// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
223
223
AnonConst ,
224
224
225
- /// For **Modern** cases, create a new anonymous region parameter
226
- /// and reference that.
227
- ///
228
- /// For **Dyn Bound** cases, pass responsibility to
229
- /// `resolve_lifetime` code.
230
- ///
231
- /// For **Deprecated** cases, report an error.
225
+ /// Create a new anonymous region parameter and reference that.
232
226
AnonymousCreateParameter ( NodeId ) ,
233
227
228
+ /// Give a hard error when generic lifetime arguments are elided.
229
+ ReportElidedInPath ,
230
+
234
231
/// Give a hard error when either `&` or `'_` is written. Used to
235
232
/// rule out things like `where T: Foo<'_>`. Does not imply an
236
233
/// error on default object bounds (e.g., `Box<dyn Foo>`).
@@ -746,8 +743,10 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
746
743
this. with_lifetime_rib (
747
744
LifetimeRibKind :: AnonymousCreateParameter ( fn_id) ,
748
745
|this| {
749
- // Add each argument to the rib.
750
- this. resolve_params ( & declaration. inputs )
746
+ this. with_lifetime_rib ( LifetimeRibKind :: ReportElidedInPath , |this| {
747
+ // Add each argument to the rib.
748
+ this. resolve_params ( & declaration. inputs )
749
+ } ) ;
751
750
} ,
752
751
) ;
753
752
@@ -1301,7 +1300,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1301
1300
let rib = & mut self . lifetime_ribs [ i] ;
1302
1301
match rib. kind {
1303
1302
LifetimeRibKind :: AnonymousCreateParameter ( item_node_id) => {
1304
- self . create_fresh_lifetime ( lifetime. id , lifetime. ident , item_node_id) ;
1303
+ let region =
1304
+ self . create_fresh_lifetime ( lifetime. id , lifetime. ident , item_node_id) ;
1305
+ self . record_lifetime_res ( lifetime. id , region) ;
1305
1306
return ;
1306
1307
}
1307
1308
LifetimeRibKind :: AnonymousReportError => {
@@ -1358,7 +1359,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1358
1359
}
1359
1360
1360
1361
#[ tracing:: instrument( level = "debug" , skip( self ) ) ]
1361
- fn create_fresh_lifetime ( & mut self , id : NodeId , ident : Ident , item_node_id : NodeId ) {
1362
+ fn create_fresh_lifetime (
1363
+ & mut self ,
1364
+ id : NodeId ,
1365
+ ident : Ident ,
1366
+ item_node_id : NodeId ,
1367
+ ) -> LifetimeRes {
1362
1368
debug_assert_eq ! ( ident. name, kw:: UnderscoreLifetime ) ;
1363
1369
debug ! ( ?ident. span) ;
1364
1370
let item_def_id = self . r . local_def_id ( item_node_id) ;
@@ -1373,12 +1379,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1373
1379
debug ! ( ?def_id) ;
1374
1380
1375
1381
let region = LifetimeRes :: Fresh { param : def_id, binder : item_node_id } ;
1376
- self . record_lifetime_res ( id, region) ;
1377
1382
self . r . extra_lifetime_params_map . entry ( item_node_id) . or_insert_with ( Vec :: new) . push ( (
1378
1383
ident,
1379
1384
def_node_id,
1380
1385
region,
1381
1386
) ) ;
1387
+ region
1382
1388
}
1383
1389
1384
1390
#[ tracing:: instrument( level = "debug" , skip( self ) ) ]
@@ -1391,7 +1397,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1391
1397
path_span : Span ,
1392
1398
) {
1393
1399
let proj_start = path. len ( ) - partial_res. unresolved_segments ( ) ;
1394
- for ( i, segment) in path. iter ( ) . enumerate ( ) {
1400
+ ' segment : for ( i, segment) in path. iter ( ) . enumerate ( ) {
1395
1401
if segment. has_lifetime_args {
1396
1402
continue ;
1397
1403
}
@@ -1428,16 +1434,69 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1428
1434
| PathSource :: Struct
1429
1435
| PathSource :: TupleStruct ( ..) => false ,
1430
1436
} ;
1431
- let mut res = LifetimeRes :: Error ;
1437
+
1438
+ let node_ids = self . r . next_node_ids ( expected_lifetimes) ;
1439
+ self . record_lifetime_res (
1440
+ segment_id,
1441
+ LifetimeRes :: ElidedAnchor { start : node_ids. start , end : node_ids. end } ,
1442
+ ) ;
1443
+
1444
+ if !missing {
1445
+ for i in 0 ..expected_lifetimes {
1446
+ let id = node_ids. start . plus ( i) ;
1447
+ self . record_lifetime_res (
1448
+ id,
1449
+ LifetimeRes :: Anonymous { binder : DUMMY_NODE_ID , elided : true } ,
1450
+ ) ;
1451
+ }
1452
+ continue ;
1453
+ }
1454
+
1455
+ let elided_lifetime_span = if segment. has_generic_args {
1456
+ // If there are brackets, but not generic arguments, then use the opening bracket
1457
+ segment. args_span . with_hi ( segment. args_span . lo ( ) + BytePos ( 1 ) )
1458
+ } else {
1459
+ // If there are no brackets, use the identifier span.
1460
+ // HACK: we use find_ancestor_inside to properly suggest elided spans in paths
1461
+ // originating from macros, since the segment's span might be from a macro arg.
1462
+ segment. ident . span . find_ancestor_inside ( path_span) . unwrap_or ( path_span)
1463
+ } ;
1464
+
1432
1465
for rib in self . lifetime_ribs . iter ( ) . rev ( ) {
1433
1466
match rib. kind {
1434
- // In create-parameter mode we error here because we don't want to support
1435
- // deprecated impl elision in new features like impl elision and `async fn`,
1436
- // both of which work using the `CreateParameter` mode:
1437
- //
1438
- // impl Foo for std::cell::Ref<u32> // note lack of '_
1439
- // async fn foo(_: std::cell::Ref<u32>) { ... }
1440
- LifetimeRibKind :: AnonymousCreateParameter ( _) => {
1467
+ // We error here because we don't want to support deprecated impl elision in
1468
+ // new features like impl elision and `async fn`,
1469
+ LifetimeRibKind :: ReportElidedInPath => {
1470
+ let sess = self . r . session ;
1471
+ let mut err = rustc_errors:: struct_span_err!(
1472
+ sess,
1473
+ path_span,
1474
+ E0726 ,
1475
+ "implicit elided lifetime not allowed here"
1476
+ ) ;
1477
+ rustc_errors:: add_elided_lifetime_in_path_suggestion (
1478
+ sess. source_map ( ) ,
1479
+ & mut err,
1480
+ expected_lifetimes,
1481
+ path_span,
1482
+ !segment. has_generic_args ,
1483
+ elided_lifetime_span,
1484
+ ) ;
1485
+ err. note ( "assuming a `'static` lifetime..." ) ;
1486
+ err. emit ( ) ;
1487
+ for i in 0 ..expected_lifetimes {
1488
+ let id = node_ids. start . plus ( i) ;
1489
+ self . record_lifetime_res ( id, LifetimeRes :: Error ) ;
1490
+ }
1491
+ continue ' segment;
1492
+ }
1493
+ LifetimeRibKind :: AnonymousCreateParameter ( binder) => {
1494
+ let ident = Ident :: new ( kw:: UnderscoreLifetime , elided_lifetime_span) ;
1495
+ for i in 0 ..expected_lifetimes {
1496
+ let id = node_ids. start . plus ( i) ;
1497
+ let res = self . create_fresh_lifetime ( id, ident, binder) ;
1498
+ self . record_lifetime_res ( id, res) ;
1499
+ }
1441
1500
break ;
1442
1501
}
1443
1502
// `PassThrough` is the normal case.
@@ -1447,75 +1506,40 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1447
1506
// lifetime. Instead, we simply create an implicit lifetime, which will be checked
1448
1507
// later, at which point a suitable error will be emitted.
1449
1508
LifetimeRibKind :: AnonymousPassThrough ( binder, _) => {
1450
- res = LifetimeRes :: Anonymous { binder, elided : true } ;
1509
+ let res = LifetimeRes :: Anonymous { binder, elided : true } ;
1510
+ for i in 0 ..expected_lifetimes {
1511
+ let id = node_ids. start . plus ( i) ;
1512
+ self . record_lifetime_res ( id, res) ;
1513
+ }
1451
1514
break ;
1452
1515
}
1453
1516
LifetimeRibKind :: AnonymousReportError | LifetimeRibKind :: Item => {
1454
1517
// FIXME(cjgillot) This resolution is wrong, but this does not matter
1455
1518
// since these cases are erroneous anyway. Lifetime resolution should
1456
1519
// emit a "missing lifetime specifier" diagnostic.
1457
- res = LifetimeRes :: Anonymous { binder : DUMMY_NODE_ID , elided : true } ;
1520
+ let res = LifetimeRes :: Anonymous { binder : DUMMY_NODE_ID , elided : true } ;
1521
+ for i in 0 ..expected_lifetimes {
1522
+ let id = node_ids. start . plus ( i) ;
1523
+ self . record_lifetime_res ( id, res) ;
1524
+ }
1458
1525
break ;
1459
1526
}
1460
1527
_ => { }
1461
1528
}
1462
1529
}
1463
1530
1464
- let node_ids = self . r . next_node_ids ( expected_lifetimes ) ;
1465
- self . record_lifetime_res (
1531
+ self . r . lint_buffer . buffer_lint_with_diagnostic (
1532
+ lint :: builtin :: ELIDED_LIFETIMES_IN_PATHS ,
1466
1533
segment_id,
1467
- LifetimeRes :: ElidedAnchor { start : node_ids. start , end : node_ids. end } ,
1468
- ) ;
1469
- for i in 0 ..expected_lifetimes {
1470
- let id = node_ids. start . plus ( i) ;
1471
- self . record_lifetime_res ( id, res) ;
1472
- }
1473
-
1474
- if !missing {
1475
- continue ;
1476
- }
1477
-
1478
- let elided_lifetime_span = if segment. has_generic_args {
1479
- // If there are brackets, but not generic arguments, then use the opening bracket
1480
- segment. args_span . with_hi ( segment. args_span . lo ( ) + BytePos ( 1 ) )
1481
- } else {
1482
- // If there are no brackets, use the identifier span.
1483
- // HACK: we use find_ancestor_inside to properly suggest elided spans in paths
1484
- // originating from macros, since the segment's span might be from a macro arg.
1485
- segment. ident . span . find_ancestor_inside ( path_span) . unwrap_or ( path_span)
1486
- } ;
1487
- if let LifetimeRes :: Error = res {
1488
- let sess = self . r . session ;
1489
- let mut err = rustc_errors:: struct_span_err!(
1490
- sess,
1491
- path_span,
1492
- E0726 ,
1493
- "implicit elided lifetime not allowed here"
1494
- ) ;
1495
- rustc_errors:: add_elided_lifetime_in_path_suggestion (
1496
- sess. source_map ( ) ,
1497
- & mut err,
1534
+ elided_lifetime_span,
1535
+ "hidden lifetime parameters in types are deprecated" ,
1536
+ lint:: BuiltinLintDiagnostics :: ElidedLifetimesInPaths (
1498
1537
expected_lifetimes,
1499
1538
path_span,
1500
1539
!segment. has_generic_args ,
1501
1540
elided_lifetime_span,
1502
- ) ;
1503
- err. note ( "assuming a `'static` lifetime..." ) ;
1504
- err. emit ( ) ;
1505
- } else {
1506
- self . r . lint_buffer . buffer_lint_with_diagnostic (
1507
- lint:: builtin:: ELIDED_LIFETIMES_IN_PATHS ,
1508
- segment_id,
1509
- elided_lifetime_span,
1510
- "hidden lifetime parameters in types are deprecated" ,
1511
- lint:: BuiltinLintDiagnostics :: ElidedLifetimesInPaths (
1512
- expected_lifetimes,
1513
- path_span,
1514
- !segment. has_generic_args ,
1515
- elided_lifetime_span,
1516
- ) ,
1517
- ) ;
1518
- }
1541
+ ) ,
1542
+ ) ;
1519
1543
}
1520
1544
}
1521
1545
@@ -2072,12 +2096,14 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
2072
2096
let mut new_id = None ;
2073
2097
if let Some ( trait_ref) = opt_trait_ref {
2074
2098
let path: Vec < _ > = Segment :: from_path ( & trait_ref. path ) ;
2075
- let res = self . smart_resolve_path_fragment (
2076
- None ,
2077
- & path,
2078
- PathSource :: Trait ( AliasPossibility :: No ) ,
2079
- Finalize :: new ( trait_ref. ref_id , trait_ref. path . span ) ,
2080
- ) ;
2099
+ let res = self . with_lifetime_rib ( LifetimeRibKind :: ReportElidedInPath , |this| {
2100
+ this. smart_resolve_path_fragment (
2101
+ None ,
2102
+ & path,
2103
+ PathSource :: Trait ( AliasPossibility :: No ) ,
2104
+ Finalize :: new ( trait_ref. ref_id , trait_ref. path . span ) ,
2105
+ )
2106
+ } ) ;
2081
2107
if let Some ( def_id) = res. base_res ( ) . opt_def_id ( ) {
2082
2108
new_id = Some ( def_id) ;
2083
2109
new_val = Some ( ( self . r . expect_module ( def_id) , trait_ref. clone ( ) ) ) ;
@@ -2130,14 +2156,16 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
2130
2156
let res =
2131
2157
Res :: SelfTy { trait_ : trait_id, alias_to : Some ( ( item_def_id, false ) ) } ;
2132
2158
this. with_self_rib ( res, |this| {
2133
- if let Some ( trait_ref) = opt_trait_reference. as_ref ( ) {
2134
- // Resolve type arguments in the trait path.
2135
- visit:: walk_trait_ref ( this, trait_ref) ;
2136
- }
2137
- // Resolve the self type.
2138
- this. visit_ty ( self_type) ;
2139
- // Resolve the generic parameters.
2140
- this. visit_generics ( generics) ;
2159
+ this. with_lifetime_rib ( LifetimeRibKind :: ReportElidedInPath , |this| {
2160
+ if let Some ( trait_ref) = opt_trait_reference. as_ref ( ) {
2161
+ // Resolve type arguments in the trait path.
2162
+ visit:: walk_trait_ref ( this, trait_ref) ;
2163
+ }
2164
+ // Resolve the self type.
2165
+ this. visit_ty ( self_type) ;
2166
+ // Resolve the generic parameters.
2167
+ this. visit_generics ( generics) ;
2168
+ } ) ;
2141
2169
2142
2170
// Resolve the items within the impl.
2143
2171
this. with_lifetime_rib ( LifetimeRibKind :: AnonymousPassThrough ( item_id, false ) ,
0 commit comments