@@ -1664,6 +1664,7 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
16641664 intravisit:: NestedVisitorMap :: All ( & self . tcx . hir ( ) )
16651665 }
16661666 fn visit_item ( & mut self , it : & ' tcx Item ) {
1667+ debug ! ( "find_existential_constraints: visiting {:?}" , it) ;
16671668 let def_id = self . tcx . hir ( ) . local_def_id ( it. hir_id ) ;
16681669 // The existential type itself or its children are not within its reveal scope.
16691670 if def_id != self . def_id {
@@ -1672,6 +1673,7 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
16721673 }
16731674 }
16741675 fn visit_impl_item ( & mut self , it : & ' tcx ImplItem ) {
1676+ debug ! ( "find_existential_constraints: visiting {:?}" , it) ;
16751677 let def_id = self . tcx . hir ( ) . local_def_id ( it. hir_id ) ;
16761678 // The existential type itself or its children are not within its reveal scope.
16771679 if def_id != self . def_id {
@@ -1680,6 +1682,7 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
16801682 }
16811683 }
16821684 fn visit_trait_item ( & mut self , it : & ' tcx TraitItem ) {
1685+ debug ! ( "find_existential_constraints: visiting {:?}" , it) ;
16831686 let def_id = self . tcx . hir ( ) . local_def_id ( it. hir_id ) ;
16841687 self . check ( def_id) ;
16851688 intravisit:: walk_trait_item ( self , it) ;
@@ -1703,9 +1706,23 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
17031706 } else {
17041707 debug ! ( "find_existential_constraints: scope={:?}" , tcx. hir( ) . get( scope) ) ;
17051708 match tcx. hir ( ) . get ( scope) {
1706- Node :: Item ( ref it) => intravisit:: walk_item ( & mut locator, it) ,
1707- Node :: ImplItem ( ref it) => intravisit:: walk_impl_item ( & mut locator, it) ,
1708- Node :: TraitItem ( ref it) => intravisit:: walk_trait_item ( & mut locator, it) ,
1709+ // We explicitly call `visit_*` methods, instead of using `intravisit::walk_*` methods
1710+ // This allows our visitor to process the defining item itself, causing
1711+ // it to pick up any 'sibling' defining uses.
1712+ //
1713+ // For example, this code:
1714+ // ```
1715+ // fn foo() {
1716+ // existential type Blah: Debug;
1717+ // let my_closure = || -> Blah { true };
1718+ // }
1719+ // ```
1720+ //
1721+ // requires us to explicitly process `foo()` in order
1722+ // to notice the defining usage of `Blah`.
1723+ Node :: Item ( ref it) => locator. visit_item ( it) ,
1724+ Node :: ImplItem ( ref it) => locator. visit_impl_item ( it) ,
1725+ Node :: TraitItem ( ref it) => locator. visit_trait_item ( it) ,
17091726 other => bug ! (
17101727 "{:?} is not a valid scope for an existential type item" ,
17111728 other
0 commit comments