1 //! This module contains the "cleaned" pieces of the AST, and the functions
13 use rustc_attr
as attr
;
14 use rustc_data_structures
::fx
::{FxHashMap, FxHashSet}
;
16 use rustc_hir
::def
::{CtorKind, DefKind, Res}
;
17 use rustc_hir
::def_id
::{CrateNum, DefId, CRATE_DEF_INDEX}
;
18 use rustc_index
::vec
::{Idx, IndexVec}
;
19 use rustc_infer
::infer
::region_constraints
::{Constraint, RegionConstraintData}
;
20 use rustc_middle
::middle
::resolve_lifetime
as rl
;
21 use rustc_middle
::middle
::stability
;
22 use rustc_middle
::ty
::fold
::TypeFolder
;
23 use rustc_middle
::ty
::subst
::InternalSubsts
;
24 use rustc_middle
::ty
::{self, AdtKind, Lift, Ty, TyCtxt}
;
25 use rustc_mir
::const_eval
::is_min_const_fn
;
26 use rustc_span
::hygiene
::MacroKind
;
27 use rustc_span
::symbol
::{kw, sym, Ident, Symbol}
;
28 use rustc_span
::{self, Pos}
;
29 use rustc_typeck
::hir_ty_to_ty
;
31 use std
::collections
::hash_map
::Entry
;
32 use std
::default::Default
;
37 use crate::core
::{self, DocContext, ImplTraitParam}
;
42 pub use utils
::{get_auto_trait_and_blanket_impls, krate, register_res}
;
44 pub use self::types
::FnRetTy
::*;
45 pub use self::types
::ItemEnum
::*;
46 pub use self::types
::SelfTy
::*;
47 pub use self::types
::Type
::*;
48 pub use self::types
::Visibility
::{Inherited, Public}
;
49 pub use self::types
::*;
51 const FN_OUTPUT_NAME
: &str = "Output";
54 fn clean(&self, cx
: &DocContext
<'_
>) -> T
;
57 impl<T
: Clean
<U
>, U
> Clean
<Vec
<U
>> for [T
] {
58 fn clean(&self, cx
: &DocContext
<'_
>) -> Vec
<U
> {
59 self.iter().map(|x
| x
.clean(cx
)).collect()
63 impl<T
: Clean
<U
>, U
, V
: Idx
> Clean
<IndexVec
<V
, U
>> for IndexVec
<V
, T
> {
64 fn clean(&self, cx
: &DocContext
<'_
>) -> IndexVec
<V
, U
> {
65 self.iter().map(|x
| x
.clean(cx
)).collect()
69 impl<T
: Clean
<U
>, U
> Clean
<U
> for &T
{
70 fn clean(&self, cx
: &DocContext
<'_
>) -> U
{
75 impl<T
: Clean
<U
>, U
> Clean
<U
> for Rc
<T
> {
76 fn clean(&self, cx
: &DocContext
<'_
>) -> U
{
81 impl<T
: Clean
<U
>, U
> Clean
<Option
<U
>> for Option
<T
> {
82 fn clean(&self, cx
: &DocContext
<'_
>) -> Option
<U
> {
83 self.as_ref().map(|v
| v
.clean(cx
))
87 impl Clean
<ExternalCrate
> for CrateNum
{
88 fn clean(&self, cx
: &DocContext
<'_
>) -> ExternalCrate
{
89 let root
= DefId { krate: *self, index: CRATE_DEF_INDEX }
;
90 let krate_span
= cx
.tcx
.def_span(root
);
91 let krate_src
= cx
.sess().source_map().span_to_filename(krate_span
);
93 // Collect all inner modules which are tagged as implementations of
96 // Note that this loop only searches the top-level items of the crate,
97 // and this is intentional. If we were to search the entire crate for an
98 // item tagged with `#[doc(primitive)]` then we would also have to
99 // search the entirety of external modules for items tagged
100 // `#[doc(primitive)]`, which is a pretty inefficient process (decoding
101 // all that metadata unconditionally).
103 // In order to keep the metadata load under control, the
104 // `#[doc(primitive)]` feature is explicitly designed to only allow the
105 // primitive tags to show up as the top level items in a crate.
107 // Also note that this does not attempt to deal with modules tagged
108 // duplicately for the same primitive. This is handled later on when
109 // rendering by delegating everything to a hash map.
110 let as_primitive
= |res
: Res
| {
111 if let Res
::Def(DefKind
::Mod
, def_id
) = res
{
112 let attrs
= cx
.tcx
.get_attrs(def_id
).clean(cx
);
114 for attr
in attrs
.lists(sym
::doc
) {
115 if let Some(v
) = attr
.value_str() {
116 if attr
.check_name(sym
::primitive
) {
117 prim
= PrimitiveType
::from_str(&v
.as_str());
121 // FIXME: should warn on unknown primitives?
125 return prim
.map(|p
| (def_id
, p
, attrs
));
129 let primitives
= if root
.is_local() {
138 let item
= cx
.tcx
.hir().expect_item(id
.id
);
140 hir
::ItemKind
::Mod(_
) => as_primitive(Res
::Def(
142 cx
.tcx
.hir().local_def_id(id
.id
).to_def_id(),
144 hir
::ItemKind
::Use(ref path
, hir
::UseKind
::Single
)
145 if item
.vis
.node
.is_pub() =>
147 as_primitive(path
.res
).map(|(_
, prim
, attrs
)| {
148 // Pretend the primitive is local.
149 (cx
.tcx
.hir().local_def_id(id
.id
).to_def_id(), prim
, attrs
)
160 .map(|item
| item
.res
)
161 .filter_map(as_primitive
)
165 let as_keyword
= |res
: Res
| {
166 if let Res
::Def(DefKind
::Mod
, def_id
) = res
{
167 let attrs
= cx
.tcx
.get_attrs(def_id
).clean(cx
);
168 let mut keyword
= None
;
169 for attr
in attrs
.lists(sym
::doc
) {
170 if let Some(v
) = attr
.value_str() {
171 if attr
.check_name(sym
::keyword
) {
172 if v
.is_doc_keyword() {
173 keyword
= Some(v
.to_string());
176 // FIXME: should warn on unknown keywords?
180 return keyword
.map(|p
| (def_id
, p
, attrs
));
184 let keywords
= if root
.is_local() {
193 let item
= cx
.tcx
.hir().expect_item(id
.id
);
195 hir
::ItemKind
::Mod(_
) => as_keyword(Res
::Def(
197 cx
.tcx
.hir().local_def_id(id
.id
).to_def_id(),
199 hir
::ItemKind
::Use(ref path
, hir
::UseKind
::Single
)
200 if item
.vis
.node
.is_pub() =>
202 as_keyword(path
.res
).map(|(_
, prim
, attrs
)| {
203 (cx
.tcx
.hir().local_def_id(id
.id
).to_def_id(), prim
, attrs
)
211 cx
.tcx
.item_children(root
).iter().map(|item
| item
.res
).filter_map(as_keyword
).collect()
215 name
: cx
.tcx
.crate_name(*self).to_string(),
217 attrs
: cx
.tcx
.get_attrs(root
).clean(cx
),
224 impl Clean
<Item
> for doctree
::Module
<'_
> {
225 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
226 let name
= if self.name
.is_some() {
227 self.name
.expect("No name provided").clean(cx
)
232 // maintain a stack of mod ids, for doc comment path resolution
233 // but we also need to resolve the module's own docs based on whether its docs were written
234 // inside or outside the module, so check for that
235 let attrs
= self.attrs
.clean(cx
);
237 let mut items
: Vec
<Item
> = vec
![];
238 items
.extend(self.extern_crates
.iter().flat_map(|x
| x
.clean(cx
)));
239 items
.extend(self.imports
.iter().flat_map(|x
| x
.clean(cx
)));
240 items
.extend(self.structs
.iter().map(|x
| x
.clean(cx
)));
241 items
.extend(self.unions
.iter().map(|x
| x
.clean(cx
)));
242 items
.extend(self.enums
.iter().map(|x
| x
.clean(cx
)));
243 items
.extend(self.fns
.iter().map(|x
| x
.clean(cx
)));
244 items
.extend(self.foreigns
.iter().map(|x
| x
.clean(cx
)));
245 items
.extend(self.mods
.iter().map(|x
| x
.clean(cx
)));
246 items
.extend(self.typedefs
.iter().map(|x
| x
.clean(cx
)));
247 items
.extend(self.opaque_tys
.iter().map(|x
| x
.clean(cx
)));
248 items
.extend(self.statics
.iter().map(|x
| x
.clean(cx
)));
249 items
.extend(self.constants
.iter().map(|x
| x
.clean(cx
)));
250 items
.extend(self.traits
.iter().map(|x
| x
.clean(cx
)));
251 items
.extend(self.impls
.iter().flat_map(|x
| x
.clean(cx
)));
252 items
.extend(self.macros
.iter().map(|x
| x
.clean(cx
)));
253 items
.extend(self.proc_macros
.iter().map(|x
| x
.clean(cx
)));
254 items
.extend(self.trait_aliases
.iter().map(|x
| x
.clean(cx
)));
256 // determine if we should display the inner contents or
257 // the outer `mod` item for the source code.
259 let sm
= cx
.sess().source_map();
260 let outer
= sm
.lookup_char_pos(self.where_outer
.lo());
261 let inner
= sm
.lookup_char_pos(self.where_inner
.lo());
262 if outer
.file
.start_pos
== inner
.file
.start_pos
{
266 // mod foo; (and a separate SourceFile for the contents)
274 source
: whence
.clean(cx
),
275 visibility
: self.vis
.clean(cx
),
276 stability
: cx
.stability(self.id
).clean(cx
),
277 deprecation
: cx
.deprecation(self.id
).clean(cx
),
278 def_id
: cx
.tcx
.hir().local_def_id(self.id
).to_def_id(),
279 inner
: ModuleItem(Module { is_crate: self.is_crate, items }
),
284 impl Clean
<Attributes
> for [ast
::Attribute
] {
285 fn clean(&self, cx
: &DocContext
<'_
>) -> Attributes
{
286 Attributes
::from_ast(cx
.sess().diagnostic(), self)
290 impl Clean
<GenericBound
> for hir
::GenericBound
<'_
> {
291 fn clean(&self, cx
: &DocContext
<'_
>) -> GenericBound
{
293 hir
::GenericBound
::Outlives(lt
) => GenericBound
::Outlives(lt
.clean(cx
)),
294 hir
::GenericBound
::Trait(ref t
, modifier
) => {
295 GenericBound
::TraitBound(t
.clean(cx
), modifier
)
301 impl Clean
<Type
> for (ty
::TraitRef
<'_
>, &[TypeBinding
]) {
302 fn clean(&self, cx
: &DocContext
<'_
>) -> Type
{
303 let (trait_ref
, bounds
) = *self;
304 inline
::record_extern_fqn(cx
, trait_ref
.def_id
, TypeKind
::Trait
);
305 let path
= external_path(
307 cx
.tcx
.item_name(trait_ref
.def_id
),
308 Some(trait_ref
.def_id
),
314 debug
!("ty::TraitRef\n subst: {:?}\n", trait_ref
.substs
);
316 ResolvedPath { path, param_names: None, did: trait_ref.def_id, is_generic: false }
320 impl<'tcx
> Clean
<GenericBound
> for ty
::TraitRef
<'tcx
> {
321 fn clean(&self, cx
: &DocContext
<'_
>) -> GenericBound
{
322 GenericBound
::TraitBound(
323 PolyTrait { trait_: (*self, &[][..]).clean(cx), generic_params: vec![] }
,
324 hir
::TraitBoundModifier
::None
,
329 impl Clean
<GenericBound
> for (ty
::PolyTraitRef
<'_
>, &[TypeBinding
]) {
330 fn clean(&self, cx
: &DocContext
<'_
>) -> GenericBound
{
331 let (poly_trait_ref
, bounds
) = *self;
332 let poly_trait_ref
= poly_trait_ref
.lift_to_tcx(cx
.tcx
).unwrap();
334 // collect any late bound regions
335 let late_bound_regions
: Vec
<_
> = cx
337 .collect_referenced_late_bound_regions(&poly_trait_ref
)
339 .filter_map(|br
| match br
{
340 ty
::BrNamed(_
, name
) => Some(GenericParamDef
{
341 name
: name
.to_string(),
342 kind
: GenericParamDefKind
::Lifetime
,
348 GenericBound
::TraitBound(
350 trait_
: (*poly_trait_ref
.skip_binder(), bounds
).clean(cx
),
351 generic_params
: late_bound_regions
,
353 hir
::TraitBoundModifier
::None
,
358 impl<'tcx
> Clean
<GenericBound
> for ty
::PolyTraitRef
<'tcx
> {
359 fn clean(&self, cx
: &DocContext
<'_
>) -> GenericBound
{
360 (*self, &[][..]).clean(cx
)
364 impl<'tcx
> Clean
<Option
<Vec
<GenericBound
>>> for InternalSubsts
<'tcx
> {
365 fn clean(&self, cx
: &DocContext
<'_
>) -> Option
<Vec
<GenericBound
>> {
366 let mut v
= Vec
::new();
367 v
.extend(self.regions().filter_map(|r
| r
.clean(cx
)).map(GenericBound
::Outlives
));
368 v
.extend(self.types().map(|t
| {
369 GenericBound
::TraitBound(
370 PolyTrait { trait_: t.clean(cx), generic_params: Vec::new() }
,
371 hir
::TraitBoundModifier
::None
,
374 if !v
.is_empty() { Some(v) }
else { None }
378 impl Clean
<Lifetime
> for hir
::Lifetime
{
379 fn clean(&self, cx
: &DocContext
<'_
>) -> Lifetime
{
380 let def
= cx
.tcx
.named_region(self.hir_id
);
383 rl
::Region
::EarlyBound(_
, node_id
, _
)
384 | rl
::Region
::LateBound(_
, node_id
, _
)
385 | rl
::Region
::Free(_
, node_id
),
387 if let Some(lt
) = cx
.lt_substs
.borrow().get(&node_id
).cloned() {
393 Lifetime(self.name
.ident().to_string())
397 impl Clean
<Lifetime
> for hir
::GenericParam
<'_
> {
398 fn clean(&self, _
: &DocContext
<'_
>) -> Lifetime
{
400 hir
::GenericParamKind
::Lifetime { .. }
=> {
401 if !self.bounds
.is_empty() {
402 let mut bounds
= self.bounds
.iter().map(|bound
| match bound
{
403 hir
::GenericBound
::Outlives(lt
) => lt
,
406 let name
= bounds
.next().expect("no more bounds").name
.ident();
407 let mut s
= format
!("{}: {}", self.name
.ident(), name
);
408 for bound
in bounds
{
409 s
.push_str(&format
!(" + {}", bound
.name
.ident()));
413 Lifetime(self.name
.ident().to_string())
421 impl Clean
<Constant
> for hir
::ConstArg
{
422 fn clean(&self, cx
: &DocContext
<'_
>) -> Constant
{
426 .type_of(cx
.tcx
.hir().body_owner_def_id(self.value
.body
).to_def_id())
428 expr
: print_const_expr(cx
, self.value
.body
),
430 is_literal
: is_literal_expr(cx
, self.value
.body
.hir_id
),
435 impl Clean
<Lifetime
> for ty
::GenericParamDef
{
436 fn clean(&self, _cx
: &DocContext
<'_
>) -> Lifetime
{
437 Lifetime(self.name
.to_string())
441 impl Clean
<Option
<Lifetime
>> for ty
::RegionKind
{
442 fn clean(&self, cx
: &DocContext
<'_
>) -> Option
<Lifetime
> {
444 ty
::ReStatic
=> Some(Lifetime
::statik()),
445 ty
::ReLateBound(_
, ty
::BrNamed(_
, name
)) => Some(Lifetime(name
.to_string())),
446 ty
::ReEarlyBound(ref data
) => Some(Lifetime(data
.name
.clean(cx
))),
451 | ty
::RePlaceholder(..)
454 debug
!("cannot clean region {:?}", self);
461 impl Clean
<WherePredicate
> for hir
::WherePredicate
<'_
> {
462 fn clean(&self, cx
: &DocContext
<'_
>) -> WherePredicate
{
464 hir
::WherePredicate
::BoundPredicate(ref wbp
) => WherePredicate
::BoundPredicate
{
465 ty
: wbp
.bounded_ty
.clean(cx
),
466 bounds
: wbp
.bounds
.clean(cx
),
469 hir
::WherePredicate
::RegionPredicate(ref wrp
) => WherePredicate
::RegionPredicate
{
470 lifetime
: wrp
.lifetime
.clean(cx
),
471 bounds
: wrp
.bounds
.clean(cx
),
474 hir
::WherePredicate
::EqPredicate(ref wrp
) => {
475 WherePredicate
::EqPredicate { lhs: wrp.lhs_ty.clean(cx), rhs: wrp.rhs_ty.clean(cx) }
481 impl<'a
> Clean
<Option
<WherePredicate
>> for ty
::Predicate
<'a
> {
482 fn clean(&self, cx
: &DocContext
<'_
>) -> Option
<WherePredicate
> {
484 ty
::PredicateKind
::Trait(ref pred
, _
) => Some(pred
.clean(cx
)),
485 ty
::PredicateKind
::Subtype(ref pred
) => Some(pred
.clean(cx
)),
486 ty
::PredicateKind
::RegionOutlives(ref pred
) => pred
.clean(cx
),
487 ty
::PredicateKind
::TypeOutlives(ref pred
) => pred
.clean(cx
),
488 ty
::PredicateKind
::Projection(ref pred
) => Some(pred
.clean(cx
)),
490 ty
::PredicateKind
::WellFormed(..)
491 | ty
::PredicateKind
::ObjectSafe(..)
492 | ty
::PredicateKind
::ClosureKind(..)
493 | ty
::PredicateKind
::ConstEvaluatable(..)
494 | ty
::PredicateKind
::ConstEquate(..) => panic
!("not user writable"),
499 impl<'a
> Clean
<WherePredicate
> for ty
::PolyTraitPredicate
<'a
> {
500 fn clean(&self, cx
: &DocContext
<'_
>) -> WherePredicate
{
501 let poly_trait_ref
= self.map_bound(|pred
| pred
.trait_ref
);
502 WherePredicate
::BoundPredicate
{
503 ty
: poly_trait_ref
.self_ty().clean(cx
),
504 bounds
: vec
![poly_trait_ref
.clean(cx
)],
509 impl<'tcx
> Clean
<WherePredicate
> for ty
::PolySubtypePredicate
<'tcx
> {
510 fn clean(&self, _cx
: &DocContext
<'_
>) -> WherePredicate
{
512 "subtype predicates are an internal rustc artifact \
513 and should not be seen by rustdoc"
518 impl<'tcx
> Clean
<Option
<WherePredicate
>>
519 for ty
::PolyOutlivesPredicate
<ty
::Region
<'tcx
>, ty
::Region
<'tcx
>>
521 fn clean(&self, cx
: &DocContext
<'_
>) -> Option
<WherePredicate
> {
522 let ty
::OutlivesPredicate(a
, b
) = self.skip_binder();
524 if let (ty
::ReEmpty(_
), ty
::ReEmpty(_
)) = (a
, b
) {
528 Some(WherePredicate
::RegionPredicate
{
529 lifetime
: a
.clean(cx
).expect("failed to clean lifetime"),
530 bounds
: vec
![GenericBound
::Outlives(b
.clean(cx
).expect("failed to clean bounds"))],
535 impl<'tcx
> Clean
<Option
<WherePredicate
>> for ty
::PolyOutlivesPredicate
<Ty
<'tcx
>, ty
::Region
<'tcx
>> {
536 fn clean(&self, cx
: &DocContext
<'_
>) -> Option
<WherePredicate
> {
537 let ty
::OutlivesPredicate(ty
, lt
) = self.skip_binder();
539 if let ty
::ReEmpty(_
) = lt
{
543 Some(WherePredicate
::BoundPredicate
{
545 bounds
: vec
![GenericBound
::Outlives(lt
.clean(cx
).expect("failed to clean lifetimes"))],
550 impl<'tcx
> Clean
<WherePredicate
> for ty
::PolyProjectionPredicate
<'tcx
> {
551 fn clean(&self, cx
: &DocContext
<'_
>) -> WherePredicate
{
552 let ty
::ProjectionPredicate { projection_ty, ty }
= *self.skip_binder();
553 WherePredicate
::EqPredicate { lhs: projection_ty.clean(cx), rhs: ty.clean(cx) }
557 impl<'tcx
> Clean
<Type
> for ty
::ProjectionTy
<'tcx
> {
558 fn clean(&self, cx
: &DocContext
<'_
>) -> Type
{
559 let lifted
= self.lift_to_tcx(cx
.tcx
).unwrap();
560 let trait_
= match lifted
.trait_ref(cx
.tcx
).clean(cx
) {
561 GenericBound
::TraitBound(t
, _
) => t
.trait_
,
562 GenericBound
::Outlives(_
) => panic
!("cleaning a trait got a lifetime"),
565 name
: cx
.tcx
.associated_item(self.item_def_id
).ident
.name
.clean(cx
),
566 self_type
: box self.self_ty().clean(cx
),
572 impl Clean
<GenericParamDef
> for ty
::GenericParamDef
{
573 fn clean(&self, cx
: &DocContext
<'_
>) -> GenericParamDef
{
574 let (name
, kind
) = match self.kind
{
575 ty
::GenericParamDefKind
::Lifetime
=> {
576 (self.name
.to_string(), GenericParamDefKind
::Lifetime
)
578 ty
::GenericParamDefKind
::Type { has_default, synthetic, .. }
=> {
580 if has_default { Some(cx.tcx.type_of(self.def_id).clean(cx)) }
else { None }
;
583 GenericParamDefKind
::Type
{
585 bounds
: vec
![], // These are filled in from the where-clauses.
591 ty
::GenericParamDefKind
::Const { .. }
=> (
593 GenericParamDefKind
::Const
{
595 ty
: cx
.tcx
.type_of(self.def_id
).clean(cx
),
600 GenericParamDef { name, kind }
604 impl Clean
<GenericParamDef
> for hir
::GenericParam
<'_
> {
605 fn clean(&self, cx
: &DocContext
<'_
>) -> GenericParamDef
{
606 let (name
, kind
) = match self.kind
{
607 hir
::GenericParamKind
::Lifetime { .. }
=> {
608 let name
= if !self.bounds
.is_empty() {
609 let mut bounds
= self.bounds
.iter().map(|bound
| match bound
{
610 hir
::GenericBound
::Outlives(lt
) => lt
,
613 let name
= bounds
.next().expect("no more bounds").name
.ident();
614 let mut s
= format
!("{}: {}", self.name
.ident(), name
);
615 for bound
in bounds
{
616 s
.push_str(&format
!(" + {}", bound
.name
.ident()));
620 self.name
.ident().to_string()
622 (name
, GenericParamDefKind
::Lifetime
)
624 hir
::GenericParamKind
::Type { ref default, synthetic }
=> (
625 self.name
.ident().name
.clean(cx
),
626 GenericParamDefKind
::Type
{
627 did
: cx
.tcx
.hir().local_def_id(self.hir_id
).to_def_id(),
628 bounds
: self.bounds
.clean(cx
),
629 default: default.clean(cx
),
633 hir
::GenericParamKind
::Const { ref ty }
=> (
634 self.name
.ident().name
.clean(cx
),
635 GenericParamDefKind
::Const
{
636 did
: cx
.tcx
.hir().local_def_id(self.hir_id
).to_def_id(),
642 GenericParamDef { name, kind }
646 impl Clean
<Generics
> for hir
::Generics
<'_
> {
647 fn clean(&self, cx
: &DocContext
<'_
>) -> Generics
{
648 // Synthetic type-parameters are inserted after normal ones.
649 // In order for normal parameters to be able to refer to synthetic ones,
651 fn is_impl_trait(param
: &hir
::GenericParam
<'_
>) -> bool
{
653 hir
::GenericParamKind
::Type { synthetic, .. }
=> {
654 synthetic
== Some(hir
::SyntheticTyParamKind
::ImplTrait
)
659 let impl_trait_params
= self
662 .filter(|param
| is_impl_trait(param
))
664 let param
: GenericParamDef
= param
.clean(cx
);
666 GenericParamDefKind
::Lifetime
=> unreachable
!(),
667 GenericParamDefKind
::Type { did, ref bounds, .. }
=> {
668 cx
.impl_trait_bounds
.borrow_mut().insert(did
.into(), bounds
.clone());
670 GenericParamDefKind
::Const { .. }
=> unreachable
!(),
674 .collect
::<Vec
<_
>>();
676 let mut params
= Vec
::with_capacity(self.params
.len());
677 for p
in self.params
.iter().filter(|p
| !is_impl_trait(p
)) {
681 params
.extend(impl_trait_params
);
684 Generics { params, where_predicates: self.where_clause.predicates.clean(cx) }
;
686 // Some duplicates are generated for ?Sized bounds between type params and where
687 // predicates. The point in here is to move the bounds definitions from type params
688 // to where predicates when such cases occur.
689 for where_pred
in &mut generics
.where_predicates
{
691 WherePredicate
::BoundPredicate { ty: Generic(ref name), ref mut bounds }
=> {
692 if bounds
.is_empty() {
693 for param
in &mut generics
.params
{
695 GenericParamDefKind
::Lifetime
=> {}
696 GenericParamDefKind
::Type { bounds: ref mut ty_bounds, .. }
=> {
697 if ¶m
.name
== name
{
698 mem
::swap(bounds
, ty_bounds
);
702 GenericParamDefKind
::Const { .. }
=> {}
714 impl<'a
, 'tcx
> Clean
<Generics
> for (&'a ty
::Generics
, ty
::GenericPredicates
<'tcx
>) {
715 fn clean(&self, cx
: &DocContext
<'_
>) -> Generics
{
716 use self::WherePredicate
as WP
;
717 use std
::collections
::BTreeMap
;
719 let (gens
, preds
) = *self;
721 // Don't populate `cx.impl_trait_bounds` before `clean`ning `where` clauses,
722 // since `Clean for ty::Predicate` would consume them.
723 let mut impl_trait
= BTreeMap
::<ImplTraitParam
, Vec
<GenericBound
>>::default();
725 // Bounds in the type_params and lifetimes fields are repeated in the
726 // predicates field (see rustc_typeck::collect::ty_generics), so remove
728 let stripped_typarams
= gens
731 .filter_map(|param
| match param
.kind
{
732 ty
::GenericParamDefKind
::Lifetime
=> None
,
733 ty
::GenericParamDefKind
::Type { synthetic, .. }
=> {
734 if param
.name
== kw
::SelfUpper
{
735 assert_eq
!(param
.index
, 0);
738 if synthetic
== Some(hir
::SyntheticTyParamKind
::ImplTrait
) {
739 impl_trait
.insert(param
.index
.into(), vec
![]);
742 Some(param
.clean(cx
))
744 ty
::GenericParamDefKind
::Const { .. }
=> None
,
746 .collect
::<Vec
<GenericParamDef
>>();
748 // param index -> [(DefId of trait, associated type name, type)]
749 let mut impl_trait_proj
= FxHashMap
::<u32, Vec
<(DefId
, String
, Ty
<'tcx
>)>>::default();
751 let where_predicates
= preds
755 let mut projection
= None
;
756 let param_idx
= (|| {
757 if let Some(trait_ref
) = p
.to_opt_poly_trait_ref() {
758 if let ty
::Param(param
) = trait_ref
.self_ty().kind
{
759 return Some(param
.index
);
761 } else if let Some(outlives
) = p
.to_opt_type_outlives() {
762 if let ty
::Param(param
) = outlives
.skip_binder().0.kind
{
763 return Some(param
.index
);
765 } else if let ty
::PredicateKind
::Projection(p
) = p
.kind() {
766 if let ty
::Param(param
) = p
.skip_binder().projection_ty
.self_ty().kind
{
767 projection
= Some(p
);
768 return Some(param
.index
);
775 if let Some(param_idx
) = param_idx
{
776 if let Some(b
) = impl_trait
.get_mut(¶m_idx
.into()) {
777 let p
= p
.clean(cx
)?
;
784 .filter(|b
| !b
.is_sized_bound(cx
)),
787 let proj
= projection
788 .map(|p
| (p
.skip_binder().projection_ty
.clean(cx
), p
.skip_binder().ty
));
789 if let Some(((_
, trait_did
, name
), rhs
)) =
790 proj
.as_ref().and_then(|(lhs
, rhs
)| Some((lhs
.projection()?
, rhs
)))
792 impl_trait_proj
.entry(param_idx
).or_default().push((
805 .collect
::<Vec
<_
>>();
807 for (param
, mut bounds
) in impl_trait
{
808 // Move trait bounds to the front.
809 bounds
.sort_by_key(|b
| if let GenericBound
::TraitBound(..) = b { false }
else { true }
);
811 if let crate::core
::ImplTraitParam
::ParamIndex(idx
) = param
{
812 if let Some(proj
) = impl_trait_proj
.remove(&idx
) {
813 for (trait_did
, name
, rhs
) in proj
{
814 simplify
::merge_bounds(cx
, &mut bounds
, trait_did
, &name
, &rhs
.clean(cx
));
821 cx
.impl_trait_bounds
.borrow_mut().insert(param
, bounds
);
824 // Now that `cx.impl_trait_bounds` is populated, we can process
825 // remaining predicates which could contain `impl Trait`.
826 let mut where_predicates
=
827 where_predicates
.into_iter().flat_map(|p
| p
.clean(cx
)).collect
::<Vec
<_
>>();
829 // Type parameters and have a Sized bound by default unless removed with
830 // ?Sized. Scan through the predicates and mark any type parameter with
831 // a Sized bound, removing the bounds as we find them.
833 // Note that associated types also have a sized bound by default, but we
834 // don't actually know the set of associated types right here so that's
835 // handled in cleaning associated types
836 let mut sized_params
= FxHashSet
::default();
837 where_predicates
.retain(|pred
| match *pred
{
838 WP
::BoundPredicate { ty: Generic(ref g), ref bounds }
=> {
839 if bounds
.iter().any(|b
| b
.is_sized_bound(cx
)) {
840 sized_params
.insert(g
.clone());
849 // Run through the type parameters again and insert a ?Sized
850 // unbound for any we didn't find to be Sized.
851 for tp
in &stripped_typarams
{
852 if !sized_params
.contains(&tp
.name
) {
853 where_predicates
.push(WP
::BoundPredicate
{
854 ty
: Type
::Generic(tp
.name
.clone()),
855 bounds
: vec
![GenericBound
::maybe_sized(cx
)],
860 // It would be nice to collect all of the bounds on a type and recombine
861 // them if possible, to avoid e.g., `where T: Foo, T: Bar, T: Sized, T: 'a`
862 // and instead see `where T: Foo + Bar + Sized + 'a`
868 .flat_map(|param
| match param
.kind
{
869 ty
::GenericParamDefKind
::Lifetime
=> Some(param
.clean(cx
)),
870 ty
::GenericParamDefKind
::Type { .. }
=> None
,
871 ty
::GenericParamDefKind
::Const { .. }
=> Some(param
.clean(cx
)),
873 .chain(simplify
::ty_params(stripped_typarams
).into_iter())
875 where_predicates
: simplify
::where_clauses(cx
, where_predicates
),
880 impl<'a
> Clean
<Method
>
881 for (&'a hir
::FnSig
<'a
>, &'a hir
::Generics
<'a
>, hir
::BodyId
, Option
<hir
::Defaultness
>)
883 fn clean(&self, cx
: &DocContext
<'_
>) -> Method
{
884 let (generics
, decl
) =
885 enter_impl_trait(cx
, || (self.1.clean(cx
), (&*self.0.decl
, self.2).clean(cx
)));
886 let (all_types
, ret_types
) = get_all_types(&generics
, &decl
, cx
);
887 Method { decl, generics, header: self.0.header, defaultness: self.3, all_types, ret_types }
891 impl Clean
<Item
> for doctree
::Function
<'_
> {
892 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
893 let (generics
, decl
) =
894 enter_impl_trait(cx
, || (self.generics
.clean(cx
), (self.decl
, self.body
).clean(cx
)));
896 let did
= cx
.tcx
.hir().local_def_id(self.id
);
897 let constness
= if is_min_const_fn(cx
.tcx
, did
.to_def_id()) {
898 hir
::Constness
::Const
900 hir
::Constness
::NotConst
902 let (all_types
, ret_types
) = get_all_types(&generics
, &decl
, cx
);
904 name
: Some(self.name
.clean(cx
)),
905 attrs
: self.attrs
.clean(cx
),
906 source
: self.whence
.clean(cx
),
907 visibility
: self.vis
.clean(cx
),
908 stability
: cx
.stability(self.id
).clean(cx
),
909 deprecation
: cx
.deprecation(self.id
).clean(cx
),
910 def_id
: did
.to_def_id(),
911 inner
: FunctionItem(Function
{
914 header
: hir
::FnHeader { constness, ..self.header }
,
922 impl<'a
> Clean
<Arguments
> for (&'a
[hir
::Ty
<'a
>], &'a
[Ident
]) {
923 fn clean(&self, cx
: &DocContext
<'_
>) -> Arguments
{
931 self.1.get(i
).map(|ident
| ident
.to_string()).unwrap_or(String
::new());
933 name
= "_".to_string();
935 Argument { name, type_: ty.clean(cx) }
942 impl<'a
> Clean
<Arguments
> for (&'a
[hir
::Ty
<'a
>], hir
::BodyId
) {
943 fn clean(&self, cx
: &DocContext
<'_
>) -> Arguments
{
944 let body
= cx
.tcx
.hir().body(self.1);
951 .map(|(i
, ty
)| Argument
{
952 name
: name_from_pat(&body
.params
[i
].pat
),
960 impl<'a
, A
: Copy
> Clean
<FnDecl
> for (&'a hir
::FnDecl
<'a
>, A
)
962 (&'a
[hir
::Ty
<'a
>], A
): Clean
<Arguments
>,
964 fn clean(&self, cx
: &DocContext
<'_
>) -> FnDecl
{
966 inputs
: (&self.0.inputs
[..], self.1).clean(cx
),
967 output
: self.0.output
.clean(cx
),
968 c_variadic
: self.0.c_variadic
,
969 attrs
: Attributes
::default(),
974 impl<'tcx
> Clean
<FnDecl
> for (DefId
, ty
::PolyFnSig
<'tcx
>) {
975 fn clean(&self, cx
: &DocContext
<'_
>) -> FnDecl
{
976 let (did
, sig
) = *self;
977 let mut names
= if did
.is_local() { &[] }
else { cx.tcx.fn_arg_names(did) }
.iter();
980 output
: Return(sig
.skip_binder().output().clean(cx
)),
981 attrs
: Attributes
::default(),
982 c_variadic
: sig
.skip_binder().c_variadic
,
990 name
: names
.next().map_or(String
::new(), |name
| name
.to_string()),
998 impl Clean
<FnRetTy
> for hir
::FnRetTy
<'_
> {
999 fn clean(&self, cx
: &DocContext
<'_
>) -> FnRetTy
{
1001 Self::Return(ref typ
) => Return(typ
.clean(cx
)),
1002 Self::DefaultReturn(..) => DefaultReturn
,
1007 impl Clean
<Item
> for doctree
::Trait
<'_
> {
1008 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
1009 let attrs
= self.attrs
.clean(cx
);
1011 name
: Some(self.name
.clean(cx
)),
1013 source
: self.whence
.clean(cx
),
1014 def_id
: cx
.tcx
.hir().local_def_id(self.id
).to_def_id(),
1015 visibility
: self.vis
.clean(cx
),
1016 stability
: cx
.stability(self.id
).clean(cx
),
1017 deprecation
: cx
.deprecation(self.id
).clean(cx
),
1018 inner
: TraitItem(Trait
{
1019 auto: self.is_auto
.clean(cx
),
1020 unsafety
: self.unsafety
,
1021 items
: self.items
.iter().map(|ti
| ti
.clean(cx
)).collect(),
1022 generics
: self.generics
.clean(cx
),
1023 bounds
: self.bounds
.clean(cx
),
1024 is_auto
: self.is_auto
.clean(cx
),
1030 impl Clean
<Item
> for doctree
::TraitAlias
<'_
> {
1031 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
1032 let attrs
= self.attrs
.clean(cx
);
1034 name
: Some(self.name
.clean(cx
)),
1036 source
: self.whence
.clean(cx
),
1037 def_id
: cx
.tcx
.hir().local_def_id(self.id
).to_def_id(),
1038 visibility
: self.vis
.clean(cx
),
1039 stability
: cx
.stability(self.id
).clean(cx
),
1040 deprecation
: cx
.deprecation(self.id
).clean(cx
),
1041 inner
: TraitAliasItem(TraitAlias
{
1042 generics
: self.generics
.clean(cx
),
1043 bounds
: self.bounds
.clean(cx
),
1049 impl Clean
<bool
> for hir
::IsAuto
{
1050 fn clean(&self, _
: &DocContext
<'_
>) -> bool
{
1052 hir
::IsAuto
::Yes
=> true,
1053 hir
::IsAuto
::No
=> false,
1058 impl Clean
<Type
> for hir
::TraitRef
<'_
> {
1059 fn clean(&self, cx
: &DocContext
<'_
>) -> Type
{
1060 resolve_type(cx
, self.path
.clean(cx
), self.hir_ref_id
)
1064 impl Clean
<PolyTrait
> for hir
::PolyTraitRef
<'_
> {
1065 fn clean(&self, cx
: &DocContext
<'_
>) -> PolyTrait
{
1067 trait_
: self.trait_ref
.clean(cx
),
1068 generic_params
: self.bound_generic_params
.clean(cx
),
1073 impl Clean
<TypeKind
> for hir
::def
::DefKind
{
1074 fn clean(&self, _
: &DocContext
<'_
>) -> TypeKind
{
1076 hir
::def
::DefKind
::Mod
=> TypeKind
::Module
,
1077 hir
::def
::DefKind
::Struct
=> TypeKind
::Struct
,
1078 hir
::def
::DefKind
::Union
=> TypeKind
::Union
,
1079 hir
::def
::DefKind
::Enum
=> TypeKind
::Enum
,
1080 hir
::def
::DefKind
::Trait
=> TypeKind
::Trait
,
1081 hir
::def
::DefKind
::TyAlias
=> TypeKind
::Typedef
,
1082 hir
::def
::DefKind
::ForeignTy
=> TypeKind
::Foreign
,
1083 hir
::def
::DefKind
::TraitAlias
=> TypeKind
::TraitAlias
,
1084 hir
::def
::DefKind
::Fn
=> TypeKind
::Function
,
1085 hir
::def
::DefKind
::Const
=> TypeKind
::Const
,
1086 hir
::def
::DefKind
::Static
=> TypeKind
::Static
,
1087 hir
::def
::DefKind
::Macro(_
) => TypeKind
::Macro
,
1088 _
=> TypeKind
::Foreign
,
1093 impl Clean
<Item
> for hir
::TraitItem
<'_
> {
1094 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
1095 let inner
= match self.kind
{
1096 hir
::TraitItemKind
::Const(ref ty
, default) => {
1097 AssocConstItem(ty
.clean(cx
), default.map(|e
| print_const_expr(cx
, e
)))
1099 hir
::TraitItemKind
::Fn(ref sig
, hir
::TraitFn
::Provided(body
)) => {
1100 MethodItem((sig
, &self.generics
, body
, None
).clean(cx
))
1102 hir
::TraitItemKind
::Fn(ref sig
, hir
::TraitFn
::Required(ref names
)) => {
1103 let (generics
, decl
) = enter_impl_trait(cx
, || {
1104 (self.generics
.clean(cx
), (&*sig
.decl
, &names
[..]).clean(cx
))
1106 let (all_types
, ret_types
) = get_all_types(&generics
, &decl
, cx
);
1107 TyMethodItem(TyMethod { header: sig.header, decl, generics, all_types, ret_types }
)
1109 hir
::TraitItemKind
::Type(ref bounds
, ref default) => {
1110 AssocTypeItem(bounds
.clean(cx
), default.clean(cx
))
1113 let local_did
= cx
.tcx
.hir().local_def_id(self.hir_id
);
1115 name
: Some(self.ident
.name
.clean(cx
)),
1116 attrs
: self.attrs
.clean(cx
),
1117 source
: self.span
.clean(cx
),
1118 def_id
: local_did
.to_def_id(),
1119 visibility
: Visibility
::Inherited
,
1120 stability
: get_stability(cx
, local_did
.to_def_id()),
1121 deprecation
: get_deprecation(cx
, local_did
.to_def_id()),
1127 impl Clean
<Item
> for hir
::ImplItem
<'_
> {
1128 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
1129 let inner
= match self.kind
{
1130 hir
::ImplItemKind
::Const(ref ty
, expr
) => {
1131 AssocConstItem(ty
.clean(cx
), Some(print_const_expr(cx
, expr
)))
1133 hir
::ImplItemKind
::Fn(ref sig
, body
) => {
1134 MethodItem((sig
, &self.generics
, body
, Some(self.defaultness
)).clean(cx
))
1136 hir
::ImplItemKind
::TyAlias(ref ty
) => {
1137 let type_
= ty
.clean(cx
);
1138 let item_type
= type_
.def_id().and_then(|did
| inline
::build_ty(cx
, did
));
1139 TypedefItem(Typedef { type_, generics: Generics::default(), item_type }
, true)
1141 hir
::ImplItemKind
::OpaqueTy(ref bounds
) => OpaqueTyItem(
1142 OpaqueTy { bounds: bounds.clean(cx), generics: Generics::default() }
,
1146 let local_did
= cx
.tcx
.hir().local_def_id(self.hir_id
);
1148 name
: Some(self.ident
.name
.clean(cx
)),
1149 source
: self.span
.clean(cx
),
1150 attrs
: self.attrs
.clean(cx
),
1151 def_id
: local_did
.to_def_id(),
1152 visibility
: self.vis
.clean(cx
),
1153 stability
: get_stability(cx
, local_did
.to_def_id()),
1154 deprecation
: get_deprecation(cx
, local_did
.to_def_id()),
1160 impl Clean
<Item
> for ty
::AssocItem
{
1161 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
1162 let inner
= match self.kind
{
1163 ty
::AssocKind
::Const
=> {
1164 let ty
= cx
.tcx
.type_of(self.def_id
);
1165 let default = if self.defaultness
.has_value() {
1166 Some(inline
::print_inlined_const(cx
, self.def_id
))
1170 AssocConstItem(ty
.clean(cx
), default)
1172 ty
::AssocKind
::Fn
=> {
1174 (cx
.tcx
.generics_of(self.def_id
), cx
.tcx
.explicit_predicates_of(self.def_id
))
1176 let sig
= cx
.tcx
.fn_sig(self.def_id
);
1177 let mut decl
= (self.def_id
, sig
).clean(cx
);
1179 if self.fn_has_self_parameter
{
1180 let self_ty
= match self.container
{
1181 ty
::ImplContainer(def_id
) => cx
.tcx
.type_of(def_id
),
1182 ty
::TraitContainer(_
) => cx
.tcx
.types
.self_param
,
1184 let self_arg_ty
= *sig
.input(0).skip_binder();
1185 if self_arg_ty
== self_ty
{
1186 decl
.inputs
.values
[0].type_
= Generic(String
::from("Self"));
1187 } else if let ty
::Ref(_
, ty
, _
) = self_arg_ty
.kind
{
1189 match decl
.inputs
.values
[0].type_
{
1190 BorrowedRef { ref mut type_, .. }
=> {
1191 **type_
= Generic(String
::from("Self"))
1193 _
=> unreachable
!(),
1199 let provided
= match self.container
{
1200 ty
::ImplContainer(_
) => true,
1201 ty
::TraitContainer(_
) => self.defaultness
.has_value(),
1203 let (all_types
, ret_types
) = get_all_types(&generics
, &decl
, cx
);
1205 let constness
= if is_min_const_fn(cx
.tcx
, self.def_id
) {
1206 hir
::Constness
::Const
1208 hir
::Constness
::NotConst
1210 let asyncness
= cx
.tcx
.asyncness(self.def_id
);
1211 let defaultness
= match self.container
{
1212 ty
::ImplContainer(_
) => Some(self.defaultness
),
1213 ty
::TraitContainer(_
) => None
,
1218 header
: hir
::FnHeader
{
1219 unsafety
: sig
.unsafety(),
1229 TyMethodItem(TyMethod
{
1232 header
: hir
::FnHeader
{
1233 unsafety
: sig
.unsafety(),
1235 constness
: hir
::Constness
::NotConst
,
1236 asyncness
: hir
::IsAsync
::NotAsync
,
1243 ty
::AssocKind
::Type
=> {
1244 let my_name
= self.ident
.name
.clean(cx
);
1246 if let ty
::TraitContainer(did
) = self.container
{
1247 // When loading a cross-crate associated type, the bounds for this type
1248 // are actually located on the trait/impl itself, so we need to load
1249 // all of the generics from there and then look for bounds that are
1250 // applied to this associated type in question.
1251 let predicates
= cx
.tcx
.explicit_predicates_of(did
);
1252 let generics
= (cx
.tcx
.generics_of(did
), predicates
).clean(cx
);
1253 let mut bounds
= generics
1256 .filter_map(|pred
| {
1257 let (name
, self_type
, trait_
, bounds
) = match *pred
{
1258 WherePredicate
::BoundPredicate
{
1259 ty
: QPath { ref name, ref self_type, ref trait_ }
,
1261 } => (name
, self_type
, trait_
, bounds
),
1264 if *name
!= my_name
{
1268 ResolvedPath { did, .. }
if did
== self.container
.id() => {}
1272 Generic(ref s
) if *s
== "Self" => {}
1277 .flat_map(|i
| i
.iter().cloned())
1278 .collect
::<Vec
<_
>>();
1279 // Our Sized/?Sized bound didn't get handled when creating the generics
1280 // because we didn't actually get our whole set of bounds until just now
1281 // (some of them may have come from the trait). If we do have a sized
1282 // bound, we remove it, and if we don't then we add the `?Sized` bound
1284 match bounds
.iter().position(|b
| b
.is_sized_bound(cx
)) {
1288 None
=> bounds
.push(GenericBound
::maybe_sized(cx
)),
1291 let ty
= if self.defaultness
.has_value() {
1292 Some(cx
.tcx
.type_of(self.def_id
))
1297 AssocTypeItem(bounds
, ty
.clean(cx
))
1299 let type_
= cx
.tcx
.type_of(self.def_id
).clean(cx
);
1300 let item_type
= type_
.def_id().and_then(|did
| inline
::build_ty(cx
, did
));
1304 generics
: Generics { params: Vec::new(), where_predicates: Vec::new() }
,
1311 ty
::AssocKind
::OpaqueTy
=> unimplemented
!(),
1314 let visibility
= match self.container
{
1315 ty
::ImplContainer(_
) => self.vis
.clean(cx
),
1316 ty
::TraitContainer(_
) => Inherited
,
1320 name
: Some(self.ident
.name
.clean(cx
)),
1322 stability
: get_stability(cx
, self.def_id
),
1323 deprecation
: get_deprecation(cx
, self.def_id
),
1324 def_id
: self.def_id
,
1325 attrs
: inline
::load_attrs(cx
, self.def_id
).clean(cx
),
1326 source
: cx
.tcx
.def_span(self.def_id
).clean(cx
),
1332 impl Clean
<Type
> for hir
::Ty
<'_
> {
1333 fn clean(&self, cx
: &DocContext
<'_
>) -> Type
{
1337 TyKind
::Never
=> Never
,
1338 TyKind
::Ptr(ref m
) => RawPointer(m
.mutbl
, box m
.ty
.clean(cx
)),
1339 TyKind
::Rptr(ref l
, ref m
) => {
1340 let lifetime
= if l
.is_elided() { None }
else { Some(l.clean(cx)) }
;
1341 BorrowedRef { lifetime, mutability: m.mutbl, type_: box m.ty.clean(cx) }
1343 TyKind
::Slice(ref ty
) => Slice(box ty
.clean(cx
)),
1344 TyKind
::Array(ref ty
, ref length
) => {
1345 let def_id
= cx
.tcx
.hir().local_def_id(length
.hir_id
);
1346 let length
= match cx
.tcx
.const_eval_poly(def_id
.to_def_id()) {
1348 print_const(cx
, ty
::Const
::from_value(cx
.tcx
, length
, cx
.tcx
.types
.usize))
1353 .span_to_snippet(cx
.tcx
.def_span(def_id
))
1354 .unwrap_or_else(|_
| "_".to_string()),
1356 Array(box ty
.clean(cx
), length
)
1358 TyKind
::Tup(ref tys
) => Tuple(tys
.clean(cx
)),
1359 TyKind
::Def(item_id
, _
) => {
1360 let item
= cx
.tcx
.hir().expect_item(item_id
.id
);
1361 if let hir
::ItemKind
::OpaqueTy(ref ty
) = item
.kind
{
1362 ImplTrait(ty
.bounds
.clean(cx
))
1367 TyKind
::Path(hir
::QPath
::Resolved(None
, ref path
)) => {
1368 if let Res
::Def(DefKind
::TyParam
, did
) = path
.res
{
1369 if let Some(new_ty
) = cx
.ty_substs
.borrow().get(&did
).cloned() {
1372 if let Some(bounds
) = cx
.impl_trait_bounds
.borrow_mut().remove(&did
.into()) {
1373 return ImplTrait(bounds
);
1377 let mut alias
= None
;
1378 if let Res
::Def(DefKind
::TyAlias
, def_id
) = path
.res
{
1379 // Substitute private type aliases
1380 if let Some(def_id
) = def_id
.as_local() {
1381 let hir_id
= cx
.tcx
.hir().as_local_hir_id(def_id
);
1382 if !cx
.renderinfo
.borrow().access_levels
.is_exported(def_id
.to_def_id()) {
1383 alias
= Some(&cx
.tcx
.hir().expect_item(hir_id
).kind
);
1388 if let Some(&hir
::ItemKind
::TyAlias(ref ty
, ref generics
)) = alias
{
1389 let provided_params
= &path
.segments
.last().expect("segments were empty");
1390 let mut ty_substs
= FxHashMap
::default();
1391 let mut lt_substs
= FxHashMap
::default();
1392 let mut ct_substs
= FxHashMap
::default();
1393 let generic_args
= provided_params
.generic_args();
1395 let mut indices
: GenericParamCount
= Default
::default();
1396 for param
in generics
.params
.iter() {
1398 hir
::GenericParamKind
::Lifetime { .. }
=> {
1401 generic_args
.args
.iter().find_map(|arg
| match arg
{
1402 hir
::GenericArg
::Lifetime(lt
) => {
1403 if indices
.lifetimes
== j
{
1411 if let Some(lt
) = lifetime
.cloned() {
1412 if !lt
.is_elided() {
1413 let lt_def_id
= cx
.tcx
.hir().local_def_id(param
.hir_id
);
1414 lt_substs
.insert(lt_def_id
.to_def_id(), lt
.clean(cx
));
1417 indices
.lifetimes
+= 1;
1419 hir
::GenericParamKind
::Type { ref default, .. }
=> {
1420 let ty_param_def_id
= cx
.tcx
.hir().local_def_id(param
.hir_id
);
1423 generic_args
.args
.iter().find_map(|arg
| match arg
{
1424 hir
::GenericArg
::Type(ty
) => {
1425 if indices
.types
== j
{
1433 if let Some(ty
) = type_
{
1434 ty_substs
.insert(ty_param_def_id
.to_def_id(), ty
.clean(cx
));
1435 } else if let Some(default) = *default {
1437 .insert(ty_param_def_id
.to_def_id(), default.clean(cx
));
1441 hir
::GenericParamKind
::Const { .. }
=> {
1442 let const_param_def_id
=
1443 cx
.tcx
.hir().local_def_id(param
.hir_id
);
1446 generic_args
.args
.iter().find_map(|arg
| match arg
{
1447 hir
::GenericArg
::Const(ct
) => {
1448 if indices
.consts
== j
{
1456 if let Some(ct
) = const_
{
1458 .insert(const_param_def_id
.to_def_id(), ct
.clean(cx
));
1460 // FIXME(const_generics:defaults)
1461 indices
.consts
+= 1;
1466 return cx
.enter_alias(ty_substs
, lt_substs
, ct_substs
, || ty
.clean(cx
));
1468 resolve_type(cx
, path
.clean(cx
), self.hir_id
)
1470 TyKind
::Path(hir
::QPath
::Resolved(Some(ref qself
), ref p
)) => {
1471 let segments
= if p
.is_global() { &p.segments[1..] }
else { &p.segments }
;
1472 let trait_segments
= &segments
[..segments
.len() - 1];
1473 let trait_path
= self::Path
{
1474 global
: p
.is_global(),
1477 cx
.tcx
.associated_item(p
.res
.def_id()).container
.id(),
1479 segments
: trait_segments
.clean(cx
),
1482 name
: p
.segments
.last().expect("segments were empty").ident
.name
.clean(cx
),
1483 self_type
: box qself
.clean(cx
),
1484 trait_
: box resolve_type(cx
, trait_path
, self.hir_id
),
1487 TyKind
::Path(hir
::QPath
::TypeRelative(ref qself
, ref segment
)) => {
1488 let mut res
= Res
::Err
;
1489 let ty
= hir_ty_to_ty(cx
.tcx
, self);
1490 if let ty
::Projection(proj
) = ty
.kind
{
1491 res
= Res
::Def(DefKind
::Trait
, proj
.trait_ref(cx
.tcx
).def_id
);
1493 let trait_path
= hir
::Path { span: self.span, res, segments: &[] }
;
1495 name
: segment
.ident
.name
.clean(cx
),
1496 self_type
: box qself
.clean(cx
),
1497 trait_
: box resolve_type(cx
, trait_path
.clean(cx
), self.hir_id
),
1500 TyKind
::TraitObject(ref bounds
, ref lifetime
) => {
1501 match bounds
[0].clean(cx
).trait_
{
1502 ResolvedPath { path, param_names: None, did, is_generic }
=> {
1503 let mut bounds
: Vec
<self::GenericBound
> = bounds
[1..]
1506 self::GenericBound
::TraitBound(
1508 hir
::TraitBoundModifier
::None
,
1512 if !lifetime
.is_elided() {
1513 bounds
.push(self::GenericBound
::Outlives(lifetime
.clean(cx
)));
1515 ResolvedPath { path, param_names: Some(bounds), did, is_generic }
1517 _
=> Infer
, // shouldn't happen
1520 TyKind
::BareFn(ref barefn
) => BareFunction(box barefn
.clean(cx
)),
1521 TyKind
::Infer
| TyKind
::Err
=> Infer
,
1522 TyKind
::Typeof(..) => panic
!("unimplemented type {:?}", self.kind
),
1527 impl<'tcx
> Clean
<Type
> for Ty
<'tcx
> {
1528 fn clean(&self, cx
: &DocContext
<'_
>) -> Type
{
1529 debug
!("cleaning type: {:?}", self);
1532 ty
::Bool
=> Primitive(PrimitiveType
::Bool
),
1533 ty
::Char
=> Primitive(PrimitiveType
::Char
),
1534 ty
::Int(int_ty
) => Primitive(int_ty
.into()),
1535 ty
::Uint(uint_ty
) => Primitive(uint_ty
.into()),
1536 ty
::Float(float_ty
) => Primitive(float_ty
.into()),
1537 ty
::Str
=> Primitive(PrimitiveType
::Str
),
1538 ty
::Slice(ty
) => Slice(box ty
.clean(cx
)),
1539 ty
::Array(ty
, n
) => {
1540 let mut n
= cx
.tcx
.lift(&n
).expect("array lift failed");
1541 n
= n
.eval(cx
.tcx
, ty
::ParamEnv
::reveal_all());
1542 let n
= print_const(cx
, n
);
1543 Array(box ty
.clean(cx
), n
)
1545 ty
::RawPtr(mt
) => RawPointer(mt
.mutbl
, box mt
.ty
.clean(cx
)),
1546 ty
::Ref(r
, ty
, mutbl
) => {
1547 BorrowedRef { lifetime: r.clean(cx), mutability: mutbl, type_: box ty.clean(cx) }
1549 ty
::FnDef(..) | ty
::FnPtr(_
) => {
1550 let ty
= cx
.tcx
.lift(self).expect("FnPtr lift failed");
1551 let sig
= ty
.fn_sig(cx
.tcx
);
1552 let def_id
= DefId
::local(CRATE_DEF_INDEX
);
1553 BareFunction(box BareFunctionDecl
{
1554 unsafety
: sig
.unsafety(),
1555 generic_params
: Vec
::new(),
1556 decl
: (def_id
, sig
).clean(cx
),
1560 ty
::Adt(def
, substs
) => {
1562 let kind
= match def
.adt_kind() {
1563 AdtKind
::Struct
=> TypeKind
::Struct
,
1564 AdtKind
::Union
=> TypeKind
::Union
,
1565 AdtKind
::Enum
=> TypeKind
::Enum
,
1567 inline
::record_extern_fqn(cx
, did
, kind
);
1568 let path
= external_path(cx
, cx
.tcx
.item_name(did
), None
, false, vec
![], substs
);
1569 ResolvedPath { path, param_names: None, did, is_generic: false }
1571 ty
::Foreign(did
) => {
1572 inline
::record_extern_fqn(cx
, did
, TypeKind
::Foreign
);
1573 let path
= external_path(
1575 cx
.tcx
.item_name(did
),
1579 InternalSubsts
::empty(),
1581 ResolvedPath { path, param_names: None, did, is_generic: false }
1583 ty
::Dynamic(ref obj
, ref reg
) => {
1584 // HACK: pick the first `did` as the `did` of the trait object. Someone
1585 // might want to implement "native" support for marker-trait-only
1587 let mut dids
= obj
.principal_def_id().into_iter().chain(obj
.auto_traits());
1590 .unwrap_or_else(|| panic
!("found trait object `{:?}` with no traits?", self));
1591 let substs
= match obj
.principal() {
1592 Some(principal
) => principal
.skip_binder().substs
,
1593 // marker traits have no substs.
1594 _
=> cx
.tcx
.intern_substs(&[]),
1597 inline
::record_extern_fqn(cx
, did
, TypeKind
::Trait
);
1599 let mut param_names
= vec
![];
1600 if let Some(b
) = reg
.clean(cx
) {
1601 param_names
.push(GenericBound
::Outlives(b
));
1604 let empty
= cx
.tcx
.intern_substs(&[]);
1606 external_path(cx
, cx
.tcx
.item_name(did
), Some(did
), false, vec
![], empty
);
1607 inline
::record_extern_fqn(cx
, did
, TypeKind
::Trait
);
1608 let bound
= GenericBound
::TraitBound(
1610 trait_
: ResolvedPath
{
1616 generic_params
: Vec
::new(),
1618 hir
::TraitBoundModifier
::None
,
1620 param_names
.push(bound
);
1623 let mut bindings
= vec
![];
1624 for pb
in obj
.projection_bounds() {
1625 bindings
.push(TypeBinding
{
1626 name
: cx
.tcx
.associated_item(pb
.item_def_id()).ident
.name
.clean(cx
),
1627 kind
: TypeBindingKind
::Equality { ty: pb.skip_binder().ty.clean(cx) }
,
1632 external_path(cx
, cx
.tcx
.item_name(did
), Some(did
), false, bindings
, substs
);
1633 ResolvedPath { path, param_names: Some(param_names), did, is_generic: false }
1635 ty
::Tuple(ref t
) => {
1636 Tuple(t
.iter().map(|t
| t
.expect_ty()).collect
::<Vec
<_
>>().clean(cx
))
1639 ty
::Projection(ref data
) => data
.clean(cx
),
1641 ty
::Param(ref p
) => {
1642 if let Some(bounds
) = cx
.impl_trait_bounds
.borrow_mut().remove(&p
.index
.into()) {
1645 Generic(p
.name
.to_string())
1649 ty
::Opaque(def_id
, substs
) => {
1650 // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
1651 // by looking up the projections associated with the def_id.
1652 let predicates_of
= cx
.tcx
.explicit_predicates_of(def_id
);
1653 let substs
= cx
.tcx
.lift(&substs
).expect("Opaque lift failed");
1654 let bounds
= predicates_of
.instantiate(cx
.tcx
, substs
);
1655 let mut regions
= vec
![];
1656 let mut has_sized
= false;
1657 let mut bounds
= bounds
1660 .filter_map(|predicate
| {
1661 let trait_ref
= if let Some(tr
) = predicate
.to_opt_poly_trait_ref() {
1663 } else if let ty
::PredicateKind
::TypeOutlives(pred
) = predicate
.kind() {
1664 // these should turn up at the end
1665 if let Some(r
) = pred
.skip_binder().1.clean(cx
) {
1666 regions
.push(GenericBound
::Outlives(r
));
1673 if let Some(sized
) = cx
.tcx
.lang_items().sized_trait() {
1674 if trait_ref
.def_id() == sized
{
1680 let bounds
: Vec
<_
> = bounds
1683 .filter_map(|pred
| {
1684 if let ty
::PredicateKind
::Projection(proj
) = pred
.kind() {
1685 let proj
= proj
.skip_binder();
1686 if proj
.projection_ty
.trait_ref(cx
.tcx
)
1687 == *trait_ref
.skip_binder()
1692 .associated_item(proj
.projection_ty
.item_def_id
)
1696 kind
: TypeBindingKind
::Equality
{
1697 ty
: proj
.ty
.clean(cx
),
1709 Some((trait_ref
, &bounds
[..]).clean(cx
))
1711 .collect
::<Vec
<_
>>();
1712 bounds
.extend(regions
);
1713 if !has_sized
&& !bounds
.is_empty() {
1714 bounds
.insert(0, GenericBound
::maybe_sized(cx
));
1719 ty
::Closure(..) | ty
::Generator(..) => Tuple(vec
![]), // FIXME(pcwalton)
1721 ty
::Bound(..) => panic
!("Bound"),
1722 ty
::Placeholder(..) => panic
!("Placeholder"),
1723 ty
::GeneratorWitness(..) => panic
!("GeneratorWitness"),
1724 ty
::Infer(..) => panic
!("Infer"),
1725 ty
::Error
=> panic
!("Error"),
1730 impl<'tcx
> Clean
<Constant
> for ty
::Const
<'tcx
> {
1731 fn clean(&self, cx
: &DocContext
<'_
>) -> Constant
{
1733 type_
: self.ty
.clean(cx
),
1734 expr
: format
!("{}", self),
1741 impl Clean
<Item
> for hir
::StructField
<'_
> {
1742 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
1743 let local_did
= cx
.tcx
.hir().local_def_id(self.hir_id
);
1746 name
: Some(self.ident
.name
).clean(cx
),
1747 attrs
: self.attrs
.clean(cx
),
1748 source
: self.span
.clean(cx
),
1749 visibility
: self.vis
.clean(cx
),
1750 stability
: get_stability(cx
, local_did
.to_def_id()),
1751 deprecation
: get_deprecation(cx
, local_did
.to_def_id()),
1752 def_id
: local_did
.to_def_id(),
1753 inner
: StructFieldItem(self.ty
.clean(cx
)),
1758 impl Clean
<Item
> for ty
::FieldDef
{
1759 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
1761 name
: Some(self.ident
.name
).clean(cx
),
1762 attrs
: cx
.tcx
.get_attrs(self.did
).clean(cx
),
1763 source
: cx
.tcx
.def_span(self.did
).clean(cx
),
1764 visibility
: self.vis
.clean(cx
),
1765 stability
: get_stability(cx
, self.did
),
1766 deprecation
: get_deprecation(cx
, self.did
),
1768 inner
: StructFieldItem(cx
.tcx
.type_of(self.did
).clean(cx
)),
1773 impl Clean
<Visibility
> for hir
::Visibility
<'_
> {
1774 fn clean(&self, cx
: &DocContext
<'_
>) -> Visibility
{
1776 hir
::VisibilityKind
::Public
=> Visibility
::Public
,
1777 hir
::VisibilityKind
::Inherited
=> Visibility
::Inherited
,
1778 hir
::VisibilityKind
::Crate(_
) => Visibility
::Crate
,
1779 hir
::VisibilityKind
::Restricted { ref path, .. }
=> {
1780 let path
= path
.clean(cx
);
1781 let did
= register_res(cx
, path
.res
);
1782 Visibility
::Restricted(did
, path
)
1788 impl Clean
<Visibility
> for ty
::Visibility
{
1789 fn clean(&self, _
: &DocContext
<'_
>) -> Visibility
{
1790 if *self == ty
::Visibility
::Public { Public }
else { Inherited }
1794 impl Clean
<Item
> for doctree
::Struct
<'_
> {
1795 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
1797 name
: Some(self.name
.clean(cx
)),
1798 attrs
: self.attrs
.clean(cx
),
1799 source
: self.whence
.clean(cx
),
1800 def_id
: cx
.tcx
.hir().local_def_id(self.id
).to_def_id(),
1801 visibility
: self.vis
.clean(cx
),
1802 stability
: cx
.stability(self.id
).clean(cx
),
1803 deprecation
: cx
.deprecation(self.id
).clean(cx
),
1804 inner
: StructItem(Struct
{
1805 struct_type
: self.struct_type
,
1806 generics
: self.generics
.clean(cx
),
1807 fields
: self.fields
.clean(cx
),
1808 fields_stripped
: false,
1814 impl Clean
<Item
> for doctree
::Union
<'_
> {
1815 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
1817 name
: Some(self.name
.clean(cx
)),
1818 attrs
: self.attrs
.clean(cx
),
1819 source
: self.whence
.clean(cx
),
1820 def_id
: cx
.tcx
.hir().local_def_id(self.id
).to_def_id(),
1821 visibility
: self.vis
.clean(cx
),
1822 stability
: cx
.stability(self.id
).clean(cx
),
1823 deprecation
: cx
.deprecation(self.id
).clean(cx
),
1824 inner
: UnionItem(Union
{
1825 struct_type
: self.struct_type
,
1826 generics
: self.generics
.clean(cx
),
1827 fields
: self.fields
.clean(cx
),
1828 fields_stripped
: false,
1834 impl Clean
<VariantStruct
> for rustc_hir
::VariantData
<'_
> {
1835 fn clean(&self, cx
: &DocContext
<'_
>) -> VariantStruct
{
1837 struct_type
: doctree
::struct_type_from_def(self),
1838 fields
: self.fields().iter().map(|x
| x
.clean(cx
)).collect(),
1839 fields_stripped
: false,
1844 impl Clean
<Item
> for doctree
::Enum
<'_
> {
1845 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
1847 name
: Some(self.name
.clean(cx
)),
1848 attrs
: self.attrs
.clean(cx
),
1849 source
: self.whence
.clean(cx
),
1850 def_id
: cx
.tcx
.hir().local_def_id(self.id
).to_def_id(),
1851 visibility
: self.vis
.clean(cx
),
1852 stability
: cx
.stability(self.id
).clean(cx
),
1853 deprecation
: cx
.deprecation(self.id
).clean(cx
),
1854 inner
: EnumItem(Enum
{
1855 variants
: self.variants
.iter().map(|v
| v
.clean(cx
)).collect(),
1856 generics
: self.generics
.clean(cx
),
1857 variants_stripped
: false,
1863 impl Clean
<Item
> for doctree
::Variant
<'_
> {
1864 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
1866 name
: Some(self.name
.clean(cx
)),
1867 attrs
: self.attrs
.clean(cx
),
1868 source
: self.whence
.clean(cx
),
1869 visibility
: Inherited
,
1870 stability
: cx
.stability(self.id
).clean(cx
),
1871 deprecation
: cx
.deprecation(self.id
).clean(cx
),
1872 def_id
: cx
.tcx
.hir().local_def_id(self.id
).to_def_id(),
1873 inner
: VariantItem(Variant { kind: self.def.clean(cx) }
),
1878 impl Clean
<Item
> for ty
::VariantDef
{
1879 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
1880 let kind
= match self.ctor_kind
{
1881 CtorKind
::Const
=> VariantKind
::CLike
,
1882 CtorKind
::Fn
=> VariantKind
::Tuple(
1883 self.fields
.iter().map(|f
| cx
.tcx
.type_of(f
.did
).clean(cx
)).collect(),
1885 CtorKind
::Fictive
=> VariantKind
::Struct(VariantStruct
{
1886 struct_type
: doctree
::Plain
,
1887 fields_stripped
: false,
1892 source
: cx
.tcx
.def_span(field
.did
).clean(cx
),
1893 name
: Some(field
.ident
.name
.clean(cx
)),
1894 attrs
: cx
.tcx
.get_attrs(field
.did
).clean(cx
),
1895 visibility
: field
.vis
.clean(cx
),
1897 stability
: get_stability(cx
, field
.did
),
1898 deprecation
: get_deprecation(cx
, field
.did
),
1899 inner
: StructFieldItem(cx
.tcx
.type_of(field
.did
).clean(cx
)),
1905 name
: Some(self.ident
.clean(cx
)),
1906 attrs
: inline
::load_attrs(cx
, self.def_id
).clean(cx
),
1907 source
: cx
.tcx
.def_span(self.def_id
).clean(cx
),
1908 visibility
: Inherited
,
1909 def_id
: self.def_id
,
1910 inner
: VariantItem(Variant { kind }
),
1911 stability
: get_stability(cx
, self.def_id
),
1912 deprecation
: get_deprecation(cx
, self.def_id
),
1917 impl Clean
<VariantKind
> for hir
::VariantData
<'_
> {
1918 fn clean(&self, cx
: &DocContext
<'_
>) -> VariantKind
{
1920 hir
::VariantData
::Struct(..) => VariantKind
::Struct(self.clean(cx
)),
1921 hir
::VariantData
::Tuple(..) => {
1922 VariantKind
::Tuple(self.fields().iter().map(|x
| x
.ty
.clean(cx
)).collect())
1924 hir
::VariantData
::Unit(..) => VariantKind
::CLike
,
1929 impl Clean
<Span
> for rustc_span
::Span
{
1930 fn clean(&self, cx
: &DocContext
<'_
>) -> Span
{
1931 if self.is_dummy() {
1932 return Span
::empty();
1935 let sm
= cx
.sess().source_map();
1936 let filename
= sm
.span_to_filename(*self);
1937 let lo
= sm
.lookup_char_pos(self.lo());
1938 let hi
= sm
.lookup_char_pos(self.hi());
1943 locol
: lo
.col
.to_usize(),
1945 hicol
: hi
.col
.to_usize(),
1951 impl Clean
<Path
> for hir
::Path
<'_
> {
1952 fn clean(&self, cx
: &DocContext
<'_
>) -> Path
{
1954 global
: self.is_global(),
1956 segments
: if self.is_global() { &self.segments[1..] }
else { &self.segments }
.clean(cx
),
1961 impl Clean
<GenericArgs
> for hir
::GenericArgs
<'_
> {
1962 fn clean(&self, cx
: &DocContext
<'_
>) -> GenericArgs
{
1963 if self.parenthesized
{
1964 let output
= self.bindings
[0].ty().clean(cx
);
1965 GenericArgs
::Parenthesized
{
1966 inputs
: self.inputs().clean(cx
),
1967 output
: if output
!= Type
::Tuple(Vec
::new()) { Some(output) }
else { None }
,
1970 let elide_lifetimes
= self.args
.iter().all(|arg
| match arg
{
1971 hir
::GenericArg
::Lifetime(lt
) => lt
.is_elided(),
1974 GenericArgs
::AngleBracketed
{
1978 .filter_map(|arg
| match arg
{
1979 hir
::GenericArg
::Lifetime(lt
) if !elide_lifetimes
=> {
1980 Some(GenericArg
::Lifetime(lt
.clean(cx
)))
1982 hir
::GenericArg
::Lifetime(_
) => None
,
1983 hir
::GenericArg
::Type(ty
) => Some(GenericArg
::Type(ty
.clean(cx
))),
1984 hir
::GenericArg
::Const(ct
) => Some(GenericArg
::Const(ct
.clean(cx
))),
1987 bindings
: self.bindings
.clean(cx
),
1993 impl Clean
<PathSegment
> for hir
::PathSegment
<'_
> {
1994 fn clean(&self, cx
: &DocContext
<'_
>) -> PathSegment
{
1995 PathSegment { name: self.ident.name.clean(cx), args: self.generic_args().clean(cx) }
1999 impl Clean
<String
> for Ident
{
2001 fn clean(&self, cx
: &DocContext
<'_
>) -> String
{
2006 impl Clean
<String
> for Symbol
{
2008 fn clean(&self, _
: &DocContext
<'_
>) -> String
{
2013 impl Clean
<Item
> for doctree
::Typedef
<'_
> {
2014 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
2015 let type_
= self.ty
.clean(cx
);
2016 let item_type
= type_
.def_id().and_then(|did
| inline
::build_ty(cx
, did
));
2018 name
: Some(self.name
.clean(cx
)),
2019 attrs
: self.attrs
.clean(cx
),
2020 source
: self.whence
.clean(cx
),
2021 def_id
: cx
.tcx
.hir().local_def_id(self.id
).to_def_id(),
2022 visibility
: self.vis
.clean(cx
),
2023 stability
: cx
.stability(self.id
).clean(cx
),
2024 deprecation
: cx
.deprecation(self.id
).clean(cx
),
2025 inner
: TypedefItem(Typedef { type_, generics: self.gen.clean(cx), item_type }
, false),
2030 impl Clean
<Item
> for doctree
::OpaqueTy
<'_
> {
2031 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
2033 name
: Some(self.name
.clean(cx
)),
2034 attrs
: self.attrs
.clean(cx
),
2035 source
: self.whence
.clean(cx
),
2036 def_id
: cx
.tcx
.hir().local_def_id(self.id
).to_def_id(),
2037 visibility
: self.vis
.clean(cx
),
2038 stability
: cx
.stability(self.id
).clean(cx
),
2039 deprecation
: cx
.deprecation(self.id
).clean(cx
),
2040 inner
: OpaqueTyItem(
2042 bounds
: self.opaque_ty
.bounds
.clean(cx
),
2043 generics
: self.opaque_ty
.generics
.clean(cx
),
2051 impl Clean
<BareFunctionDecl
> for hir
::BareFnTy
<'_
> {
2052 fn clean(&self, cx
: &DocContext
<'_
>) -> BareFunctionDecl
{
2053 let (generic_params
, decl
) = enter_impl_trait(cx
, || {
2054 (self.generic_params
.clean(cx
), (&*self.decl
, &self.param_names
[..]).clean(cx
))
2056 BareFunctionDecl { unsafety: self.unsafety, abi: self.abi, decl, generic_params }
2060 impl Clean
<Item
> for doctree
::Static
<'_
> {
2061 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
2062 debug
!("cleaning static {}: {:?}", self.name
.clean(cx
), self);
2064 name
: Some(self.name
.clean(cx
)),
2065 attrs
: self.attrs
.clean(cx
),
2066 source
: self.whence
.clean(cx
),
2067 def_id
: cx
.tcx
.hir().local_def_id(self.id
).to_def_id(),
2068 visibility
: self.vis
.clean(cx
),
2069 stability
: cx
.stability(self.id
).clean(cx
),
2070 deprecation
: cx
.deprecation(self.id
).clean(cx
),
2071 inner
: StaticItem(Static
{
2072 type_
: self.type_
.clean(cx
),
2073 mutability
: self.mutability
,
2074 expr
: print_const_expr(cx
, self.expr
),
2080 impl Clean
<Item
> for doctree
::Constant
<'_
> {
2081 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
2082 let def_id
= cx
.tcx
.hir().local_def_id(self.id
);
2085 name
: Some(self.name
.clean(cx
)),
2086 attrs
: self.attrs
.clean(cx
),
2087 source
: self.whence
.clean(cx
),
2088 def_id
: def_id
.to_def_id(),
2089 visibility
: self.vis
.clean(cx
),
2090 stability
: cx
.stability(self.id
).clean(cx
),
2091 deprecation
: cx
.deprecation(self.id
).clean(cx
),
2092 inner
: ConstantItem(Constant
{
2093 type_
: self.type_
.clean(cx
),
2094 expr
: print_const_expr(cx
, self.expr
),
2095 value
: print_evaluated_const(cx
, def_id
.to_def_id()),
2096 is_literal
: is_literal_expr(cx
, self.expr
.hir_id
),
2102 impl Clean
<ImplPolarity
> for ty
::ImplPolarity
{
2103 fn clean(&self, _
: &DocContext
<'_
>) -> ImplPolarity
{
2105 &ty
::ImplPolarity
::Positive
|
2106 // FIXME: do we want to do something else here?
2107 &ty
::ImplPolarity
::Reservation
=> ImplPolarity
::Positive
,
2108 &ty
::ImplPolarity
::Negative
=> ImplPolarity
::Negative
,
2113 impl Clean
<Vec
<Item
>> for doctree
::Impl
<'_
> {
2114 fn clean(&self, cx
: &DocContext
<'_
>) -> Vec
<Item
> {
2115 let mut ret
= Vec
::new();
2116 let trait_
= self.trait_
.clean(cx
);
2117 let items
= self.items
.iter().map(|ii
| ii
.clean(cx
)).collect
::<Vec
<_
>>();
2118 let def_id
= cx
.tcx
.hir().local_def_id(self.id
);
2120 // If this impl block is an implementation of the Deref trait, then we
2121 // need to try inlining the target's inherent impl blocks as well.
2122 if trait_
.def_id() == cx
.tcx
.lang_items().deref_trait() {
2123 build_deref_target_impls(cx
, &items
, &mut ret
);
2126 let provided
: FxHashSet
<String
> = trait_
2129 cx
.tcx
.provided_trait_methods(did
).map(|meth
| meth
.ident
.to_string()).collect()
2131 .unwrap_or_default();
2133 let for_
= self.for_
.clean(cx
);
2134 let type_alias
= for_
.def_id().and_then(|did
| match cx
.tcx
.def_kind(did
) {
2135 DefKind
::TyAlias
=> Some(cx
.tcx
.type_of(did
).clean(cx
)),
2138 let make_item
= |trait_
: Option
<Type
>, for_
: Type
, items
: Vec
<Item
>| Item
{
2140 attrs
: self.attrs
.clean(cx
),
2141 source
: self.whence
.clean(cx
),
2142 def_id
: def_id
.to_def_id(),
2143 visibility
: self.vis
.clean(cx
),
2144 stability
: cx
.stability(self.id
).clean(cx
),
2145 deprecation
: cx
.deprecation(self.id
).clean(cx
),
2146 inner
: ImplItem(Impl
{
2147 unsafety
: self.unsafety
,
2148 generics
: self.generics
.clean(cx
),
2149 provided_trait_methods
: provided
.clone(),
2153 polarity
: Some(cx
.tcx
.impl_polarity(def_id
).clean(cx
)),
2158 if let Some(type_alias
) = type_alias
{
2159 ret
.push(make_item(trait_
.clone(), type_alias
, items
.clone()));
2161 ret
.push(make_item(trait_
, for_
, items
));
2166 impl Clean
<Vec
<Item
>> for doctree
::ExternCrate
<'_
> {
2167 fn clean(&self, cx
: &DocContext
<'_
>) -> Vec
<Item
> {
2168 let please_inline
= self.vis
.node
.is_pub()
2169 && self.attrs
.iter().any(|a
| {
2170 a
.check_name(sym
::doc
)
2171 && match a
.meta_item_list() {
2172 Some(l
) => attr
::list_contains_name(&l
, sym
::inline
),
2178 let mut visited
= FxHashSet
::default();
2180 let res
= Res
::Def(DefKind
::Mod
, DefId { krate: self.cnum, index: CRATE_DEF_INDEX }
);
2182 if let Some(items
) =
2183 inline
::try_inline(cx
, res
, self.name
, Some(self.attrs
), &mut visited
)
2191 attrs
: self.attrs
.clean(cx
),
2192 source
: self.whence
.clean(cx
),
2193 def_id
: DefId { krate: self.cnum, index: CRATE_DEF_INDEX }
,
2194 visibility
: self.vis
.clean(cx
),
2197 inner
: ExternCrateItem(self.name
.clean(cx
), self.path
.clone()),
2202 impl Clean
<Vec
<Item
>> for doctree
::Import
<'_
> {
2203 fn clean(&self, cx
: &DocContext
<'_
>) -> Vec
<Item
> {
2204 // We consider inlining the documentation of `pub use` statements, but we
2205 // forcefully don't inline if this is not public or if the
2206 // #[doc(no_inline)] attribute is present.
2207 // Don't inline doc(hidden) imports so they can be stripped at a later stage.
2208 let mut denied
= !self.vis
.node
.is_pub()
2209 || self.attrs
.iter().any(|a
| {
2210 a
.check_name(sym
::doc
)
2211 && match a
.meta_item_list() {
2213 attr
::list_contains_name(&l
, sym
::no_inline
)
2214 || attr
::list_contains_name(&l
, sym
::hidden
)
2219 // Also check whether imports were asked to be inlined, in case we're trying to re-export a
2220 // crate in Rust 2018+
2221 let please_inline
= self.attrs
.lists(sym
::doc
).has_word(sym
::inline
);
2222 let path
= self.path
.clean(cx
);
2223 let inner
= if self.glob
{
2225 let mut visited
= FxHashSet
::default();
2226 if let Some(items
) = inline
::try_inline_glob(cx
, path
.res
, &mut visited
) {
2231 Import
::Glob(resolve_use_source(cx
, path
))
2233 let name
= self.name
;
2235 if let Res
::Def(DefKind
::Mod
, did
) = path
.res
{
2236 if !did
.is_local() && did
.index
== CRATE_DEF_INDEX
{
2237 // if we're `pub use`ing an extern crate root, don't inline it unless we
2238 // were specifically asked for it
2244 let mut visited
= FxHashSet
::default();
2245 if let Some(items
) =
2246 inline
::try_inline(cx
, path
.res
, name
, Some(self.attrs
), &mut visited
)
2251 Import
::Simple(name
.clean(cx
), resolve_use_source(cx
, path
))
2256 attrs
: self.attrs
.clean(cx
),
2257 source
: self.whence
.clean(cx
),
2258 def_id
: DefId
::local(CRATE_DEF_INDEX
),
2259 visibility
: self.vis
.clean(cx
),
2262 inner
: ImportItem(inner
),
2267 impl Clean
<Item
> for doctree
::ForeignItem
<'_
> {
2268 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
2269 let inner
= match self.kind
{
2270 hir
::ForeignItemKind
::Fn(ref decl
, ref names
, ref generics
) => {
2271 let abi
= cx
.tcx
.hir().get_foreign_abi(self.id
);
2272 let (generics
, decl
) =
2273 enter_impl_trait(cx
, || (generics
.clean(cx
), (&**decl
, &names
[..]).clean(cx
)));
2274 let (all_types
, ret_types
) = get_all_types(&generics
, &decl
, cx
);
2275 ForeignFunctionItem(Function
{
2278 header
: hir
::FnHeader
{
2279 unsafety
: hir
::Unsafety
::Unsafe
,
2281 constness
: hir
::Constness
::NotConst
,
2282 asyncness
: hir
::IsAsync
::NotAsync
,
2288 hir
::ForeignItemKind
::Static(ref ty
, mutbl
) => ForeignStaticItem(Static
{
2289 type_
: ty
.clean(cx
),
2291 expr
: String
::new(),
2293 hir
::ForeignItemKind
::Type
=> ForeignTypeItem
,
2297 name
: Some(self.name
.clean(cx
)),
2298 attrs
: self.attrs
.clean(cx
),
2299 source
: self.whence
.clean(cx
),
2300 def_id
: cx
.tcx
.hir().local_def_id(self.id
).to_def_id(),
2301 visibility
: self.vis
.clean(cx
),
2302 stability
: cx
.stability(self.id
).clean(cx
),
2303 deprecation
: cx
.deprecation(self.id
).clean(cx
),
2309 impl Clean
<Item
> for doctree
::Macro
<'_
> {
2310 fn clean(&self, cx
: &DocContext
<'_
>) -> Item
{
2311 let name
= self.name
.clean(cx
);
2313 name
: Some(name
.clone()),
2314 attrs
: self.attrs
.clean(cx
),
2315 source
: self.whence
.clean(cx
),
2317 stability
: cx
.stability(self.hid
).clean(cx
),
2318 deprecation
: cx
.deprecation(self.hid
).clean(cx
),
2319 def_id
: self.def_id
,
2320 inner
: MacroItem(Macro
{
2322 "macro_rules! {} {{\n{}}}",
2326 .map(|span
| { format!(" {}
=> {{ ... }
};\n", span.to_src(cx)) })
2327 .collect::<String>()
2329 imported_from: self.imported_from.clean(cx),
2335 impl Clean<Item> for doctree::ProcMacro<'_> {
2336 fn clean(&self, cx: &DocContext<'_>) -> Item {
2338 name: Some(self.name.clean(cx)),
2339 attrs: self.attrs.clean(cx),
2340 source: self.whence.clean(cx),
2342 stability: cx.stability(self.id).clean(cx),
2343 deprecation: cx.deprecation(self.id).clean(cx),
2344 def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
2345 inner: ProcMacroItem(ProcMacro { kind: self.kind, helpers: self.helpers.clean(cx) }),
2350 impl Clean<Stability> for attr::Stability {
2351 fn clean(&self, _: &DocContext<'_>) -> Stability {
2353 level: stability::StabilityLevel::from_attr_level(&self.level),
2354 feature: Some(self.feature.to_string()).filter(|f| !f.is_empty()),
2355 since: match self.level {
2356 attr::Stable { ref since } => since.to_string(),
2359 deprecation: self.rustc_depr.as_ref().map(|d| Deprecation {
2360 note: Some(d.reason.to_string()).filter(|r| !r.is_empty()),
2361 since: Some(d.since.to_string()).filter(|d| !d.is_empty()),
2363 unstable_reason: match self.level {
2364 attr::Unstable { reason: Some(ref reason), .. } => Some(reason.to_string()),
2367 issue: match self.level {
2368 attr::Unstable { issue, .. } => issue,
2375 impl Clean<Deprecation> for attr::Deprecation {
2376 fn clean(&self, _: &DocContext<'_>) -> Deprecation {
2378 since: self.since.map(|s| s.to_string()).filter(|s| !s.is_empty()),
2379 note: self.note.map(|n| n.to_string()).filter(|n| !n.is_empty()),
2384 impl Clean<TypeBinding> for hir::TypeBinding<'_> {
2385 fn clean(&self, cx: &DocContext<'_>) -> TypeBinding {
2386 TypeBinding { name: self.ident.name.clean(cx), kind: self.kind.clean(cx) }
2390 impl Clean<TypeBindingKind> for hir::TypeBindingKind<'_> {
2391 fn clean(&self, cx: &DocContext<'_>) -> TypeBindingKind {
2393 hir::TypeBindingKind::Equality { ref ty } => {
2394 TypeBindingKind::Equality { ty: ty.clean(cx) }
2396 hir::TypeBindingKind::Constraint { ref bounds } => {
2397 TypeBindingKind::Constraint { bounds: bounds.iter().map(|b| b.clean(cx)).collect() }
2404 TraitBound(Vec<PathSegment>, Vec<SimpleBound>, Vec<GenericParamDef>, hir::TraitBoundModifier),
2408 impl From<GenericBound> for SimpleBound {
2409 fn from(bound: GenericBound) -> Self {
2410 match bound.clone() {
2411 GenericBound::Outlives(l) => SimpleBound::Outlives(l),
2412 GenericBound::TraitBound(t, mod_) => match t.trait_ {
2413 Type::ResolvedPath { path, param_names, .. } => SimpleBound::TraitBound(
2415 param_names.map_or_else(Vec::new, |v| {
2416 v.iter().map(|p| SimpleBound::from(p.clone())).collect()
2421 _ => panic!("Unexpected bound {:?}
", bound),