@@ -160,7 +160,7 @@ impl TryFrom<ResolveRes> for Res {
160160}
161161
162162/// A link failed to resolve.
163- #[ derive( Debug ) ]
163+ #[ derive( Clone , Debug ) ]
164164enum ResolutionFailure < ' a > {
165165 /// This resolved, but with the wrong namespace.
166166 WrongNamespace {
@@ -200,7 +200,7 @@ enum ResolutionFailure<'a> {
200200 Dummy ,
201201}
202202
203- #[ derive( Debug ) ]
203+ #[ derive( Clone , Debug ) ]
204204enum MalformedGenerics {
205205 /// This link has unbalanced angle brackets.
206206 ///
@@ -253,6 +253,7 @@ impl ResolutionFailure<'_> {
253253 }
254254}
255255
256+ #[ derive( Clone , Copy ) ]
256257enum AnchorFailure {
257258 /// User error: `[std#x#y]` is not valid
258259 MultipleAnchors ,
@@ -1064,7 +1065,7 @@ impl<'a, 'tcx> DocVisitor for LinkCollector<'a, 'tcx> {
10641065 . take ( )
10651066 . expect ( "`markdown_links` are already borrowed" ) ;
10661067 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) ) ;
10681069 }
10691070 for md_link in & tmp_links[ & doc] {
10701071 let link = self . resolve_link ( & item, & doc, parent_node, md_link) ;
@@ -1088,34 +1089,38 @@ impl<'a, 'tcx> DocVisitor for LinkCollector<'a, 'tcx> {
10881089 }
10891090}
10901091
1091- enum PreprocessingError < ' a > {
1092+ enum PreprocessingError {
10921093 Anchor ( AnchorFailure ) ,
10931094 Disambiguator ( Range < usize > , String ) ,
1094- Resolution ( ResolutionFailure < ' a > , String , Option < Disambiguator > ) ,
1095+ Resolution ( ResolutionFailure < ' static > , String , Option < Disambiguator > ) ,
10951096}
10961097
1097- impl From < AnchorFailure > for PreprocessingError < ' _ > {
1098+ impl From < AnchorFailure > for PreprocessingError {
10981099 fn from ( err : AnchorFailure ) -> Self {
10991100 Self :: Anchor ( err)
11001101 }
11011102}
11021103
1104+ #[ derive( Clone ) ]
11031105struct PreprocessingInfo {
11041106 path_str : String ,
11051107 disambiguator : Option < Disambiguator > ,
11061108 extra_fragment : Option < String > ,
11071109 link_text : String ,
11081110}
11091111
1112+ // Not a typedef to avoid leaking several private structures from this module.
1113+ crate struct PreprocessedMarkdownLink ( Result < PreprocessingInfo , PreprocessingError > , MarkdownLink ) ;
1114+
11101115/// Returns:
11111116/// - `None` if the link should be ignored.
11121117/// - `Some(Err)` if the link should emit an error
11131118/// - `Some(Ok)` if the link is valid
11141119///
11151120/// `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 > > {
11191124 // [] is mostly likely not supposed to be a link
11201125 if ori_link. link . is_empty ( ) {
11211126 return None ;
@@ -1194,6 +1199,12 @@ fn preprocess_link<'a>(
11941199 } ) )
11951200}
11961201
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+
11971208impl LinkCollector < ' _ , ' _ > {
11981209 /// This is the entry point for resolving an intra-doc link.
11991210 ///
@@ -1203,8 +1214,9 @@ impl LinkCollector<'_, '_> {
12031214 item : & Item ,
12041215 dox : & str ,
12051216 parent_node : Option < DefId > ,
1206- ori_link : & MarkdownLink ,
1217+ link : & PreprocessedMarkdownLink ,
12071218 ) -> Option < ItemLink > {
1219+ let PreprocessedMarkdownLink ( pp_link, ori_link) = link;
12081220 trace ! ( "considering link '{}'" , ori_link. link) ;
12091221
12101222 let diag_info = DiagnosticInfo {
@@ -1214,28 +1226,29 @@ impl LinkCollector<'_, '_> {
12141226 link_range : ori_link. range . clone ( ) ,
12151227 } ;
12161228
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+ ) ;
12351246 }
1236- return None ;
12371247 }
1238- } ;
1248+ return None ;
1249+ }
1250+ } ;
1251+ let disambiguator = * disambiguator;
12391252
12401253 let inner_docs = item. inner_docs ( self . cx . tcx ) ;
12411254
@@ -1272,7 +1285,7 @@ impl LinkCollector<'_, '_> {
12721285 module_id,
12731286 dis : disambiguator,
12741287 path_str : path_str. to_owned ( ) ,
1275- extra_fragment,
1288+ extra_fragment : extra_fragment . clone ( ) ,
12761289 } ,
12771290 diag_info. clone ( ) , // this struct should really be Copy, but Range is not :(
12781291 matches ! ( ori_link. kind, LinkType :: Reference | LinkType :: Shortcut ) ,
@@ -1343,7 +1356,7 @@ impl LinkCollector<'_, '_> {
13431356
13441357 Some ( ItemLink {
13451358 link : ori_link. link . clone ( ) ,
1346- link_text,
1359+ link_text : link_text . clone ( ) ,
13471360 did : res. def_id ( self . cx . tcx ) ,
13481361 fragment,
13491362 } )
@@ -1365,7 +1378,12 @@ impl LinkCollector<'_, '_> {
13651378 & diag_info,
13661379 ) ?;
13671380 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+ } )
13691387 }
13701388 }
13711389 }
0 commit comments