Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display associated types of implementors #88490

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 62 additions & 29 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,11 +710,15 @@ fn render_impls(
containing_item,
assoc_link,
RenderMode::Normal,
true,
None,
false,
true,
&[],
ImplRenderingParameters {
show_def_docs: true,
is_on_foreign_type: false,
show_default_items: true,
show_non_assoc_items: true,
toggle_open_by_default: true,
},
);
buffer.into_inner()
})
Expand Down Expand Up @@ -1049,11 +1053,15 @@ fn render_assoc_items(
containing_item,
AssocItemLink::Anchor(None),
render_mode,
true,
None,
false,
true,
&[],
ImplRenderingParameters {
show_def_docs: true,
is_on_foreign_type: false,
show_default_items: true,
show_non_assoc_items: true,
toggle_open_by_default: true,
},
);
}
}
Expand Down Expand Up @@ -1243,20 +1251,26 @@ fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String {
out.into_inner()
}

#[derive(Clone, Copy, Debug)]
struct ImplRenderingParameters {
show_def_docs: bool,
is_on_foreign_type: bool,
show_default_items: bool,
/// Whether or not to show methods.
show_non_assoc_items: bool,
toggle_open_by_default: bool,
}

fn render_impl(
w: &mut Buffer,
cx: &Context<'_>,
i: &Impl,
parent: &clean::Item,
link: AssocItemLink<'_>,
render_mode: RenderMode,
show_def_docs: bool,
use_absolute: Option<bool>,
is_on_foreign_type: bool,
show_default_items: bool,
// This argument is used to reference same type with different paths to avoid duplication
// in documentation pages for trait with automatic implementations like "Send" and "Sync".
aliases: &[String],
rendering_params: ImplRenderingParameters,
) {
let cache = cx.cache();
let traits = &cache.traits;
Expand All @@ -1279,17 +1293,18 @@ fn render_impl(
render_mode: RenderMode,
is_default_item: bool,
trait_: Option<&clean::Trait>,
show_def_docs: bool,
rendering_params: ImplRenderingParameters,
) {
let item_type = item.type_();
let name = item.name.as_ref().unwrap();

let render_method_item = match render_mode {
RenderMode::Normal => true,
RenderMode::ForDeref { mut_: deref_mut_ } => {
should_render_item(&item, deref_mut_, cx.cache())
}
};
let render_method_item = rendering_params.show_non_assoc_items
&& match render_mode {
RenderMode::Normal => true,
RenderMode::ForDeref { mut_: deref_mut_ } => {
should_render_item(&item, deref_mut_, cx.cache())
}
};

let in_trait_class = if trait_.is_some() { " trait-impl" } else { "" };

Expand All @@ -1312,18 +1327,32 @@ fn render_impl(
} else {
// In case the item isn't documented,
// provide short documentation from the trait.
document_short(&mut doc_buffer, it, cx, link, parent, show_def_docs);
document_short(
&mut doc_buffer,
it,
cx,
link,
parent,
rendering_params.show_def_docs,
);
}
}
} else {
document_item_info(&mut info_buffer, cx, item, Some(parent));
if show_def_docs {
if rendering_params.show_def_docs {
document_full(&mut doc_buffer, item, cx);
short_documented = false;
}
}
} else {
document_short(&mut doc_buffer, item, cx, link, parent, show_def_docs);
document_short(
&mut doc_buffer,
item,
cx,
link,
parent,
rendering_params.show_def_docs,
);
}
}
let w = if short_documented && trait_.is_some() { interesting } else { boring };
Expand Down Expand Up @@ -1455,7 +1484,7 @@ fn render_impl(
render_mode,
false,
trait_.map(|t| &t.trait_),
show_def_docs,
rendering_params,
);
}

