rustdoc: remove def_ctor hack.

This commit is contained in:
Eduard-Mihai Burtescu 2019-04-20 18:27:44 +03:00
parent f843ad60ef
commit c835607907
10 changed files with 146 additions and 518 deletions

View File

@ -77,15 +77,15 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
/// in the future.
pub fn find_auto_trait_generics<A>(
&self,
did: DefId,
ty: Ty<'tcx>,
param_env_def_id: DefId,
trait_did: DefId,
generics: &ty::Generics,
auto_trait_callback: impl for<'i> Fn(&InferCtxt<'_, 'tcx, 'i>, AutoTraitInfo<'i>) -> A,
) -> AutoTraitResult<A> {
let tcx = self.tcx;
let ty = self.tcx.type_of(did);
let orig_params = tcx.param_env(did);
let orig_params = tcx.param_env(param_env_def_id);
let trait_ref = ty::TraitRef {
def_id: trait_did,
@ -105,9 +105,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
match result {
Ok(Some(Vtable::VtableImpl(_))) => {
debug!(
"find_auto_trait_generics(did={:?}, trait_did={:?}, generics={:?}): \
"find_auto_trait_generics(ty={:?}, trait_did={:?}, generics={:?}): \
manual impl found, bailing out",
did, trait_did, generics
ty, trait_did, generics
);
true
}
@ -158,7 +158,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
let (new_env, user_env) = match self.evaluate_predicates(
&mut infcx,
did,
trait_did,
ty,
orig_params.clone(),
@ -172,7 +171,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
let (full_env, full_user_env) = self.evaluate_predicates(
&mut infcx,
did,
trait_did,
ty,
new_env.clone(),
@ -187,9 +185,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
});
debug!(
"find_auto_trait_generics(did={:?}, trait_did={:?}, generics={:?}): fulfilling \
"find_auto_trait_generics(ty={:?}, trait_did={:?}, generics={:?}): fulfilling \
with {:?}",
did, trait_did, generics, full_env
ty, trait_did, generics, full_env
);
infcx.clear_caches();
@ -289,7 +287,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
pub fn evaluate_predicates<'b, 'gcx, 'c>(
&self,
infcx: &InferCtxt<'b, 'tcx, 'c>,
ty_did: DefId,
trait_did: DefId,
ty: Ty<'c>,
param_env: ty::ParamEnv<'c>,
@ -401,9 +398,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
None
);
debug!(
"evaluate_nested_obligations(ty_did={:?}, trait_did={:?}): succeeded with '{:?}' \
"evaluate_nested_obligations(ty={:?}, trait_did={:?}): succeeded with '{:?}' \
'{:?}'",
ty_did, trait_did, new_env, final_user_env
ty, trait_did, new_env, final_user_env
);
return Some((new_env, final_user_env));

View File

@ -3,8 +3,6 @@ use rustc::traits::auto_trait as auto;
use rustc::ty::{self, TypeFoldable};
use std::fmt::Debug;
use self::def_ctor::{get_def_from_def_id, get_def_from_hir_id};
use super::*;
pub struct AutoTraitFinder<'a, 'tcx> {
@ -19,103 +17,71 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
AutoTraitFinder { cx, f }
}
pub fn get_with_def_id(&self, def_id: DefId) -> Vec<Item> {
get_def_from_def_id(&self.cx, def_id, &|def_ctor| {
self.get_auto_trait_impls(def_id, &def_ctor, None)
})
}
pub fn get_with_hir_id(&self, id: hir::HirId, name: String) -> Vec<Item> {
get_def_from_hir_id(&self.cx, id, name, &|def_ctor, name| {
let did = self.cx.tcx.hir().local_def_id_from_hir_id(id);
self.get_auto_trait_impls(did, &def_ctor, Some(name))
})
}
pub fn get_auto_trait_impls<F>(
// FIXME(eddyb) figure out a better way to pass information about
// parametrization of `ty` than `param_env_def_id`.
pub fn get_auto_trait_impls(
&self,
def_id: DefId,
def_ctor: &F,
name: Option<String>,
) -> Vec<Item>
where F: Fn(DefId) -> Def {
if self.cx
.tcx
.get_attrs(def_id)
.lists("doc")
.has_word("hidden")
{
debug!(
"get_auto_trait_impls(def_id={:?}, def_ctor=...): item has doc('hidden'), \
aborting",
def_id
);
return Vec::new();
}
let tcx = self.cx.tcx;
let generics = self.cx.tcx.generics_of(def_id);
ty: Ty<'tcx>,
param_env_def_id: DefId,
) -> Vec<Item> {
let generics = self.cx.tcx.generics_of(param_env_def_id);
debug!(
"get_auto_trait_impls(def_id={:?}, def_ctor=..., generics={:?}",
def_id, generics
"get_auto_trait_impls(param_env_def_id={:?}, generics={:?}",
param_env_def_id, generics
);
let auto_traits: Vec<_> = self.cx
.send_trait
.and_then(|send_trait| {
self.get_auto_trait_impl_for(
def_id,
name.clone(),
generics.clone(),
def_ctor,
ty,
param_env_def_id,
generics,
send_trait,
)
})
.into_iter()
.chain(self.get_auto_trait_impl_for(
def_id,
name,
generics.clone(),
def_ctor,
tcx.require_lang_item(lang_items::SyncTraitLangItem),
ty,
param_env_def_id,
generics,
self.cx.tcx.require_lang_item(lang_items::SyncTraitLangItem),
).into_iter())
.collect();
debug!(
"get_auto_traits: type {:?} auto_traits {:?}",
def_id, auto_traits
param_env_def_id, auto_traits
);
auto_traits
}
fn get_auto_trait_impl_for<F>(
fn get_auto_trait_impl_for(
&self,
def_id: DefId,
name: Option<String>,
generics: ty::Generics,
def_ctor: &F,
ty: Ty<'tcx>,
param_env_def_id: DefId,
generics: &ty::Generics,
trait_def_id: DefId,
) -> Option<Item>
where F: Fn(DefId) -> Def {
) -> Option<Item> {
if !self.cx
.generated_synthetics
.borrow_mut()
.insert((def_id, trait_def_id))
.insert((param_env_def_id, trait_def_id))
{
debug!(
"get_auto_trait_impl_for(def_id={:?}, generics={:?}, def_ctor=..., \
"get_auto_trait_impl_for(param_env_def_id={:?}, generics={:?}, \
trait_def_id={:?}): already generated, aborting",
def_id, generics, trait_def_id
param_env_def_id, generics, trait_def_id
);
return None;
}
let result = self.find_auto_trait_generics(def_id, trait_def_id, &generics);
let result = self.find_auto_trait_generics(ty, param_env_def_id, trait_def_id, &generics);
if result.is_auto() {
let trait_ = hir::TraitRef {
path: get_path_for_type(self.cx.tcx, trait_def_id, hir::def::Def::Trait),
hir_ref_id: hir::DUMMY_HIR_ID,
let trait_ref = ty::TraitRef {
def_id: trait_def_id,
substs: self.cx.tcx.mk_substs_trait(ty, &[]),
};
let polarity;
@ -140,7 +106,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
// Instead, we generate `impl !Send for Foo<T>`, which better
// expresses the fact that `Foo<T>` never implements `Send`,
// regardless of the choice of `T`.
let real_generics = (&generics, &Default::default());
let real_generics = (generics, &Default::default());
// Clean the generics, but ignore the '?Sized' bounds generated
// by the `Clean` impl
@ -153,22 +119,20 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
}
_ => unreachable!(),
};
let real_name = name.map(|name| Ident::from_str(&name));
let ty = self.cx.get_real_ty(def_id, def_ctor, &real_name, &generics);
return Some(Item {
source: Span::empty(),
name: None,
attrs: Default::default(),
visibility: None,
def_id: self.cx.next_def_id(def_id.krate),
def_id: self.cx.next_def_id(param_env_def_id.krate),
stability: None,
deprecation: None,
inner: ImplItem(Impl {
unsafety: hir::Unsafety::Normal,
generics: new_generics,
provided_trait_methods: Default::default(),
trait_: Some(trait_.clean(self.cx)),
trait_: Some(trait_ref.clean(self.cx).get_trait_type().unwrap()),
for_: ty.clean(self.cx),
items: Vec::new(),
polarity,
@ -182,11 +146,12 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
fn find_auto_trait_generics(
&self,
did: DefId,
ty: Ty<'tcx>,
param_env_def_id: DefId,
trait_did: DefId,
generics: &ty::Generics,
) -> AutoTraitResult {
match self.f.find_auto_trait_generics(did, trait_did, generics,
match self.f.find_auto_trait_generics(ty, param_env_def_id, trait_did, generics,
|infcx, mut info| {
let region_data = info.region_data;
let names_map =
@ -198,17 +163,17 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
self.handle_lifetimes(&region_data, &names_map);
let new_generics = self.param_env_to_generics(
infcx.tcx,
did,
param_env_def_id,
info.full_user_env,
generics.clone(),
generics,
lifetime_predicates,
info.vid_to_region,
);
debug!(
"find_auto_trait_generics(did={:?}, trait_did={:?}, generics={:?}): \
"find_auto_trait_generics(ty={:?}, trait_did={:?}, generics={:?}): \
finished with {:?}",
did, trait_did, generics, new_generics
ty, trait_did, generics, new_generics
);
new_generics
@ -530,16 +495,16 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
fn param_env_to_generics<'b, 'c, 'cx>(
&self,
tcx: TyCtxt<'b, 'c, 'cx>,
did: DefId,
param_env_def_id: DefId,
param_env: ty::ParamEnv<'cx>,
type_generics: ty::Generics,
type_generics: &ty::Generics,
mut existing_predicates: Vec<WherePredicate>,
vid_to_region: FxHashMap<ty::RegionVid, ty::Region<'cx>>,
) -> Generics {
debug!(
"param_env_to_generics(did={:?}, param_env={:?}, type_generics={:?}, \
"param_env_to_generics(param_env_def_id={:?}, param_env={:?}, type_generics={:?}, \
existing_predicates={:?})",
did, param_env, type_generics, existing_predicates
param_env_def_id, param_env, type_generics, existing_predicates
);
// The `Sized` trait must be handled specially, since we only display it when
@ -553,7 +518,8 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
tcx,
};
let orig_bounds: FxHashSet<_> = self.cx.tcx.param_env(did).caller_bounds.iter().collect();
let orig_bounds: FxHashSet<_> =
self.cx.tcx.param_env(param_env_def_id).caller_bounds.iter().collect();
let clean_where_predicates = param_env
.caller_bounds
.iter()
@ -568,7 +534,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
(replaced.clone(), replaced.clean(self.cx))
});
let full_generics = (&type_generics, &tcx.explicit_predicates_of(did));
let full_generics = (type_generics, &tcx.explicit_predicates_of(param_env_def_id));
let Generics {
params: mut generic_params,
..
@ -757,10 +723,14 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
.or_default()
.insert(*trait_.clone());
}
_ => panic!("Unexpected trait {:?} for {:?}", trait_, did),
_ => panic!(
"Unexpected trait {:?} for {:?}",
trait_,
param_env_def_id,
),
}
}
_ => panic!("Unexpected LHS {:?} for {:?}", lhs, did),
_ => panic!("Unexpected LHS {:?} for {:?}", lhs, param_env_def_id),
}
}
};

View File

@ -9,8 +9,6 @@ use crate::core::DocAccessLevels;
use super::*;
use self::def_ctor::{get_def_from_def_id, get_def_from_hir_id};
pub struct BlanketImplFinder<'a, 'tcx> {
pub cx: &'a core::DocContext<'tcx>,
}
@ -20,67 +18,36 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
BlanketImplFinder { cx }
}
pub fn get_with_def_id(&self, def_id: DefId) -> Vec<Item> {
get_def_from_def_id(&self.cx, def_id, &|def_ctor| {
self.get_blanket_impls(def_id, &def_ctor, None)
})
}
pub fn get_with_hir_id(&self, id: hir::HirId, name: String) -> Vec<Item> {
get_def_from_hir_id(&self.cx, id, name, &|def_ctor, name| {
let did = self.cx.tcx.hir().local_def_id_from_hir_id(id);
self.get_blanket_impls(did, &def_ctor, Some(name))
})
}
pub fn get_blanket_impls<F>(
// FIXME(eddyb) figure out a better way to pass information about
// parametrization of `ty` than `param_env_def_id`.
pub fn get_blanket_impls(
&self,
def_id: DefId,
def_ctor: &F,
name: Option<String>,
) -> Vec<Item>
where F: Fn(DefId) -> Def {
debug!("get_blanket_impls(def_id={:?}, ...)", def_id);
ty: Ty<'tcx>,
param_env_def_id: DefId,
) -> Vec<Item> {
debug!("get_blanket_impls(param_env_def_id={:?}, ...)", param_env_def_id);
let mut impls = Vec::new();
if self.cx
.tcx
.get_attrs(def_id)
.lists("doc")
.has_word("hidden")
{
debug!(
"get_blanket_impls(def_id={:?}, def_ctor=...): item has doc('hidden'), \
aborting",
def_id
);
return impls;
}
let ty = self.cx.tcx.type_of(def_id);
let generics = self.cx.tcx.generics_of(def_id);
let real_name = name.map(|name| Ident::from_str(&name));
let param_env = self.cx.tcx.param_env(def_id);
let param_env = self.cx.tcx.param_env(param_env_def_id);
for &trait_def_id in self.cx.all_traits.iter() {
if !self.cx.renderinfo.borrow().access_levels.is_doc_reachable(trait_def_id) ||
self.cx.generated_synthetics
.borrow_mut()
.get(&(def_id, trait_def_id))
.get(&(param_env_def_id, trait_def_id))
.is_some() {
continue
}
self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| {
self.cx.tcx.infer_ctxt().enter(|infcx| {
debug!("get_blanet_impls: Considering impl for trait '{:?}' {:?}",
let trait_ref = self.cx.tcx.impl_trait_ref(impl_def_id).unwrap();
let may_apply = self.cx.tcx.infer_ctxt().enter(|infcx| {
debug!("get_blanket_impls: Considering impl for trait '{:?}' {:?}",
trait_def_id, impl_def_id);
let t_generics = infcx.tcx.generics_of(impl_def_id);
let trait_ref = infcx.tcx.impl_trait_ref(impl_def_id)
.expect("Cannot get impl trait");
match trait_ref.self_ty().sty {
ty::Param(_) => {},
_ => return,
_ => return false,
}
let substs = infcx.fresh_substs_for_item(DUMMY_SP, def_id);
let substs = infcx.fresh_substs_for_item(DUMMY_SP, param_env_def_id);
let ty = ty.subst(infcx.tcx, substs);
let param_env = param_env.subst(infcx.tcx, substs);
@ -100,7 +67,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
"invoking predicate_may_hold: param_env={:?}, trait_ref={:?}, ty={:?}",
param_env, trait_ref, ty
);
let may_apply = match infcx.evaluate_obligation(
match infcx.evaluate_obligation(
&traits::Obligation::new(
cause,
param_env,
@ -109,56 +76,51 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
) {
Ok(eval_result) => eval_result.may_apply(),
Err(traits::OverflowError) => true, // overflow doesn't mean yes *or* no
};
debug!("get_blanket_impls: found applicable impl: {}\
for trait_ref={:?}, ty={:?}",
may_apply, trait_ref, ty);
if !may_apply {
return
}
self.cx.generated_synthetics.borrow_mut()
.insert((def_id, trait_def_id));
let trait_ = hir::TraitRef {
path: get_path_for_type(infcx.tcx,
trait_def_id,
hir::def::Def::Trait),
hir_ref_id: hir::DUMMY_HIR_ID,
};
let provided_trait_methods =
infcx.tcx.provided_trait_methods(trait_def_id)
.into_iter()
.map(|meth| meth.ident.to_string())
.collect();
let ty = self.cx.get_real_ty(def_id, def_ctor, &real_name, generics);
let predicates = infcx.tcx.explicit_predicates_of(impl_def_id);
impls.push(Item {
source: infcx.tcx.def_span(impl_def_id).clean(self.cx),
name: None,
attrs: Default::default(),
visibility: None,
def_id: self.cx.next_def_id(impl_def_id.krate),
stability: None,
deprecation: None,
inner: ImplItem(Impl {
unsafety: hir::Unsafety::Normal,
generics: (t_generics, &predicates).clean(self.cx),
provided_trait_methods,
trait_: Some(trait_.clean(self.cx)),
for_: ty.clean(self.cx),
items: infcx.tcx.associated_items(impl_def_id)
.collect::<Vec<_>>()
.clean(self.cx),
polarity: None,
synthetic: false,
blanket_impl: Some(infcx.tcx.type_of(impl_def_id)
.clean(self.cx)),
}),
});
} else {
false
}
});
debug!("get_blanket_impls: found applicable impl: {}\
for trait_ref={:?}, ty={:?}",
may_apply, trait_ref, ty);
if !may_apply {
return
}
self.cx.generated_synthetics.borrow_mut()
.insert((param_env_def_id, trait_def_id));
let provided_trait_methods =
self.cx.tcx.provided_trait_methods(trait_def_id)
.into_iter()
.map(|meth| meth.ident.to_string())
.collect();
impls.push(Item {
source: self.cx.tcx.def_span(impl_def_id).clean(self.cx),
name: None,
attrs: Default::default(),
visibility: None,
def_id: self.cx.next_def_id(impl_def_id.krate),
stability: None,
deprecation: None,
inner: ImplItem(Impl {
unsafety: hir::Unsafety::Normal,
generics: (
self.cx.tcx.generics_of(impl_def_id),
&self.cx.tcx.explicit_predicates_of(impl_def_id),
).clean(self.cx),
provided_trait_methods,
trait_: Some(trait_ref.clean(self.cx).get_trait_type().unwrap()),
for_: ty.clean(self.cx),
items: self.cx.tcx.associated_items(impl_def_id)
.collect::<Vec<_>>()
.clean(self.cx),
polarity: None,
synthetic: false,
blanket_impl: Some(trait_ref.self_ty().clean(self.cx)),
}),
});
});
}
impls

View File

@ -1,55 +0,0 @@
use crate::core::DocContext;
use super::*;
pub fn get_def_from_def_id<F>(cx: &DocContext<'_>,
def_id: DefId,
callback: &F,
) -> Vec<Item>
where F: Fn(& dyn Fn(DefId) -> Def) -> Vec<Item> {
let ty = cx.tcx.type_of(def_id);
match ty.sty {
ty::Adt(adt, _) => callback(&match adt.adt_kind() {
AdtKind::Struct => Def::Struct,
AdtKind::Enum => Def::Enum,
AdtKind::Union => Def::Union,
}),
ty::Int(_) |
ty::Uint(_) |
ty::Float(_) |
ty::Str |
ty::Bool |
ty::Char => callback(&move |_: DefId| {
match ty.sty {
ty::Int(x) => Def::PrimTy(hir::Int(x)),
ty::Uint(x) => Def::PrimTy(hir::Uint(x)),
ty::Float(x) => Def::PrimTy(hir::Float(x)),
ty::Str => Def::PrimTy(hir::Str),
ty::Bool => Def::PrimTy(hir::Bool),
ty::Char => Def::PrimTy(hir::Char),
_ => unreachable!(),
}
}),
_ => {
debug!("Unexpected type {:?}", def_id);
Vec::new()
}
}
}
pub fn get_def_from_hir_id<F>(cx: &DocContext<'_>,
id: hir::HirId,
name: String,
callback: &F,
) -> Vec<Item>
where F: Fn(& dyn Fn(DefId) -> Def, String) -> Vec<Item> {
let item = &cx.tcx.hir().expect_item_by_hir_id(id).node;
callback(&match *item {
hir::ItemKind::Struct(_, _) => Def::Struct,
hir::ItemKind::Union(_, _) => Def::Union,
hir::ItemKind::Enum(_, _) => Def::Enum,
_ => panic!("Unexpected type {:?} {:?}", item, id),
}, name)
}

View File

@ -8,7 +8,6 @@ pub mod cfg;
mod simplify;
mod auto_trait;
mod blanket_impl;
pub mod def_ctor;
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use rustc_data_structures::sync::Lrc;
@ -22,8 +21,7 @@ use rustc::mir::interpret::{GlobalId, ConstValue};
use rustc::hir::{self, HirVec};
use rustc::hir::def::{self, Def, CtorKind};
use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc::hir::map::DisambiguatedDefPathData;
use rustc::ty::subst::{Kind, InternalSubsts, SubstsRef, UnpackedKind};
use rustc::ty::subst::{InternalSubsts, SubstsRef, UnpackedKind};
use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind};
use rustc::ty::fold::TypeFolder;
use rustc::ty::layout::VariantIdx;
@ -35,7 +33,7 @@ use syntax::source_map::{dummy_spanned, Spanned};
use syntax::ptr::P;
use syntax::symbol::keywords::{self, Keyword};
use syntax::symbol::InternedString;
use syntax_pos::{self, DUMMY_SP, Pos, FileName};
use syntax_pos::{self, Pos, FileName};
use std::collections::hash_map::Entry;
use std::fmt;
@ -3776,40 +3774,13 @@ pub struct Impl {
pub blanket_impl: Option<Type>,
}
pub fn get_auto_traits_with_hir_id(
cx: &DocContext<'_>,
id: hir::HirId,
name: String
) -> Vec<Item> {
let finder = AutoTraitFinder::new(cx);
finder.get_with_hir_id(id, name)
}
pub fn get_auto_traits_with_def_id(
cx: &DocContext<'_>,
id: DefId
) -> Vec<Item> {
let finder = AutoTraitFinder::new(cx);
finder.get_with_def_id(id)
}
pub fn get_blanket_impls_with_hir_id(
cx: &DocContext<'_>,
id: hir::HirId,
name: String
) -> Vec<Item> {
let finder = BlanketImplFinder::new(cx);
finder.get_with_hir_id(id, name)
}
pub fn get_blanket_impls_with_def_id(
cx: &DocContext<'_>,
id: DefId
) -> Vec<Item> {
let finder = BlanketImplFinder::new(cx);
finder.get_with_def_id(id)
pub fn get_auto_trait_and_blanket_impls(
cx: &DocContext<'tcx>,
ty: Ty<'tcx>,
param_env_def_id: DefId,
) -> impl Iterator<Item = Item> {
AutoTraitFinder::new(cx).get_auto_trait_impls(ty, param_env_def_id).into_iter()
.chain(BlanketImplFinder::new(cx).get_blanket_impls(ty, param_env_def_id))
}
impl Clean<Vec<Item>> for doctree::Impl {
@ -4461,125 +4432,8 @@ pub fn path_to_def(tcx: TyCtxt<'_, '_, '_>, path: &[&str]) -> Option<DefId> {
}
}
pub fn get_path_for_type(
tcx: TyCtxt<'_, '_, '_>,
def_id: DefId,
def_ctor: impl Fn(DefId) -> Def,
) -> hir::Path {
use rustc::ty::print::Printer;
struct AbsolutePathPrinter<'a, 'tcx> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
impl Printer<'tcx, 'tcx> for AbsolutePathPrinter<'_, 'tcx> {
type Error = !;
type Path = Vec<String>;
type Region = ();
type Type = ();
type DynExistential = ();
fn tcx(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
self.tcx
}
fn print_region(
self,
_region: ty::Region<'_>,
) -> Result<Self::Region, Self::Error> {
Ok(())
}
fn print_type(
self,
_ty: Ty<'tcx>,
) -> Result<Self::Type, Self::Error> {
Ok(())
}
fn print_dyn_existential(
self,
_predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error> {
Ok(())
}
fn path_crate(
self,
cnum: CrateNum,
) -> Result<Self::Path, Self::Error> {
Ok(vec![self.tcx.original_crate_name(cnum).to_string()])
}
fn path_qualified(
self,
self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
// This shouldn't ever be needed, but just in case:
Ok(vec![match trait_ref {
Some(trait_ref) => format!("{:?}", trait_ref),
None => format!("<{}>", self_ty),
}])
}
fn path_append_impl(
self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
_disambiguated_data: &DisambiguatedDefPathData,
self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
let mut path = print_prefix(self)?;
// This shouldn't ever be needed, but just in case:
path.push(match trait_ref {
Some(trait_ref) => {
format!("<impl {} for {}>", trait_ref, self_ty)
}
None => format!("<impl {}>", self_ty),
});
Ok(path)
}
fn path_append(
self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self::Path, Self::Error> {
let mut path = print_prefix(self)?;
path.push(disambiguated_data.data.as_interned_str().to_string());
Ok(path)
}
fn path_generic_args(
self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
_args: &[Kind<'tcx>],
) -> Result<Self::Path, Self::Error> {
print_prefix(self)
}
}
let names = AbsolutePathPrinter { tcx: tcx.global_tcx() }
.print_def_path(def_id, &[])
.unwrap();
hir::Path {
span: DUMMY_SP,
def: def_ctor(def_id),
segments: hir::HirVec::from_vec(names.iter().map(|s| hir::PathSegment {
ident: ast::Ident::from_str(&s),
hir_id: None,
def: None,
args: None,
infer_types: false,
}).collect())
}
}
// End of code copied from rust-clippy
#[derive(Eq, PartialEq, Hash, Copy, Clone, Debug)]
enum RegionTarget<'tcx> {
Region(Region<'tcx>),

View File

@ -2,10 +2,10 @@ use rustc_lint;
use rustc::session::{self, config};
use rustc::hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CrateNum, LOCAL_CRATE};
use rustc::hir::def::Def;
use rustc::hir::{self, HirId, HirVec};
use rustc::hir::HirId;
use rustc::middle::cstore::CrateStore;
use rustc::middle::privacy::AccessLevels;
use rustc::ty::{self, TyCtxt};
use rustc::ty::TyCtxt;
use rustc::lint::{self, LintPass};
use rustc::session::config::ErrorOutputType;
use rustc::session::DiagnosticOutput;
@ -16,13 +16,9 @@ use rustc_resolve as resolve;
use rustc_metadata::cstore::CStore;
use rustc_target::spec::TargetTriple;
use syntax::ast::{self, Ident};
use syntax::source_map;
use syntax::feature_gate::UnstableFeatures;
use syntax::json::JsonEmitter;
use syntax::ptr::P;
use syntax::symbol::keywords;
use syntax_pos::DUMMY_SP;
use errors;
use errors::emitter::{Emitter, EmitterWriter};
use parking_lot::ReentrantMutex;
@ -36,7 +32,7 @@ use std::rc::Rc;
use crate::visit_ast::RustdocVisitor;
use crate::config::{Options as RustdocOptions, RenderOptions};
use crate::clean;
use crate::clean::{get_path_for_type, Clean, MAX_DEF_ID, AttributesExt};
use crate::clean::{Clean, MAX_DEF_ID, AttributesExt};
use crate::html::render::RenderInfo;
use crate::passes;
@ -173,98 +169,6 @@ impl<'tcx> DocContext<'tcx> {
self.tcx.hir().as_local_hir_id(def_id)
}
}
pub fn get_real_ty<F>(&self,
def_id: DefId,
def_ctor: &F,
real_name: &Option<Ident>,
generics: &ty::Generics,
) -> hir::Ty
where F: Fn(DefId) -> Def {
let path = get_path_for_type(self.tcx, def_id, def_ctor);
let mut segments = path.segments.into_vec();
let last = segments.pop().expect("segments were empty");
segments.push(hir::PathSegment::new(
real_name.unwrap_or(last.ident),
None,
None,
self.generics_to_path_params(generics.clone()),
false,
));
let new_path = hir::Path {
span: path.span,
def: path.def,
segments: HirVec::from_vec(segments),
};
hir::Ty {
node: hir::TyKind::Path(hir::QPath::Resolved(None, P(new_path))),
span: DUMMY_SP,
hir_id: hir::DUMMY_HIR_ID,
}
}
pub fn generics_to_path_params(&self, generics: ty::Generics) -> hir::GenericArgs {
let mut args = vec![];
for param in generics.params.iter() {
match param.kind {
ty::GenericParamDefKind::Lifetime => {
let name = if param.name == "" {
hir::ParamName::Plain(keywords::StaticLifetime.ident())
} else {
hir::ParamName::Plain(ast::Ident::from_interned_str(param.name))
};
args.push(hir::GenericArg::Lifetime(hir::Lifetime {
hir_id: hir::DUMMY_HIR_ID,
span: DUMMY_SP,
name: hir::LifetimeName::Param(name),
}));
}
ty::GenericParamDefKind::Type { .. } => {
args.push(hir::GenericArg::Type(self.ty_param_to_ty(param.clone())));
}
ty::GenericParamDefKind::Const => {
args.push(hir::GenericArg::Const(hir::ConstArg {
value: hir::AnonConst {
hir_id: hir::DUMMY_HIR_ID,
body: hir::BodyId {
hir_id: hir::DUMMY_HIR_ID,
}
},
span: DUMMY_SP,
}))
}
}
}
hir::GenericArgs {
args: HirVec::from_vec(args),
bindings: HirVec::new(),
parenthesized: false,
}
}
pub fn ty_param_to_ty(&self, param: ty::GenericParamDef) -> hir::Ty {
debug!("ty_param_to_ty({:?}) {:?}", param, param.def_id);
hir::Ty {
node: hir::TyKind::Path(hir::QPath::Resolved(
None,
P(hir::Path {
span: DUMMY_SP,
def: Def::TyParam(param.def_id),
segments: HirVec::from_vec(vec![
hir::PathSegment::from_ident(Ident::from_interned_str(param.name))
]),
}),
)),
span: DUMMY_SP,
hir_id: hir::DUMMY_HIR_ID,
}
}
}
pub trait DocAccessLevels {

View File

@ -67,16 +67,14 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
if !def_id.is_local() {
inline::build_impl(cx, def_id, &mut new_items);
let auto_impls = get_auto_traits_with_def_id(cx, def_id);
let blanket_impls = get_blanket_impls_with_def_id(cx, def_id);
let mut renderinfo = cx.renderinfo.borrow_mut();
// FIXME(eddyb) is this `doc(hidden)` check needed?
if !cx.tcx.get_attrs(def_id).lists("doc").has_word("hidden") {
let self_ty = cx.tcx.type_of(def_id);
let impls = get_auto_trait_and_blanket_impls(cx, self_ty, def_id);
let mut renderinfo = cx.renderinfo.borrow_mut();
let new_impls: Vec<Item> = auto_impls.into_iter()
.chain(blanket_impls.into_iter())
.filter(|i| renderinfo.inlined.insert(i.def_id))
.collect();
new_items.extend(new_impls);
new_items.extend(impls.filter(|i| renderinfo.inlined.insert(i.def_id)));
}
}
}
@ -155,14 +153,13 @@ impl<'a, 'tcx> SyntheticImplCollector<'a, 'tcx> {
impl<'a, 'tcx> DocFolder for SyntheticImplCollector<'a, 'tcx> {
fn fold_item(&mut self, i: Item) -> Option<Item> {
if i.is_struct() || i.is_enum() || i.is_union() {
if let (Some(hir_id), Some(name)) =
(self.cx.tcx.hir().as_local_hir_id(i.def_id), i.name.clone())
{
self.impls.extend(get_auto_traits_with_hir_id(self.cx, hir_id, name.clone()));
self.impls.extend(get_blanket_impls_with_hir_id(self.cx, hir_id, name));
} else {
self.impls.extend(get_auto_traits_with_def_id(self.cx, i.def_id));
self.impls.extend(get_blanket_impls_with_def_id(self.cx, i.def_id));
// FIXME(eddyb) is this `doc(hidden)` check needed?
if !self.cx.tcx.get_attrs(i.def_id).lists("doc").has_word("hidden") {
self.impls.extend(get_auto_trait_and_blanket_impls(
self.cx,
self.cx.tcx.type_of(i.def_id),
i.def_id,
));
}
}

View File

@ -1,6 +1,6 @@
#![crate_name = "foo"]
// @has foo/struct.S.html '//h3[@id="impl-Into"]//code' 'impl<T, U> Into for T'
// @has foo/struct.S.html '//h3[@id="impl-Into%3CU%3E"]//code' 'impl<T, U> Into<U> for T'
pub struct S2 {}
mod m {
pub struct S {}

View File

@ -7,6 +7,5 @@ mod second {
// @has foo/index.html
// @!has - SomeTypeWithLongName
// @has foo/struct.SomeType.html
// @!has - SomeTypeWithLongName
// @!has foo/struct.SomeTypeWithLongName.html
pub use second::{SomeTypeWithLongName as SomeType};

View File

@ -21,7 +21,7 @@ mod foo {
// @has complex/struct.NotOuter.html
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<'a, T, K: \
// ?Sized> Send for NotOuter<'a, T, K> where K: for<'b> Fn((&'b bool, &'a u8)) \
// ?Sized> Send for Outer<'a, T, K> where K: for<'b> Fn((&'b bool, &'a u8)) \
// -> &'b i8, T: MyTrait<'a>, <T as MyTrait<'a>>::MyItem: Copy, 'a: 'static"
pub use foo::{Foo, Inner as NotInner, MyTrait as NotMyTrait, Outer as NotOuter};