From cc615b2072e497a5ca6a77fee550c3314606b2b0 Mon Sep 17 00:00:00 2001 From: mitaa Date: Thu, 21 Apr 2016 18:05:15 +0200 Subject: [PATCH 1/3] Inline impls on traits too --- src/librustdoc/clean/inline.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index fd57a452e0aba..ff92a4583772c 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -76,6 +76,7 @@ fn try_inline_def(cx: &DocContext, tcx: &TyCtxt, let inner = match def { Def::Trait(did) => { record_extern_fqn(cx, did, clean::TypeTrait); + ret.extend(build_impls(cx, tcx, did)); clean::TraitItem(build_external_trait(cx, tcx, did)) } Def::Fn(did) => { From dca7f0162c862f0b592614da6d2215307da7e6c2 Mon Sep 17 00:00:00 2001 From: mitaa Date: Wed, 20 Apr 2016 17:30:26 +0200 Subject: [PATCH 2/3] Remove, now unnecessary, workaround This used to be done to avoid inlining impls referencing private items, but is now unnecessary since we actually check that impls do not reference non-doc-reachable items. --- src/librustdoc/clean/inline.rs | 20 ++-------------- src/librustdoc/core.rs | 6 ++--- src/librustdoc/test.rs | 4 ++-- src/test/auxiliary/issue-33113.rs | 17 +++++++++++++ .../auxiliary/rustdoc-trait-object-impl.rs | 24 +++++++++++++++++++ src/test/rustdoc/inline_cross/issue-32881.rs | 22 +++++++++++++++++ src/test/rustdoc/inline_cross/issue-33113.rs | 20 ++++++++++++++++ 7 files changed, 90 insertions(+), 23 deletions(-) create mode 100644 src/test/auxiliary/issue-33113.rs create mode 100644 src/test/auxiliary/rustdoc-trait-object-impl.rs create mode 100644 src/test/rustdoc/inline_cross/issue-32881.rs create mode 100644 src/test/rustdoc/inline_cross/issue-33113.rs diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index ff92a4583772c..e13b268878890 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -248,12 +248,10 @@ pub fn build_impls(cx: &DocContext, // Primarily, the impls will be used to populate the documentation for this // type being inlined, but impls can also be used when generating // documentation for primitives (no way to find those specifically). - if !cx.all_crate_impls.borrow_mut().contains_key(&did.krate) { - let mut impls = Vec::new(); + if cx.populated_crate_impls.borrow_mut().insert(did.krate) { for item in tcx.sess.cstore.crate_top_level_items(did.krate) { populate_impls(cx, tcx, item.def, &mut impls); } - cx.all_crate_impls.borrow_mut().insert(did.krate, impls); fn populate_impls(cx: &DocContext, tcx: &TyCtxt, def: cstore::DefLike, @@ -270,21 +268,7 @@ pub fn build_impls(cx: &DocContext, } } - let mut candidates = cx.all_crate_impls.borrow_mut(); - let candidates = candidates.get_mut(&did.krate).unwrap(); - for i in (0..candidates.len()).rev() { - let remove = match candidates[i].inner { - clean::ImplItem(ref i) => { - i.for_.def_id() == Some(did) || i.for_.primitive_type().is_some() - } - _ => continue, - }; - if remove { - impls.push(candidates.swap_remove(i)); - } - } - - return impls; + impls } pub fn build_impl(cx: &DocContext, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 6d1e91a687e58..0b3a0c19dacc4 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -30,7 +30,7 @@ use syntax::feature_gate::UnstableFeatures; use syntax::parse::token; use std::cell::{RefCell, Cell}; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::rc::Rc; use visit_ast::RustdocVisitor; @@ -54,7 +54,7 @@ pub struct DocContext<'a, 'tcx: 'a> { pub map: &'a hir_map::Map<'tcx>, pub maybe_typed: MaybeTyped<'a, 'tcx>, pub input: Input, - pub all_crate_impls: RefCell>>, + pub populated_crate_impls: RefCell>, pub deref_trait_did: Cell>, // 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 @@ -189,7 +189,7 @@ pub fn run_core(search_paths: SearchPaths, map: &tcx.map, maybe_typed: Typed(tcx), input: input, - all_crate_impls: RefCell::new(HashMap::new()), + populated_crate_impls: RefCell::new(HashSet::new()), deref_trait_did: Cell::new(None), access_levels: RefCell::new(access_levels), external_traits: RefCell::new(HashMap::new()), diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 487aac1806ea7..81fd1128afac8 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -9,7 +9,7 @@ // except according to those terms. use std::cell::{RefCell, Cell}; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::env; use std::ffi::OsString; use std::io::prelude::*; @@ -111,7 +111,7 @@ pub fn run(input: &str, maybe_typed: core::NotTyped(&sess), input: input, external_traits: RefCell::new(HashMap::new()), - all_crate_impls: RefCell::new(HashMap::new()), + populated_crate_impls: RefCell::new(HashSet::new()), deref_trait_did: Cell::new(None), access_levels: Default::default(), renderinfo: Default::default(), diff --git a/src/test/auxiliary/issue-33113.rs b/src/test/auxiliary/issue-33113.rs new file mode 100644 index 0000000000000..c476dda269029 --- /dev/null +++ b/src/test/auxiliary/issue-33113.rs @@ -0,0 +1,17 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name="bar"] + +pub trait Bar {} +pub struct Foo; + +impl<'a> Bar for &'a char {} +impl Bar for Foo {} diff --git a/src/test/auxiliary/rustdoc-trait-object-impl.rs b/src/test/auxiliary/rustdoc-trait-object-impl.rs new file mode 100644 index 0000000000000..317262f417512 --- /dev/null +++ b/src/test/auxiliary/rustdoc-trait-object-impl.rs @@ -0,0 +1,24 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::fmt; + +pub trait Bar {} + +impl<'a> Bar + 'a { + pub fn bar(&self) -> usize { 42 } +} + +impl<'a> fmt::Debug for Bar + 'a { + fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { + Ok(()) + } +} + diff --git a/src/test/rustdoc/inline_cross/issue-32881.rs b/src/test/rustdoc/inline_cross/issue-32881.rs new file mode 100644 index 0000000000000..948061bdcbed5 --- /dev/null +++ b/src/test/rustdoc/inline_cross/issue-32881.rs @@ -0,0 +1,22 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:rustdoc-trait-object-impl.rs +// build-aux-docs +// ignore-cross-compile + +extern crate rustdoc_trait_object_impl; + +// @has issue_32881/trait.Bar.html +// @has - '//code' "impl<'a> Bar" +// @has - '//code' "impl<'a> Debug for Bar" + +pub use rustdoc_trait_object_impl::Bar; + diff --git a/src/test/rustdoc/inline_cross/issue-33113.rs b/src/test/rustdoc/inline_cross/issue-33113.rs new file mode 100644 index 0000000000000..9ae8fefe730ef --- /dev/null +++ b/src/test/rustdoc/inline_cross/issue-33113.rs @@ -0,0 +1,20 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:issue-33113.rs +// build-aux-docs +// ignore-cross-compile + +extern crate bar; + +// @has issue_33113/trait.Bar.html +// @has - '//code' "for &'a char" +// @has - '//code' "for Foo" +pub use bar::Bar; From 6603c95414bd3adb10e6b3ba548f69952df8f290 Mon Sep 17 00:00:00 2001 From: mitaa Date: Sun, 24 Apr 2016 14:11:26 +0200 Subject: [PATCH 3/3] Check reachability for inlined extern links too An item is inlined and recorded as inlined even if it is `doc(hidden)`, leading to unchecked external links. --- src/librustdoc/html/format.rs | 8 ++++--- src/test/auxiliary/rustdoc-hidden.rs | 14 ++++++++++++ .../rustdoc/inline_cross/inline_hidden.rs | 22 +++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 src/test/auxiliary/rustdoc-hidden.rs create mode 100644 src/test/rustdoc/inline_cross/inline_hidden.rs diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index d4212bba59060..26d82ccea5b86 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -291,17 +291,19 @@ impl fmt::Display for clean::Path { pub fn href(did: DefId) -> Option<(String, ItemType, Vec)> { let cache = cache(); + if !did.is_local() && !cache.access_levels.is_doc_reachable(did) { + return None + } + let loc = CURRENT_LOCATION_KEY.with(|l| l.borrow().clone()); let &(ref fqp, shortty) = match cache.paths.get(&did) { Some(p) => p, None => return None, }; + let mut url = if did.is_local() || cache.inlined.contains(&did) { repeat("../").take(loc.len()).collect::() } else { - if !cache.access_levels.is_doc_reachable(did) { - return None - } match cache.extern_locations[&did.krate] { (_, render::Remote(ref s)) => s.to_string(), (_, render::Local) => repeat("../").take(loc.len()).collect(), diff --git a/src/test/auxiliary/rustdoc-hidden.rs b/src/test/auxiliary/rustdoc-hidden.rs new file mode 100644 index 0000000000000..aae3eb84fb5dd --- /dev/null +++ b/src/test/auxiliary/rustdoc-hidden.rs @@ -0,0 +1,14 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[doc(hidden)] +pub struct Foo; + +pub struct Bar; diff --git a/src/test/rustdoc/inline_cross/inline_hidden.rs b/src/test/rustdoc/inline_cross/inline_hidden.rs new file mode 100644 index 0000000000000..c59b5afd1c483 --- /dev/null +++ b/src/test/rustdoc/inline_cross/inline_hidden.rs @@ -0,0 +1,22 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:rustdoc-hidden.rs +// build-aux-docs +// ignore-cross-compile + +extern crate rustdoc_hidden; + +#[doc(no_inline)] +pub use rustdoc_hidden::Foo; + +// @has inline_hidden/fn.foo.html +// @!has - '//a/@title' 'Foo' +pub fn foo(_: Foo) {}