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_hir::Mutability;
|
||||||
use rustc_middle::middle::stability;
|
use rustc_middle::middle::stability;
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
|
||||||
use rustc_span::{
|
use rustc_span::{
|
||||||
symbol::{sym, Symbol},
|
symbol::{sym, Symbol},
|
||||||
BytePos, FileName, RealFileName,
|
BytePos, FileName, RealFileName,
|
||||||
|
@ -530,7 +530,11 @@ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|||||||
.values()
|
.values()
|
||||||
.flat_map(|AliasedTypeImpl { impl_, type_aliases }| {
|
.flat_map(|AliasedTypeImpl { impl_, type_aliases }| {
|
||||||
let mut ret = Vec::new();
|
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
|
// render_impl will filter out "impossible-to-call" methods
|
||||||
// to make that functionality work here, it needs to be called with
|
// 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
|
// 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();
|
let mut buf = Buffer::html();
|
||||||
cx.id_map = Default::default();
|
cx.id_map = Default::default();
|
||||||
cx.deref_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(
|
super::render_impl(
|
||||||
&mut buf,
|
&mut buf,
|
||||||
cx,
|
cx,
|
||||||
*impl_,
|
*impl_,
|
||||||
&type_alias_item,
|
&type_alias_item,
|
||||||
AssocItemLink::Anchor(None),
|
assoc_link,
|
||||||
RenderMode::Normal,
|
RenderMode::Normal,
|
||||||
None,
|
None,
|
||||||
&[],
|
&[],
|
||||||
|
@ -680,12 +680,14 @@ function preLoadCss(cssUrl) {
|
|||||||
|
|
||||||
let implementations = document.getElementById("implementations-list");
|
let implementations = document.getElementById("implementations-list");
|
||||||
let trait_implementations = document.getElementById("trait-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.
|
// We want to include the current type alias's impls, and no others.
|
||||||
const script = document.querySelector("script[data-self-path]");
|
const script = document.querySelector("script[data-self-path]");
|
||||||
const selfPath = script ? script.getAttribute("data-self-path") : null;
|
const selfPath = script ? script.getAttribute("data-self-path") : null;
|
||||||
|
|
||||||
// These sidebar blocks need filled in, too.
|
// These sidebar blocks need filled in, too.
|
||||||
|
const mainContent = document.querySelector("#main-content");
|
||||||
const sidebarSection = document.querySelector(".sidebar section");
|
const sidebarSection = document.querySelector(".sidebar section");
|
||||||
let methods = document.querySelector(".sidebar .block.method");
|
let methods = document.querySelector(".sidebar .block.method");
|
||||||
let associatedTypes = document.querySelector(".sidebar .block.associatedtype");
|
let associatedTypes = document.querySelector(".sidebar .block.associatedtype");
|
||||||
@ -719,18 +721,18 @@ function preLoadCss(cssUrl) {
|
|||||||
const h = document.createElement("h3");
|
const h = document.createElement("h3");
|
||||||
h.appendChild(link);
|
h.appendChild(link);
|
||||||
trait_implementations = outputList;
|
trait_implementations = outputList;
|
||||||
|
trait_implementations_header = outputListHeader;
|
||||||
sidebarSection.appendChild(h);
|
sidebarSection.appendChild(h);
|
||||||
sidebarTraitList = document.createElement("ul");
|
sidebarTraitList = document.createElement("ul");
|
||||||
sidebarTraitList.className = "block trait-implementation";
|
sidebarTraitList.className = "block trait-implementation";
|
||||||
sidebarSection.appendChild(sidebarTraitList);
|
sidebarSection.appendChild(sidebarTraitList);
|
||||||
const mainContent = document.querySelector("#main-content");
|
|
||||||
mainContent.appendChild(outputListHeader);
|
mainContent.appendChild(outputListHeader);
|
||||||
mainContent.appendChild(outputList);
|
mainContent.appendChild(outputList);
|
||||||
} else {
|
} else {
|
||||||
implementations = outputList;
|
implementations = outputList;
|
||||||
if (trait_implementations) {
|
if (trait_implementations) {
|
||||||
document.insertBefore(outputListHeader, trait_implementations);
|
mainContent.insertBefore(outputListHeader, trait_implementations_header);
|
||||||
document.insertBefore(outputList, trait_implementations);
|
mainContent.insertBefore(outputList, trait_implementations_header);
|
||||||
} else {
|
} else {
|
||||||
const mainContent = document.querySelector("#main-content");
|
const mainContent = document.querySelector("#main-content");
|
||||||
mainContent.appendChild(outputListHeader);
|
mainContent.appendChild(outputListHeader);
|
||||||
@ -762,7 +764,14 @@ function preLoadCss(cssUrl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i !== 0) {
|
if (i !== 0) {
|
||||||
|
const oldHref = `#${el.id}`;
|
||||||
|
const newHref = `#${el.id}-${i}`;
|
||||||
el.id = `${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);
|
idMap.set(el.id, i + 1);
|
||||||
});
|
});
|
||||||
|
@ -167,6 +167,26 @@ impl SomeOtherTypeWithMethodsAndInlining {
|
|||||||
pub fn some_other_method_directly(&self) {}
|
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 {
|
pub mod huge_amount_of_consts {
|
||||||
include!(concat!(env!("OUT_DIR"), "/huge_amount_of_consts.rs"));
|
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(3)", 'warning1')
|
||||||
assert-text: (".block.method li:nth-child(4)", 'warning2')
|
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 //
|
// Now, if JavaScript is disabled, only the first method will be present //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
javascript: false
|
javascript: false
|
||||||
reload:
|
go-to: "file://" + |DOC_PATH| + "/test_docs/type.SomeOtherTypeWithMethodsAndInlining.html"
|
||||||
|
|
||||||
// method directly on type alias
|
// method directly on type alias
|
||||||
wait-for: "//*[@id='method.some_other_method_directly']"
|
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.must_use']"
|
||||||
assert-false: "//*[@id='method.warning1']"
|
assert-false: "//*[@id='method.warning1']"
|
||||||
assert-false: "//*[@id='method.warning2']"
|
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.
|
// 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'
|
// @has - '//*[@class="sidebar-elems"]//h3/a[@href="#aliased-type"]' 'Aliased type'
|
||||||
// We check that we have the implementation of the type alias itself.
|
// 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()'
|
// @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.
|
// This trait implementation doesn't match the type alias parameters so shouldn't appear in docs.
|
||||||
// @!has - '//h3' 'impl Bar for GenericStruct<u32> {}'
|
// @!has - '//h3' 'impl Bar for GenericStruct<u32> {}'
|
||||||
|
Loading…
Reference in New Issue
Block a user