@@ -315,6 +315,11 @@ enum AnonymousLifetimeMode {
315
315
/// For **Deprecated** cases, report an error.
316
316
CreateParameter ,
317
317
318
+ /// Give a hard error when either `&` or `'_` is written. Used to
319
+ /// rule out things like `where T: Foo<'_>`. Does not imply an
320
+ /// error on default object bounds (e.g., `Box<dyn Foo>`).
321
+ ReportError ,
322
+
318
323
/// Pass responsibility to `resolve_lifetime` code for all cases.
319
324
PassThrough ,
320
325
}
@@ -735,6 +740,10 @@ impl<'a> LoweringContext<'a> {
735
740
keywords:: UnderscoreLifetime . name ( ) . as_interned_str ( ) ,
736
741
hir:: LifetimeParamKind :: Elided ,
737
742
) ,
743
+ ParamName :: Error => (
744
+ keywords:: UnderscoreLifetime . name ( ) . as_interned_str ( ) ,
745
+ hir:: LifetimeParamKind :: Error ,
746
+ ) ,
738
747
} ;
739
748
740
749
// Add a definition for the in-band lifetime def
@@ -791,7 +800,7 @@ impl<'a> LoweringContext<'a> {
791
800
}
792
801
793
802
/// When we have either an elided or `'_` lifetime in an impl
794
- /// header, we convert it to
803
+ /// header, we convert it to an in-band lifetime.
795
804
fn collect_fresh_in_band_lifetime ( & mut self , span : Span ) -> ParamName {
796
805
assert ! ( self . is_collecting_in_band_lifetimes) ;
797
806
let index = self . lifetimes_to_define . len ( ) ;
@@ -1474,7 +1483,7 @@ impl<'a> LoweringContext<'a> {
1474
1483
}
1475
1484
}
1476
1485
hir:: LifetimeName :: Param ( _) => lifetime. name ,
1477
- hir:: LifetimeName :: Static => return ,
1486
+ hir:: LifetimeName :: Error | hir :: LifetimeName :: Static => return ,
1478
1487
} ;
1479
1488
1480
1489
if !self . currently_bound_lifetimes . contains ( & name)
@@ -2162,7 +2171,7 @@ impl<'a> LoweringContext<'a> {
2162
2171
}
2163
2172
}
2164
2173
hir:: LifetimeName :: Param ( _) => lifetime. name ,
2165
- hir:: LifetimeName :: Static => return ,
2174
+ hir:: LifetimeName :: Error | hir :: LifetimeName :: Static => return ,
2166
2175
} ;
2167
2176
2168
2177
if !self . currently_bound_lifetimes . contains ( & name) {
@@ -2293,10 +2302,12 @@ impl<'a> LoweringContext<'a> {
2293
2302
itctx : ImplTraitContext < ' _ > ,
2294
2303
) -> hir:: GenericBound {
2295
2304
match * tpb {
2296
- GenericBound :: Trait ( ref ty, modifier) => hir:: GenericBound :: Trait (
2297
- self . lower_poly_trait_ref ( ty, itctx) ,
2298
- self . lower_trait_bound_modifier ( modifier) ,
2299
- ) ,
2305
+ GenericBound :: Trait ( ref ty, modifier) => {
2306
+ hir:: GenericBound :: Trait (
2307
+ self . lower_poly_trait_ref ( ty, itctx) ,
2308
+ self . lower_trait_bound_modifier ( modifier) ,
2309
+ )
2310
+ }
2300
2311
GenericBound :: Outlives ( ref lifetime) => {
2301
2312
hir:: GenericBound :: Outlives ( self . lower_lifetime ( lifetime) )
2302
2313
}
@@ -2318,6 +2329,8 @@ impl<'a> LoweringContext<'a> {
2318
2329
AnonymousLifetimeMode :: PassThrough => {
2319
2330
self . new_named_lifetime ( l. id , span, hir:: LifetimeName :: Underscore )
2320
2331
}
2332
+
2333
+ AnonymousLifetimeMode :: ReportError => self . new_error_lifetime ( Some ( l. id ) , span) ,
2321
2334
} ,
2322
2335
ident => {
2323
2336
self . maybe_collect_in_band_lifetime ( ident) ;
@@ -2356,16 +2369,26 @@ impl<'a> LoweringContext<'a> {
2356
2369
add_bounds : & NodeMap < Vec < GenericBound > > ,
2357
2370
mut itctx : ImplTraitContext < ' _ > )
2358
2371
-> hir:: GenericParam {
2359
- let mut bounds = self . lower_param_bounds ( & param. bounds , itctx. reborrow ( ) ) ;
2372
+ let mut bounds = self . with_anonymous_lifetime_mode (
2373
+ AnonymousLifetimeMode :: ReportError ,
2374
+ |this| this. lower_param_bounds ( & param. bounds , itctx. reborrow ( ) ) ,
2375
+ ) ;
2376
+
2360
2377
match param. kind {
2361
2378
GenericParamKind :: Lifetime => {
2362
2379
let was_collecting_in_band = self . is_collecting_in_band_lifetimes ;
2363
2380
self . is_collecting_in_band_lifetimes = false ;
2364
2381
2365
- let lt = self . lower_lifetime ( & Lifetime { id : param. id , ident : param. ident } ) ;
2382
+ let lt = self . with_anonymous_lifetime_mode (
2383
+ AnonymousLifetimeMode :: ReportError ,
2384
+ |this| this. lower_lifetime ( & Lifetime { id : param. id , ident : param. ident } ) ,
2385
+ ) ;
2366
2386
let param_name = match lt. name {
2367
2387
hir:: LifetimeName :: Param ( param_name) => param_name,
2368
- _ => hir:: ParamName :: Plain ( lt. name . ident ( ) ) ,
2388
+ hir:: LifetimeName :: Implicit
2389
+ | hir:: LifetimeName :: Underscore
2390
+ | hir:: LifetimeName :: Static => hir:: ParamName :: Plain ( lt. name . ident ( ) ) ,
2391
+ hir:: LifetimeName :: Error => ParamName :: Error ,
2369
2392
} ;
2370
2393
let param = hir:: GenericParam {
2371
2394
id : lt. id ,
@@ -2489,13 +2512,18 @@ impl<'a> LoweringContext<'a> {
2489
2512
}
2490
2513
2491
2514
fn lower_where_clause ( & mut self , wc : & WhereClause ) -> hir:: WhereClause {
2492
- hir:: WhereClause {
2493
- id : self . lower_node_id ( wc. id ) . node_id ,
2494
- predicates : wc. predicates
2495
- . iter ( )
2496
- . map ( |predicate| self . lower_where_predicate ( predicate) )
2497
- . collect ( ) ,
2498
- }
2515
+ self . with_anonymous_lifetime_mode (
2516
+ AnonymousLifetimeMode :: ReportError ,
2517
+ |this| {
2518
+ hir:: WhereClause {
2519
+ id : this. lower_node_id ( wc. id ) . node_id ,
2520
+ predicates : wc. predicates
2521
+ . iter ( )
2522
+ . map ( |predicate| this. lower_where_predicate ( predicate) )
2523
+ . collect ( ) ,
2524
+ }
2525
+ } ,
2526
+ )
2499
2527
}
2500
2528
2501
2529
fn lower_where_predicate ( & mut self , pred : & WherePredicate ) -> hir:: WherePredicate {
@@ -4837,10 +4865,38 @@ impl<'a> LoweringContext<'a> {
4837
4865
}
4838
4866
}
4839
4867
4868
+ AnonymousLifetimeMode :: ReportError => self . new_error_lifetime ( None , span) ,
4869
+
4840
4870
AnonymousLifetimeMode :: PassThrough => self . new_implicit_lifetime ( span) ,
4841
4871
}
4842
4872
}
4843
4873
4874
+ /// Report an error on illegal use of `'_` or a `&T` with no explicit lifetime;
4875
+ /// return a "error lifetime".
4876
+ fn new_error_lifetime ( & mut self , id : Option < NodeId > , span : Span ) -> hir:: Lifetime {
4877
+ let ( id, msg, label) = match id {
4878
+ Some ( id) => ( id, "`'_` cannot be used here" , "`'_` is a reserved lifetime name" ) ,
4879
+
4880
+ None => (
4881
+ self . next_id ( ) . node_id ,
4882
+ "`&` without an explicit lifetime name cannot be used here" ,
4883
+ "explicit lifetime name needed here" ,
4884
+ ) ,
4885
+ } ;
4886
+
4887
+ let mut err = struct_span_err ! (
4888
+ self . sess,
4889
+ span,
4890
+ E0637 ,
4891
+ "{}" ,
4892
+ msg,
4893
+ ) ;
4894
+ err. span_label ( span, label) ;
4895
+ err. emit ( ) ;
4896
+
4897
+ self . new_named_lifetime ( id, span, hir:: LifetimeName :: Error )
4898
+ }
4899
+
4844
4900
/// Invoked to create the lifetime argument(s) for a path like
4845
4901
/// `std::cell::Ref<T>`; note that implicit lifetimes in these
4846
4902
/// sorts of cases are deprecated. This may therefore report a warning or an
@@ -4855,6 +4911,12 @@ impl<'a> LoweringContext<'a> {
4855
4911
// impl Foo for std::cell::Ref<u32> // note lack of '_
4856
4912
AnonymousLifetimeMode :: CreateParameter => { }
4857
4913
4914
+ AnonymousLifetimeMode :: ReportError => {
4915
+ return ( 0 ..count)
4916
+ . map ( |_| self . new_error_lifetime ( None , span) )
4917
+ . collect ( ) ;
4918
+ }
4919
+
4858
4920
// This is the normal case.
4859
4921
AnonymousLifetimeMode :: PassThrough => { }
4860
4922
}
@@ -4885,6 +4947,10 @@ impl<'a> LoweringContext<'a> {
4885
4947
// `resolve_lifetime` has the code to make that happen.
4886
4948
AnonymousLifetimeMode :: CreateParameter => { }
4887
4949
4950
+ AnonymousLifetimeMode :: ReportError => {
4951
+ // ReportError applies to explicit use of `'_`.
4952
+ }
4953
+
4888
4954
// This is the normal case.
4889
4955
AnonymousLifetimeMode :: PassThrough => { }
4890
4956
}
0 commit comments