@@ -1664,6 +1664,7 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
1664
1664
intravisit:: NestedVisitorMap :: All ( & self . tcx . hir ( ) )
1665
1665
}
1666
1666
fn visit_item ( & mut self , it : & ' tcx Item ) {
1667
+ debug ! ( "find_existential_constraints: visiting {:?}" , it) ;
1667
1668
let def_id = self . tcx . hir ( ) . local_def_id ( it. hir_id ) ;
1668
1669
// The existential type itself or its children are not within its reveal scope.
1669
1670
if def_id != self . def_id {
@@ -1672,6 +1673,7 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
1672
1673
}
1673
1674
}
1674
1675
fn visit_impl_item ( & mut self , it : & ' tcx ImplItem ) {
1676
+ debug ! ( "find_existential_constraints: visiting {:?}" , it) ;
1675
1677
let def_id = self . tcx . hir ( ) . local_def_id ( it. hir_id ) ;
1676
1678
// The existential type itself or its children are not within its reveal scope.
1677
1679
if def_id != self . def_id {
@@ -1680,6 +1682,7 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
1680
1682
}
1681
1683
}
1682
1684
fn visit_trait_item ( & mut self , it : & ' tcx TraitItem ) {
1685
+ debug ! ( "find_existential_constraints: visiting {:?}" , it) ;
1683
1686
let def_id = self . tcx . hir ( ) . local_def_id ( it. hir_id ) ;
1684
1687
self . check ( def_id) ;
1685
1688
intravisit:: walk_trait_item ( self , it) ;
@@ -1703,9 +1706,23 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
1703
1706
} else {
1704
1707
debug ! ( "find_existential_constraints: scope={:?}" , tcx. hir( ) . get( scope) ) ;
1705
1708
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) ,
1709
1726
other => bug ! (
1710
1727
"{:?} is not a valid scope for an existential type item" ,
1711
1728
other
0 commit comments