Auto merge of #36266 - Sawyer47:issue-35169, r=alexcrichton
rustdoc: Filter more incorrect methods inherited through Deref Old code filtered out only static methods. This code also excludes &mut self methods if there is no DerefMut implementation. Fixes #35169
This commit is contained in:
commit
9627e9ef6e
@ -134,6 +134,8 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
|
|||||||
if let Some(t) = cx.tcx_opt() {
|
if let Some(t) = cx.tcx_opt() {
|
||||||
cx.deref_trait_did.set(t.lang_items.deref_trait());
|
cx.deref_trait_did.set(t.lang_items.deref_trait());
|
||||||
cx.renderinfo.borrow_mut().deref_trait_did = cx.deref_trait_did.get();
|
cx.renderinfo.borrow_mut().deref_trait_did = cx.deref_trait_did.get();
|
||||||
|
cx.deref_mut_trait_did.set(t.lang_items.deref_mut_trait());
|
||||||
|
cx.renderinfo.borrow_mut().deref_mut_trait_did = cx.deref_mut_trait_did.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut externs = Vec::new();
|
let mut externs = Vec::new();
|
||||||
@ -1117,6 +1119,10 @@ impl FnDecl {
|
|||||||
pub fn has_self(&self) -> bool {
|
pub fn has_self(&self) -> bool {
|
||||||
return self.inputs.values.len() > 0 && self.inputs.values[0].name == "self";
|
return self.inputs.values.len() > 0 && self.inputs.values[0].name == "self";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn self_type(&self) -> Option<SelfTy> {
|
||||||
|
self.inputs.values.get(0).and_then(|v| v.to_self())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
||||||
|
@ -53,6 +53,7 @@ pub struct DocContext<'a, 'tcx: 'a> {
|
|||||||
pub input: Input,
|
pub input: Input,
|
||||||
pub populated_crate_impls: RefCell<FnvHashSet<ast::CrateNum>>,
|
pub populated_crate_impls: RefCell<FnvHashSet<ast::CrateNum>>,
|
||||||
pub deref_trait_did: Cell<Option<DefId>>,
|
pub deref_trait_did: Cell<Option<DefId>>,
|
||||||
|
pub deref_mut_trait_did: Cell<Option<DefId>>,
|
||||||
// Note that external items for which `doc(hidden)` applies to are shown as
|
// Note that external items for which `doc(hidden)` applies to are shown as
|
||||||
// non-reachable while local items aren't. This is because we're reusing
|
// non-reachable while local items aren't. This is because we're reusing
|
||||||
// the access levels from crateanalysis.
|
// the access levels from crateanalysis.
|
||||||
@ -180,6 +181,7 @@ pub fn run_core(search_paths: SearchPaths,
|
|||||||
input: input,
|
input: input,
|
||||||
populated_crate_impls: RefCell::new(FnvHashSet()),
|
populated_crate_impls: RefCell::new(FnvHashSet()),
|
||||||
deref_trait_did: Cell::new(None),
|
deref_trait_did: Cell::new(None),
|
||||||
|
deref_mut_trait_did: Cell::new(None),
|
||||||
access_levels: RefCell::new(access_levels),
|
access_levels: RefCell::new(access_levels),
|
||||||
external_traits: RefCell::new(FnvHashMap()),
|
external_traits: RefCell::new(FnvHashMap()),
|
||||||
renderinfo: RefCell::new(Default::default()),
|
renderinfo: RefCell::new(Default::default()),
|
||||||
|
@ -64,7 +64,7 @@ use rustc::hir;
|
|||||||
use rustc::util::nodemap::{FnvHashMap, FnvHashSet};
|
use rustc::util::nodemap::{FnvHashMap, FnvHashSet};
|
||||||
use rustc_data_structures::flock;
|
use rustc_data_structures::flock;
|
||||||
|
|
||||||
use clean::{self, Attributes, GetDefId};
|
use clean::{self, Attributes, GetDefId, SelfTy, Mutability};
|
||||||
use doctree;
|
use doctree;
|
||||||
use fold::DocFolder;
|
use fold::DocFolder;
|
||||||
use html::escape::Escape;
|
use html::escape::Escape;
|
||||||
@ -266,6 +266,7 @@ pub struct Cache {
|
|||||||
seen_mod: bool,
|
seen_mod: bool,
|
||||||
stripped_mod: bool,
|
stripped_mod: bool,
|
||||||
deref_trait_did: Option<DefId>,
|
deref_trait_did: Option<DefId>,
|
||||||
|
deref_mut_trait_did: Option<DefId>,
|
||||||
|
|
||||||
// In rare case where a structure is defined in one module but implemented
|
// In rare case where a structure is defined in one module but implemented
|
||||||
// in another, if the implementing module is parsed before defining module,
|
// in another, if the implementing module is parsed before defining module,
|
||||||
@ -283,6 +284,7 @@ pub struct RenderInfo {
|
|||||||
pub external_paths: ::core::ExternalPaths,
|
pub external_paths: ::core::ExternalPaths,
|
||||||
pub external_typarams: FnvHashMap<DefId, String>,
|
pub external_typarams: FnvHashMap<DefId, String>,
|
||||||
pub deref_trait_did: Option<DefId>,
|
pub deref_trait_did: Option<DefId>,
|
||||||
|
pub deref_mut_trait_did: Option<DefId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper struct to render all source code to HTML pages
|
/// Helper struct to render all source code to HTML pages
|
||||||
@ -508,6 +510,7 @@ pub fn run(mut krate: clean::Crate,
|
|||||||
external_paths,
|
external_paths,
|
||||||
external_typarams,
|
external_typarams,
|
||||||
deref_trait_did,
|
deref_trait_did,
|
||||||
|
deref_mut_trait_did,
|
||||||
} = renderinfo;
|
} = renderinfo;
|
||||||
|
|
||||||
let external_paths = external_paths.into_iter()
|
let external_paths = external_paths.into_iter()
|
||||||
@ -532,6 +535,7 @@ pub fn run(mut krate: clean::Crate,
|
|||||||
orphan_impl_items: Vec::new(),
|
orphan_impl_items: Vec::new(),
|
||||||
traits: mem::replace(&mut krate.external_traits, FnvHashMap()),
|
traits: mem::replace(&mut krate.external_traits, FnvHashMap()),
|
||||||
deref_trait_did: deref_trait_did,
|
deref_trait_did: deref_trait_did,
|
||||||
|
deref_mut_trait_did: deref_mut_trait_did,
|
||||||
typarams: external_typarams,
|
typarams: external_typarams,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2603,7 +2607,13 @@ impl<'a> AssocItemLink<'a> {
|
|||||||
|
|
||||||
enum AssocItemRender<'a> {
|
enum AssocItemRender<'a> {
|
||||||
All,
|
All,
|
||||||
DerefFor { trait_: &'a clean::Type, type_: &'a clean::Type },
|
DerefFor { trait_: &'a clean::Type, type_: &'a clean::Type, deref_mut_: bool }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
|
enum RenderMode {
|
||||||
|
Normal,
|
||||||
|
ForDeref { mut_: bool },
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_assoc_items(w: &mut fmt::Formatter,
|
fn render_assoc_items(w: &mut fmt::Formatter,
|
||||||
@ -2620,19 +2630,19 @@ fn render_assoc_items(w: &mut fmt::Formatter,
|
|||||||
i.inner_impl().trait_.is_none()
|
i.inner_impl().trait_.is_none()
|
||||||
});
|
});
|
||||||
if !non_trait.is_empty() {
|
if !non_trait.is_empty() {
|
||||||
let render_header = match what {
|
let render_mode = match what {
|
||||||
AssocItemRender::All => {
|
AssocItemRender::All => {
|
||||||
write!(w, "<h2 id='methods'>Methods</h2>")?;
|
write!(w, "<h2 id='methods'>Methods</h2>")?;
|
||||||
true
|
RenderMode::Normal
|
||||||
}
|
}
|
||||||
AssocItemRender::DerefFor { trait_, type_ } => {
|
AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
|
||||||
write!(w, "<h2 id='deref-methods'>Methods from \
|
write!(w, "<h2 id='deref-methods'>Methods from \
|
||||||
{}<Target={}></h2>", trait_, type_)?;
|
{}<Target={}></h2>", trait_, type_)?;
|
||||||
false
|
RenderMode::ForDeref { mut_: deref_mut_ }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
for i in &non_trait {
|
for i in &non_trait {
|
||||||
render_impl(w, cx, i, AssocItemLink::Anchor(None), render_header,
|
render_impl(w, cx, i, AssocItemLink::Anchor(None), render_mode,
|
||||||
containing_item.stable_since())?;
|
containing_item.stable_since())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2644,21 +2654,25 @@ fn render_assoc_items(w: &mut fmt::Formatter,
|
|||||||
t.inner_impl().trait_.def_id() == c.deref_trait_did
|
t.inner_impl().trait_.def_id() == c.deref_trait_did
|
||||||
});
|
});
|
||||||
if let Some(impl_) = deref_impl {
|
if let Some(impl_) = deref_impl {
|
||||||
render_deref_methods(w, cx, impl_, containing_item)?;
|
let has_deref_mut = traits.iter().find(|t| {
|
||||||
|
t.inner_impl().trait_.def_id() == c.deref_mut_trait_did
|
||||||
|
}).is_some();
|
||||||
|
render_deref_methods(w, cx, impl_, containing_item, has_deref_mut)?;
|
||||||
}
|
}
|
||||||
write!(w, "<h2 id='implementations'>Trait \
|
write!(w, "<h2 id='implementations'>Trait \
|
||||||
Implementations</h2>")?;
|
Implementations</h2>")?;
|
||||||
for i in &traits {
|
for i in &traits {
|
||||||
let did = i.trait_did().unwrap();
|
let did = i.trait_did().unwrap();
|
||||||
let assoc_link = AssocItemLink::GotoSource(did, &i.inner_impl().provided_trait_methods);
|
let assoc_link = AssocItemLink::GotoSource(did, &i.inner_impl().provided_trait_methods);
|
||||||
render_impl(w, cx, i, assoc_link, true, containing_item.stable_since())?;
|
render_impl(w, cx, i, assoc_link,
|
||||||
|
RenderMode::Normal, containing_item.stable_since())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl,
|
fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl,
|
||||||
container_item: &clean::Item) -> fmt::Result {
|
container_item: &clean::Item, deref_mut: bool) -> fmt::Result {
|
||||||
let deref_type = impl_.inner_impl().trait_.as_ref().unwrap();
|
let deref_type = impl_.inner_impl().trait_.as_ref().unwrap();
|
||||||
let target = impl_.inner_impl().items.iter().filter_map(|item| {
|
let target = impl_.inner_impl().items.iter().filter_map(|item| {
|
||||||
match item.inner {
|
match item.inner {
|
||||||
@ -2666,7 +2680,8 @@ fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl,
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}).next().expect("Expected associated type binding");
|
}).next().expect("Expected associated type binding");
|
||||||
let what = AssocItemRender::DerefFor { trait_: deref_type, type_: target };
|
let what = AssocItemRender::DerefFor { trait_: deref_type, type_: target,
|
||||||
|
deref_mut_: deref_mut };
|
||||||
if let Some(did) = target.def_id() {
|
if let Some(did) = target.def_id() {
|
||||||
render_assoc_items(w, cx, container_item, did, what)
|
render_assoc_items(w, cx, container_item, did, what)
|
||||||
} else {
|
} else {
|
||||||
@ -2680,12 +2695,9 @@ fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render_header is false when we are rendering a `Deref` impl and true
|
|
||||||
// otherwise. If render_header is false, we will avoid rendering static
|
|
||||||
// methods, since they are not accessible for the type implementing `Deref`
|
|
||||||
fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLink,
|
fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLink,
|
||||||
render_header: bool, outer_version: Option<&str>) -> fmt::Result {
|
render_mode: RenderMode, outer_version: Option<&str>) -> fmt::Result {
|
||||||
if render_header {
|
if render_mode == RenderMode::Normal {
|
||||||
write!(w, "<h3 class='impl'><span class='in-band'><code>{}</code>", i.inner_impl())?;
|
write!(w, "<h3 class='impl'><span class='in-band'><code>{}</code>", i.inner_impl())?;
|
||||||
write!(w, "</span><span class='out-of-band'>")?;
|
write!(w, "</span><span class='out-of-band'>")?;
|
||||||
let since = i.impl_item.stability.as_ref().map(|s| &s.since[..]);
|
let since = i.impl_item.stability.as_ref().map(|s| &s.since[..]);
|
||||||
@ -2706,22 +2718,43 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn doc_impl_item(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item,
|
fn doc_impl_item(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item,
|
||||||
link: AssocItemLink, render_static: bool,
|
link: AssocItemLink, render_mode: RenderMode,
|
||||||
is_default_item: bool, outer_version: Option<&str>,
|
is_default_item: bool, outer_version: Option<&str>,
|
||||||
trait_: Option<&clean::Trait>) -> fmt::Result {
|
trait_: Option<&clean::Trait>) -> fmt::Result {
|
||||||
let item_type = item_type(item);
|
let item_type = item_type(item);
|
||||||
let name = item.name.as_ref().unwrap();
|
let name = item.name.as_ref().unwrap();
|
||||||
|
|
||||||
let is_static = match item.inner {
|
let render_method_item: bool = match render_mode {
|
||||||
clean::MethodItem(ref method) => !method.decl.has_self(),
|
RenderMode::Normal => true,
|
||||||
clean::TyMethodItem(ref method) => !method.decl.has_self(),
|
RenderMode::ForDeref { mut_: deref_mut_ } => {
|
||||||
_ => false
|
let self_type_opt = match item.inner {
|
||||||
|
clean::MethodItem(ref method) => method.decl.self_type(),
|
||||||
|
clean::TyMethodItem(ref method) => method.decl.self_type(),
|
||||||
|
_ => None
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(self_ty) = self_type_opt {
|
||||||
|
let by_mut_ref = match self_ty {
|
||||||
|
SelfTy::SelfBorrowed(_lifetime, mutability) => {
|
||||||
|
mutability == Mutability::Mutable
|
||||||
|
},
|
||||||
|
SelfTy::SelfExplicit(clean::BorrowedRef { mutability, .. }) => {
|
||||||
|
mutability == Mutability::Mutable
|
||||||
|
},
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
deref_mut_ || !by_mut_ref
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
match item.inner {
|
match item.inner {
|
||||||
clean::MethodItem(..) | clean::TyMethodItem(..) => {
|
clean::MethodItem(..) | clean::TyMethodItem(..) => {
|
||||||
// Only render when the method is not static or we allow static methods
|
// Only render when the method is not static or we allow static methods
|
||||||
if !is_static || render_static {
|
if render_method_item {
|
||||||
let id = derive_id(format!("{}.{}", item_type, name));
|
let id = derive_id(format!("{}.{}", item_type, name));
|
||||||
let ns_id = derive_id(format!("{}.{}", name, item_type.name_space()));
|
let ns_id = derive_id(format!("{}.{}", name, item_type.name_space()));
|
||||||
write!(w, "<h4 id='{}' class='{}'>", id, item_type)?;
|
write!(w, "<h4 id='{}' class='{}'>", id, item_type)?;
|
||||||
@ -2769,7 +2802,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
|
|||||||
_ => panic!("can't make docs for trait item with name {:?}", item.name)
|
_ => panic!("can't make docs for trait item with name {:?}", item.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !is_static || render_static {
|
if render_method_item || render_mode == RenderMode::Normal {
|
||||||
if !is_default_item {
|
if !is_default_item {
|
||||||
if let Some(t) = trait_ {
|
if let Some(t) = trait_ {
|
||||||
// The trait item may have been stripped so we might not
|
// The trait item may have been stripped so we might not
|
||||||
@ -2802,7 +2835,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
|
|||||||
|
|
||||||
write!(w, "<div class='impl-items'>")?;
|
write!(w, "<div class='impl-items'>")?;
|
||||||
for trait_item in &i.inner_impl().items {
|
for trait_item in &i.inner_impl().items {
|
||||||
doc_impl_item(w, cx, trait_item, link, render_header,
|
doc_impl_item(w, cx, trait_item, link, render_mode,
|
||||||
false, outer_version, trait_)?;
|
false, outer_version, trait_)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2810,7 +2843,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
|
|||||||
cx: &Context,
|
cx: &Context,
|
||||||
t: &clean::Trait,
|
t: &clean::Trait,
|
||||||
i: &clean::Impl,
|
i: &clean::Impl,
|
||||||
render_static: bool,
|
render_mode: RenderMode,
|
||||||
outer_version: Option<&str>) -> fmt::Result {
|
outer_version: Option<&str>) -> fmt::Result {
|
||||||
for trait_item in &t.items {
|
for trait_item in &t.items {
|
||||||
let n = trait_item.name.clone();
|
let n = trait_item.name.clone();
|
||||||
@ -2820,7 +2853,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
|
|||||||
let did = i.trait_.as_ref().unwrap().def_id().unwrap();
|
let did = i.trait_.as_ref().unwrap().def_id().unwrap();
|
||||||
let assoc_link = AssocItemLink::GotoSource(did, &i.provided_trait_methods);
|
let assoc_link = AssocItemLink::GotoSource(did, &i.provided_trait_methods);
|
||||||
|
|
||||||
doc_impl_item(w, cx, trait_item, assoc_link, render_static, true,
|
doc_impl_item(w, cx, trait_item, assoc_link, render_mode, true,
|
||||||
outer_version, None)?;
|
outer_version, None)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -2829,7 +2862,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
|
|||||||
// If we've implemented a trait, then also emit documentation for all
|
// If we've implemented a trait, then also emit documentation for all
|
||||||
// default items which weren't overridden in the implementation block.
|
// default items which weren't overridden in the implementation block.
|
||||||
if let Some(t) = trait_ {
|
if let Some(t) = trait_ {
|
||||||
render_default_items(w, cx, t, &i.inner_impl(), render_header, outer_version)?;
|
render_default_items(w, cx, t, &i.inner_impl(), render_mode, outer_version)?;
|
||||||
}
|
}
|
||||||
write!(w, "</div>")?;
|
write!(w, "</div>")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -110,6 +110,7 @@ pub fn run(input: &str,
|
|||||||
external_traits: RefCell::new(FnvHashMap()),
|
external_traits: RefCell::new(FnvHashMap()),
|
||||||
populated_crate_impls: RefCell::new(FnvHashSet()),
|
populated_crate_impls: RefCell::new(FnvHashSet()),
|
||||||
deref_trait_did: Cell::new(None),
|
deref_trait_did: Cell::new(None),
|
||||||
|
deref_mut_trait_did: Cell::new(None),
|
||||||
access_levels: Default::default(),
|
access_levels: Default::default(),
|
||||||
renderinfo: Default::default(),
|
renderinfo: Default::default(),
|
||||||
};
|
};
|
||||||
|
45
src/test/rustdoc/issue-35169-2.rs
Normal file
45
src/test/rustdoc/issue-35169-2.rs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
use std::ops::Deref;
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
|
||||||
|
pub struct Foo;
|
||||||
|
pub struct Bar;
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
pub fn by_ref(&self) {}
|
||||||
|
pub fn by_explicit_ref(self: &Foo) {}
|
||||||
|
pub fn by_mut_ref(&mut self) {}
|
||||||
|
pub fn by_explicit_mut_ref(self: &mut Foo) {}
|
||||||
|
pub fn static_foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for Bar {
|
||||||
|
type Target = Foo;
|
||||||
|
fn deref(&self) -> &Foo { loop {} }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for Bar {
|
||||||
|
fn deref_mut(&mut self) -> &mut Foo { loop {} }
|
||||||
|
}
|
||||||
|
|
||||||
|
// @has issue_35169_2/Bar.t.html
|
||||||
|
// @has issue_35169_2/struct.Bar.html
|
||||||
|
// @has - '//*[@id="by_ref.v"]' 'fn by_ref(&self)'
|
||||||
|
// @has - '//*[@id="method.by_ref"]' 'fn by_ref(&self)'
|
||||||
|
// @has - '//*[@id="by_explicit_ref.v"]' 'fn by_explicit_ref(self: &Foo)'
|
||||||
|
// @has - '//*[@id="method.by_explicit_ref"]' 'fn by_explicit_ref(self: &Foo)'
|
||||||
|
// @has - '//*[@id="by_mut_ref.v"]' 'fn by_mut_ref(&mut self)'
|
||||||
|
// @has - '//*[@id="method.by_mut_ref"]' 'fn by_mut_ref(&mut self)'
|
||||||
|
// @has - '//*[@id="by_explicit_mut_ref.v"]' 'fn by_explicit_mut_ref(self: &mut Foo)'
|
||||||
|
// @has - '//*[@id="method.by_explicit_mut_ref"]' 'fn by_explicit_mut_ref(self: &mut Foo)'
|
||||||
|
// @!has - '//*[@id="static_foo.v"]' 'fn static_foo()'
|
||||||
|
// @!has - '//*[@id="method.static_foo"]' 'fn static_foo()'
|
40
src/test/rustdoc/issue-35169.rs
Normal file
40
src/test/rustdoc/issue-35169.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
pub struct Foo;
|
||||||
|
pub struct Bar;
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
pub fn by_ref(&self) {}
|
||||||
|
pub fn by_explicit_ref(self: &Foo) {}
|
||||||
|
pub fn by_mut_ref(&mut self) {}
|
||||||
|
pub fn by_explicit_mut_ref(self: &mut Foo) {}
|
||||||
|
pub fn static_foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for Bar {
|
||||||
|
type Target = Foo;
|
||||||
|
fn deref(&self) -> &Foo { loop {} }
|
||||||
|
}
|
||||||
|
|
||||||
|
// @has issue_35169/Bar.t.html
|
||||||
|
// @has issue_35169/struct.Bar.html
|
||||||
|
// @has - '//*[@id="by_ref.v"]' 'fn by_ref(&self)'
|
||||||
|
// @has - '//*[@id="method.by_ref"]' 'fn by_ref(&self)'
|
||||||
|
// @has - '//*[@id="by_explicit_ref.v"]' 'fn by_explicit_ref(self: &Foo)'
|
||||||
|
// @has - '//*[@id="method.by_explicit_ref"]' 'fn by_explicit_ref(self: &Foo)'
|
||||||
|
// @!has - '//*[@id="by_mut_ref.v"]' 'fn by_mut_ref(&mut self)'
|
||||||
|
// @!has - '//*[@id="method.by_mut_ref"]' 'fn by_mut_ref(&mut self)'
|
||||||
|
// @!has - '//*[@id="by_explicit_mut_ref.v"]' 'fn by_explicit_mut_ref(self: &mut Foo)'
|
||||||
|
// @!has - '//*[@id="method.by_explicit_mut_ref"]' 'fn by_explicit_mut_ref(self: &mut Foo)'
|
||||||
|
// @!has - '//*[@id="static_foo.v"]' 'fn static_foo()'
|
||||||
|
// @!has - '//*[@id="method.static_foo"]' 'fn static_foo()'
|
Loading…
Reference in New Issue
Block a user