@@ -153,6 +153,10 @@ pub struct NamedRegionMap {
153
153
// (b) it DOES appear in the arguments.
154
154
pub late_bound : NodeSet ,
155
155
156
+ // Contains the node-ids for lifetimes that were (incorrectly) categorized
157
+ // as late-bound, until #32330 was fixed.
158
+ pub issue_32330 : NodeMap < ty:: Issue32330 > ,
159
+
156
160
// For each type and trait definition, maps type parameters
157
161
// to the trait object lifetime defaults computed from them.
158
162
pub object_lifetime_defaults : NodeMap < Vec < ObjectLifetimeDefault > > ,
@@ -257,6 +261,7 @@ pub fn krate(sess: &Session,
257
261
let mut map = NamedRegionMap {
258
262
defs : NodeMap ( ) ,
259
263
late_bound : NodeSet ( ) ,
264
+ issue_32330 : NodeMap ( ) ,
260
265
object_lifetime_defaults : compute_object_lifetime_defaults ( sess, hir_map) ,
261
266
} ;
262
267
sess. track_errors ( || {
@@ -298,7 +303,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
298
303
fn visit_item ( & mut self , item : & ' tcx hir:: Item ) {
299
304
match item. node {
300
305
hir:: ItemFn ( ref decl, _, _, _, ref generics, _) => {
301
- self . visit_early_late ( None , decl, generics, |this| {
306
+ self . visit_early_late ( item . id , None , decl, generics, |this| {
302
307
intravisit:: walk_item ( this, item) ;
303
308
} ) ;
304
309
}
@@ -350,7 +355,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
350
355
fn visit_foreign_item ( & mut self , item : & ' tcx hir:: ForeignItem ) {
351
356
match item. node {
352
357
hir:: ForeignItemFn ( ref decl, _, ref generics) => {
353
- self . visit_early_late ( None , decl, generics, |this| {
358
+ self . visit_early_late ( item . id , None , decl, generics, |this| {
354
359
intravisit:: walk_foreign_item ( this, item) ;
355
360
} )
356
361
}
@@ -401,6 +406,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
401
406
fn visit_trait_item ( & mut self , trait_item : & ' tcx hir:: TraitItem ) {
402
407
if let hir:: TraitItemKind :: Method ( ref sig, _) = trait_item. node {
403
408
self . visit_early_late (
409
+ trait_item. id ,
404
410
Some ( self . hir_map . get_parent ( trait_item. id ) ) ,
405
411
& sig. decl , & sig. generics ,
406
412
|this| intravisit:: walk_trait_item ( this, trait_item) )
@@ -412,6 +418,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
412
418
fn visit_impl_item ( & mut self , impl_item : & ' tcx hir:: ImplItem ) {
413
419
if let hir:: ImplItemKind :: Method ( ref sig, _) = impl_item. node {
414
420
self . visit_early_late (
421
+ impl_item. id ,
415
422
Some ( self . hir_map . get_parent ( impl_item. id ) ) ,
416
423
& sig. decl , & sig. generics ,
417
424
|this| intravisit:: walk_impl_item ( this, impl_item) )
@@ -804,13 +811,18 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
804
811
/// bound lifetimes are resolved by name and associated with a binder id (`binder_id`), so the
805
812
/// ordering is not important there.
806
813
fn visit_early_late < F > ( & mut self ,
814
+ fn_id : ast:: NodeId ,
807
815
parent_id : Option < ast:: NodeId > ,
808
816
decl : & ' tcx hir:: FnDecl ,
809
817
generics : & ' tcx hir:: Generics ,
810
818
walk : F ) where
811
819
F : for <' b , ' c > FnOnce ( & ' b mut LifetimeContext < ' c , ' tcx > ) ,
812
820
{
813
- insert_late_bound_lifetimes ( self . map , decl, generics) ;
821
+ let fn_def_id = self . hir_map . local_def_id ( fn_id) ;
822
+ insert_late_bound_lifetimes ( self . map ,
823
+ fn_def_id,
824
+ decl,
825
+ generics) ;
814
826
815
827
// Find the start of nested early scopes, e.g. in methods.
816
828
let mut index = 0 ;
@@ -1522,6 +1534,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
1522
1534
/// not amongst the inputs to a projection. In other words, `<&'a
1523
1535
/// T as Trait<''b>>::Foo` does not constrain `'a` or `'b`.
1524
1536
fn insert_late_bound_lifetimes ( map : & mut NamedRegionMap ,
1537
+ fn_def_id : DefId ,
1525
1538
decl : & hir:: FnDecl ,
1526
1539
generics : & hir:: Generics ) {
1527
1540
debug ! ( "insert_late_bound_lifetimes(decl={:?}, generics={:?})" , decl, generics) ;
@@ -1579,9 +1592,22 @@ fn insert_late_bound_lifetimes(map: &mut NamedRegionMap,
1579
1592
// any `impl Trait` in the return type? early-bound.
1580
1593
if appears_in_output. impl_trait { continue ; }
1581
1594
1582
- // does not appear in the inputs, but appears in the return type? early-bound.
1583
- if !constrained_by_input. regions . contains ( & name) &&
1584
- appears_in_output. regions . contains ( & name) {
1595
+ // does not appear in the inputs, but appears in the return
1596
+ // type? eventually this will be early-bound, but for now we
1597
+ // just mark it so we can issue warnings.
1598
+ let constrained_by_input = constrained_by_input. regions . contains ( & name) ;
1599
+ let appears_in_output = appears_in_output. regions . contains ( & name) ;
1600
+ if !constrained_by_input && appears_in_output {
1601
+ debug ! ( "inserting issue_32330 entry for {:?}, {:?} on {:?}" ,
1602
+ lifetime. lifetime. id,
1603
+ name,
1604
+ fn_def_id) ;
1605
+ map. issue_32330 . insert (
1606
+ lifetime. lifetime . id ,
1607
+ ty:: Issue32330 {
1608
+ fn_def_id,
1609
+ region_name : name,
1610
+ } ) ;
1585
1611
continue ;
1586
1612
}
1587
1613
0 commit comments