@@ -934,28 +934,105 @@ impl<'hir> Map<'hir> {
934934 }
935935
936936 /// 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`.
938938 pub fn span ( self , hir_id : HirId ) -> Span {
939939 self . opt_span ( hir_id)
940940 . unwrap_or_else ( || bug ! ( "hir::map::Map::span: id not in map: {:?}" , hir_id) )
941941 }
942942
943943 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+
944967 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.
9461012 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 ( ) ) ,
9491015 } ,
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 ) ,
9581020 } ,
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 ,
9591036 Node :: Variant ( variant) => variant. span ,
9601037 Node :: Field ( field) => field. span ,
9611038 Node :: AnonConst ( constant) => self . body ( constant. body ) . value . span ,
@@ -973,29 +1050,12 @@ impl<'hir> Map<'hir> {
9731050 Node :: Pat ( pat) => pat. span ,
9741051 Node :: Arm ( arm) => arm. span ,
9751052 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) ) ,
9811054 Node :: Lifetime ( lifetime) => lifetime. span ,
9821055 Node :: GenericParam ( param) => param. span ,
9831056 Node :: Infer ( i) => i. span ,
9841057 Node :: Local ( local) => local. span ,
9851058 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) ,
9991059 }
10001060 }
10011061
0 commit comments