@@ -349,13 +349,23 @@ pub(crate) enum HrefError {
349349 UnnamableItem ,
350350}
351351
352+ /// Type representing information of an `href` attribute.
353+ pub ( crate ) struct HrefInfo {
354+ /// URL to the item page.
355+ pub ( crate ) url : String ,
356+ /// Kind of the item (used to generate the `title` attribute).
357+ pub ( crate ) kind : ItemType ,
358+ /// Rust path to the item (used to generate the `title` attribute).
359+ pub ( crate ) rust_path : Vec < Symbol > ,
360+ }
361+
352362/// This function is to get the external macro path because they are not in the cache used in
353363/// `href_with_root_path`.
354364fn generate_macro_def_id_path (
355365 def_id : DefId ,
356366 cx : & Context < ' _ > ,
357367 root_path : Option < & str > ,
358- ) -> Result < ( String , ItemType , Vec < Symbol > ) , HrefError > {
368+ ) -> Result < HrefInfo , HrefError > {
359369 let tcx = cx. tcx ( ) ;
360370 let crate_name = tcx. crate_name ( def_id. krate ) ;
361371 let cache = cx. cache ( ) ;
@@ -384,9 +394,11 @@ fn generate_macro_def_id_path(
384394 return Err ( HrefError :: NotInExternalCache ) ;
385395 }
386396
387- let fqp = path. clone ( ) ;
388- if let Some ( last) = path. last_mut ( ) {
389- * last = Symbol :: intern ( & format ! ( "{}.{last}.html" , item_type. as_str( ) ) ) ;
397+ // FIXME: Try to use `iter().chain().once()` instead.
398+ let mut prev = None ;
399+ if let Some ( last) = path. pop ( ) {
400+ path. push ( Symbol :: intern ( & format ! ( "{}.{last}.html" , item_type. as_str( ) ) ) ) ;
401+ prev = Some ( last) ;
390402 }
391403
392404 let url = match cache. extern_locations [ & def_id. krate ] {
@@ -407,18 +419,20 @@ fn generate_macro_def_id_path(
407419 return Err ( HrefError :: NotInExternalCache ) ;
408420 }
409421 } ;
410- Ok ( ( url, item_type, fqp) )
422+ if let Some ( prev) = prev {
423+ path. pop ( ) ;
424+ path. push ( prev) ;
425+ }
426+ Ok ( HrefInfo { url, kind : item_type, rust_path : path } )
411427}
412428
413- /// If the function succeeded, it will return the full URL to the item, its type and a `Vec`
414- /// representing its `use` path.
415429fn generate_item_def_id_path (
416430 mut def_id : DefId ,
417431 original_def_id : DefId ,
418432 cx : & Context < ' _ > ,
419433 root_path : Option < & str > ,
420434 original_def_kind : DefKind ,
421- ) -> Result < ( String , ItemType , Vec < Symbol > ) , HrefError > {
435+ ) -> Result < HrefInfo , HrefError > {
422436 use rustc_middle:: traits:: ObligationCause ;
423437 use rustc_trait_selection:: infer:: TyCtxtInferExt ;
424438 use rustc_trait_selection:: traits:: query:: normalize:: QueryNormalizeExt ;
@@ -454,7 +468,7 @@ fn generate_item_def_id_path(
454468 let kind = ItemType :: from_def_kind ( original_def_kind, Some ( def_kind) ) ;
455469 url_parts = format ! ( "{url_parts}#{kind}.{}" , tcx. item_name( original_def_id) )
456470 } ;
457- Ok ( ( url_parts, shortty, fqp) )
471+ Ok ( HrefInfo { url : url_parts, kind : shortty, rust_path : fqp } )
458472}
459473
460474/// Checks if the given defid refers to an item that is unnamable, such as one defined in a const block.
@@ -529,7 +543,7 @@ pub(crate) fn href_with_root_path(
529543 original_did : DefId ,
530544 cx : & Context < ' _ > ,
531545 root_path : Option < & str > ,
532- ) -> Result < ( String , ItemType , Vec < Symbol > ) , HrefError > {
546+ ) -> Result < HrefInfo , HrefError > {
533547 let tcx = cx. tcx ( ) ;
534548 let def_kind = tcx. def_kind ( original_did) ;
535549 let did = match def_kind {
@@ -595,14 +609,14 @@ pub(crate) fn href_with_root_path(
595609 }
596610 }
597611 } ;
598- let url_parts = make_href ( root_path, shortty, url_parts, fqp, is_remote) ;
599- Ok ( ( url_parts, shortty, fqp. clone ( ) ) )
612+ Ok ( HrefInfo {
613+ url : make_href ( root_path, shortty, url_parts, fqp, is_remote) ,
614+ kind : shortty,
615+ rust_path : fqp. clone ( ) ,
616+ } )
600617}
601618
602- pub ( crate ) fn href (
603- did : DefId ,
604- cx : & Context < ' _ > ,
605- ) -> Result < ( String , ItemType , Vec < Symbol > ) , HrefError > {
619+ pub ( crate ) fn href ( did : DefId , cx : & Context < ' _ > ) -> Result < HrefInfo , HrefError > {
606620 href_with_root_path ( did, cx, None )
607621}
608622
@@ -689,12 +703,12 @@ fn resolved_path(
689703 } else {
690704 let path = fmt:: from_fn ( |f| {
691705 if use_absolute {
692- if let Ok ( ( _ , _ , fqp ) ) = href ( did, cx) {
706+ if let Ok ( HrefInfo { rust_path , .. } ) = href ( did, cx) {
693707 write ! (
694708 f,
695709 "{path}::{anchor}" ,
696- path = join_path_syms( & fqp [ ..fqp . len( ) - 1 ] ) ,
697- anchor = print_anchor( did, * fqp . last( ) . unwrap( ) , cx)
710+ path = join_path_syms( & rust_path [ ..rust_path . len( ) - 1 ] ) ,
711+ anchor = print_anchor( did, * rust_path . last( ) . unwrap( ) , cx)
698712 )
699713 } else {
700714 write ! ( f, "{}" , last. name)
@@ -823,12 +837,11 @@ fn print_higher_ranked_params_with_space(
823837
824838pub ( crate ) fn print_anchor ( did : DefId , text : Symbol , cx : & Context < ' _ > ) -> impl Display {
825839 fmt:: from_fn ( move |f| {
826- let parts = href ( did, cx) ;
827- if let Ok ( ( url, short_ty, fqp) ) = parts {
840+ if let Ok ( HrefInfo { url, kind, rust_path } ) = href ( did, cx) {
828841 write ! (
829842 f,
830- r#"<a class="{short_ty }" href="{url}" title="{short_ty } {path}">{text}</a>"# ,
831- path = join_path_syms( fqp ) ,
843+ r#"<a class="{kind }" href="{url}" title="{kind } {path}">{text}</a>"# ,
844+ path = join_path_syms( rust_path ) ,
832845 text = EscapeBodyText ( text. as_str( ) ) ,
833846 )
834847 } else {
@@ -1055,14 +1068,14 @@ fn print_qpath_data(qpath_data: &clean::QPathData, cx: &Context<'_>) -> impl Dis
10551068 None => self_type. def_id ( cx. cache ( ) ) . and_then ( |did| href ( did, cx) . ok ( ) ) ,
10561069 } ;
10571070
1058- if let Some ( ( url, _ , path ) ) = parent_href {
1071+ if let Some ( HrefInfo { url, rust_path , .. } ) = parent_href {
10591072 write ! (
10601073 f,
10611074 "<a class=\" associatedtype\" href=\" {url}#{shortty}.{name}\" \
10621075 title=\" type {path}::{name}\" >{name}</a>",
10631076 shortty = ItemType :: AssocType ,
10641077 name = assoc. name,
1065- path = join_path_syms( path ) ,
1078+ path = join_path_syms( rust_path ) ,
10661079 )
10671080 } else {
10681081 write ! ( f, "{}" , assoc. name)
0 commit comments