Skip to content

Commit 4c8d00a

Browse files
committed
rustdoc: generate implementors for all auto traits
Previously we would only generate a list of synthetic implementations for two well known traits – Send and Sync. With this patch all the auto traits known to rustc are considered. This includes such traits like Unpin and user’s own traits. Sadly the implementation still iterates through the list of crate items and checks them against the traits, which for non-std crates containing their own auto-traits will still not include types defined in std/core. It is an improvement nontheless.
1 parent 4fb77a0 commit 4c8d00a

File tree

8 files changed

+24
-83
lines changed

8 files changed

+24
-83
lines changed

src/librustdoc/clean/auto_trait.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
2727
let param_env = self.cx.tcx.param_env(param_env_def_id);
2828

2929
debug!("get_auto_trait_impls({:?})", ty);
30-
let auto_traits = self.cx.send_trait.into_iter().chain(
31-
Some(self.cx.tcx.require_lang_item(lang_items::SyncTraitLangItem))
32-
);
30+
let auto_traits = self.cx.auto_traits.iter().cloned();
3331
auto_traits.filter_map(|trait_def_id| {
3432
let trait_ref = ty::TraitRef {
3533
def_id: trait_def_id,

src/librustdoc/clean/mod.rs

+2-68
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use rustc::middle::resolve_lifetime as rl;
1717
use rustc::middle::lang_items;
1818
use rustc::middle::stability;
1919
use rustc::mir::interpret::{GlobalId, ConstValue};
20-
use rustc::hir::{self, HirVec};
21-
use rustc::hir::def::{self, Res, DefKind, CtorKind};
20+
use rustc::hir;
21+
use rustc::hir::def::{CtorKind, DefKind, Res};
2222
use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
2323
use rustc::ty::subst::{InternalSubsts, SubstsRef, UnpackedKind};
2424
use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind};
@@ -4418,72 +4418,6 @@ where
44184418
r
44194419
}
44204420

4421-
// Start of code copied from rust-clippy
4422-
4423-
pub fn path_to_def_local(tcx: TyCtxt<'_>, path: &[Symbol]) -> Option<DefId> {
4424-
let krate = tcx.hir().krate();
4425-
let mut items = krate.module.item_ids.clone();
4426-
let mut path_it = path.iter().peekable();
4427-
4428-
loop {
4429-
let segment = path_it.next()?;
4430-
4431-
for item_id in mem::replace(&mut items, HirVec::new()).iter() {
4432-
let item = tcx.hir().expect_item(item_id.id);
4433-
if item.ident.name == *segment {
4434-
if path_it.peek().is_none() {
4435-
return Some(tcx.hir().local_def_id_from_hir_id(item_id.id))
4436-
}
4437-
4438-
items = match &item.node {
4439-
&hir::ItemKind::Mod(ref m) => m.item_ids.clone(),
4440-
_ => panic!("Unexpected item {:?} in path {:?} path")
4441-
};
4442-
break;
4443-
}
4444-
}
4445-
}
4446-
}
4447-
4448-
pub fn path_to_def(tcx: TyCtxt<'_>, path: &[Symbol]) -> Option<DefId> {
4449-
let crates = tcx.crates();
4450-
4451-
let krate = crates
4452-
.iter()
4453-
.find(|&&krate| tcx.crate_name(krate) == path[0]);
4454-
4455-
if let Some(krate) = krate {
4456-
let krate = DefId {
4457-
krate: *krate,
4458-
index: CRATE_DEF_INDEX,
4459-
};
4460-
let mut items = tcx.item_children(krate);
4461-
let mut path_it = path.iter().skip(1).peekable();
4462-
4463-
loop {
4464-
let segment = path_it.next()?;
4465-
4466-
for item in mem::replace(&mut items, &[]).iter() {
4467-
if item.ident.name == *segment {
4468-
if path_it.peek().is_none() {
4469-
return match item.res {
4470-
def::Res::Def(DefKind::Trait, did) => Some(did),
4471-
_ => None,
4472-
}
4473-
}
4474-
4475-
items = tcx.item_children(item.res.def_id());
4476-
break;
4477-
}
4478-
}
4479-
}
4480-
} else {
4481-
None
4482-
}
4483-
}
4484-
4485-
// End of code copied from rust-clippy
4486-
44874421
#[derive(Eq, PartialEq, Hash, Copy, Clone, Debug)]
44884422
enum RegionTarget<'tcx> {
44894423
Region(Region<'tcx>),

src/librustdoc/core.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,13 @@ pub struct DocContext<'tcx> {
6767
pub ct_substs: RefCell<FxHashMap<DefId, clean::Constant>>,
6868
/// Table DefId of `impl Trait` in argument position -> bounds
6969
pub impl_trait_bounds: RefCell<FxHashMap<DefId, Vec<clean::GenericBound>>>,
70-
pub send_trait: Option<DefId>,
7170
pub fake_def_ids: RefCell<FxHashMap<CrateNum, DefId>>,
7271
pub all_fake_def_ids: RefCell<FxHashSet<DefId>>,
7372
/// Auto-trait or blanket impls processed so far, as `(self_ty, trait_def_id)`.
7473
// FIXME(eddyb) make this a `ty::TraitRef<'tcx>` set.
7574
pub generated_synthetics: RefCell<FxHashSet<(Ty<'tcx>, DefId)>>,
7675
pub all_traits: Vec<DefId>,
76+
pub auto_traits: Vec<DefId>,
7777
}
7878

7979
impl<'tcx> DocContext<'tcx> {
@@ -367,15 +367,10 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
367367
.collect()
368368
};
369369

370-
let send_trait = if crate_name == Some("core".to_string()) {
371-
clean::path_to_def_local(tcx, &[sym::marker, sym::Send])
372-
} else {
373-
clean::path_to_def(tcx, &[sym::core, sym::marker, sym::Send])
374-
};
375-
376370
let mut renderinfo = RenderInfo::default();
377371
renderinfo.access_levels = access_levels;
378372

373+
let all_traits = tcx.all_traits(LOCAL_CRATE).to_vec();
379374
let ctxt = DocContext {
380375
tcx,
381376
resolver,
@@ -388,11 +383,13 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
388383
lt_substs: Default::default(),
389384
ct_substs: Default::default(),
390385
impl_trait_bounds: Default::default(),
391-
send_trait: send_trait,
392386
fake_def_ids: Default::default(),
393387
all_fake_def_ids: Default::default(),
394388
generated_synthetics: Default::default(),
395-
all_traits: tcx.all_traits(LOCAL_CRATE).to_vec(),
389+
auto_traits: all_traits.iter().cloned().filter(|trait_def_id| {
390+
tcx.trait_is_auto(*trait_def_id)
391+
}).collect(),
392+
all_traits,
396393
};
397394
debug!("crate: {:?}", tcx.hir().krate());
398395

src/test/rustdoc/empty-section.rs

+3
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ pub struct Foo;
88
// @!has - 'Auto Trait Implementations'
99
impl !Send for Foo {}
1010
impl !Sync for Foo {}
11+
impl !std::marker::Unpin for Foo {}
12+
impl !std::panic::RefUnwindSafe for Foo {}
13+
impl !std::panic::UnwindSafe for Foo {}

src/test/rustdoc/issue-50159.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ impl<B, C> Signal2 for B where B: Signal<Item = C> {
1414
// @has - '//code' 'impl<B> Send for Switch<B> where <B as Signal>::Item: Send'
1515
// @has - '//code' 'impl<B> Sync for Switch<B> where <B as Signal>::Item: Sync'
1616
// @count - '//*[@id="implementations-list"]/*[@class="impl"]' 0
17-
// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 2
17+
// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 5
1818
pub struct Switch<B: Signal> {
1919
pub inner: <B as Signal2>::Item2,
2020
}

src/test/rustdoc/synthetic_auto/basic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// @has - '//code' 'impl<T> Send for Foo<T> where T: Send'
33
// @has - '//code' 'impl<T> Sync for Foo<T> where T: Sync'
44
// @count - '//*[@id="implementations-list"]/*[@class="impl"]' 0
5-
// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 2
5+
// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 5
66
pub struct Foo<T> {
77
field: T,
88
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#![feature(optin_builtin_traits)]
2+
3+
pub auto trait Banana {}
4+
5+
// @has crate_local/struct.Peach.html
6+
// @has - '//code' 'impl Banana for Peach'
7+
// @has - '//code' 'impl Send for Peach'
8+
// @has - '//code' 'impl Sync for Peach'
9+
pub struct Peach;

src/test/rustdoc/synthetic_auto/manual.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// 'impl<T> Send for Foo<T>'
77
//
88
// @count - '//*[@id="implementations-list"]/*[@class="impl"]' 1
9-
// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 1
9+
// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 4
1010
pub struct Foo<T> {
1111
field: T,
1212
}

0 commit comments

Comments
 (0)