@@ -153,6 +153,10 @@ pub struct NamedRegionMap {
153153 // (b) it DOES appear in the arguments.
154154 pub late_bound : NodeSet ,
155155
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+
156160 // For each type and trait definition, maps type parameters
157161 // to the trait object lifetime defaults computed from them.
158162 pub object_lifetime_defaults : NodeMap < Vec < ObjectLifetimeDefault > > ,
@@ -257,6 +261,7 @@ pub fn krate(sess: &Session,
257261 let mut map = NamedRegionMap {
258262 defs : NodeMap ( ) ,
259263 late_bound : NodeSet ( ) ,
264+ issue_32330 : NodeMap ( ) ,
260265 object_lifetime_defaults : compute_object_lifetime_defaults ( sess, hir_map) ,
261266 } ;
262267 sess. track_errors ( || {
@@ -298,7 +303,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
298303 fn visit_item ( & mut self , item : & ' tcx hir:: Item ) {
299304 match item. node {
300305 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| {
302307 intravisit:: walk_item ( this, item) ;
303308 } ) ;
304309 }
@@ -350,7 +355,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
350355 fn visit_foreign_item ( & mut self , item : & ' tcx hir:: ForeignItem ) {
351356 match item. node {
352357 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| {
354359 intravisit:: walk_foreign_item ( this, item) ;
355360 } )
356361 }
@@ -401,6 +406,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
401406 fn visit_trait_item ( & mut self , trait_item : & ' tcx hir:: TraitItem ) {
402407 if let hir:: TraitItemKind :: Method ( ref sig, _) = trait_item. node {
403408 self . visit_early_late (
409+ trait_item. id ,
404410 Some ( self . hir_map . get_parent ( trait_item. id ) ) ,
405411 & sig. decl , & sig. generics ,
406412 |this| intravisit:: walk_trait_item ( this, trait_item) )
@@ -412,6 +418,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
412418 fn visit_impl_item ( & mut self , impl_item : & ' tcx hir:: ImplItem ) {
413419 if let hir:: ImplItemKind :: Method ( ref sig, _) = impl_item. node {
414420 self . visit_early_late (
421+ impl_item. id ,
415422 Some ( self . hir_map . get_parent ( impl_item. id ) ) ,
416423 & sig. decl , & sig. generics ,
417424 |this| intravisit:: walk_impl_item ( this, impl_item) )
@@ -804,13 +811,18 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
804811 /// bound lifetimes are resolved by name and associated with a binder id (`binder_id`), so the
805812 /// ordering is not important there.
806813 fn visit_early_late < F > ( & mut self ,
814+ fn_id : ast:: NodeId ,
807815 parent_id : Option < ast:: NodeId > ,
808816 decl : & ' tcx hir:: FnDecl ,
809817 generics : & ' tcx hir:: Generics ,
810818 walk : F ) where
811819 F : for <' b , ' c > FnOnce ( & ' b mut LifetimeContext < ' c , ' tcx > ) ,
812820 {
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) ;
814826
815827 // Find the start of nested early scopes, e.g. in methods.
816828 let mut index = 0 ;
@@ -1522,6 +1534,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
15221534/// not amongst the inputs to a projection. In other words, `<&'a
15231535/// T as Trait<''b>>::Foo` does not constrain `'a` or `'b`.
15241536fn insert_late_bound_lifetimes ( map : & mut NamedRegionMap ,
1537+ fn_def_id : DefId ,
15251538 decl : & hir:: FnDecl ,
15261539 generics : & hir:: Generics ) {
15271540 debug ! ( "insert_late_bound_lifetimes(decl={:?}, generics={:?})" , decl, generics) ;
@@ -1579,9 +1592,22 @@ fn insert_late_bound_lifetimes(map: &mut NamedRegionMap,
15791592 // any `impl Trait` in the return type? early-bound.
15801593 if appears_in_output. impl_trait { continue ; }
15811594
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+ } ) ;
15851611 continue ;
15861612 }
15871613
0 commit comments