@@ -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,7 +419,11 @@ 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
413429/// If the function succeeded, it will return the full URL to the item, its type and a `Vec`
@@ -418,7 +434,7 @@ fn generate_item_def_id_path(
418434 cx : & Context < ' _ > ,
419435 root_path : Option < & str > ,
420436 original_def_kind : DefKind ,
421- ) -> Result < ( String , ItemType , Vec < Symbol > ) , HrefError > {
437+ ) -> Result < HrefInfo , HrefError > {
422438 use rustc_middle:: traits:: ObligationCause ;
423439 use rustc_trait_selection:: infer:: TyCtxtInferExt ;
424440 use rustc_trait_selection:: traits:: query:: normalize:: QueryNormalizeExt ;
@@ -454,7 +470,7 @@ fn generate_item_def_id_path(
454470 let kind = ItemType :: from_def_kind ( original_def_kind, Some ( def_kind) ) ;
455471 url_parts = format ! ( "{url_parts}#{kind}.{}" , tcx. item_name( original_def_id) )
456472 } ;
457- Ok ( ( url_parts, shortty, fqp) )
473+ Ok ( HrefInfo { url : url_parts, kind : shortty, rust_path : fqp } )
458474}
459475
460476/// Checks if the given defid refers to an item that is unnamable, such as one defined in a const block.
@@ -529,7 +545,7 @@ pub(crate) fn href_with_root_path(
529545 original_did : DefId ,
530546 cx : & Context < ' _ > ,
531547 root_path : Option < & str > ,
532- ) -> Result < ( String , ItemType , Vec < Symbol > ) , HrefError > {
548+ ) -> Result < HrefInfo , HrefError > {
533549 let tcx = cx. tcx ( ) ;
534550 let def_kind = tcx. def_kind ( original_did) ;
535551 let did = match def_kind {
@@ -595,14 +611,14 @@ pub(crate) fn href_with_root_path(
595611 }
596612 }
597613 } ;
598- let url_parts = make_href ( root_path, shortty, url_parts, fqp, is_remote) ;
599- Ok ( ( url_parts, shortty, fqp. clone ( ) ) )
614+ Ok ( HrefInfo {
615+ url : make_href ( root_path, shortty, url_parts, fqp, is_remote) ,
616+ kind : shortty,
617+ rust_path : fqp. clone ( ) ,
618+ } )
600619}
601620
602- pub ( crate ) fn href (
603- did : DefId ,
604- cx : & Context < ' _ > ,
605- ) -> Result < ( String , ItemType , Vec < Symbol > ) , HrefError > {
621+ pub ( crate ) fn href ( did : DefId , cx : & Context < ' _ > ) -> Result < HrefInfo , HrefError > {
606622 href_with_root_path ( did, cx, None )
607623}
608624
@@ -689,12 +705,12 @@ fn resolved_path(
689705 } else {
690706 let path = fmt:: from_fn ( |f| {
691707 if use_absolute {
692- if let Ok ( ( _ , _ , fqp ) ) = href ( did, cx) {
708+ if let Ok ( HrefInfo { rust_path , .. } ) = href ( did, cx) {
693709 write ! (
694710 f,
695711 "{path}::{anchor}" ,
696- path = join_path_syms( & fqp [ ..fqp . len( ) - 1 ] ) ,
697- anchor = print_anchor( did, * fqp . last( ) . unwrap( ) , cx)
712+ path = join_path_syms( & rust_path [ ..rust_path . len( ) - 1 ] ) ,
713+ anchor = print_anchor( did, * rust_path . last( ) . unwrap( ) , cx)
698714 )
699715 } else {
700716 write ! ( f, "{}" , last. name)
@@ -823,12 +839,11 @@ fn print_higher_ranked_params_with_space(
823839
824840pub ( crate ) fn print_anchor ( did : DefId , text : Symbol , cx : & Context < ' _ > ) -> impl Display {
825841 fmt:: from_fn ( move |f| {
826- let parts = href ( did, cx) ;
827- if let Ok ( ( url, short_ty, fqp) ) = parts {
842+ if let Ok ( HrefInfo { url, kind, rust_path } ) = href ( did, cx) {
828843 write ! (
829844 f,
830- r#"<a class="{short_ty }" href="{url}" title="{short_ty } {path}">{text}</a>"# ,
831- path = join_path_syms( fqp ) ,
845+ r#"<a class="{kind }" href="{url}" title="{kind } {path}">{text}</a>"# ,
846+ path = join_path_syms( rust_path ) ,
832847 text = EscapeBodyText ( text. as_str( ) ) ,
833848 )
834849 } else {
@@ -1055,14 +1070,14 @@ fn print_qpath_data(qpath_data: &clean::QPathData, cx: &Context<'_>) -> impl Dis
10551070 None => self_type. def_id ( cx. cache ( ) ) . and_then ( |did| href ( did, cx) . ok ( ) ) ,
10561071 } ;
10571072
1058- if let Some ( ( url, _ , path ) ) = parent_href {
1073+ if let Some ( HrefInfo { url, rust_path , .. } ) = parent_href {
10591074 write ! (
10601075 f,
10611076 "<a class=\" associatedtype\" href=\" {url}#{shortty}.{name}\" \
10621077 title=\" type {path}::{name}\" >{name}</a>",
10631078 shortty = ItemType :: AssocType ,
10641079 name = assoc. name,
1065- path = join_path_syms( path ) ,
1080+ path = join_path_syms( rust_path ) ,
10661081 )
10671082 } else {
10681083 write ! ( f, "{}" , assoc. name)
0 commit comments