@@ -1050,6 +1050,64 @@ fn string<T: Display, W: Write>(
1050
1050
}
1051
1051
}
1052
1052
1053
+ fn generate_link_to_def (
1054
+ out : & mut impl Write ,
1055
+ text_s : & str ,
1056
+ klass : Class ,
1057
+ href_context : & Option < HrefContext < ' _ , ' _ > > ,
1058
+ def_span : Span ,
1059
+ open_tag : bool ,
1060
+ ) -> bool {
1061
+ if let Some ( href_context) = href_context
1062
+ && let Some ( href) =
1063
+ href_context. context . shared . span_correspondence_map . get ( & def_span) . and_then ( |href| {
1064
+ let context = href_context. context ;
1065
+ // FIXME: later on, it'd be nice to provide two links (if possible) for all items:
1066
+ // one to the documentation page and one to the source definition.
1067
+ // FIXME: currently, external items only generate a link to their documentation,
1068
+ // a link to their definition can be generated using this:
1069
+ // https://github.com/rust-lang/rust/blob/60f1a2fc4b535ead9c85ce085fdce49b1b097531/src/librustdoc/html/render/context.rs#L315-L338
1070
+ match href {
1071
+ LinkFromSrc :: Local ( span) => {
1072
+ context. href_from_span_relative ( * span, & href_context. current_href )
1073
+ }
1074
+ LinkFromSrc :: External ( def_id) => {
1075
+ format:: href_with_root_path ( * def_id, context, Some ( href_context. root_path ) )
1076
+ . ok ( )
1077
+ . map ( |( url, _, _) | url)
1078
+ }
1079
+ LinkFromSrc :: Primitive ( prim) => format:: href_with_root_path (
1080
+ PrimitiveType :: primitive_locations ( context. tcx ( ) ) [ prim] ,
1081
+ context,
1082
+ Some ( href_context. root_path ) ,
1083
+ )
1084
+ . ok ( )
1085
+ . map ( |( url, _, _) | url) ,
1086
+ LinkFromSrc :: Doc ( def_id) => {
1087
+ format:: href_with_root_path ( * def_id, context, Some ( href_context. root_path ) )
1088
+ . ok ( )
1089
+ . map ( |( doc_link, _, _) | doc_link)
1090
+ }
1091
+ }
1092
+ } )
1093
+ {
1094
+ if !open_tag {
1095
+ // We're already inside an element which has the same klass, no need to give it
1096
+ // again.
1097
+ write ! ( out, "<a href=\" {href}\" >{text_s}" ) . unwrap ( ) ;
1098
+ } else {
1099
+ let klass_s = klass. as_html ( ) ;
1100
+ if klass_s. is_empty ( ) {
1101
+ write ! ( out, "<a href=\" {href}\" >{text_s}" ) . unwrap ( ) ;
1102
+ } else {
1103
+ write ! ( out, "<a class=\" {klass_s}\" href=\" {href}\" >{text_s}" ) . unwrap ( ) ;
1104
+ }
1105
+ }
1106
+ return true ;
1107
+ }
1108
+ false
1109
+ }
1110
+
1053
1111
/// This function writes `text` into `out` with some modifications depending on `klass`:
1054
1112
///
1055
1113
/// * If `klass` is `None`, `text` is written into `out` with no modification.
@@ -1079,10 +1137,14 @@ fn string_without_closing_tag<T: Display>(
1079
1137
return Some ( "</span>" ) ;
1080
1138
} ;
1081
1139
1140
+ let mut added_links = false ;
1082
1141
let mut text_s = text. to_string ( ) ;
1083
1142
if text_s. contains ( "::" ) {
1143
+ let mut span = def_span. with_hi ( def_span. lo ( ) ) ;
1084
1144
text_s = text_s. split ( "::" ) . intersperse ( "::" ) . fold ( String :: new ( ) , |mut path, t| {
1145
+ span = span. with_hi ( span. hi ( ) + BytePos ( t. len ( ) as _ ) ) ;
1085
1146
match t {
1147
+ "::" => write ! ( & mut path, "::" ) ,
1086
1148
"self" | "Self" => write ! (
1087
1149
& mut path,
1088
1150
"<span class=\" {klass}\" >{t}</span>" ,
@@ -1095,58 +1157,24 @@ fn string_without_closing_tag<T: Display>(
1095
1157
klass = Class :: KeyWord . as_html( ) ,
1096
1158
)
1097
1159
}
1098
- t => write ! ( & mut path, "{t}" ) ,
1160
+ t => {
1161
+ if !t. is_empty ( )
1162
+ && generate_link_to_def ( & mut path, t, klass, href_context, span, open_tag)
1163
+ {
1164
+ added_links = true ;
1165
+ write ! ( & mut path, "</a>" )
1166
+ } else {
1167
+ write ! ( & mut path, "{t}" )
1168
+ }
1169
+ }
1099
1170
}
1100
1171
. expect ( "Failed to build source HTML path" ) ;
1172
+ span = span. with_lo ( span. lo ( ) + BytePos ( t. len ( ) as _ ) ) ;
1101
1173
path
1102
1174
} ) ;
1103
1175
}
1104
1176
1105
- if let Some ( href_context) = href_context
1106
- && let Some ( href) = href_context. context . shared . span_correspondence_map . get ( & def_span)
1107
- && let Some ( href) = {
1108
- let context = href_context. context ;
1109
- // FIXME: later on, it'd be nice to provide two links (if possible) for all items:
1110
- // one to the documentation page and one to the source definition.
1111
- // FIXME: currently, external items only generate a link to their documentation,
1112
- // a link to their definition can be generated using this:
1113
- // https://github.com/rust-lang/rust/blob/60f1a2fc4b535ead9c85ce085fdce49b1b097531/src/librustdoc/html/render/context.rs#L315-L338
1114
- match href {
1115
- LinkFromSrc :: Local ( span) => {
1116
- context. href_from_span_relative ( * span, & href_context. current_href )
1117
- }
1118
- LinkFromSrc :: External ( def_id) => {
1119
- format:: href_with_root_path ( * def_id, context, Some ( href_context. root_path ) )
1120
- . ok ( )
1121
- . map ( |( url, _, _) | url)
1122
- }
1123
- LinkFromSrc :: Primitive ( prim) => format:: href_with_root_path (
1124
- PrimitiveType :: primitive_locations ( context. tcx ( ) ) [ prim] ,
1125
- context,
1126
- Some ( href_context. root_path ) ,
1127
- )
1128
- . ok ( )
1129
- . map ( |( url, _, _) | url) ,
1130
- LinkFromSrc :: Doc ( def_id) => {
1131
- format:: href_with_root_path ( * def_id, context, Some ( href_context. root_path ) )
1132
- . ok ( )
1133
- . map ( |( doc_link, _, _) | doc_link)
1134
- }
1135
- }
1136
- }
1137
- {
1138
- if !open_tag {
1139
- // We're already inside an element which has the same klass, no need to give it
1140
- // again.
1141
- write ! ( out, "<a href=\" {href}\" >{text_s}" ) . unwrap ( ) ;
1142
- } else {
1143
- let klass_s = klass. as_html ( ) ;
1144
- if klass_s. is_empty ( ) {
1145
- write ! ( out, "<a href=\" {href}\" >{text_s}" ) . unwrap ( ) ;
1146
- } else {
1147
- write ! ( out, "<a class=\" {klass_s}\" href=\" {href}\" >{text_s}" ) . unwrap ( ) ;
1148
- }
1149
- }
1177
+ if !added_links && generate_link_to_def ( out, & text_s, klass, href_context, def_span, open_tag) {
1150
1178
return Some ( "</a>" ) ;
1151
1179
}
1152
1180
if !open_tag {
0 commit comments