Skip to content

Commit 002b000

Browse files
rename the type in an impl to match its containing page
1 parent 9649c1f commit 002b000

File tree

4 files changed

+76
-29
lines changed

4 files changed

+76
-29
lines changed

src/librustdoc/html/format.rs

+36-19
Original file line numberDiff line numberDiff line change
@@ -440,28 +440,29 @@ pub fn href(did: DefId) -> Option<(String, ItemType, Vec<String>)> {
440440
/// Used when rendering a `ResolvedPath` structure. This invokes the `path`
441441
/// rendering function with the necessary arguments for linking to a local path.
442442
fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path,
443-
print_all: bool, use_absolute: bool) -> fmt::Result {
443+
print_all: bool, use_absolute: bool, rename: Option<&str>) -> fmt::Result {
444444
let last = path.segments.last().unwrap();
445+
let last_name = rename.unwrap_or(&last.name);
445446

446447
if print_all {
447448
for seg in &path.segments[..path.segments.len() - 1] {
448449
write!(w, "{}::", seg.name)?;
449450
}
450451
}
451452
if w.alternate() {
452-
write!(w, "{:#}{:#}", HRef::new(did, &last.name), last.args)?;
453+
write!(w, "{:#}{:#}", HRef::new(did, last_name), last.args)?;
453454
} else {
454455
let path = if use_absolute {
455456
match href(did) {
456457
Some((_, _, fqp)) => {
457458
format!("{}::{}",
458459
fqp[..fqp.len() - 1].join("::"),
459-
HRef::new(did, fqp.last().unwrap()))
460+
HRef::new(did, rename.or(fqp.last().map(|n| &**n)).unwrap()))
460461
}
461-
None => HRef::new(did, &last.name).to_string(),
462+
None => HRef::new(did, last_name).to_string(),
462463
}
463464
} else {
464-
HRef::new(did, &last.name).to_string()
465+
HRef::new(did, last_name).to_string()
465466
};
466467
write!(w, "{}{}", path, last.args)?;
467468
}
@@ -547,7 +548,14 @@ impl<'a> fmt::Display for HRef<'a> {
547548
}
548549
}
549550

550-
fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt::Result {
551+
/// Writes the given type into the given formatter, optionally printing its full path or using the
552+
/// given name instead.
553+
fn fmt_type(
554+
t: &clean::Type,
555+
f: &mut fmt::Formatter,
556+
use_absolute: bool,
557+
rename: Option<&str>,
558+
) -> fmt::Result {
551559
match *t {
552560
clean::Generic(ref name) => {
553561
f.write_str(name)
@@ -557,7 +565,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt:
557565
f.write_str("dyn ")?;
558566
}
559567
// Paths like T::Output and Self::Output should be rendered with all segments
560-
resolved_path(f, did, path, is_generic, use_absolute)?;
568+
resolved_path(f, did, path, is_generic, use_absolute, rename)?;
561569
tybounds(f, typarams)
562570
}
563571
clean::Infer => write!(f, "_"),
@@ -657,17 +665,17 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt:
657665
}
658666
clean::ResolvedPath { typarams: Some(ref v), .. } if !v.is_empty() => {
659667
write!(f, "{}{}{}(", amp, lt, m)?;
660-
fmt_type(&ty, f, use_absolute)?;
668+
fmt_type(&ty, f, use_absolute, rename)?;
661669
write!(f, ")")
662670
}
663671
clean::Generic(..) => {
664672
primitive_link(f, PrimitiveType::Reference,
665673
&format!("{}{}{}", amp, lt, m))?;
666-
fmt_type(&ty, f, use_absolute)
674+
fmt_type(&ty, f, use_absolute, rename)
667675
}
668676
_ => {
669677
write!(f, "{}{}{}", amp, lt, m)?;
670-
fmt_type(&ty, f, use_absolute)
678+
fmt_type(&ty, f, use_absolute, rename)
671679
}
672680
}
673681
}
@@ -736,14 +744,15 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt:
736744

737745
impl fmt::Display for clean::Type {
738746
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
739-
fmt_type(self, f, false)
747+
fmt_type(self, f, false, None)
740748
}
741749
}
742750

