@@ -41,7 +41,7 @@ use std::collections::{BTreeMap, HashMap, HashSet};
4141use std:: default:: Default ;
4242use std:: error;
4343use std:: fmt:: { self , Display , Formatter } ;
44- use std:: fs:: { self , File } ;
44+ use std:: fs:: { self , File , OpenOptions } ;
4545use std:: io:: prelude:: * ;
4646use std:: io:: { self , BufWriter , BufReader } ;
4747use std:: iter:: repeat;
@@ -1409,11 +1409,23 @@ impl Context {
14091409 self . render_item ( & mut buf, & item, true ) . unwrap ( ) ;
14101410 // buf will be empty if the item is stripped and there is no redirect for it
14111411 if !buf. is_empty ( ) {
1412- let joint_dst = self . dst . join ( & item_path ( item_type ( & item) ,
1413- item. name . as_ref ( ) . unwrap ( ) ) ) ;
1412+ let name = item. name . as_ref ( ) . unwrap ( ) ;
1413+ let item_type = item_type ( & item) ;
1414+ let file_name = & item_path ( item_type, name) ;
1415+ let joint_dst = self . dst . join ( file_name) ;
14141416 try_err ! ( fs:: create_dir_all( & self . dst) , & self . dst) ;
14151417 let mut dst = try_err ! ( File :: create( & joint_dst) , & joint_dst) ;
14161418 try_err ! ( dst. write_all( & buf) , & joint_dst) ;
1419+
1420+ // Redirect from a sane URL using the namespace to Rustdoc's
1421+ // URL for the page.
1422+ let redir_name = format ! ( "{}.{}.html" , name, item_type. name_space( ) ) ;
1423+ let redir_dst = self . dst . join ( redir_name) ;
1424+ if let Ok ( mut redirect_out) = OpenOptions :: new ( ) . create_new ( true )
1425+ . write ( true )
1426+ . open ( & redir_dst) {
1427+ try_err ! ( layout:: redirect( & mut redirect_out, file_name) , & redir_dst) ;
1428+ }
14171429 }
14181430 }
14191431 Ok ( ( ) )
@@ -2270,9 +2282,12 @@ fn item_struct(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
22702282 if fields. peek ( ) . is_some ( ) {
22712283 write ! ( w, "<h2 class='fields'>Fields</h2>" ) ?;
22722284 for ( field, ty) in fields {
2273- write ! ( w, "<span id='{item_type}.{name}' class='{item_type}'><code>{name}: {ty}</code>
2274- </span><span class='stab {stab}'></span>" ,
2285+ write ! ( w, "<span id='{item_type}.{name}' class='{item_type}'>
2286+ <a id='{name}.{name_space}'>
2287+ <code>{name}: {ty}</code>
2288+ </a></span><span class='stab {stab}'></span>" ,
22752289 item_type = ItemType :: StructField ,
2290+ name_space = ItemType :: StructField . name_space( ) ,
22762291 stab = field. stability_class( ) ,
22772292 name = field. name. as_ref( ) . unwrap( ) ,
22782293 ty = ty) ?;
@@ -2341,8 +2356,10 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
23412356 if !e. variants . is_empty ( ) {
23422357 write ! ( w, "<h2 class='variants'>Variants</h2>\n " ) ?;
23432358 for variant in & e. variants {
2344- write ! ( w, "<span id='{item_type}.{name}' class='variant'><code>{name}" ,
2359+ write ! ( w, "<span id='{item_type}.{name}' class='variant'>\
2360+ <a id='{name}.{name_space}'><code>{name}",
23452361 item_type = ItemType :: Variant ,
2362+ name_space = ItemType :: Variant . name_space( ) ,
23462363 name = variant. name. as_ref( ) . unwrap( ) ) ?;
23472364 if let clean:: VariantItem ( ref var) = variant. inner {
23482365 if let clean:: TupleVariant ( ref tys) = var. kind {
@@ -2356,7 +2373,7 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
23562373 write ! ( w, ")" ) ?;
23572374 }
23582375 }
2359- write ! ( w, "</code></span>" ) ?;
2376+ write ! ( w, "</code></a></ span>" ) ?;
23602377 document ( w, cx, variant) ?;
23612378
23622379 use clean:: { Variant , StructVariant } ;
@@ -2368,9 +2385,12 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
23682385 if let StructFieldItem ( ref ty) = field. inner {
23692386 write ! ( w, "<tr><td \
23702387 id='variant.{v}.field.{f}'>\
2371- <code>{f}: {t}</code></td><td>",
2388+ <a id='{v}.{vns}.{f}.{fns}'>\
2389+ <code>{f}: {t}</code></a></td><td>",
23722390 v = variant. name. as_ref( ) . unwrap( ) ,
23732391 f = field. name. as_ref( ) . unwrap( ) ,
2392+ vns = ItemType :: Variant . name_space( ) ,
2393+ fns = ItemType :: StructField . name_space( ) ,
23742394 t = * ty) ?;
23752395 document ( w, cx, field) ?;
23762396 write ! ( w, "</td></tr>" ) ?;
@@ -2605,36 +2625,41 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
26052625 if !is_static || render_static {
26062626 let id = derive_id ( format ! ( "{}.{}" , item_type, name) ) ;
26072627 write ! ( w, "<h4 id='{}' class='{}'>" , id, item_type) ?;
2628+ write ! ( w, "<a id='{}.{}'>" , name, item_type. name_space( ) ) ?;
26082629 write ! ( w, "<code>" ) ?;
26092630 render_assoc_item ( w, item, link. anchor ( & id) ) ?;
26102631 write ! ( w, "</code>" ) ?;
26112632 render_stability_since_raw ( w, item. stable_since ( ) , outer_version) ?;
2612- write ! ( w, "</h4>\n " ) ?;
2633+ write ! ( w, "</a></ h4>\n " ) ?;
26132634 }
26142635 }
26152636 clean:: TypedefItem ( ref tydef, _) => {
26162637 let id = derive_id ( format ! ( "{}.{}" , ItemType :: AssociatedType , name) ) ;
2617- write ! ( w, "<h4 id='{}' class='{}'><code>" , id, item_type) ?;
2638+ write ! ( w, "<h4 id='{}' class='{}'>" , id, item_type) ?;
2639+ write ! ( w, "<a id='{}.{}'><code>" , name, item_type. name_space( ) ) ?;
26182640 assoc_type ( w, item, & Vec :: new ( ) , Some ( & tydef. type_ ) , link. anchor ( & id) ) ?;
2619- write ! ( w, "</code></h4>\n " ) ?;
2641+ write ! ( w, "</code></a></ h4>\n " ) ?;
26202642 }
26212643 clean:: AssociatedConstItem ( ref ty, ref default) => {
26222644 let id = derive_id ( format ! ( "{}.{}" , item_type, name) ) ;
2623- write ! ( w, "<h4 id='{}' class='{}'><code>" , id, item_type) ?;
2645+ write ! ( w, "<h4 id='{}' class='{}'>" , id, item_type) ?;
2646+ write ! ( w, "<a id='{}.{}'><code>" , name, item_type. name_space( ) ) ?;
26242647 assoc_const ( w, item, ty, default. as_ref ( ) , link. anchor ( & id) ) ?;
2625- write ! ( w, "</code></h4>\n " ) ?;
2648+ write ! ( w, "</code></a></ h4>\n " ) ?;
26262649 }
26272650 clean:: ConstantItem ( ref c) => {
26282651 let id = derive_id ( format ! ( "{}.{}" , item_type, name) ) ;
2629- write ! ( w, "<h4 id='{}' class='{}'><code>" , id, item_type) ?;
2652+ write ! ( w, "<h4 id='{}' class='{}'>" , id, item_type) ?;
2653+ write ! ( w, "<a id='{}.{}'><code>" , name, item_type. name_space( ) ) ?;
26302654 assoc_const ( w, item, & c. type_ , Some ( & c. expr ) , link. anchor ( & id) ) ?;
2631- write ! ( w, "</code></h4>\n " ) ?;
2655+ write ! ( w, "</code></a></ h4>\n " ) ?;
26322656 }
26332657 clean:: AssociatedTypeItem ( ref bounds, ref default) => {
26342658 let id = derive_id ( format ! ( "{}.{}" , item_type, name) ) ;
2635- write ! ( w, "<h4 id='{}' class='{}'><code>" , id, item_type) ?;
2659+ write ! ( w, "<h4 id='{}' class='{}'>" , id, item_type) ?;
2660+ write ! ( w, "<a id='{}.{}'><code>" , name, item_type. name_space( ) ) ?;
26362661 assoc_type ( w, item, bounds, default. as_ref ( ) , link. anchor ( & id) ) ?;
2637- write ! ( w, "</code></h4>\n " ) ?;
2662+ write ! ( w, "</code></a></ h4>\n " ) ?;
26382663 }
26392664 clean:: StrippedItem ( ..) => return Ok ( ( ) ) ,
26402665 _ => panic ! ( "can't make docs for trait item with name {:?}" , item. name)
0 commit comments