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