@@ -153,17 +153,13 @@ pub struct Map<'hir> {
153153 hir_to_node_id : FxHashMap < HirId , NodeId > ,
154154}
155155
156- struct ParentHirIterator < ' map , ' hir > {
156+ /// An iterator that walks up the ancestor tree of a given `HirId`.
157+ /// Constructed using `tcx.hir().parent_iter(hir_id)`.
158+ pub struct ParentHirIterator < ' map , ' hir > {
157159 current_id : HirId ,
158160 map : & ' map Map < ' hir > ,
159161}
160162
161- impl < ' map , ' hir > ParentHirIterator < ' map , ' hir > {
162- fn new ( current_id : HirId , map : & ' map Map < ' hir > ) -> Self {
163- Self { current_id, map }
164- }
165- }
166-
167163impl < ' hir > Iterator for ParentHirIterator < ' _ , ' hir > {
168164 type Item = ( HirId , Node < ' hir > ) ;
169165
@@ -618,6 +614,12 @@ impl<'hir> Map<'hir> {
618614 self . find_entry ( hir_id) . and_then ( |x| x. parent_node ( ) ) . unwrap_or ( hir_id)
619615 }
620616
617+ /// Returns an iterator for the nodes in the ancestor tree of the `current_id`
618+ /// until the crate root is reached. Prefer this over your own loop using `get_parent_node`.
619+ pub fn parent_iter ( & self , current_id : HirId ) -> ParentHirIterator < ' _ , ' hir > {
620+ ParentHirIterator { current_id, map : self }
621+ }
622+
621623 /// Checks if the node is an argument. An argument is a local variable whose
622624 /// immediate parent is an item or a closure.
623625 pub fn is_argument ( & self , id : HirId ) -> bool {
@@ -684,7 +686,7 @@ impl<'hir> Map<'hir> {
684686 /// }
685687 /// ```
686688 pub fn get_return_block ( & self , id : HirId ) -> Option < HirId > {
687- let mut iter = ParentHirIterator :: new ( id, & self ) . peekable ( ) ;
689+ let mut iter = self . parent_iter ( id) . peekable ( ) ;
688690 let mut ignore_tail = false ;
689691 if let Some ( entry) = self . find_entry ( id) {
690692 if let Node :: Expr ( Expr { kind : ExprKind :: Ret ( _) , .. } ) = entry. node {
@@ -731,7 +733,7 @@ impl<'hir> Map<'hir> {
731733 /// in the HIR which is recorded by the map and is an item, either an item
732734 /// in a module, trait, or impl.
733735 pub fn get_parent_item ( & self , hir_id : HirId ) -> HirId {
734- for ( hir_id, node) in ParentHirIterator :: new ( hir_id, & self ) {
736+ for ( hir_id, node) in self . parent_iter ( hir_id) {
735737 match node {
736738 Node :: Crate
737739 | Node :: Item ( _)
@@ -753,7 +755,7 @@ impl<'hir> Map<'hir> {
753755 /// Returns the `HirId` of `id`'s nearest module parent, or `id` itself if no
754756 /// module parent is in this map.
755757 pub fn get_module_parent_node ( & self , hir_id : HirId ) -> HirId {
756- for ( hir_id, node) in ParentHirIterator :: new ( hir_id, & self ) {
758+ for ( hir_id, node) in self . parent_iter ( hir_id) {
757759 if let Node :: Item ( & Item { kind : ItemKind :: Mod ( _) , .. } ) = node {
758760 return hir_id;
759761 }
@@ -767,7 +769,7 @@ impl<'hir> Map<'hir> {
767769 /// Used by error reporting when there's a type error in a match arm caused by the `match`
768770 /// expression needing to be unit.
769771 pub fn get_match_if_cause ( & self , hir_id : HirId ) -> Option < & ' hir Expr < ' hir > > {
770- for ( _, node) in ParentHirIterator :: new ( hir_id, & self ) {
772+ for ( _, node) in self . parent_iter ( hir_id) {
771773 match node {
772774 Node :: Item ( _) | Node :: ForeignItem ( _) | Node :: TraitItem ( _) | Node :: ImplItem ( _) => {
773775 break ;
@@ -788,7 +790,7 @@ impl<'hir> Map<'hir> {
788790
789791 /// Returns the nearest enclosing scope. A scope is roughly an item or block.
790792 pub fn get_enclosing_scope ( & self , hir_id : HirId ) -> Option < HirId > {
791- for ( hir_id, node) in ParentHirIterator :: new ( hir_id, & self ) {
793+ for ( hir_id, node) in self . parent_iter ( hir_id) {
792794 if match node {
793795 Node :: Item ( i) => match i. kind {
794796 ItemKind :: Fn ( ..)
0 commit comments