@@ -160,7 +160,7 @@ impl TryFrom<ResolveRes> for Res {
160
160
}
161
161
162
162
/// A link failed to resolve.
163
- #[ derive( Debug ) ]
163
+ #[ derive( Clone , Debug ) ]
164
164
enum ResolutionFailure < ' a > {
165
165
/// This resolved, but with the wrong namespace.
166
166
WrongNamespace {
@@ -200,7 +200,7 @@ enum ResolutionFailure<'a> {
200
200
Dummy ,
201
201
}
202
202
203
- #[ derive( Debug ) ]
203
+ #[ derive( Clone , Debug ) ]
204
204
enum MalformedGenerics {
205
205
/// This link has unbalanced angle brackets.
206
206
///
@@ -253,6 +253,7 @@ impl ResolutionFailure<'_> {
253
253
}
254
254
}
255
255
256
+ #[ derive( Clone , Copy ) ]
256
257
enum AnchorFailure {
257
258
/// User error: `[std#x#y]` is not valid
258
259
MultipleAnchors ,
@@ -1064,7 +1065,7 @@ impl<'a, 'tcx> DocVisitor for LinkCollector<'a, 'tcx> {
1064
1065
. take ( )
1065
1066
. expect ( "`markdown_links` are already borrowed" ) ;
1066
1067
if !tmp_links. contains_key ( & doc) {
1067
- tmp_links. insert ( doc. clone ( ) , markdown_links ( & doc) ) ;
1068
+ tmp_links. insert ( doc. clone ( ) , preprocessed_markdown_links ( & doc) ) ;
1068
1069
}
1069
1070
for md_link in & tmp_links[ & doc] {
1070
1071
let link = self . resolve_link ( & item, & doc, parent_node, md_link) ;
@@ -1088,34 +1089,38 @@ impl<'a, 'tcx> DocVisitor for LinkCollector<'a, 'tcx> {
1088
1089
}
1089
1090
}
1090
1091
1091
- enum PreprocessingError < ' a > {
1092
+ enum PreprocessingError {
1092
1093
Anchor ( AnchorFailure ) ,
1093
1094
Disambiguator ( Range < usize > , String ) ,
1094
- Resolution ( ResolutionFailure < ' a > , String , Option < Disambiguator > ) ,
1095
+ Resolution ( ResolutionFailure < ' static > , String , Option < Disambiguator > ) ,
1095
1096
}
1096
1097
1097
- impl From < AnchorFailure > for PreprocessingError < ' _ > {
1098
+ impl From < AnchorFailure > for PreprocessingError {
1098
1099
fn from ( err : AnchorFailure ) -> Self {
1099
1100
Self :: Anchor ( err)
1100
1101
}
1101
1102
}
1102
1103
1104
+ #[ derive( Clone ) ]
1103
1105
struct PreprocessingInfo {
1104
1106
path_str : String ,
1105
1107
disambiguator : Option < Disambiguator > ,
1106
1108
extra_fragment : Option < String > ,
1107
1109
link_text : String ,
1108
1110
}
1109
1111
1112
+ // Not a typedef to avoid leaking several private structures from this module.
1113
+ crate struct PreprocessedMarkdownLink ( Result < PreprocessingInfo , PreprocessingError > , MarkdownLink ) ;
1114
+
1110
1115
/// Returns:
1111
1116
/// - `None` if the link should be ignored.
1112
1117
/// - `Some(Err)` if the link should emit an error
1113
1118
/// - `Some(Ok)` if the link is valid
1114
1119
///
1115
1120
/// `link_buffer` is needed for lifetime reasons; it will always be overwritten and the contents ignored.
1116
- fn preprocess_link < ' a > (
1117
- ori_link : & ' a MarkdownLink ,
1118
- ) -> Option < Result < PreprocessingInfo , PreprocessingError < ' a > > > {
1121
+ fn preprocess_link (
1122
+ ori_link : & MarkdownLink ,
1123
+ ) -> Option < Result < PreprocessingInfo , PreprocessingError > > {
1119
1124
// [] is mostly likely not supposed to be a link
1120
1125
if ori_link. link . is_empty ( ) {
1121
1126
return None ;
@@ -1194,6 +1199,12 @@ fn preprocess_link<'a>(
1194
1199
} ) )
1195
1200
}
1196
1201
1202
+ fn preprocessed_markdown_links ( s : & str ) -> Vec < PreprocessedMarkdownLink > {
1203
+ markdown_links ( s, |link| {
1204
+ preprocess_link ( & link) . map ( |pp_link| PreprocessedMarkdownLink ( pp_link, link) )
1205
+ } )
1206
+ }
1207
+
1197
1208
impl LinkCollector < ' _ , ' _ > {
1198
1209
/// This is the entry point for resolving an intra-doc link.
1199
1210
///
@@ -1203,8 +1214,9 @@ impl LinkCollector<'_, '_> {
1203
1214
item : & Item ,
1204
1215
dox : & str ,
1205
1216
parent_node : Option < DefId > ,
1206
- ori_link : & MarkdownLink ,
1217
+ link : & PreprocessedMarkdownLink ,
1207
1218
) -> Option < ItemLink > {
1219
+ let PreprocessedMarkdownLink ( pp_link, ori_link) = link;
1208
1220
trace ! ( "considering link '{}'" , ori_link. link) ;
1209
1221
1210
1222
let diag_info = DiagnosticInfo {
@@ -1214,28 +1226,29 @@ impl LinkCollector<'_, '_> {
1214
1226
link_range : ori_link. range . clone ( ) ,
1215
1227
} ;
1216
1228
1217
- let PreprocessingInfo { ref path_str, disambiguator, extra_fragment, link_text } =
1218
- match preprocess_link ( & ori_link) ? {
1219
- Ok ( x) => x,
1220
- Err ( err) => {
1221
- match err {
1222
- PreprocessingError :: Anchor ( err) => anchor_failure ( self . cx , diag_info, err) ,
1223
- PreprocessingError :: Disambiguator ( range, msg) => {
1224
- disambiguator_error ( self . cx , diag_info, range, & msg)
1225
- }
1226
- PreprocessingError :: Resolution ( err, path_str, disambiguator) => {
1227
- resolution_failure (
1228
- self ,
1229
- diag_info,
1230
- & path_str,
1231
- disambiguator,
1232
- smallvec ! [ err] ,
1233
- ) ;
1234
- }
1229
+ let PreprocessingInfo { path_str, disambiguator, extra_fragment, link_text } = match pp_link
1230
+ {
1231
+ Ok ( x) => x,
1232
+ Err ( err) => {
1233
+ match err {
1234
+ PreprocessingError :: Anchor ( err) => anchor_failure ( self . cx , diag_info, * err) ,
1235
+ PreprocessingError :: Disambiguator ( range, msg) => {
1236
+ disambiguator_error ( self . cx , diag_info, range. clone ( ) , msg)
1237
+ }
1238
+ PreprocessingError :: Resolution ( err, path_str, disambiguator) => {
1239
+ resolution_failure (
1240
+ self ,
1241
+ diag_info,
1242
+ path_str,
1243
+ * disambiguator,
1244
+ smallvec ! [ err. clone( ) ] ,
1245
+ ) ;
1235
1246
}
1236
- return None ;
1237
1247
}
1238
- } ;
1248
+ return None ;
1249
+ }
1250
+ } ;
1251
+ let disambiguator = * disambiguator;
1239
1252
1240
1253
let inner_docs = item. inner_docs ( self . cx . tcx ) ;
1241
1254
@@ -1272,7 +1285,7 @@ impl LinkCollector<'_, '_> {
1272
1285
module_id,
1273
1286
dis : disambiguator,
1274
1287
path_str : path_str. to_owned ( ) ,
1275
- extra_fragment,
1288
+ extra_fragment : extra_fragment . clone ( ) ,
1276
1289
} ,
1277
1290
diag_info. clone ( ) , // this struct should really be Copy, but Range is not :(
1278
1291
matches ! ( ori_link. kind, LinkType :: Reference | LinkType :: Shortcut ) ,
@@ -1343,7 +1356,7 @@ impl LinkCollector<'_, '_> {
1343
1356
1344
1357
Some ( ItemLink {
1345
1358
link : ori_link. link . clone ( ) ,
1346
- link_text,
1359
+ link_text : link_text . clone ( ) ,
1347
1360
did : res. def_id ( self . cx . tcx ) ,
1348
1361
fragment,
1349
1362
} )
@@ -1365,7 +1378,12 @@ impl LinkCollector<'_, '_> {
1365
1378
& diag_info,
1366
1379
) ?;
1367
1380
let id = clean:: register_res ( self . cx , rustc_hir:: def:: Res :: Def ( kind, id) ) ;
1368
- Some ( ItemLink { link : ori_link. link . clone ( ) , link_text, did : id, fragment } )
1381
+ Some ( ItemLink {
1382
+ link : ori_link. link . clone ( ) ,
1383
+ link_text : link_text. clone ( ) ,
1384
+ did : id,
1385
+ fragment,
1386
+ } )
1369
1387
}
1370
1388
}
1371
1389
}
0 commit comments