@@ -934,28 +934,105 @@ impl<'hir> Map<'hir> {
934
934
}
935
935
936
936
/// Gets the span of the definition of the specified HIR node.
937
- /// This is used by `tcx.get_span`
937
+ /// This is used by `tcx.def_span`.
938
938
pub fn span ( self , hir_id : HirId ) -> Span {
939
939
self . opt_span ( hir_id)
940
940
. unwrap_or_else ( || bug ! ( "hir::map::Map::span: id not in map: {:?}" , hir_id) )
941
941
}
942
942
943
943
pub fn opt_span ( self , hir_id : HirId ) -> Option < Span > {
944
+ fn until_within ( outer : Span , end : Span ) -> Span {
945
+ if let Some ( end) = end. find_ancestor_inside ( outer) {
946
+ outer. with_hi ( end. hi ( ) )
947
+ } else {
948
+ outer
949
+ }
950
+ }
951
+
952
+ fn named_span ( item_span : Span , ident : Ident , generics : Option < & Generics < ' _ > > ) -> Span {
953
+ if ident. name != kw:: Empty {
954
+ let mut span = until_within ( item_span, ident. span ) ;
955
+ if let Some ( g) = generics
956
+ && !g. span . is_dummy ( )
957
+ && let Some ( g_span) = g. span . find_ancestor_inside ( item_span)
958
+ {
959
+ span = span. to ( g_span) ;
960
+ }
961
+ span
962
+ } else {
963
+ item_span
964
+ }
965
+ }
966
+
944
967
let span = match self . find ( hir_id) ? {
945
- Node :: Param ( param) => param. span ,
968
+ // Function-like.
969
+ Node :: Item ( Item { kind : ItemKind :: Fn ( sig, ..) , .. } )
970
+ | Node :: TraitItem ( TraitItem { kind : TraitItemKind :: Fn ( sig, ..) , .. } )
971
+ | Node :: ImplItem ( ImplItem { kind : ImplItemKind :: Fn ( sig, ..) , .. } ) => sig. span ,
972
+ // Constants and Statics.
973
+ Node :: Item ( Item {
974
+ kind :
975
+ ItemKind :: Const ( ty, ..)
976
+ | ItemKind :: Static ( ty, ..)
977
+ | ItemKind :: Impl ( Impl { self_ty : ty, .. } ) ,
978
+ span : outer_span,
979
+ ..
980
+ } )
981
+ | Node :: TraitItem ( TraitItem {
982
+ kind : TraitItemKind :: Const ( ty, ..) ,
983
+ span : outer_span,
984
+ ..
985
+ } )
986
+ | Node :: ImplItem ( ImplItem {
987
+ kind : ImplItemKind :: Const ( ty, ..) ,
988
+ span : outer_span,
989
+ ..
990
+ } )
991
+ | Node :: ForeignItem ( ForeignItem {
992
+ kind : ForeignItemKind :: Static ( ty, ..) ,
993
+ span : outer_span,
994
+ ..
995
+ } ) => until_within ( * outer_span, ty. span ) ,
996
+ // With generics and bounds.
997
+ Node :: Item ( Item {
998
+ kind : ItemKind :: Trait ( _, _, generics, bounds, _) ,
999
+ span : outer_span,
1000
+ ..
1001
+ } )
1002
+ | Node :: TraitItem ( TraitItem {
1003
+ kind : TraitItemKind :: Type ( bounds, _) ,
1004
+ generics,
1005
+ span : outer_span,
1006
+ ..
1007
+ } ) => {
1008
+ let end = if let Some ( b) = bounds. last ( ) { b. span ( ) } else { generics. span } ;
1009
+ until_within ( * outer_span, end)
1010
+ }
1011
+ // Other cases.
946
1012
Node :: Item ( item) => match & item. kind {
947
- ItemKind :: Fn ( sig , _, _ ) => sig . span ,
948
- _ => item. span ,
1013
+ ItemKind :: Use ( path , _) => path . span ,
1014
+ _ => named_span ( item. span , item . ident , item . kind . generics ( ) ) ,
949
1015
} ,
950
- Node :: ForeignItem ( foreign_item) => foreign_item. span ,
951
- Node :: TraitItem ( trait_item) => match & trait_item. kind {
952
- TraitItemKind :: Fn ( sig, _) => sig. span ,
953
- _ => trait_item. span ,
954
- } ,
955
- Node :: ImplItem ( impl_item) => match & impl_item. kind {
956
- ImplItemKind :: Fn ( sig, _) => sig. span ,
957
- _ => impl_item. span ,
1016
+ Node :: ImplItem ( item) => named_span ( item. span , item. ident , Some ( item. generics ) ) ,
1017
+ Node :: ForeignItem ( item) => match item. kind {
1018
+ ForeignItemKind :: Fn ( decl, _, _) => until_within ( item. span , decl. output . span ( ) ) ,
1019
+ _ => named_span ( item. span , item. ident , None ) ,
958
1020
} ,
1021
+ Node :: Ctor ( ..) => return self . opt_span ( self . get_parent_node ( hir_id) ) ,
1022
+ _ => self . span_with_body ( hir_id) ,
1023
+ } ;
1024
+ Some ( span)
1025
+ }
1026
+
1027
+ /// Like `hir.span()`, but includes the body of items
1028
+ /// (instead of just the item header)
1029
+ pub fn span_with_body ( self , hir_id : HirId ) -> Span {
1030
+ match self . get ( hir_id) {
1031
+ Node :: Param ( param) => param. span ,
1032
+ Node :: Item ( item) => item. span ,
1033
+ Node :: ForeignItem ( foreign_item) => foreign_item. span ,
1034
+ Node :: TraitItem ( trait_item) => trait_item. span ,
1035
+ Node :: ImplItem ( impl_item) => impl_item. span ,
959
1036
Node :: Variant ( variant) => variant. span ,
960
1037
Node :: Field ( field) => field. span ,
961
1038
Node :: AnonConst ( constant) => self . body ( constant. body ) . value . span ,
@@ -973,29 +1050,12 @@ impl<'hir> Map<'hir> {
973
1050
Node :: Pat ( pat) => pat. span ,
974
1051
Node :: Arm ( arm) => arm. span ,
975
1052
Node :: Block ( block) => block. span ,
976
- Node :: Ctor ( ..) => match self . find ( self . get_parent_node ( hir_id) ) ? {
977
- Node :: Item ( item) => item. span ,
978
- Node :: Variant ( variant) => variant. span ,
979
- _ => unreachable ! ( ) ,
980
- } ,
1053
+ Node :: Ctor ( ..) => self . span_with_body ( self . get_parent_node ( hir_id) ) ,
981
1054
Node :: Lifetime ( lifetime) => lifetime. span ,
982
1055
Node :: GenericParam ( param) => param. span ,
983
1056
Node :: Infer ( i) => i. span ,
984
1057
Node :: Local ( local) => local. span ,
985
1058
Node :: Crate ( item) => item. spans . inner_span ,
986
- } ;
987
- Some ( span)
988
- }
989
-
990
- /// Like `hir.span()`, but includes the body of function items
991
- /// (instead of just the function header)
992
- pub fn span_with_body ( self , hir_id : HirId ) -> Span {
993
- match self . find ( hir_id) {
994
- Some ( Node :: TraitItem ( item) ) => item. span ,
995
- Some ( Node :: ImplItem ( impl_item) ) => impl_item. span ,
996
- Some ( Node :: Item ( item) ) => item. span ,
997
- Some ( _) => self . span ( hir_id) ,
998
- _ => bug ! ( "hir::map::Map::span_with_body: id not in map: {:?}" , hir_id) ,
999
1059
}
1000
1060
}
1001
1061
0 commit comments