rustdoc: make JS trait impls act more like HTML
This commit is contained in:
parent
62c67a6438
commit
46fdeb24fd
@ -55,7 +55,6 @@
|
||||
use rustc_hir::Mutability;
|
||||
use rustc_middle::middle::stability;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
||||
use rustc_span::{
|
||||
symbol::{sym, Symbol},
|
||||
BytePos, FileName, RealFileName,
|
||||
|
@ -530,7 +530,11 @@ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
.values()
|
||||
.flat_map(|AliasedTypeImpl { impl_, type_aliases }| {
|
||||
let mut ret = Vec::new();
|
||||
let trait_ = impl_.inner_impl().trait_.as_ref().map(|path| path.last().to_string());
|
||||
let trait_ = impl_
|
||||
.inner_impl()
|
||||
.trait_
|
||||
.as_ref()
|
||||
.map(|trait_| format!("{:#}", trait_.print(cx)));
|
||||
// render_impl will filter out "impossible-to-call" methods
|
||||
// to make that functionality work here, it needs to be called with
|
||||
// each type alias, and if it gives a different result, split the impl
|
||||
@ -538,12 +542,25 @@ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
let mut buf = Buffer::html();
|
||||
cx.id_map = Default::default();
|
||||
cx.deref_id_map = Default::default();
|
||||
let target_did = impl_
|
||||
.inner_impl()
|
||||
.trait_
|
||||
.as_ref()
|
||||
.map(|trait_| trait_.def_id())
|
||||
.or_else(|| impl_.inner_impl().for_.def_id(cache));
|
||||
let provided_methods;
|
||||
let assoc_link = if let Some(target_did) = target_did {
|
||||
provided_methods = impl_.inner_impl().provided_trait_methods(cx.tcx());
|
||||
AssocItemLink::GotoSource(ItemId::DefId(target_did), &provided_methods)
|
||||
} else {
|
||||
AssocItemLink::Anchor(None)
|
||||
};
|
||||
super::render_impl(
|
||||
&mut buf,
|
||||
cx,
|
||||
*impl_,
|
||||
&type_alias_item,
|
||||
AssocItemLink::Anchor(None),
|
||||
assoc_link,
|
||||
RenderMode::Normal,
|
||||
None,
|
||||
&[],
|
||||
|
@ -680,12 +680,14 @@ function preLoadCss(cssUrl) {
|
||||
|
||||
let implementations = document.getElementById("implementations-list");
|
||||
let trait_implementations = document.getElementById("trait-implementations-list");
|
||||
let trait_implementations_header = document.getElementById("trait-implementations");
|
||||
|
||||
// We want to include the current type alias's impls, and no others.
|
||||
const script = document.querySelector("script[data-self-path]");
|
||||
const selfPath = script ? script.getAttribute("data-self-path") : null;
|
||||
|
||||
// These sidebar blocks need filled in, too.
|
||||
const mainContent = document.querySelector("#main-content");
|
||||
const sidebarSection = document.querySelector(".sidebar section");
|
||||
let methods = document.querySelector(".sidebar .block.method");
|
||||
let associatedTypes = document.querySelector(".sidebar .block.associatedtype");
|
||||
@ -719,18 +721,18 @@ function preLoadCss(cssUrl) {
|
||||
const h = document.createElement("h3");
|
||||
h.appendChild(link);
|
||||
trait_implementations = outputList;
|
||||
trait_implementations_header = outputListHeader;
|
||||
sidebarSection.appendChild(h);
|
||||
sidebarTraitList = document.createElement("ul");
|
||||
sidebarTraitList.className = "block trait-implementation";
|
||||
sidebarSection.appendChild(sidebarTraitList);
|
||||
const mainContent = document.querySelector("#main-content");
|
||||
mainContent.appendChild(outputListHeader);
|
||||
mainContent.appendChild(outputList);
|
||||
} else {
|
||||
implementations = outputList;
|
||||
if (trait_implementations) {
|
||||
document.insertBefore(outputListHeader, trait_implementations);
|
||||
document.insertBefore(outputList, trait_implementations);
|
||||
mainContent.insertBefore(outputListHeader, trait_implementations_header);
|
||||
mainContent.insertBefore(outputList, trait_implementations_header);
|
||||
} else {
|
||||
const mainContent = document.querySelector("#main-content");
|
||||
mainContent.appendChild(outputListHeader);
|
||||
@ -762,7 +764,14 @@ function preLoadCss(cssUrl) {
|
||||
}
|
||||
}
|
||||
if (i !== 0) {
|
||||
const oldHref = `#${el.id}`;
|
||||
const newHref = `#${el.id}-${i}`;
|
||||
el.id = `${el.id}-${i}`;
|
||||
onEachLazy(template.content.querySelectorAll("a[href]"), link => {
|
||||
if (link.getAttribute("href") === oldHref) {
|
||||
link.href = newHref;
|
||||
}
|
||||
});
|
||||
}
|
||||
idMap.set(el.id, i + 1);
|
||||
});
|
||||
|
@ -167,6 +167,26 @@ impl SomeOtherTypeWithMethodsAndInlining {
|
||||
pub fn some_other_method_directly(&self) {}
|
||||
}
|
||||
|
||||
/// Another type alias, this time with methods.
|
||||
pub struct UnderlyingFooBarBaz;
|
||||
pub type SomeOtherTypeWithMethodsAndInliningAndTraits = UnderlyingFooBarBaz;
|
||||
|
||||
impl AsRef<str> for UnderlyingFooBarBaz {
|
||||
fn as_ref(&self) -> &str {
|
||||
"hello"
|
||||
}
|
||||
}
|
||||
|
||||
impl UnderlyingFooBarBaz {
|
||||
pub fn inherent_fn(&self) {}
|
||||
}
|
||||
|
||||
impl AsRef<u8> for SomeOtherTypeWithMethodsAndInliningAndTraits {
|
||||
fn as_ref(&self) -> &u8 {
|
||||
b"hello"
|
||||
}
|
||||
}
|
||||
|
||||
pub mod huge_amount_of_consts {
|
||||
include!(concat!(env!("OUT_DIR"), "/huge_amount_of_consts.rs"));
|
||||
}
|
||||
|
@ -24,11 +24,39 @@ assert-text: (".block.method li:nth-child(2)", 'some_other_method_directly')
|
||||
assert-text: (".block.method li:nth-child(3)", 'warning1')
|
||||
assert-text: (".block.method li:nth-child(4)", 'warning2')
|
||||
|
||||
// Now try trait implementation merging and duplicate renumbering
|
||||
go-to: "file://" + |DOC_PATH| + "/test_docs/type.SomeOtherTypeWithMethodsAndInliningAndTraits.html"
|
||||
|
||||
// method directly on type alias
|
||||
assert: "//*[@id='method.as_ref']"
|
||||
assert-count: ("//*[@id='method.as_ref']", 1)
|
||||
// method on underlying type
|
||||
assert: "//*[@id='method.as_ref-1']"
|
||||
|
||||
// sidebar items
|
||||
assert-count: (
|
||||
"//*[@class='sidebar-elems']//h3/a[@href='#trait-implementations']",
|
||||
1
|
||||
)
|
||||
assert-text: ("//*[@class='sidebar-elems']//li/a[@href='#impl-AsRef%3Cstr%3E-for-UnderlyingFooBarBaz']", "AsRef<str>")
|
||||
assert-text: (
|
||||
"//*[@class='sidebar-elems']//li/a[@href='#impl-AsRef%3Cu8%3E-for-UnderlyingFooBarBaz']",
|
||||
"AsRef<u8>"
|
||||
)
|
||||
assert-count: ("#trait-implementations-list", 1)
|
||||
assert-count: ("#trait-implementations-list > details", 2)
|
||||
// Both links point at the underlying trait
|
||||
store-property: ("//*[@id='method.as_ref']//a[@class='fn']", {"href": href})
|
||||
assert-property: ("//*[@id='method.as_ref-1']//a[@class='fn']", {"href": |href|})
|
||||
// Both links have a self-anchor
|
||||
assert: "//*[@id='method.as_ref']//a[@class='anchor'][@href='#method.as_ref']"
|
||||
assert: "//*[@id='method.as_ref-1']//a[@class='anchor'][@href='#method.as_ref-1']"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Now, if JavaScript is disabled, only the first method will be present //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
javascript: false
|
||||
reload:
|
||||
go-to: "file://" + |DOC_PATH| + "/test_docs/type.SomeOtherTypeWithMethodsAndInlining.html"
|
||||
|
||||
// method directly on type alias
|
||||
wait-for: "//*[@id='method.some_other_method_directly']"
|
||||
@ -37,3 +65,22 @@ wait-for: "//*[@id='method.some_other_method_directly']"
|
||||
assert-false: "//*[@id='method.must_use']"
|
||||
assert-false: "//*[@id='method.warning1']"
|
||||
assert-false: "//*[@id='method.warning2']"
|
||||
|
||||
// Now try trait implementation merging and duplicate renumbering
|
||||
go-to: "file://" + |DOC_PATH| + "/test_docs/type.SomeOtherTypeWithMethodsAndInliningAndTraits.html"
|
||||
|
||||
// methods directly on type alias
|
||||
assert: "//*[@id='method.as_ref']"
|
||||
assert-count: ("//*[@id='method.as_ref']", 1)
|
||||
// method on target type
|
||||
assert-false: "//*[@id='method.as_ref-1']"
|
||||
|
||||
// sidebar items
|
||||
assert-count: (
|
||||
"//*[@class='sidebar-elems']//h3/a[@href='#trait-implementations']",
|
||||
1
|
||||
)
|
||||
assert-false: "//a[@href='#impl-AsRef%3Cstr%3E-for-UnderlyingFooBarBaz']"
|
||||
assert: "//a[@href='#impl-AsRef%3Cu8%3E-for-UnderlyingFooBarBaz']"
|
||||
assert-count: ("#trait-implementations-list", 1)
|
||||
assert-count: ("#trait-implementations-list > details", 1)
|
||||
|
@ -22,7 +22,7 @@ impl Bar for GenericStruct<u32> {}
|
||||
// We check that "Aliased type" is also present as a title in the sidebar.
|
||||
// @has - '//*[@class="sidebar-elems"]//h3/a[@href="#aliased-type"]' 'Aliased type'
|
||||
// We check that we have the implementation of the type alias itself.
|
||||
// @has - '//*[@id="impl-TypedefStruct"]/h3' 'impl TypedefStruct'
|
||||
// @has - '//*[@id="impl-GenericStruct%3Cu8%3E"]/h3' 'impl TypedefStruct'
|
||||
// @has - '//*[@id="method.on_alias"]/h4' 'pub fn on_alias()'
|
||||
// This trait implementation doesn't match the type alias parameters so shouldn't appear in docs.
|
||||
// @!has - '//h3' 'impl Bar for GenericStruct<u32> {}'
|
||||
|
Loading…
Reference in New Issue
Block a user