Expand All @@ -1468,7 +1497,7 @@ fn render_impl(
parent: &clean::Item,
containing_item: &clean::Item,
render_mode: RenderMode,
show_def_docs: bool,
rendering_params: ImplRenderingParameters,
) {
for trait_item in &t.items {
let n = trait_item.name;
Expand All @@ -1490,7 +1519,7 @@ fn render_impl(
render_mode,
true,
Some(t),
show_def_docs,
rendering_params,
);
}
}
Expand All @@ -1499,7 +1528,7 @@ fn render_impl(
// default items which weren't overridden in the implementation block.
// We don't emit documentation for default items if they appear in the
// Implementations on Foreign Types or Implementors sections.
if show_default_items {
if rendering_params.show_default_items {
if let Some(t) = trait_ {
render_default_items(
&mut default_impl_items,
Expand All @@ -1510,15 +1539,19 @@ fn render_impl(
&i.impl_item,
parent,
render_mode,
show_def_docs,
rendering_params,
);
}
}
if render_mode == RenderMode::Normal {
let toggled = !(impl_items.is_empty() && default_impl_items.is_empty());
if toggled {
close_tags.insert_str(0, "</details>");
write!(w, "<details class=\"rustdoc-toggle implementors-toggle\" open>");
write!(
w,
"<details class=\"rustdoc-toggle implementors-toggle\"{}>",
if rendering_params.toggle_open_by_default { " open" } else { "" }
);
write!(w, "<summary>")
}
render_impl_summary(
Expand All @@ -1527,9 +1560,9 @@ fn render_impl(
i,
parent,
parent,
show_def_docs,
rendering_params.show_def_docs,
use_absolute,
is_on_foreign_type,
rendering_params.is_on_foreign_type,
aliases,
);
if toggled {
Expand Down
28 changes: 19 additions & 9 deletions src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use rustc_span::symbol::{kw, sym, Symbol};
use super::{
collect_paths_for_type, document, ensure_trailing_slash, item_ty_to_strs, notable_traits_decl,
render_assoc_item, render_assoc_items, render_attributes_in_code, render_attributes_in_pre,
render_impl, render_impl_summary, render_stability_since_raw, write_srclink, AssocItemLink,
Context,
render_impl, render_stability_since_raw, write_srclink, AssocItemLink, Context,
ImplRenderingParameters,
};
use crate::clean::{self, GetDefId};
use crate::formats::item_type::ItemType;
Expand Down Expand Up @@ -736,11 +736,15 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
it,
assoc_link,
RenderMode::Normal,
false,
None,
true,
false,
&[],
ImplRenderingParameters {
show_def_docs: false,
is_on_foreign_type: true,
show_default_items: false,
show_non_assoc_items: true,
toggle_open_by_default: false,
},
);
}
}
Expand Down Expand Up @@ -1388,16 +1392,22 @@ fn render_implementor(
} => implementor_dups[&path.last()].1,
_ => false,
};
render_impl_summary(
render_impl(
w,
cx,
implementor,
trait_,
trait_,
false,
AssocItemLink::Anchor(None),
RenderMode::Normal,
Some(use_absolute),
false,
aliases,
ImplRenderingParameters {
show_def_docs: false,
is_on_foreign_type: false,
show_default_items: false,
show_non_assoc_items: false,
toggle_open_by_default: false,
},
);
}

Expand Down
18 changes: 9 additions & 9 deletions src/test/rustdoc-gui/implementors.goml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
goto: file://|DOC_PATH|/implementors/trait.Whatever.html
assert: "#implementors-list"
// There are supposed to be two implementors listed.
assert-count: ("#implementors-list > .impl", 2)
assert-count: ("#implementors-list .impl", 2)
// Now we check that both implementors have an anchor, an ID and a similar DOM.
assert: ("#implementors-list > .impl:nth-child(1) > a.anchor")
assert-attribute: ("#implementors-list > .impl:nth-child(1)", {"id": "impl-Whatever"})
assert-attribute: ("#implementors-list > .impl:nth-child(1) > a.anchor", {"href": "#impl-Whatever"})
assert: "#implementors-list > .impl:nth-child(1) > .code-header.in-band"
assert: ("#implementors-list .impl:nth-child(1) > a.anchor")
assert-attribute: ("#implementors-list .impl:nth-child(1)", {"id": "impl-Whatever"})
assert-attribute: ("#implementors-list .impl:nth-child(1) > a.anchor", {"href": "#impl-Whatever"})
assert: "#implementors-list .impl:nth-child(1) > .code-header.in-band"

assert: ("#implementors-list > .impl:nth-child(2) > a.anchor")
assert-attribute: ("#implementors-list > .impl:nth-child(2)", {"id": "impl-Whatever-1"})
assert-attribute: ("#implementors-list > .impl:nth-child(2) > a.anchor", {"href": "#impl-Whatever-1"})
assert: "#implementors-list > .impl:nth-child(2) > .code-header.in-band"
assert: ("#implementors-list .impl:nth-child(2) > a.anchor")
assert-attribute: ("#implementors-list .impl:nth-child(2)", {"id": "impl-Whatever-1"})
assert-attribute: ("#implementors-list .impl:nth-child(2) > a.anchor", {"href": "#impl-Whatever-1"})
assert: "#implementors-list .impl:nth-child(2) > .code-header.in-band"
6 changes: 5 additions & 1 deletion src/test/rustdoc-gui/src/lib2/implementors/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
pub trait Whatever {
type Foo;

fn method() {}
}

pub struct Struct;

impl Whatever for Struct {}
impl Whatever for Struct {
type Foo = u8;
}
4 changes: 3 additions & 1 deletion src/test/rustdoc-gui/src/lib2/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ impl Trait for Foo {
}


impl implementors::Whatever for Foo {}
impl implementors::Whatever for Foo {
type Foo = u32;
}

pub mod sub_mod {
/// ```txt
Expand Down
4 changes: 4 additions & 0 deletions src/test/rustdoc-gui/toggle-implementors.goml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// This test ensures that the implementors toggle are not open by default.
goto: file://|DOC_PATH|/implementors/trait.Whatever.html

assert-attribute-false: ("#implementors-list > details", {"open": ""}, ALL)
11 changes: 10 additions & 1 deletion src/test/rustdoc/trait-impl-items-links-and-anchors.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub trait MyTrait {
type Assoc;
const VALUE: u32;
const VALUE: u32 = 12;
fn trait_function(&self);
fn defaulted(&self) {}
fn defaulted_override(&self) {}
Expand Down Expand Up @@ -38,9 +38,11 @@ impl MyTrait for Vec<u8> {
}

impl MyTrait for MyStruct {
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//div[@id="associatedtype.Assoc-3"]//a[@class="anchor"]/@href' #associatedtype.Assoc-3
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//div[@id="associatedtype.Assoc"]//a[@class="type"]/@href' trait.MyTrait.html#associatedtype.Assoc
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//div[@id="associatedtype.Assoc"]//a[@class="anchor"]/@href' #associatedtype.Assoc
type Assoc = bool;
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//div[@id="associatedconstant.VALUE-3"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-3
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//div[@id="associatedconstant.VALUE"]//a[@class="constant"]/@href' trait.MyTrait.html#associatedconstant.VALUE
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//div[@id="associatedconstant.VALUE"]//a[@class="anchor"]/@href' #associatedconstant.VALUE
const VALUE: u32 = 20;
Expand All @@ -55,3 +57,10 @@ impl MyTrait for MyStruct {
}

pub struct MyStruct;

// We check that associated items with default values aren't generated in the implementors list.
impl MyTrait for (u8, u8) {
// @!has trait_impl_items_links_and_anchors/trait.MyTrait.html '//div[@id="associatedconstant.VALUE-4"]'
type Assoc = bool;
fn trait_function(&self) {}
}