77
88use std:: cell:: Cell ;
99use std:: fmt;
10+ use std:: iter;
1011
1112use rustc_data_structures:: captures:: Captures ;
1213use rustc_data_structures:: fx:: FxHashSet ;
@@ -16,12 +17,10 @@ use rustc_span::def_id::{DefId, CRATE_DEF_INDEX};
1617use rustc_target:: spec:: abi:: Abi ;
1718
1819use crate :: clean:: { self , utils:: find_nearest_parent_module, PrimitiveType } ;
19- use crate :: formats:: cache:: Cache ;
2020use crate :: formats:: item_type:: ItemType ;
2121use crate :: html:: escape:: Escape ;
2222use crate :: html:: render:: cache:: ExternalLocation ;
2323use crate :: html:: render:: Context ;
24- use crate :: html:: render:: CURRENT_DEPTH ;
2524
2625crate trait Print {
2726 fn print ( self , buffer : & mut Buffer ) ;
@@ -497,7 +496,7 @@ crate fn href_relative_parts<'a>(fqp: &'a [String], relative_to_fqp: &'a [String
497496 if f != r {
498497 let dissimilar_part_count = relative_to_fqp. len ( ) - i;
499498 let fqp_module = fqp[ i..fqp. len ( ) ] . iter ( ) . map ( String :: as_str) ;
500- return std :: iter:: repeat ( ".." ) . take ( dissimilar_part_count) . chain ( fqp_module) . collect ( ) ;
499+ return iter:: repeat ( ".." ) . take ( dissimilar_part_count) . chain ( fqp_module) . collect ( ) ;
501500 }
502501 }
503502 // e.g. linking to std::sync::atomic from std::sync
@@ -506,7 +505,7 @@ crate fn href_relative_parts<'a>(fqp: &'a [String], relative_to_fqp: &'a [String
506505 // e.g. linking to std::sync from std::sync::atomic
507506 } else if fqp. len ( ) < relative_to_fqp. len ( ) {
508507 let dissimilar_part_count = relative_to_fqp. len ( ) - fqp. len ( ) ;
509- std :: iter:: repeat ( ".." ) . take ( dissimilar_part_count) . collect ( )
508+ iter:: repeat ( ".." ) . take ( dissimilar_part_count) . collect ( )
510509 // linking to the same module
511510 } else {
512511 Vec :: new ( )
@@ -555,13 +554,14 @@ fn primitive_link(
555554 f : & mut fmt:: Formatter < ' _ > ,
556555 prim : clean:: PrimitiveType ,
557556 name : & str ,
558- m : & Cache ,
557+ cx : & Context < ' _ > ,
559558) -> fmt:: Result {
559+ let m = & cx. cache ( ) ;
560560 let mut needs_termination = false ;
561561 if !f. alternate ( ) {
562562 match m. primitive_locations . get ( & prim) {
563563 Some ( & def_id) if def_id. is_local ( ) => {
564- let len = CURRENT_DEPTH . with ( |s| s . get ( ) ) ;
564+ let len = cx . current . len ( ) ;
565565 let len = if len == 0 { 0 } else { len - 1 } ;
566566 write ! (
567567 f,
@@ -572,20 +572,28 @@ fn primitive_link(
572572 needs_termination = true ;
573573 }
574574 Some ( & def_id) => {
575+ let cname_str;
575576 let loc = match m. extern_locations [ & def_id. krate ] {
576- ( ref cname, _, ExternalLocation :: Remote ( ref s) ) => Some ( ( cname, s. to_string ( ) ) ) ,
577+ ( ref cname, _, ExternalLocation :: Remote ( ref s) ) => {
578+ cname_str = cname. as_str ( ) ;
579+ Some ( vec ! [ s. trim_end_matches( '/' ) , & cname_str[ ..] ] )
580+ }
577581 ( ref cname, _, ExternalLocation :: Local ) => {
578- let len = CURRENT_DEPTH . with ( |s| s. get ( ) ) ;
579- Some ( ( cname, "../" . repeat ( len) ) )
582+ cname_str = cname. as_str ( ) ;
583+ Some ( if cx. current . first ( ) . map ( |x| & x[ ..] ) == Some ( & cname_str[ ..] ) {
584+ iter:: repeat ( ".." ) . take ( cx. current . len ( ) - 1 ) . collect ( )
585+ } else {
586+ let cname = iter:: once ( & cname_str[ ..] ) ;
587+ iter:: repeat ( ".." ) . take ( cx. current . len ( ) ) . chain ( cname) . collect ( )
588+ } )
580589 }
581590 ( .., ExternalLocation :: Unknown ) => None ,
582591 } ;
583- if let Some ( ( cname , root ) ) = loc {
592+ if let Some ( loc ) = loc {
584593 write ! (
585594 f,
586- "<a class=\" primitive\" href=\" {}{}/primitive.{}.html\" >" ,
587- root,
588- cname,
595+ "<a class=\" primitive\" href=\" {}/primitive.{}.html\" >" ,
596+ loc. join( "/" ) ,
589597 prim. to_url_str( )
590598 ) ?;
591599 needs_termination = true ;
@@ -660,7 +668,7 @@ fn fmt_type<'cx>(
660668 fmt:: Display :: fmt ( & tybounds ( param_names, cx) , f)
661669 }
662670 clean:: Infer => write ! ( f, "_" ) ,
663- clean:: Primitive ( prim) => primitive_link ( f, prim, prim. as_str ( ) , & cx . cache ( ) ) ,
671+ clean:: Primitive ( prim) => primitive_link ( f, prim, prim. as_str ( ) , cx ) ,
664672 clean:: BareFunction ( ref decl) => {
665673 if f. alternate ( ) {
666674 write ! (
@@ -679,46 +687,46 @@ fn fmt_type<'cx>(
679687 decl. unsafety. print_with_space( ) ,
680688 print_abi_with_space( decl. abi)
681689 ) ?;
682- primitive_link ( f, PrimitiveType :: Fn , "fn" , & cx . cache ( ) ) ?;
690+ primitive_link ( f, PrimitiveType :: Fn , "fn" , cx ) ?;
683691 write ! ( f, "{}" , decl. decl. print( cx) )
684692 }
685693 }
686694 clean:: Tuple ( ref typs) => {
687695 match & typs[ ..] {
688- & [ ] => primitive_link ( f, PrimitiveType :: Unit , "()" , & cx . cache ( ) ) ,
696+ & [ ] => primitive_link ( f, PrimitiveType :: Unit , "()" , cx ) ,
689697 & [ ref one] => {
690- primitive_link ( f, PrimitiveType :: Tuple , "(" , & cx . cache ( ) ) ?;
698+ primitive_link ( f, PrimitiveType :: Tuple , "(" , cx ) ?;
691699 // Carry `f.alternate()` into this display w/o branching manually.
692700 fmt:: Display :: fmt ( & one. print ( cx) , f) ?;
693- primitive_link ( f, PrimitiveType :: Tuple , ",)" , & cx . cache ( ) )
701+ primitive_link ( f, PrimitiveType :: Tuple , ",)" , cx )
694702 }
695703 many => {
696- primitive_link ( f, PrimitiveType :: Tuple , "(" , & cx . cache ( ) ) ?;
704+ primitive_link ( f, PrimitiveType :: Tuple , "(" , cx ) ?;
697705 for ( i, item) in many. iter ( ) . enumerate ( ) {
698706 if i != 0 {
699707 write ! ( f, ", " ) ?;
700708 }
701709 fmt:: Display :: fmt ( & item. print ( cx) , f) ?;
702710 }
703- primitive_link ( f, PrimitiveType :: Tuple , ")" , & cx . cache ( ) )
711+ primitive_link ( f, PrimitiveType :: Tuple , ")" , cx )
704712 }
705713 }
706714 }
707715 clean:: Slice ( ref t) => {
708- primitive_link ( f, PrimitiveType :: Slice , "[" , & cx . cache ( ) ) ?;
716+ primitive_link ( f, PrimitiveType :: Slice , "[" , cx ) ?;
709717 fmt:: Display :: fmt ( & t. print ( cx) , f) ?;
710- primitive_link ( f, PrimitiveType :: Slice , "]" , & cx . cache ( ) )
718+ primitive_link ( f, PrimitiveType :: Slice , "]" , cx )
711719 }
712720 clean:: Array ( ref t, ref n) => {
713- primitive_link ( f, PrimitiveType :: Array , "[" , & cx . cache ( ) ) ?;
721+ primitive_link ( f, PrimitiveType :: Array , "[" , cx ) ?;
714722 fmt:: Display :: fmt ( & t. print ( cx) , f) ?;
715723 if f. alternate ( ) {
716- primitive_link ( f, PrimitiveType :: Array , & format ! ( "; {}]" , n) , & cx . cache ( ) )
724+ primitive_link ( f, PrimitiveType :: Array , & format ! ( "; {}]" , n) , cx )
717725 } else {
718- primitive_link ( f, PrimitiveType :: Array , & format ! ( "; {}]" , Escape ( n) ) , & cx . cache ( ) )
726+ primitive_link ( f, PrimitiveType :: Array , & format ! ( "; {}]" , Escape ( n) ) , cx )
719727 }
720728 }
721- clean:: Never => primitive_link ( f, PrimitiveType :: Never , "!" , & cx . cache ( ) ) ,
729+ clean:: Never => primitive_link ( f, PrimitiveType :: Never , "!" , cx ) ,
722730 clean:: RawPointer ( m, ref t) => {
723731 let m = match m {
724732 hir:: Mutability :: Mut => "mut" ,
@@ -731,24 +739,19 @@ fn fmt_type<'cx>(
731739 f,
732740 clean:: PrimitiveType :: RawPointer ,
733741 & format ! ( "*{} {:#}" , m, t. print( cx) ) ,
734- & cx . cache ( ) ,
742+ cx ,
735743 )
736744 } else {
737745 primitive_link (
738746 f,
739747 clean:: PrimitiveType :: RawPointer ,
740748 & format ! ( "*{} {}" , m, t. print( cx) ) ,
741- & cx . cache ( ) ,
749+ cx ,
742750 )
743751 }
744752 }
745753 _ => {
746- primitive_link (
747- f,
748- clean:: PrimitiveType :: RawPointer ,
749- & format ! ( "*{} " , m) ,
750- & cx. cache ( ) ,
751- ) ?;
754+ primitive_link ( f, clean:: PrimitiveType :: RawPointer , & format ! ( "*{} " , m) , cx) ?;
752755 fmt:: Display :: fmt ( & t. print ( cx) , f)
753756 }
754757 }
@@ -770,14 +773,14 @@ fn fmt_type<'cx>(
770773 f,
771774 PrimitiveType :: Slice ,
772775 & format ! ( "{}{}{}[{:#}]" , amp, lt, m, bt. print( cx) ) ,
773- & cx . cache ( ) ,
776+ cx ,
774777 )
775778 } else {
776779 primitive_link (
777780 f,
778781 PrimitiveType :: Slice ,
779782 & format ! ( "{}{}{}[{}]" , amp, lt, m, bt. print( cx) ) ,
780- & cx . cache ( ) ,
783+ cx ,
781784 )
782785 }
783786 }
@@ -786,14 +789,14 @@ fn fmt_type<'cx>(
786789 f,
787790 PrimitiveType :: Slice ,
788791 & format ! ( "{}{}{}[" , amp, lt, m) ,
789- & cx . cache ( ) ,
792+ cx ,
790793 ) ?;
791794 if f. alternate ( ) {
792795 write ! ( f, "{:#}" , bt. print( cx) ) ?;
793796 } else {
794797 write ! ( f, "{}" , bt. print( cx) ) ?;
795798 }
796- primitive_link ( f, PrimitiveType :: Slice , "]" , & cx . cache ( ) )
799+ primitive_link ( f, PrimitiveType :: Slice , "]" , cx )
797800 }
798801 }
799802 }
@@ -807,7 +810,7 @@ fn fmt_type<'cx>(
807810 f,
808811 PrimitiveType :: Reference ,
809812 & format ! ( "{}{}{}" , amp, lt, m) ,
810- & cx . cache ( ) ,
813+ cx ,
811814 ) ?;
812815 fmt_type ( & ty, f, use_absolute, cx)
813816 }
@@ -1292,7 +1295,7 @@ impl clean::ImportSource {
12921295 }
12931296 let name = self . path . last_name ( ) ;
12941297 if let hir:: def:: Res :: PrimTy ( p) = self . path . res {
1295- primitive_link ( f, PrimitiveType :: from ( p) , & * name, & cx . cache ( ) ) ?;
1298+ primitive_link ( f, PrimitiveType :: from ( p) , & * name, cx ) ?;
12961299 } else {
12971300 write ! ( f, "{}" , name) ?;
12981301 }
0 commit comments