@@ -824,34 +824,43 @@ impl AttributesExt for Attributes {
824
824
}
825
825
}
826
826
827
+ enum PathKind {
828
+ /// can be either value or type, not a macro
829
+ Unknown ,
830
+ /// macro
831
+ Macro ,
832
+ /// values, functions, consts, statics, everything in the value namespace
833
+ Value ,
834
+ /// types, traits, everything in the type namespace
835
+ Type
836
+ }
827
837
impl Clean < Attributes > for [ ast:: Attribute ] {
828
838
fn clean ( & self , cx : & DocContext ) -> Attributes {
829
839
let mut attrs = Attributes :: from_ast ( cx. sess ( ) . diagnostic ( ) , self ) ;
830
840
831
841
if UnstableFeatures :: from_environment ( ) . is_nightly_build ( ) {
832
842
let dox = attrs. collapsed_doc_value ( ) . unwrap_or_else ( String :: new) ;
833
843
for link in markdown_links ( & dox, cx. render_type ) {
834
- let path = {
835
- let is_value ;
844
+ let def = {
845
+ let mut kind = PathKind :: Unknown ;
836
846
let path_str = if let Some ( prefix) =
837
847
[ "struct" , "enum" , "type" ,
838
848
"trait" , "union" ] . iter ( )
839
849
. find ( |p| link. starts_with ( * * p) ) {
840
- is_value = Some ( false ) ;
850
+ kind = PathKind :: Type ;
841
851
link. trim_left_matches ( prefix) . trim ( )
842
852
} else if let Some ( prefix) =
843
853
[ "const" , "static" ] . iter ( )
844
854
. find ( |p| link. starts_with ( * * p) ) {
845
- is_value = Some ( true ) ;
855
+ kind = PathKind :: Value ;
846
856
link. trim_left_matches ( prefix) . trim ( )
847
857
} else if link. ends_with ( "()" ) {
848
- is_value = Some ( true ) ;
858
+ kind = PathKind :: Value ;
849
859
link. trim_right_matches ( "()" ) . trim ( )
850
- } else if link. ends_with ( "!" ) {
851
- // FIXME (misdreavus): macros are resolved with different machinery
852
- continue ;
860
+ } else if link. ends_with ( '!' ) {
861
+ kind = PathKind :: Macro ;
862
+ link . trim_right_matches ( '!' ) . trim ( )
853
863
} else {
854
- is_value = None ;
855
864
link. trim ( )
856
865
} ;
857
866
@@ -879,34 +888,68 @@ impl Clean<Attributes> for [ast::Attribute] {
879
888
}
880
889
} ;
881
890
882
- if let Some ( is_value) = is_value {
883
- if let Ok ( path) = resolve ( is_value) {
884
- path
885
- } else {
886
- // this could just be a normal link or a broken link
887
- // we could potentially check if something is
888
- // "intra-doc-link-like" and warn in that case
889
- continue ;
891
+ match kind {
892
+ PathKind :: Value => {
893
+ if let Ok ( path) = resolve ( true ) {
894
+ path. def
895
+ } else {
896
+ // this could just be a normal link or a broken link
897
+ // we could potentially check if something is
898
+ // "intra-doc-link-like" and warn in that case
899
+ continue ;
900
+ }
890
901
}
891
- } else {
892
- // try both!
893
- // It is imperative we search for not-a-value first
894
- // Otherwise we will find struct ctors for when we are looking
895
- // for structs, etc, and the link won't work.
896
- if let Ok ( path) = resolve ( false ) {
897
- path
898
- } else if let Ok ( path) = resolve ( true ) {
899
- path
900
- } else {
901
- // this could just be a normal link
902
- continue ;
902
+ PathKind :: Type => {
903
+ if let Ok ( path) = resolve ( false ) {
904
+ path. def
905
+ } else {
906
+ // this could just be a normal link
907
+ continue ;
908
+ }
909
+ }
910
+ PathKind :: Unknown => {
911
+ // try both!
912
+ // It is imperative we search for not-a-value first
913
+ // Otherwise we will find struct ctors for when we are looking
914
+ // for structs, etc, and the link won't work.
915
+ if let Ok ( path) = resolve ( false ) {
916
+ path. def
917
+ } else if let Ok ( path) = resolve ( true ) {
918
+ path. def
919
+ } else {
920
+ // this could just be a normal link
921
+ continue ;
922
+ }
923
+ }
924
+ PathKind :: Macro => {
925
+ use syntax:: ext:: base:: MacroKind ;
926
+ use syntax:: ext:: hygiene:: Mark ;
927
+ let segment = ast:: PathSegment {
928
+ identifier : ast:: Ident :: from_str ( path_str) ,
929
+ span : DUMMY_SP ,
930
+ parameters : None ,
931
+ } ;
932
+ let path = ast:: Path {
933
+ span : DUMMY_SP ,
934
+ segments : vec ! [ segment] ,
935
+ } ;
936
+
937
+ let mut resolver = cx. resolver . borrow_mut ( ) ;
938
+ let mark = Mark :: root ( ) ;
939
+ let res = resolver
940
+ . resolve_macro_to_def_inner ( mark, & path, MacroKind :: Bang , false ) ;
941
+ if let Ok ( def) = res {
942
+ def
943
+ } else {
944
+ continue ;
945
+ }
903
946
}
904
947
}
905
948
} ;
906
949
907
- register_def ( cx, def) ;
908
950
909
- attrs. links . push ( ( link, path. def . def_id ( ) ) ) ;
951
+ register_def ( cx, def) ;
952
+ attrs. links . push ( ( link, def. def_id ( ) ) ) ;
910
953
}
911
954
912
955
cx. sess ( ) . abort_if_errors ( ) ;
@@ -1970,6 +2013,7 @@ pub enum TypeKind {
1970
2013
Variant ,
1971
2014
Typedef ,
1972
2015
Foreign ,
2016
+ Macro ,
1973
2017
}
1974
2018
1975
2019
pub trait GetDefId {
@@ -3271,6 +3315,7 @@ fn register_def(cx: &DocContext, def: Def) -> DefId {
3271
3315
Def :: TyForeign ( i) => ( i, TypeKind :: Foreign ) ,
3272
3316
Def :: Static ( i, _) => ( i, TypeKind :: Static ) ,
3273
3317
Def :: Variant ( i) => ( cx. tcx . parent_def_id ( i) . unwrap ( ) , TypeKind :: Enum ) ,
3318
+ Def :: Macro ( i, _) => ( i, TypeKind :: Macro ) ,
3274
3319
Def :: SelfTy ( Some ( def_id) , _) => ( def_id, TypeKind :: Trait ) ,
3275
3320
Def :: SelfTy ( _, Some ( impl_def_id) ) => {
3276
3321
return impl_def_id
0 commit comments