743751
fn fmt_impl(i: &clean::Impl,
744752
f: &mut fmt::Formatter,
745753
link_trait: bool,
746-
use_absolute: bool) -> fmt::Result {
754+
use_absolute: bool,
755+
rename: Option<&str>) -> fmt::Result {
747756
if f.alternate() {
748757
write!(f, "impl{:#} ", i.generics)?;
749758
} else {
@@ -771,9 +780,9 @@ fn fmt_impl(i: &clean::Impl,
771780
}
772781

773782
if let Some(ref ty) = i.blanket_impl {
774-
fmt_type(ty, f, use_absolute)?;
783+
fmt_type(ty, f, use_absolute, rename)?;
775784
} else {
776-
fmt_type(&i.for_, f, use_absolute)?;
785+
fmt_type(&i.for_, f, use_absolute, rename)?;
777786
}
778787

779788
fmt::Display::fmt(&WhereClause { gens: &i.generics, indent: 0, end_newline: true }, f)?;
@@ -782,15 +791,23 @@ fn fmt_impl(i: &clean::Impl,
782791

783792
impl fmt::Display for clean::Impl {
784793
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
785-
fmt_impl(self, f, true, false)
794+
fmt_impl(self, f, true, false, None)
786795
}
787796
}
788797

789798
// The difference from above is that trait is not hyperlinked.
790799
pub fn fmt_impl_for_trait_page(i: &clean::Impl,
791800
f: &mut fmt::Formatter,
792-
use_absolute: bool) -> fmt::Result {
793-
fmt_impl(i, f, false, use_absolute)
801+
use_absolute: bool,
802+
rename: Option<&str>) -> fmt::Result {
803+
fmt_impl(i, f, false, use_absolute, rename)
804+
}
805+
806+
/// Renders an `impl` block signature, but with the `for` type renamed to the given name.
807+
pub fn fmt_impl_renamed(i: &clean::Impl,
808+
f: &mut fmt::Formatter,
809+
rename: Option<&str>) -> fmt::Result {
810+
fmt_impl(i, f, true, false, rename)
794811
}
795812

796813
impl fmt::Display for clean::Arguments {
@@ -946,7 +963,7 @@ impl<'a> fmt::Display for VisSpace<'a> {
946963
{
947964
f.write_str("in ")?;
948965
}
949-
resolved_path(f, did, path, true, false)?;
966+
resolved_path(f, did, path, true, false, None)?;
950967
f.write_str(") ")
951968
}
952969
}
@@ -1004,7 +1021,7 @@ impl fmt::Display for clean::Import {
10041021
impl fmt::Display for clean::ImportSource {
10051022
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10061023
match self.did {
1007-
Some(did) => resolved_path(f, did, &self.path, true, false),
1024+
Some(did) => resolved_path(f, did, &self.path, true, false, None),
10081025
_ => {
10091026
for (i, seg) in self.path.segments.iter().enumerate() {
10101027
if i > 0 {

src/librustdoc/html/render.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ use html::escape::Escape;
7373
use html::format::{AsyncSpace, ConstnessSpace};
7474
use html::format::{GenericBounds, WhereClause, href, AbiSpace};
7575
use html::format::{VisSpace, Method, UnsafetySpace, MutableSpace};
76-
use html::format::fmt_impl_for_trait_page;
76+
use html::format::{fmt_impl_for_trait_page, fmt_impl_renamed};
7777
use html::item_type::ItemType;
7878
use html::markdown::{self, Markdown, MarkdownHtml, MarkdownSummaryLine, ErrorCodes, IdMap};
7979
use html::{highlight, layout, static_files};
@@ -2796,7 +2796,7 @@ fn render_implementor(cx: &Context, implementor: &Impl, w: &mut fmt::Formatter,
27962796
_ => false,
27972797
};
27982798
render_impl(w, cx, implementor, AssocItemLink::Anchor(None), RenderMode::Normal,
2799-
implementor.impl_item.stable_since(), false, Some(use_absolute))?;
2799+
implementor.impl_item.stable_since(), false, Some(use_absolute), None)?;
28002800
Ok(())
28012801
}
28022802

@@ -2806,8 +2806,9 @@ fn render_impls(cx: &Context, w: &mut fmt::Formatter,
28062806
for i in traits {
28072807
let did = i.trait_did().unwrap();
28082808
let assoc_link = AssocItemLink::GotoSource(did, &i.inner_impl().provided_trait_methods);
2809-
render_impl(w, cx, i, assoc_link,
2810-
RenderMode::Normal, containing_item.stable_since(), true, None)?;
2809+
let rename = containing_item.name.deref();
2810+
render_impl(w, cx, i, assoc_link, RenderMode::Normal,
2811+
containing_item.stable_since(), true, None, rename)?;
28112812
}
28122813
Ok(())
28132814
}
@@ -3065,7 +3066,7 @@ fn item_trait(
30653066
);
30663067
render_impl(w, cx, &implementor, assoc_link,
30673068
RenderMode::Normal, implementor.impl_item.stable_since(), false,
3068-
None)?;
3069+
None, None)?;
30693070
}
30703071
}
30713072

@@ -3713,9 +3714,10 @@ fn render_assoc_items(w: &mut fmt::Formatter,
37133714
RenderMode::ForDeref { mut_: deref_mut_ }
37143715
}
37153716
};
3717+
let rename = containing_item.name.deref();
37163718
for i in &non_trait {
37173719
render_impl(w, cx, i, AssocItemLink::Anchor(None), render_mode,
3718-
containing_item.stable_since(), true, None)?;
3720+
containing_item.stable_since(), true, None, rename)?;
37193721
}
37203722
}
37213723
if let AssocItemRender::DerefFor { .. } = what {
@@ -3896,7 +3898,8 @@ fn spotlight_decl(decl: &clean::FnDecl) -> Result<String, fmt::Error> {
38963898

38973899
fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLink,
38983900
render_mode: RenderMode, outer_version: Option<&str>,
3899-
show_def_docs: bool, use_absolute: Option<bool>) -> fmt::Result {
3901+
show_def_docs: bool, use_absolute: Option<bool>, rename: Option<&str>,
3902+
) -> fmt::Result {
39003903
if render_mode == RenderMode::Normal {
39013904
let id = cx.derive_id(match i.inner_impl().trait_ {
39023905
Some(ref t) => format!("impl-{}", small_url_encode(&format!("{:#}", t))),
@@ -3905,7 +3908,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
39053908
if let Some(use_absolute) = use_absolute {
39063909
write!(w, "<h3 id='{}' class='impl'><span class='in-band'><table class='table-display'>\
39073910
<tbody><tr><td><code>", id)?;
3908-
fmt_impl_for_trait_page(&i.inner_impl(), w, use_absolute)?;
3911+
fmt_impl_for_trait_page(&i.inner_impl(), w, use_absolute, rename)?;
39093912
if show_def_docs {
39103913
for it in &i.inner_impl().items {
39113914
if let clean::TypedefItem(ref tydef, _) = it.inner {
@@ -3919,8 +3922,10 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
39193922
write!(w, "</code>")?;
39203923
} else {
39213924
write!(w, "<h3 id='{}' class='impl'><span class='in-band'><table class='table-display'>\
3922-
<tbody><tr><td><code>{}</code>",
3923-
id, i.inner_impl())?;
3925+
<tbody><tr><td><code>",
3926+
id)?;
3927+
fmt_impl_renamed(i.inner_impl(), w, rename)?;
3928+
write!(w, "</code>")?;
39243929
}
39253930
write!(w, "<a href='#{}' class='anchor'></a>", id)?;
39263931
write!(w, "</span></td><td><span class='out-of-band'>")?;

src/librustdoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#![feature(crate_visibility_modifier)]
2626
#![feature(const_fn)]
2727
#![feature(drain_filter)]
28+
#![feature(inner_deref)]
2829

2930
#![recursion_limit="256"]
3031

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
mod inner {
12+
pub struct SomeStruct;
13+
14+
impl SomeStruct {
15+
pub fn new() -> SomeStruct { SomeStruct }
16+
}
17+
}
18+
19+
// @has rename/index.html
20+
// @has - '//a/@href' 'struct.MyStruct.html'
21+
// @has rename/struct.MyStruct.html
22+
// @has - '//code' 'impl MyStruct'
23+
// @!has - '//code' 'impl SomeStruct'
24+
pub use inner::SomeStruct as MyStruct;

0 commit comments

Comments
 (0)