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