@@ -944,6 +944,65 @@ fn string<T: Display>(
944
944
}
945
945
}
946
946
947
+ fn generate_link_to_def (
948
+ out : & mut impl Write ,
949
+ text_s : & str ,
950
+ klass : Class ,
951
+ href_context : & Option < HrefContext < ' _ , ' _ > > ,
952
+ def_span : Span ,
953
+ open_tag : bool ,
954
+ ) -> bool {
955
+ if let Some ( href_context) = href_context {
956
+ if let Some ( href) =
957
+ href_context. context . shared . span_correspondence_map . get ( & def_span) . and_then ( |href| {
958
+ let context = href_context. context ;
959
+ // FIXME: later on, it'd be nice to provide two links (if possible) for all items:
960
+ // one to the documentation page and one to the source definition.
961
+ // FIXME: currently, external items only generate a link to their documentation,
962
+ // a link to their definition can be generated using this:
963
+ // https://github.com/rust-lang/rust/blob/60f1a2fc4b535ead9c85ce085fdce49b1b097531/src/librustdoc/html/render/context.rs#L315-L338
964
+ match href {
965
+ LinkFromSrc :: Local ( span) => {
966
+ context. href_from_span_relative ( * span, & href_context. current_href )
967
+ }
968
+ LinkFromSrc :: External ( def_id) => {
969
+ format:: href_with_root_path ( * def_id, context, Some ( href_context. root_path ) )
970
+ . ok ( )
971
+ . map ( |( url, _, _) | url)
972
+ }
973
+ LinkFromSrc :: Primitive ( prim) => format:: href_with_root_path (
974
+ PrimitiveType :: primitive_locations ( context. tcx ( ) ) [ prim] ,
975
+ context,
976
+ Some ( href_context. root_path ) ,
977
+ )
978
+ . ok ( )
979
+ . map ( |( url, _, _) | url) ,
980
+ LinkFromSrc :: Doc ( def_id) => {
981
+ format:: href_with_root_path ( * def_id, context, Some ( href_context. root_path ) )
982
+ . ok ( )
983
+ . map ( |( doc_link, _, _) | doc_link)
984
+ }
985
+ }
986
+ } )
987
+ {
988
+ if !open_tag {
989
+ // We're already inside an element which has the same klass, no need to give it
990
+ // again.
991
+ write ! ( out, "<a href=\" {href}\" >{text_s}" ) . unwrap ( ) ;
992
+ } else {
993
+ let klass_s = klass. as_html ( ) ;
994
+ if klass_s. is_empty ( ) {
995
+ write ! ( out, "<a href=\" {href}\" >{text_s}" ) . unwrap ( ) ;
996
+ } else {
997
+ write ! ( out, "<a class=\" {klass_s}\" href=\" {href}\" >{text_s}" ) . unwrap ( ) ;
998
+ }
999
+ }
1000
+ return true ;
1001
+ }
1002
+ }
1003
+ false
1004
+ }
1005
+
947
1006
/// This function writes `text` into `out` with some modifications depending on `klass`:
948
1007
///
949
1008
/// * If `klass` is `None`, `text` is written into `out` with no modification.
@@ -973,10 +1032,14 @@ fn string_without_closing_tag<T: Display>(
973
1032
return Some ( "</span>" ) ;
974
1033
} ;
975
1034
1035
+ let mut added_links = false ;
976
1036
let mut text_s = text. to_string ( ) ;
977
1037
if text_s. contains ( "::" ) {
1038
+ let mut span = def_span. with_hi ( def_span. lo ( ) ) ;
978
1039
text_s = text_s. split ( "::" ) . intersperse ( "::" ) . fold ( String :: new ( ) , |mut path, t| {
1040
+ span = span. with_hi ( span. hi ( ) + BytePos ( t. len ( ) as _ ) ) ;
979
1041
match t {
1042
+ "::" => write ! ( & mut path, "::" ) ,
980
1043
"self" | "Self" => write ! (
981
1044
& mut path,
982
1045
"<span class=\" {klass}\" >{t}</span>" ,
@@ -989,60 +1052,25 @@ fn string_without_closing_tag<T: Display>(
989
1052
klass = Class :: KeyWord . as_html( ) ,
990
1053
)
991
1054
}
992
- t => write ! ( & mut path, "{t}" ) ,
1055
+ t => {
1056
+ if !t. is_empty ( )
1057
+ && generate_link_to_def ( & mut path, t, klass, href_context, span, open_tag)
1058
+ {
1059
+ added_links = true ;
1060
+ write ! ( & mut path, "</a>" )
1061
+ } else {
1062
+ write ! ( & mut path, "{t}" )
1063
+ }
1064
+ }
993
1065
}
994
1066
. expect ( "Failed to build source HTML path" ) ;
1067
+ span = span. with_lo ( span. lo ( ) + BytePos ( t. len ( ) as _ ) ) ;
995
1068
path
996
1069
} ) ;
997
1070
}
998
1071
999
- if let Some ( href_context) = href_context {
1000
- if let Some ( href) =
1001
- href_context. context . shared . span_correspondence_map . get ( & def_span) . and_then ( |href| {
1002
- let context = href_context. context ;
1003
- // FIXME: later on, it'd be nice to provide two links (if possible) for all items:
1004
- // one to the documentation page and one to the source definition.
1005
- // FIXME: currently, external items only generate a link to their documentation,
1006
- // a link to their definition can be generated using this:
1007
- // https://github.com/rust-lang/rust/blob/60f1a2fc4b535ead9c85ce085fdce49b1b097531/src/librustdoc/html/render/context.rs#L315-L338
1008
- match href {
1009
- LinkFromSrc :: Local ( span) => {
1010
- context. href_from_span_relative ( * span, & href_context. current_href )
1011
- }
1012
- LinkFromSrc :: External ( def_id) => {
1013
- format:: href_with_root_path ( * def_id, context, Some ( href_context. root_path ) )
1014
- . ok ( )
1015
- . map ( |( url, _, _) | url)
1016
- }
1017
- LinkFromSrc :: Primitive ( prim) => format:: href_with_root_path (
1018
- PrimitiveType :: primitive_locations ( context. tcx ( ) ) [ prim] ,
1019
- context,
1020
- Some ( href_context. root_path ) ,
1021
- )
1022
- . ok ( )
1023
- . map ( |( url, _, _) | url) ,
1024
- LinkFromSrc :: Doc ( def_id) => {
1025
- format:: href_with_root_path ( * def_id, context, Some ( href_context. root_path ) )
1026
- . ok ( )
1027
- . map ( |( doc_link, _, _) | doc_link)
1028
- }
1029
- }
1030
- } )
1031
- {
1032
- if !open_tag {
1033
- // We're already inside an element which has the same klass, no need to give it
1034
- // again.
1035
- write ! ( out, "<a href=\" {href}\" >{text_s}" ) . unwrap ( ) ;
1036
- } else {
1037
- let klass_s = klass. as_html ( ) ;
1038
- if klass_s. is_empty ( ) {
1039
- write ! ( out, "<a href=\" {href}\" >{text_s}" ) . unwrap ( ) ;
1040
- } else {
1041
- write ! ( out, "<a class=\" {klass_s}\" href=\" {href}\" >{text_s}" ) . unwrap ( ) ;
1042
- }
1043
- }
1044
- return Some ( "</a>" ) ;
1045
- }
1072
+ if !added_links && generate_link_to_def ( out, & text_s, klass, href_context, def_span, open_tag) {
1073
+ return Some ( "</a>" ) ;
1046
1074
}
1047
1075
if !open_tag {
1048
1076
write ! ( out, "{}" , text_s) . unwrap ( ) ;
0 commit comments