let param_env = self.cx.tcx.param_env(param_env_def_id);
debug!("get_auto_trait_impls({:?})", ty);
- let auto_traits = self.cx.send_trait.into_iter().chain(
- Some(self.cx.tcx.require_lang_item(lang_items::SyncTraitLangItem))
- );
+ let auto_traits = self.cx.auto_traits.iter().cloned();
auto_traits.filter_map(|trait_def_id| {
let trait_ref = ty::TraitRef {
def_id: trait_def_id,
use rustc::middle::lang_items;
use rustc::middle::stability;
use rustc::mir::interpret::{GlobalId, ConstValue};
-use rustc::hir::{self, HirVec};
-use rustc::hir::def::{self, Res, DefKind, CtorKind};
+use rustc::hir;
+use rustc::hir::def::{CtorKind, DefKind, Res};
use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc::ty::subst::{InternalSubsts, SubstsRef, UnpackedKind};
use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind};
r
}
-// Start of code copied from rust-clippy
-
-pub fn path_to_def_local(tcx: TyCtxt<'_>, path: &[Symbol]) -> Option<DefId> {
- let krate = tcx.hir().krate();
- let mut items = krate.module.item_ids.clone();
- let mut path_it = path.iter().peekable();
-
- loop {
- let segment = path_it.next()?;
-
- for item_id in mem::replace(&mut items, HirVec::new()).iter() {
- let item = tcx.hir().expect_item(item_id.id);
- if item.ident.name == *segment {
- if path_it.peek().is_none() {
- return Some(tcx.hir().local_def_id_from_hir_id(item_id.id))
- }
-
- items = match &item.node {
- &hir::ItemKind::Mod(ref m) => m.item_ids.clone(),
- _ => panic!("Unexpected item {:?} in path {:?} path")
- };
- break;
- }
- }
- }
-}
-
-pub fn path_to_def(tcx: TyCtxt<'_>, path: &[Symbol]) -> Option<DefId> {
- let crates = tcx.crates();
-
- let krate = crates
- .iter()
- .find(|&&krate| tcx.crate_name(krate) == path[0]);
-
- if let Some(krate) = krate {
- let krate = DefId {
- krate: *krate,
- index: CRATE_DEF_INDEX,
- };
- let mut items = tcx.item_children(krate);
- let mut path_it = path.iter().skip(1).peekable();
-
- loop {
- let segment = path_it.next()?;
-
- for item in mem::replace(&mut items, &[]).iter() {
- if item.ident.name == *segment {
- if path_it.peek().is_none() {
- return match item.res {
- def::Res::Def(DefKind::Trait, did) => Some(did),
- _ => None,
- }
- }
-
- items = tcx.item_children(item.res.def_id());
- break;
- }
- }
- }
- } else {
- None
- }
-}
-
-// End of code copied from rust-clippy
-
#[derive(Eq, PartialEq, Hash, Copy, Clone, Debug)]
enum RegionTarget<'tcx> {
Region(Region<'tcx>),
pub ct_substs: RefCell<FxHashMap<DefId, clean::Constant>>,
/// Table DefId of `impl Trait` in argument position -> bounds
pub impl_trait_bounds: RefCell<FxHashMap<DefId, Vec<clean::GenericBound>>>,
- pub send_trait: Option<DefId>,
pub fake_def_ids: RefCell<FxHashMap<CrateNum, DefId>>,
pub all_fake_def_ids: RefCell<FxHashSet<DefId>>,
/// Auto-trait or blanket impls processed so far, as `(self_ty, trait_def_id)`.
// FIXME(eddyb) make this a `ty::TraitRef<'tcx>` set.
pub generated_synthetics: RefCell<FxHashSet<(Ty<'tcx>, DefId)>>,
pub all_traits: Vec<DefId>,
+ pub auto_traits: Vec<DefId>,
}
impl<'tcx> DocContext<'tcx> {
.collect()
};
- let send_trait = if crate_name == Some("core".to_string()) {
- clean::path_to_def_local(tcx, &[sym::marker, sym::Send])
- } else {
- clean::path_to_def(tcx, &[sym::core, sym::marker, sym::Send])
- };
-
let mut renderinfo = RenderInfo::default();
renderinfo.access_levels = access_levels;
+ let all_traits = tcx.all_traits(LOCAL_CRATE).to_vec();
let ctxt = DocContext {
tcx,
resolver,
lt_substs: Default::default(),
ct_substs: Default::default(),
impl_trait_bounds: Default::default(),
- send_trait: send_trait,
fake_def_ids: Default::default(),
all_fake_def_ids: Default::default(),
generated_synthetics: Default::default(),
- all_traits: tcx.all_traits(LOCAL_CRATE).to_vec(),
+ auto_traits: all_traits.iter().cloned().filter(|trait_def_id| {
+ tcx.trait_is_auto(*trait_def_id)
+ }).collect(),
+ all_traits,
};
debug!("crate: {:?}", tcx.hir().krate());
// @!has - 'Auto Trait Implementations'
impl !Send for Foo {}
impl !Sync for Foo {}
+impl !std::marker::Unpin for Foo {}
+impl !std::panic::RefUnwindSafe for Foo {}
+impl !std::panic::UnwindSafe for Foo {}
// @has - '//code' 'impl<B> Send for Switch<B> where <B as Signal>::Item: Send'
// @has - '//code' 'impl<B> Sync for Switch<B> where <B as Signal>::Item: Sync'
// @count - '//*[@id="implementations-list"]/*[@class="impl"]' 0
-// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 2
+// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 5
pub struct Switch<B: Signal> {
pub inner: <B as Signal2>::Item2,
}
// @has - '//code' 'impl<T> Send for Foo<T> where T: Send'
// @has - '//code' 'impl<T> Sync for Foo<T> where T: Sync'
// @count - '//*[@id="implementations-list"]/*[@class="impl"]' 0
-// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 2
+// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 5
pub struct Foo<T> {
field: T,
}
--- /dev/null
+#![feature(optin_builtin_traits)]
+
+pub auto trait Banana {}
+
+// @has crate_local/struct.Peach.html
+// @has - '//code' 'impl Banana for Peach'
+// @has - '//code' 'impl Send for Peach'
+// @has - '//code' 'impl Sync for Peach'
+pub struct Peach;
// 'impl<T> Send for Foo<T>'
//
// @count - '//*[@id="implementations-list"]/*[@class="impl"]' 1
-// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 1
+// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 4
pub struct Foo<T> {
field: T,
}