1 // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! This module contains the "cleaned" pieces of the AST, and the functions
14 pub use self::Type
::*;
15 pub use self::PrimitiveType
::*;
16 pub use self::TypeKind
::*;
17 pub use self::StructField
::*;
18 pub use self::VariantKind
::*;
19 pub use self::Mutability
::*;
20 pub use self::Import
::*;
21 pub use self::ItemEnum
::*;
22 pub use self::Attribute
::*;
23 pub use self::TyParamBound
::*;
24 pub use self::SelfTy
::*;
25 pub use self::FunctionRetTy
::*;
31 use syntax
::codemap
::{DUMMY_SP, Pos, Spanned}
;
32 use syntax
::parse
::token
::{self, InternedString, special_idents}
;
35 use rustc_trans
::back
::link
;
36 use rustc
::metadata
::cstore
;
37 use rustc
::metadata
::csearch
;
38 use rustc
::metadata
::decoder
;
39 use rustc
::middle
::def
;
40 use rustc
::middle
::def_id
::{DefId, LOCAL_CRATE}
;
41 use rustc
::middle
::subst
::{self, ParamSpace, VecPerParamSpace}
;
42 use rustc
::middle
::ty
;
43 use rustc
::middle
::stability
;
46 use rustc_front
::attr
;
47 use rustc_front
::attr
::{AttributeMethods, AttrMetaMethods}
;
48 use rustc_front
::lowering
::unlower_attribute
;
50 use std
::collections
::HashMap
;
51 use std
::path
::PathBuf
;
59 /// A stable identifier to the particular version of JSON output.
60 /// Increment this when the `Crate` and related structures change.
61 pub const SCHEMA_VERSION
: &'
static str = "0.8.3";
66 // extract the stability index for a node from tcx, if possible
67 fn get_stability(cx
: &DocContext
, def_id
: DefId
) -> Option
<Stability
> {
68 cx
.tcx_opt().and_then(|tcx
| stability
::lookup(tcx
, def_id
)).clean(cx
)
72 fn clean(&self, cx
: &DocContext
) -> T
;
75 impl<T
: Clean
<U
>, U
> Clean
<Vec
<U
>> for [T
] {
76 fn clean(&self, cx
: &DocContext
) -> Vec
<U
> {
77 self.iter().map(|x
| x
.clean(cx
)).collect()
81 impl<T
: Clean
<U
>, U
> Clean
<VecPerParamSpace
<U
>> for VecPerParamSpace
<T
> {
82 fn clean(&self, cx
: &DocContext
) -> VecPerParamSpace
<U
> {
83 self.map(|x
| x
.clean(cx
))
87 impl<T
: Clean
<U
>, U
> Clean
<U
> for P
<T
> {
88 fn clean(&self, cx
: &DocContext
) -> U
{
93 impl<T
: Clean
<U
>, U
> Clean
<U
> for Rc
<T
> {
94 fn clean(&self, cx
: &DocContext
) -> U
{
99 impl<T
: Clean
<U
>, U
> Clean
<Option
<U
>> for Option
<T
> {
100 fn clean(&self, cx
: &DocContext
) -> Option
<U
> {
103 &Some(ref v
) => Some(v
.clean(cx
))
108 impl<T
, U
> Clean
<U
> for ty
::Binder
<T
> where T
: Clean
<U
> {
109 fn clean(&self, cx
: &DocContext
) -> U
{
114 impl<T
: Clean
<U
>, U
> Clean
<Vec
<U
>> for syntax
::owned_slice
::OwnedSlice
<T
> {
115 fn clean(&self, cx
: &DocContext
) -> Vec
<U
> {
116 self.iter().map(|x
| x
.clean(cx
)).collect()
120 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
124 pub module
: Option
<Item
>,
125 pub externs
: Vec
<(ast
::CrateNum
, ExternalCrate
)>,
126 pub primitives
: Vec
<PrimitiveType
>,
127 pub external_traits
: HashMap
<DefId
, Trait
>,
130 impl<'a
, 'tcx
> Clean
<Crate
> for visit_ast
::RustdocVisitor
<'a
, 'tcx
> {
131 fn clean(&self, cx
: &DocContext
) -> Crate
{
132 use rustc
::session
::config
::Input
;
134 if let Some(t
) = cx
.tcx_opt() {
135 cx
.deref_trait_did
.set(t
.lang_items
.deref_trait());
138 let mut externs
= Vec
::new();
139 cx
.sess().cstore
.iter_crate_data(|n
, meta
| {
140 externs
.push((n
, meta
.clean(cx
)));
142 externs
.sort_by(|&(a
, _
), &(b
, _
)| a
.cmp(&b
));
144 // Figure out the name of this crate
145 let input
= &cx
.input
;
146 let attrs
: Vec
<_
> = self.attrs
.iter().map(|a
| unlower_attribute(a
)).collect();
147 let name
= link
::find_crate_name(None
, &attrs
, input
);
149 // Clean the crate, translating the entire libsyntax AST to one that is
150 // understood by rustdoc.
151 let mut module
= self.module
.clean(cx
);
153 // Collect all inner modules which are tagged as implementations of
156 // Note that this loop only searches the top-level items of the crate,
157 // and this is intentional. If we were to search the entire crate for an
158 // item tagged with `#[doc(primitive)]` then we we would also have to
159 // search the entirety of external modules for items tagged
160 // `#[doc(primitive)]`, which is a pretty inefficient process (decoding
161 // all that metadata unconditionally).
163 // In order to keep the metadata load under control, the
164 // `#[doc(primitive)]` feature is explicitly designed to only allow the
165 // primitive tags to show up as the top level items in a crate.
167 // Also note that this does not attempt to deal with modules tagged
168 // duplicately for the same primitive. This is handled later on when
169 // rendering by delegating everything to a hash map.
170 let mut primitives
= Vec
::new();
172 let m
= match module
.inner
{
173 ModuleItem(ref mut m
) => m
,
176 let mut tmp
= Vec
::new();
177 for child
in &mut m
.items
{
182 let prim
= match PrimitiveType
::find(&child
.attrs
) {
186 primitives
.push(prim
);
188 source
: Span
::empty(),
189 name
: Some(prim
.to_url_str().to_string()),
190 attrs
: child
.attrs
.clone(),
191 visibility
: Some(hir
::Public
),
193 def_id
: DefId
::local(prim
.to_node_id()),
194 inner
: PrimitiveItem(prim
),
200 let src
= match cx
.input
{
201 Input
::File(ref path
) => path
.clone(),
202 Input
::Str(_
) => PathBuf
::new() // FIXME: this is wrong
206 name
: name
.to_string(),
208 module
: Some(module
),
210 primitives
: primitives
,
211 external_traits
: cx
.external_traits
.borrow_mut().take()
212 .unwrap_or(HashMap
::new()),
217 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
218 pub struct ExternalCrate
{
220 pub attrs
: Vec
<Attribute
>,
221 pub primitives
: Vec
<PrimitiveType
>,
224 impl Clean
<ExternalCrate
> for cstore
::crate_metadata
{
225 fn clean(&self, cx
: &DocContext
) -> ExternalCrate
{
226 let mut primitives
= Vec
::new();
227 cx
.tcx_opt().map(|tcx
| {
228 csearch
::each_top_level_item_of_crate(&tcx
.sess
.cstore
,
231 let did
= match def
{
232 decoder
::DlDef(def
::DefMod(did
)) => did
,
235 let attrs
= inline
::load_attrs(cx
, tcx
, did
);
236 PrimitiveType
::find(&attrs
).map(|prim
| primitives
.push(prim
));
240 name
: self.name
.to_string(),
241 attrs
: decoder
::get_crate_attributes(self.data()).clean(cx
),
242 primitives
: primitives
,
247 /// Anything with a source location and set of attributes and, optionally, a
248 /// name. That is, anything that can be documented. This doesn't correspond
249 /// directly to the AST's concept of an item; it's a strict superset.
250 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
254 /// Not everything has a name. E.g., impls
255 pub name
: Option
<String
>,
256 pub attrs
: Vec
<Attribute
> ,
258 pub visibility
: Option
<Visibility
>,
260 pub stability
: Option
<Stability
>,
264 /// Finds the `doc` attribute as a List and returns the list of attributes
266 pub fn doc_list
<'a
>(&'a
self) -> Option
<&'a
[Attribute
]> {
267 for attr
in &self.attrs
{
269 List(ref x
, ref list
) if "doc" == *x
=> {
278 /// Finds the `doc` attribute as a NameValue and returns the corresponding
280 pub fn doc_value
<'a
>(&'a
self) -> Option
<&'a
str> {
281 for attr
in &self.attrs
{
283 NameValue(ref x
, ref v
) if "doc" == *x
=> {
292 pub fn is_hidden_from_doc(&self) -> bool
{
293 match self.doc_list() {
297 Word(ref s
) if "hidden" == *s
=> {
309 pub fn is_mod(&self) -> bool
{
310 match self.inner { ModuleItem(..) => true, _ => false }
312 pub fn is_trait(&self) -> bool
{
313 match self.inner { TraitItem(..) => true, _ => false }
315 pub fn is_struct(&self) -> bool
{
316 match self.inner { StructItem(..) => true, _ => false }
318 pub fn is_enum(&self) -> bool
{
319 match self.inner { EnumItem(..) => true, _ => false }
321 pub fn is_fn(&self) -> bool
{
322 match self.inner { FunctionItem(..) => true, _ => false }
325 pub fn stability_class(&self) -> String
{
326 match self.stability
{
328 let mut base
= match s
.level
{
329 attr
::Unstable
=> "unstable".to_string(),
330 attr
::Stable
=> String
::new(),
332 if !s
.deprecated_since
.is_empty() {
333 base
.push_str(" deprecated");
342 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
344 ExternCrateItem(String
, Option
<String
>),
348 FunctionItem(Function
),
350 TypedefItem(Typedef
, bool
/* is associated type */),
352 ConstantItem(Constant
),
355 /// A method signature only. Used for required methods in traits (ie,
356 /// non-default-methods).
357 TyMethodItem(TyMethod
),
358 /// A method with a body.
360 StructFieldItem(StructField
),
361 VariantItem(Variant
),
362 /// `fn`s from an extern block
363 ForeignFunctionItem(Function
),
364 /// `static`s from an extern block
365 ForeignStaticItem(Static
),
367 PrimitiveItem(PrimitiveType
),
368 AssociatedConstItem(Type
, Option
<String
>),
369 AssociatedTypeItem(Vec
<TyParamBound
>, Option
<Type
>),
370 DefaultImplItem(DefaultImpl
),
373 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
375 pub items
: Vec
<Item
>,
379 impl Clean
<Item
> for doctree
::Module
{
380 fn clean(&self, cx
: &DocContext
) -> Item
{
381 let name
= if self.name
.is_some() {
382 self.name
.unwrap().clean(cx
)
387 let mut items
: Vec
<Item
> = vec
![];
388 items
.extend(self.extern_crates
.iter().map(|x
| x
.clean(cx
)));
389 items
.extend(self.imports
.iter().flat_map(|x
| x
.clean(cx
)));
390 items
.extend(self.structs
.iter().map(|x
| x
.clean(cx
)));
391 items
.extend(self.enums
.iter().map(|x
| x
.clean(cx
)));
392 items
.extend(self.fns
.iter().map(|x
| x
.clean(cx
)));
393 items
.extend(self.foreigns
.iter().flat_map(|x
| x
.clean(cx
)));
394 items
.extend(self.mods
.iter().map(|x
| x
.clean(cx
)));
395 items
.extend(self.typedefs
.iter().map(|x
| x
.clean(cx
)));
396 items
.extend(self.statics
.iter().map(|x
| x
.clean(cx
)));
397 items
.extend(self.constants
.iter().map(|x
| x
.clean(cx
)));
398 items
.extend(self.traits
.iter().map(|x
| x
.clean(cx
)));
399 items
.extend(self.impls
.iter().flat_map(|x
| x
.clean(cx
)));
400 items
.extend(self.macros
.iter().map(|x
| x
.clean(cx
)));
401 items
.extend(self.def_traits
.iter().map(|x
| x
.clean(cx
)));
403 // determine if we should display the inner contents or
404 // the outer `mod` item for the source code.
406 let cm
= cx
.sess().codemap();
407 let outer
= cm
.lookup_char_pos(self.where_outer
.lo
);
408 let inner
= cm
.lookup_char_pos(self.where_inner
.lo
);
409 if outer
.file
.start_pos
== inner
.file
.start_pos
{
413 // mod foo; (and a separate FileMap for the contents)
420 attrs
: self.attrs
.clean(cx
),
421 source
: whence
.clean(cx
),
422 visibility
: self.vis
.clean(cx
),
423 stability
: self.stab
.clean(cx
),
424 def_id
: DefId
::local(self.id
),
425 inner
: ModuleItem(Module
{
426 is_crate
: self.is_crate
,
433 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
436 List(String
, Vec
<Attribute
> ),
437 NameValue(String
, String
)
440 impl Clean
<Attribute
> for hir
::MetaItem
{
441 fn clean(&self, cx
: &DocContext
) -> Attribute
{
443 hir
::MetaWord(ref s
) => Word(s
.to_string()),
444 hir
::MetaList(ref s
, ref l
) => {
445 List(s
.to_string(), l
.clean(cx
))
447 hir
::MetaNameValue(ref s
, ref v
) => {
448 NameValue(s
.to_string(), lit_to_string(v
))
454 impl Clean
<Attribute
> for hir
::Attribute
{
455 fn clean(&self, cx
: &DocContext
) -> Attribute
{
456 self.with_desugared_doc(|a
| a
.node
.value
.clean(cx
))
460 // This is a rough approximation that gets us what we want.
461 impl attr
::AttrMetaMethods
for Attribute
{
462 fn name(&self) -> InternedString
{
464 Word(ref n
) | List(ref n
, _
) | NameValue(ref n
, _
) => {
465 token
::intern_and_get_ident(n
)
470 fn value_str(&self) -> Option
<InternedString
> {
472 NameValue(_
, ref v
) => {
473 Some(token
::intern_and_get_ident(v
))
478 fn meta_item_list
<'a
>(&'a
self) -> Option
<&'a
[P
<hir
::MetaItem
>]> { None }
479 fn span(&self) -> codemap
::Span { unimplemented!() }
481 impl<'a
> attr
::AttrMetaMethods
for &'a Attribute
{
482 fn name(&self) -> InternedString { (**self).name() }
483 fn value_str(&self) -> Option
<InternedString
> { (**self).value_str() }
484 fn meta_item_list(&self) -> Option
<&[P
<hir
::MetaItem
>]> { None }
485 fn span(&self) -> codemap
::Span { unimplemented!() }
488 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
492 pub bounds
: Vec
<TyParamBound
>,
493 pub default: Option
<Type
>,
496 impl Clean
<TyParam
> for hir
::TyParam
{
497 fn clean(&self, cx
: &DocContext
) -> TyParam
{
499 name
: self.ident
.clean(cx
),
500 did
: DefId { krate: LOCAL_CRATE, node: self.id }
,
501 bounds
: self.bounds
.clean(cx
),
502 default: self.default.clean(cx
),
507 impl<'tcx
> Clean
<TyParam
> for ty
::TypeParameterDef
<'tcx
> {
508 fn clean(&self, cx
: &DocContext
) -> TyParam
{
509 cx
.external_typarams
.borrow_mut().as_mut().unwrap()
510 .insert(self.def_id
, self.name
.clean(cx
));
512 name
: self.name
.clean(cx
),
514 bounds
: vec
![], // these are filled in from the where-clauses
515 default: self.default.clean(cx
),
520 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
521 pub enum TyParamBound
{
522 RegionBound(Lifetime
),
523 TraitBound(PolyTrait
, hir
::TraitBoundModifier
)
527 fn maybe_sized(cx
: &DocContext
) -> TyParamBound
{
528 use rustc_front
::hir
::TraitBoundModifier
as TBM
;
529 let mut sized_bound
= ty
::BoundSized
.clean(cx
);
530 if let TyParamBound
::TraitBound(_
, ref mut tbm
) = sized_bound
{
536 fn is_sized_bound(&self, cx
: &DocContext
) -> bool
{
537 use rustc_front
::hir
::TraitBoundModifier
as TBM
;
538 if let Some(tcx
) = cx
.tcx_opt() {
539 let sized_did
= match tcx
.lang_items
.sized_trait() {
543 if let TyParamBound
::TraitBound(PolyTrait
{
544 trait_
: Type
::ResolvedPath { did, .. }
, ..
545 }, TBM
::None
) = *self {
546 if did
== sized_did
{
555 impl Clean
<TyParamBound
> for hir
::TyParamBound
{
556 fn clean(&self, cx
: &DocContext
) -> TyParamBound
{
558 hir
::RegionTyParamBound(lt
) => RegionBound(lt
.clean(cx
)),
559 hir
::TraitTyParamBound(ref t
, modifier
) => TraitBound(t
.clean(cx
), modifier
),
564 impl<'tcx
> Clean
<(Vec
<TyParamBound
>, Vec
<TypeBinding
>)> for ty
::ExistentialBounds
<'tcx
> {
565 fn clean(&self, cx
: &DocContext
) -> (Vec
<TyParamBound
>, Vec
<TypeBinding
>) {
566 let mut tp_bounds
= vec
![];
567 self.region_bound
.clean(cx
).map(|b
| tp_bounds
.push(RegionBound(b
)));
568 for bb
in &self.builtin_bounds
{
569 tp_bounds
.push(bb
.clean(cx
));
572 let mut bindings
= vec
![];
573 for &ty
::Binder(ref pb
) in &self.projection_bounds
{
574 bindings
.push(TypeBinding
{
575 name
: pb
.projection_ty
.item_name
.clean(cx
),
580 (tp_bounds
, bindings
)
584 fn external_path_params(cx
: &DocContext
, trait_did
: Option
<DefId
>,
585 bindings
: Vec
<TypeBinding
>, substs
: &subst
::Substs
) -> PathParameters
{
586 let lifetimes
= substs
.regions().get_slice(subst
::TypeSpace
)
588 .filter_map(|v
| v
.clean(cx
))
590 let types
= substs
.types
.get_slice(subst
::TypeSpace
).to_vec();
592 match (trait_did
, cx
.tcx_opt()) {
593 // Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
594 (Some(did
), Some(ref tcx
)) if tcx
.lang_items
.fn_trait_kind(did
).is_some() => {
595 assert_eq
!(types
.len(), 1);
596 let inputs
= match types
[0].sty
{
597 ty
::TyTuple(ref tys
) => tys
.iter().map(|t
| t
.clean(cx
)).collect(),
599 return PathParameters
::AngleBracketed
{
600 lifetimes
: lifetimes
,
601 types
: types
.clean(cx
),
607 // FIXME(#20299) return type comes from a projection now
608 // match types[1].sty {
609 // ty::TyTuple(ref v) if v.is_empty() => None, // -> ()
610 // _ => Some(types[1].clean(cx))
612 PathParameters
::Parenthesized
{
618 PathParameters
::AngleBracketed
{
619 lifetimes
: lifetimes
,
620 types
: types
.clean(cx
),
627 // trait_did should be set to a trait's DefId if called on a TraitRef, in order to sugar
628 // from Fn<(A, B,), C> to Fn(A, B) -> C
629 fn external_path(cx
: &DocContext
, name
: &str, trait_did
: Option
<DefId
>,
630 bindings
: Vec
<TypeBinding
>, substs
: &subst
::Substs
) -> Path
{
633 segments
: vec
![PathSegment
{
634 name
: name
.to_string(),
635 params
: external_path_params(cx
, trait_did
, bindings
, substs
)
640 impl Clean
<TyParamBound
> for ty
::BuiltinBound
{
641 fn clean(&self, cx
: &DocContext
) -> TyParamBound
{
642 let tcx
= match cx
.tcx_opt() {
644 None
=> return RegionBound(Lifetime
::statik())
646 let empty
= subst
::Substs
::empty();
647 let (did
, path
) = match *self {
649 (tcx
.lang_items
.send_trait().unwrap(),
650 external_path(cx
, "Send", None
, vec
![], &empty
)),
652 (tcx
.lang_items
.sized_trait().unwrap(),
653 external_path(cx
, "Sized", None
, vec
![], &empty
)),
655 (tcx
.lang_items
.copy_trait().unwrap(),
656 external_path(cx
, "Copy", None
, vec
![], &empty
)),
658 (tcx
.lang_items
.sync_trait().unwrap(),
659 external_path(cx
, "Sync", None
, vec
![], &empty
)),
661 let fqn
= csearch
::get_item_path(tcx
, did
);
662 let fqn
= fqn
.into_iter().map(|i
| i
.to_string()).collect();
663 cx
.external_paths
.borrow_mut().as_mut().unwrap().insert(did
,
665 TraitBound(PolyTrait
{
666 trait_
: ResolvedPath
{
673 }, hir
::TraitBoundModifier
::None
)
677 impl<'tcx
> Clean
<TyParamBound
> for ty
::TraitRef
<'tcx
> {
678 fn clean(&self, cx
: &DocContext
) -> TyParamBound
{
679 let tcx
= match cx
.tcx_opt() {
681 None
=> return RegionBound(Lifetime
::statik())
683 let fqn
= csearch
::get_item_path(tcx
, self.def_id
);
684 let fqn
= fqn
.into_iter().map(|i
| i
.to_string())
685 .collect
::<Vec
<String
>>();
686 let path
= external_path(cx
, fqn
.last().unwrap(),
687 Some(self.def_id
), vec
![], self.substs
);
688 cx
.external_paths
.borrow_mut().as_mut().unwrap().insert(self.def_id
,
691 debug
!("ty::TraitRef\n substs.types(TypeSpace): {:?}\n",
692 self.substs
.types
.get_slice(ParamSpace
::TypeSpace
));
694 // collect any late bound regions
695 let mut late_bounds
= vec
![];
696 for &ty_s
in self.substs
.types
.get_slice(ParamSpace
::TypeSpace
) {
697 if let ty
::TyTuple(ref ts
) = ty_s
.sty
{
699 if let ty
::TyRef(ref reg
, _
) = ty_s
.sty
{
700 if let &ty
::Region
::ReLateBound(_
, _
) = *reg
{
701 debug
!(" hit an ReLateBound {:?}", reg
);
702 if let Some(lt
) = reg
.clean(cx
) {
711 TraitBound(PolyTrait
{
712 trait_
: ResolvedPath
{
718 lifetimes
: late_bounds
719 }, hir
::TraitBoundModifier
::None
)
723 impl<'tcx
> Clean
<Option
<Vec
<TyParamBound
>>> for subst
::Substs
<'tcx
> {
724 fn clean(&self, cx
: &DocContext
) -> Option
<Vec
<TyParamBound
>> {
725 let mut v
= Vec
::new();
726 v
.extend(self.regions().iter().filter_map(|r
| r
.clean(cx
)).map(RegionBound
));
727 v
.extend(self.types
.iter().map(|t
| TraitBound(PolyTrait
{
730 }, hir
::TraitBoundModifier
::None
)));
731 if !v
.is_empty() {Some(v)}
else {None}
735 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
736 pub struct Lifetime(String
);
739 pub fn get_ref
<'a
>(&'a
self) -> &'a
str {
740 let Lifetime(ref s
) = *self;
745 pub fn statik() -> Lifetime
{
746 Lifetime("'static".to_string())
750 impl Clean
<Lifetime
> for hir
::Lifetime
{
751 fn clean(&self, _
: &DocContext
) -> Lifetime
{
752 Lifetime(self.name
.to_string())
756 impl Clean
<Lifetime
> for hir
::LifetimeDef
{
757 fn clean(&self, _
: &DocContext
) -> Lifetime
{
758 Lifetime(self.lifetime
.name
.to_string())
762 impl Clean
<Lifetime
> for ty
::RegionParameterDef
{
763 fn clean(&self, _
: &DocContext
) -> Lifetime
{
764 Lifetime(self.name
.to_string())
768 impl Clean
<Option
<Lifetime
>> for ty
::Region
{
769 fn clean(&self, cx
: &DocContext
) -> Option
<Lifetime
> {
771 ty
::ReStatic
=> Some(Lifetime
::statik()),
772 ty
::ReLateBound(_
, ty
::BrNamed(_
, name
)) =>
773 Some(Lifetime(name
.to_string())),
774 ty
::ReEarlyBound(ref data
) => Some(Lifetime(data
.name
.clean(cx
))),
776 ty
::ReLateBound(..) |
780 ty
::ReSkolemized(..) |
781 ty
::ReEmpty(..) => None
786 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
787 pub enum WherePredicate
{
788 BoundPredicate { ty: Type, bounds: Vec<TyParamBound> }
,
789 RegionPredicate { lifetime: Lifetime, bounds: Vec<Lifetime>}
,
790 EqPredicate { lhs: Type, rhs: Type }
793 impl Clean
<WherePredicate
> for hir
::WherePredicate
{
794 fn clean(&self, cx
: &DocContext
) -> WherePredicate
{
796 hir
::WherePredicate
::BoundPredicate(ref wbp
) => {
797 WherePredicate
::BoundPredicate
{
798 ty
: wbp
.bounded_ty
.clean(cx
),
799 bounds
: wbp
.bounds
.clean(cx
)
803 hir
::WherePredicate
::RegionPredicate(ref wrp
) => {
804 WherePredicate
::RegionPredicate
{
805 lifetime
: wrp
.lifetime
.clean(cx
),
806 bounds
: wrp
.bounds
.clean(cx
)
810 hir
::WherePredicate
::EqPredicate(_
) => {
811 unimplemented
!() // FIXME(#20041)
817 impl<'a
> Clean
<WherePredicate
> for ty
::Predicate
<'a
> {
818 fn clean(&self, cx
: &DocContext
) -> WherePredicate
{
819 use rustc
::middle
::ty
::Predicate
;
822 Predicate
::Trait(ref pred
) => pred
.clean(cx
),
823 Predicate
::Equate(ref pred
) => pred
.clean(cx
),
824 Predicate
::RegionOutlives(ref pred
) => pred
.clean(cx
),
825 Predicate
::TypeOutlives(ref pred
) => pred
.clean(cx
),
826 Predicate
::Projection(ref pred
) => pred
.clean(cx
),
827 Predicate
::WellFormed(_
) => panic
!("not user writable"),
828 Predicate
::ObjectSafe(_
) => panic
!("not user writable"),
833 impl<'a
> Clean
<WherePredicate
> for ty
::TraitPredicate
<'a
> {
834 fn clean(&self, cx
: &DocContext
) -> WherePredicate
{
835 WherePredicate
::BoundPredicate
{
836 ty
: self.trait_ref
.substs
.self_ty().clean(cx
).unwrap(),
837 bounds
: vec
![self.trait_ref
.clean(cx
)]
842 impl<'tcx
> Clean
<WherePredicate
> for ty
::EquatePredicate
<'tcx
> {
843 fn clean(&self, cx
: &DocContext
) -> WherePredicate
{
844 let ty
::EquatePredicate(ref lhs
, ref rhs
) = *self;
845 WherePredicate
::EqPredicate
{
852 impl Clean
<WherePredicate
> for ty
::OutlivesPredicate
<ty
::Region
, ty
::Region
> {
853 fn clean(&self, cx
: &DocContext
) -> WherePredicate
{
854 let ty
::OutlivesPredicate(ref a
, ref b
) = *self;
855 WherePredicate
::RegionPredicate
{
856 lifetime
: a
.clean(cx
).unwrap(),
857 bounds
: vec
![b
.clean(cx
).unwrap()]
862 impl<'tcx
> Clean
<WherePredicate
> for ty
::OutlivesPredicate
<ty
::Ty
<'tcx
>, ty
::Region
> {
863 fn clean(&self, cx
: &DocContext
) -> WherePredicate
{
864 let ty
::OutlivesPredicate(ref ty
, ref lt
) = *self;
866 WherePredicate
::BoundPredicate
{
868 bounds
: vec
![TyParamBound
::RegionBound(lt
.clean(cx
).unwrap())]
873 impl<'tcx
> Clean
<WherePredicate
> for ty
::ProjectionPredicate
<'tcx
> {
874 fn clean(&self, cx
: &DocContext
) -> WherePredicate
{
875 WherePredicate
::EqPredicate
{
876 lhs
: self.projection_ty
.clean(cx
),
877 rhs
: self.ty
.clean(cx
)
882 impl<'tcx
> Clean
<Type
> for ty
::ProjectionTy
<'tcx
> {
883 fn clean(&self, cx
: &DocContext
) -> Type
{
884 let trait_
= match self.trait_ref
.clean(cx
) {
885 TyParamBound
::TraitBound(t
, _
) => t
.trait_
,
886 TyParamBound
::RegionBound(_
) => {
887 panic
!("cleaning a trait got a region")
891 name
: self.item_name
.clean(cx
),
892 self_type
: box self.trait_ref
.self_ty().clean(cx
),
898 // maybe use a Generic enum and use Vec<Generic>?
899 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
900 pub struct Generics
{
901 pub lifetimes
: Vec
<Lifetime
>,
902 pub type_params
: Vec
<TyParam
>,
903 pub where_predicates
: Vec
<WherePredicate
>
906 impl Clean
<Generics
> for hir
::Generics
{
907 fn clean(&self, cx
: &DocContext
) -> Generics
{
909 lifetimes
: self.lifetimes
.clean(cx
),
910 type_params
: self.ty_params
.clean(cx
),
911 where_predicates
: self.where_clause
.predicates
.clean(cx
)
916 impl<'a
, 'tcx
> Clean
<Generics
> for (&'a ty
::Generics
<'tcx
>,
917 &'a ty
::GenericPredicates
<'tcx
>,
919 fn clean(&self, cx
: &DocContext
) -> Generics
{
920 use std
::collections
::HashSet
;
921 use self::WherePredicate
as WP
;
923 let (gens
, preds
, space
) = *self;
925 // Bounds in the type_params and lifetimes fields are repeated in the
926 // predicates field (see rustc_typeck::collect::ty_generics), so remove
928 let stripped_typarams
= gens
.types
.get_slice(space
).iter().map(|tp
| {
930 }).collect
::<Vec
<_
>>();
931 let stripped_lifetimes
= gens
.regions
.get_slice(space
).iter().map(|rp
| {
932 let mut srp
= rp
.clone();
933 srp
.bounds
= Vec
::new();
935 }).collect
::<Vec
<_
>>();
937 let mut where_predicates
= preds
.predicates
.get_slice(space
)
940 // Type parameters and have a Sized bound by default unless removed with
941 // ?Sized. Scan through the predicates and mark any type parameter with
942 // a Sized bound, removing the bounds as we find them.
944 // Note that associated types also have a sized bound by default, but we
945 // don't actually know the set of associated types right here so that's
946 // handled in cleaning associated types
947 let mut sized_params
= HashSet
::new();
948 where_predicates
.retain(|pred
| {
950 WP
::BoundPredicate { ty: Generic(ref g), ref bounds }
=> {
951 if bounds
.iter().any(|b
| b
.is_sized_bound(cx
)) {
952 sized_params
.insert(g
.clone());
962 // Run through the type parameters again and insert a ?Sized
963 // unbound for any we didn't find to be Sized.
964 for tp
in &stripped_typarams
{
965 if !sized_params
.contains(&tp
.name
) {
966 where_predicates
.push(WP
::BoundPredicate
{
967 ty
: Type
::Generic(tp
.name
.clone()),
968 bounds
: vec
![TyParamBound
::maybe_sized(cx
)],
973 // It would be nice to collect all of the bounds on a type and recombine
974 // them if possible, to avoid e.g. `where T: Foo, T: Bar, T: Sized, T: 'a`
975 // and instead see `where T: Foo + Bar + Sized + 'a`
978 type_params
: simplify
::ty_params(stripped_typarams
),
979 lifetimes
: stripped_lifetimes
,
980 where_predicates
: simplify
::where_clauses(cx
, where_predicates
),
985 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
987 pub generics
: Generics
,
989 pub unsafety
: hir
::Unsafety
,
990 pub constness
: hir
::Constness
,
995 impl Clean
<Method
> for hir
::MethodSig
{
996 fn clean(&self, cx
: &DocContext
) -> Method
{
997 let all_inputs
= &self.decl
.inputs
;
998 let inputs
= match self.explicit_self
.node
{
999 hir
::SelfStatic
=> &**all_inputs
,
1000 _
=> &all_inputs
[1..]
1004 values
: inputs
.clean(cx
),
1006 output
: self.decl
.output
.clean(cx
),
1011 generics
: self.generics
.clean(cx
),
1012 self_
: self.explicit_self
.node
.clean(cx
),
1013 unsafety
: self.unsafety
,
1014 constness
: self.constness
,
1021 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1022 pub struct TyMethod
{
1023 pub unsafety
: hir
::Unsafety
,
1025 pub generics
: Generics
,
1030 impl Clean
<TyMethod
> for hir
::MethodSig
{
1031 fn clean(&self, cx
: &DocContext
) -> TyMethod
{
1032 let inputs
= match self.explicit_self
.node
{
1033 hir
::SelfStatic
=> &*self.decl
.inputs
,
1034 _
=> &self.decl
.inputs
[1..]
1038 values
: inputs
.clean(cx
),
1040 output
: self.decl
.output
.clean(cx
),
1045 unsafety
: self.unsafety
.clone(),
1047 self_
: self.explicit_self
.node
.clean(cx
),
1048 generics
: self.generics
.clean(cx
),
1054 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
1058 SelfBorrowed(Option
<Lifetime
>, Mutability
),
1062 impl Clean
<SelfTy
> for hir
::ExplicitSelf_
{
1063 fn clean(&self, cx
: &DocContext
) -> SelfTy
{
1065 hir
::SelfStatic
=> SelfStatic
,
1066 hir
::SelfValue(_
) => SelfValue
,
1067 hir
::SelfRegion(ref lt
, ref mt
, _
) => {
1068 SelfBorrowed(lt
.clean(cx
), mt
.clean(cx
))
1070 hir
::SelfExplicit(ref typ
, _
) => SelfExplicit(typ
.clean(cx
)),
1075 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1076 pub struct Function
{
1078 pub generics
: Generics
,
1079 pub unsafety
: hir
::Unsafety
,
1080 pub constness
: hir
::Constness
,
1084 impl Clean
<Item
> for doctree
::Function
{
1085 fn clean(&self, cx
: &DocContext
) -> Item
{
1087 name
: Some(self.name
.clean(cx
)),
1088 attrs
: self.attrs
.clean(cx
),
1089 source
: self.whence
.clean(cx
),
1090 visibility
: self.vis
.clean(cx
),
1091 stability
: self.stab
.clean(cx
),
1092 def_id
: DefId
::local(self.id
),
1093 inner
: FunctionItem(Function
{
1094 decl
: self.decl
.clean(cx
),
1095 generics
: self.generics
.clean(cx
),
1096 unsafety
: self.unsafety
,
1097 constness
: self.constness
,
1104 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
1106 pub inputs
: Arguments
,
1107 pub output
: FunctionRetTy
,
1109 pub attrs
: Vec
<Attribute
>,
1112 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
1113 pub struct Arguments
{
1114 pub values
: Vec
<Argument
>,
1117 impl Clean
<FnDecl
> for hir
::FnDecl
{
1118 fn clean(&self, cx
: &DocContext
) -> FnDecl
{
1121 values
: self.inputs
.clean(cx
),
1123 output
: self.output
.clean(cx
),
1124 variadic
: self.variadic
,
1130 impl<'tcx
> Clean
<Type
> for ty
::FnOutput
<'tcx
> {
1131 fn clean(&self, cx
: &DocContext
) -> Type
{
1133 ty
::FnConverging(ty
) => ty
.clean(cx
),
1134 ty
::FnDiverging
=> Bottom
1139 impl<'a
, 'tcx
> Clean
<FnDecl
> for (DefId
, &'a ty
::PolyFnSig
<'tcx
>) {
1140 fn clean(&self, cx
: &DocContext
) -> FnDecl
{
1141 let (did
, sig
) = *self;
1142 let mut names
= if did
.node
!= 0 {
1143 csearch
::get_method_arg_names(&cx
.tcx().sess
.cstore
, did
).into_iter()
1145 Vec
::new().into_iter()
1147 if names
.peek().map(|s
| &**s
) == Some("self") {
1148 let _
= names
.next();
1151 output
: Return(sig
.0.output
.clean(cx
)),
1153 variadic
: sig
.0.variadic
,
1155 values
: sig
.0.inputs
.iter().map(|t
| {
1159 name
: names
.next().unwrap_or("".to_string()),
1167 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
1168 pub struct Argument
{
1171 pub id
: ast
::NodeId
,
1174 impl Clean
<Argument
> for hir
::Arg
{
1175 fn clean(&self, cx
: &DocContext
) -> Argument
{
1177 name
: name_from_pat(&*self.pat
),
1178 type_
: (self.ty
.clean(cx
)),
1184 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
1185 pub enum FunctionRetTy
{
1191 impl Clean
<FunctionRetTy
> for hir
::FunctionRetTy
{
1192 fn clean(&self, cx
: &DocContext
) -> FunctionRetTy
{
1194 hir
::Return(ref typ
) => Return(typ
.clean(cx
)),
1195 hir
::DefaultReturn(..) => DefaultReturn
,
1196 hir
::NoReturn(..) => NoReturn
1201 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1203 pub unsafety
: hir
::Unsafety
,
1204 pub items
: Vec
<Item
>,
1205 pub generics
: Generics
,
1206 pub bounds
: Vec
<TyParamBound
>,
1209 impl Clean
<Item
> for doctree
::Trait
{
1210 fn clean(&self, cx
: &DocContext
) -> Item
{
1212 name
: Some(self.name
.clean(cx
)),
1213 attrs
: self.attrs
.clean(cx
),
1214 source
: self.whence
.clean(cx
),
1215 def_id
: DefId
::local(self.id
),
1216 visibility
: self.vis
.clean(cx
),
1217 stability
: self.stab
.clean(cx
),
1218 inner
: TraitItem(Trait
{
1219 unsafety
: self.unsafety
,
1220 items
: self.items
.clean(cx
),
1221 generics
: self.generics
.clean(cx
),
1222 bounds
: self.bounds
.clean(cx
),
1228 impl Clean
<Type
> for hir
::TraitRef
{
1229 fn clean(&self, cx
: &DocContext
) -> Type
{
1230 resolve_type(cx
, self.path
.clean(cx
), self.ref_id
)
1234 impl Clean
<PolyTrait
> for hir
::PolyTraitRef
{
1235 fn clean(&self, cx
: &DocContext
) -> PolyTrait
{
1237 trait_
: self.trait_ref
.clean(cx
),
1238 lifetimes
: self.bound_lifetimes
.clean(cx
)
1243 impl Clean
<Item
> for hir
::TraitItem
{
1244 fn clean(&self, cx
: &DocContext
) -> Item
{
1245 let inner
= match self.node
{
1246 hir
::ConstTraitItem(ref ty
, ref default) => {
1247 AssociatedConstItem(ty
.clean(cx
),
1248 default.as_ref().map(|expr
|
1249 expr
.span
.to_src(cx
)))
1251 hir
::MethodTraitItem(ref sig
, Some(_
)) => {
1252 MethodItem(sig
.clean(cx
))
1254 hir
::MethodTraitItem(ref sig
, None
) => {
1255 TyMethodItem(sig
.clean(cx
))
1257 hir
::TypeTraitItem(ref bounds
, ref default) => {
1258 AssociatedTypeItem(bounds
.clean(cx
), default.clean(cx
))
1262 name
: Some(self.ident
.clean(cx
)),
1263 attrs
: self.attrs
.clean(cx
),
1264 source
: self.span
.clean(cx
),
1265 def_id
: DefId
::local(self.id
),
1267 stability
: get_stability(cx
, DefId
::local(self.id
)),
1273 impl Clean
<Item
> for hir
::ImplItem
{
1274 fn clean(&self, cx
: &DocContext
) -> Item
{
1275 let inner
= match self.node
{
1276 hir
::ConstImplItem(ref ty
, ref expr
) => {
1277 ConstantItem(Constant
{
1278 type_
: ty
.clean(cx
),
1279 expr
: expr
.span
.to_src(cx
),
1282 hir
::MethodImplItem(ref sig
, _
) => {
1283 MethodItem(sig
.clean(cx
))
1285 hir
::TypeImplItem(ref ty
) => TypedefItem(Typedef
{
1286 type_
: ty
.clean(cx
),
1287 generics
: Generics
{
1288 lifetimes
: Vec
::new(),
1289 type_params
: Vec
::new(),
1290 where_predicates
: Vec
::new()
1295 name
: Some(self.ident
.clean(cx
)),
1296 source
: self.span
.clean(cx
),
1297 attrs
: self.attrs
.clean(cx
),
1298 def_id
: DefId
::local(self.id
),
1299 visibility
: self.vis
.clean(cx
),
1300 stability
: get_stability(cx
, DefId
::local(self.id
)),
1306 impl<'tcx
> Clean
<Item
> for ty
::Method
<'tcx
> {
1307 fn clean(&self, cx
: &DocContext
) -> Item
{
1308 let (self_
, sig
) = match self.explicit_self
{
1309 ty
::StaticExplicitSelfCategory
=> (hir
::SelfStatic
.clean(cx
),
1310 self.fty
.sig
.clone()),
1312 let sig
= ty
::Binder(ty
::FnSig
{
1313 inputs
: self.fty
.sig
.0.inputs
[1..].to_vec(),
1314 ..self.fty
.sig
.0.clone()
1317 ty
::ByValueExplicitSelfCategory
=> SelfValue
,
1318 ty
::ByReferenceExplicitSelfCategory(..) => {
1319 match self.fty
.sig
.0.inputs
[0].sty
{
1320 ty
::TyRef(r
, mt
) => {
1321 SelfBorrowed(r
.clean(cx
), mt
.mutbl
.clean(cx
))
1323 _
=> unreachable
!(),
1326 ty
::ByBoxExplicitSelfCategory
=> {
1327 SelfExplicit(self.fty
.sig
.0.inputs
[0].clean(cx
))
1329 ty
::StaticExplicitSelfCategory
=> unreachable
!(),
1335 let generics
= (&self.generics
, &self.predicates
,
1336 subst
::FnSpace
).clean(cx
);
1337 let decl
= (self.def_id
, &sig
).clean(cx
);
1338 let provided
= match self.container
{
1339 ty
::ImplContainer(..) => false,
1340 ty
::TraitContainer(did
) => {
1341 cx
.tcx().provided_trait_methods(did
).iter().any(|m
| {
1342 m
.def_id
== self.def_id
1346 let inner
= if provided
{
1348 unsafety
: self.fty
.unsafety
,
1354 // trait methods canot (currently, at least) be const
1355 constness
: hir
::Constness
::NotConst
,
1358 TyMethodItem(TyMethod
{
1359 unsafety
: self.fty
.unsafety
,
1368 name
: Some(self.name
.clean(cx
)),
1369 visibility
: Some(hir
::Inherited
),
1370 stability
: get_stability(cx
, self.def_id
),
1371 def_id
: self.def_id
,
1372 attrs
: inline
::load_attrs(cx
, cx
.tcx(), self.def_id
),
1373 source
: Span
::empty(),
1379 impl<'tcx
> Clean
<Item
> for ty
::ImplOrTraitItem
<'tcx
> {
1380 fn clean(&self, cx
: &DocContext
) -> Item
{
1382 ty
::ConstTraitItem(ref cti
) => cti
.clean(cx
),
1383 ty
::MethodTraitItem(ref mti
) => mti
.clean(cx
),
1384 ty
::TypeTraitItem(ref tti
) => tti
.clean(cx
),
1389 /// A trait reference, which may have higher ranked lifetimes.
1390 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
1391 pub struct PolyTrait
{
1393 pub lifetimes
: Vec
<Lifetime
>
1396 /// A representation of a Type suitable for hyperlinking purposes. Ideally one can get the original
1397 /// type out of the AST/ty::ctxt given one of these, if more information is needed. Most importantly
1398 /// it does not preserve mutability or boxes.
1399 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
1401 /// structs/enums/traits (most that'd be an hir::TyPath)
1404 typarams
: Option
<Vec
<TyParamBound
>>,
1406 /// true if is a `T::Name` path for associated types
1409 /// For parameterized types, so the consumer of the JSON don't go
1410 /// looking for types which don't exist anywhere.
1412 /// Primitives are the fixed-size numeric types (plus int/usize/float), char,
1413 /// arrays, slices, and tuples.
1414 Primitive(PrimitiveType
),
1416 BareFunction(Box
<BareFunctionDecl
>),
1419 FixedVector(Box
<Type
>, String
),
1423 RawPointer(Mutability
, Box
<Type
>),
1425 lifetime
: Option
<Lifetime
>,
1426 mutability
: Mutability
,
1430 // <Type as Trait>::Name
1433 self_type
: Box
<Type
>,
1441 PolyTraitRef(Vec
<TyParamBound
>),
1444 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Copy, Debug)]
1445 pub enum PrimitiveType
{
1446 Isize
, I8
, I16
, I32
, I64
,
1447 Usize
, U8
, U16
, U32
, U64
,
1455 PrimitiveRawPointer
,
1458 #[derive(Clone, RustcEncodable, RustcDecodable, Copy, Debug)]
1472 pub fn primitive_type(&self) -> Option
<PrimitiveType
> {
1474 Primitive(p
) | BorrowedRef { type_: box Primitive(p), ..}
=> Some(p
),
1475 Vector(..) | BorrowedRef{ type_: box Vector(..), .. }
=> Some(Slice
),
1476 FixedVector(..) | BorrowedRef { type_: box FixedVector(..), .. }
=> {
1479 Tuple(..) => Some(PrimitiveTuple
),
1480 RawPointer(..) => Some(PrimitiveRawPointer
),
1486 impl PrimitiveType
{
1487 fn from_str(s
: &str) -> Option
<PrimitiveType
> {
1489 "isize" => Some(Isize
),
1494 "usize" => Some(Usize
),
1499 "bool" => Some(Bool
),
1500 "char" => Some(Char
),
1504 "array" => Some(Array
),
1505 "slice" => Some(Slice
),
1506 "tuple" => Some(PrimitiveTuple
),
1507 "pointer" => Some(PrimitiveRawPointer
),
1512 fn find(attrs
: &[Attribute
]) -> Option
<PrimitiveType
> {
1514 let list
= match *attr
{
1515 List(ref k
, ref l
) if *k
== "doc" => l
,
1518 for sub_attr
in list
{
1519 let value
= match *sub_attr
{
1520 NameValue(ref k
, ref v
)
1521 if *k
== "primitive" => v
,
1524 match PrimitiveType
::from_str(value
) {
1525 Some(p
) => return Some(p
),
1533 pub fn to_string(&self) -> &'
static str {
1552 PrimitiveTuple
=> "tuple",
1553 PrimitiveRawPointer
=> "pointer",
1557 pub fn to_url_str(&self) -> &'
static str {
1561 /// Creates a rustdoc-specific node id for primitive types.
1563 /// These node ids are generally never used by the AST itself.
1564 pub fn to_node_id(&self) -> ast
::NodeId
{
1565 u32::MAX
- 1 - (*self as u32)
1569 impl Clean
<Type
> for hir
::Ty
{
1570 fn clean(&self, cx
: &DocContext
) -> Type
{
1571 use rustc_front
::hir
::*;
1573 TyPtr(ref m
) => RawPointer(m
.mutbl
.clean(cx
), box m
.ty
.clean(cx
)),
1574 TyRptr(ref l
, ref m
) =>
1575 BorrowedRef
{lifetime
: l
.clean(cx
), mutability
: m
.mutbl
.clean(cx
),
1576 type_
: box m
.ty
.clean(cx
)},
1577 TyVec(ref ty
) => Vector(box ty
.clean(cx
)),
1578 TyFixedLengthVec(ref ty
, ref e
) => FixedVector(box ty
.clean(cx
),
1580 TyTup(ref tys
) => Tuple(tys
.clean(cx
)),
1581 TyPath(None
, ref p
) => {
1582 resolve_type(cx
, p
.clean(cx
), self.id
)
1584 TyPath(Some(ref qself
), ref p
) => {
1585 let mut trait_path
= p
.clone();
1586 trait_path
.segments
.pop();
1588 name
: p
.segments
.last().unwrap().identifier
.clean(cx
),
1589 self_type
: box qself
.ty
.clean(cx
),
1590 trait_
: box resolve_type(cx
, trait_path
.clean(cx
), self.id
)
1593 TyObjectSum(ref lhs
, ref bounds
) => {
1594 let lhs_ty
= lhs
.clean(cx
);
1596 ResolvedPath { path, typarams: None, did, is_generic }
=> {
1599 typarams
: Some(bounds
.clean(cx
)),
1601 is_generic
: is_generic
,
1605 lhs_ty
// shouldn't happen
1609 TyBareFn(ref barefn
) => BareFunction(box barefn
.clean(cx
)),
1610 TyParen(ref ty
) => ty
.clean(cx
),
1611 TyPolyTraitRef(ref bounds
) => {
1612 PolyTraitRef(bounds
.clean(cx
))
1618 panic
!("Unimplemented type {:?}", self.node
)
1624 impl<'tcx
> Clean
<Type
> for ty
::Ty
<'tcx
> {
1625 fn clean(&self, cx
: &DocContext
) -> Type
{
1627 ty
::TyBool
=> Primitive(Bool
),
1628 ty
::TyChar
=> Primitive(Char
),
1629 ty
::TyInt(hir
::TyIs
) => Primitive(Isize
),
1630 ty
::TyInt(hir
::TyI8
) => Primitive(I8
),
1631 ty
::TyInt(hir
::TyI16
) => Primitive(I16
),
1632 ty
::TyInt(hir
::TyI32
) => Primitive(I32
),
1633 ty
::TyInt(hir
::TyI64
) => Primitive(I64
),
1634 ty
::TyUint(hir
::TyUs
) => Primitive(Usize
),
1635 ty
::TyUint(hir
::TyU8
) => Primitive(U8
),
1636 ty
::TyUint(hir
::TyU16
) => Primitive(U16
),
1637 ty
::TyUint(hir
::TyU32
) => Primitive(U32
),
1638 ty
::TyUint(hir
::TyU64
) => Primitive(U64
),
1639 ty
::TyFloat(hir
::TyF32
) => Primitive(F32
),
1640 ty
::TyFloat(hir
::TyF64
) => Primitive(F64
),
1641 ty
::TyStr
=> Primitive(Str
),
1643 let box_did
= cx
.tcx_opt().and_then(|tcx
| {
1644 tcx
.lang_items
.owned_box()
1646 lang_struct(cx
, box_did
, t
, "Box", Unique
)
1648 ty
::TySlice(ty
) => Vector(box ty
.clean(cx
)),
1649 ty
::TyArray(ty
, i
) => FixedVector(box ty
.clean(cx
),
1651 ty
::TyRawPtr(mt
) => RawPointer(mt
.mutbl
.clean(cx
), box mt
.ty
.clean(cx
)),
1652 ty
::TyRef(r
, mt
) => BorrowedRef
{
1653 lifetime
: r
.clean(cx
),
1654 mutability
: mt
.mutbl
.clean(cx
),
1655 type_
: box mt
.ty
.clean(cx
),
1657 ty
::TyBareFn(_
, ref fty
) => BareFunction(box BareFunctionDecl
{
1658 unsafety
: fty
.unsafety
,
1659 generics
: Generics
{
1660 lifetimes
: Vec
::new(),
1661 type_params
: Vec
::new(),
1662 where_predicates
: Vec
::new()
1664 decl
: (DefId
::local(0), &fty
.sig
).clean(cx
),
1665 abi
: fty
.abi
.to_string(),
1667 ty
::TyStruct(def
, substs
) |
1668 ty
::TyEnum(def
, substs
) => {
1670 let fqn
= csearch
::get_item_path(cx
.tcx(), did
);
1671 let fqn
: Vec
<_
> = fqn
.into_iter().map(|i
| i
.to_string()).collect();
1672 let kind
= match self.sty
{
1673 ty
::TyStruct(..) => TypeStruct
,
1676 let path
= external_path(cx
, &fqn
.last().unwrap().to_string(),
1677 None
, vec
![], substs
);
1678 cx
.external_paths
.borrow_mut().as_mut().unwrap().insert(did
, (fqn
, kind
));
1686 ty
::TyTrait(box ty
::TraitTy { ref principal, ref bounds }
) => {
1687 let did
= principal
.def_id();
1688 let fqn
= csearch
::get_item_path(cx
.tcx(), did
);
1689 let fqn
: Vec
<_
> = fqn
.into_iter().map(|i
| i
.to_string()).collect();
1690 let (typarams
, bindings
) = bounds
.clean(cx
);
1691 let path
= external_path(cx
, &fqn
.last().unwrap().to_string(),
1692 Some(did
), bindings
, principal
.substs());
1693 cx
.external_paths
.borrow_mut().as_mut().unwrap().insert(did
, (fqn
, TypeTrait
));
1696 typarams
: Some(typarams
),
1701 ty
::TyTuple(ref t
) => Tuple(t
.clean(cx
)),
1703 ty
::TyProjection(ref data
) => data
.clean(cx
),
1705 ty
::TyParam(ref p
) => Generic(p
.name
.to_string()),
1707 ty
::TyClosure(..) => Tuple(vec
![]), // FIXME(pcwalton)
1709 ty
::TyInfer(..) => panic
!("TyInfer"),
1710 ty
::TyError
=> panic
!("TyError"),
1715 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1716 pub enum StructField
{
1717 HiddenStructField
, // inserted later by strip passes
1718 TypedStructField(Type
),
1721 impl Clean
<Item
> for hir
::StructField
{
1722 fn clean(&self, cx
: &DocContext
) -> Item
{
1723 let (name
, vis
) = match self.node
.kind
{
1724 hir
::NamedField(id
, vis
) => (Some(id
), vis
),
1725 hir
::UnnamedField(vis
) => (None
, vis
)
1728 name
: name
.clean(cx
),
1729 attrs
: self.node
.attrs
.clean(cx
),
1730 source
: self.span
.clean(cx
),
1731 visibility
: Some(vis
),
1732 stability
: get_stability(cx
, DefId
::local(self.node
.id
)),
1733 def_id
: DefId
::local(self.node
.id
),
1734 inner
: StructFieldItem(TypedStructField(self.node
.ty
.clean(cx
))),
1739 impl<'tcx
> Clean
<Item
> for ty
::FieldDefData
<'tcx
, '
static> {
1740 fn clean(&self, cx
: &DocContext
) -> Item
{
1741 use syntax
::parse
::token
::special_idents
::unnamed_field
;
1742 use rustc
::metadata
::csearch
;
1744 let attr_map
= csearch
::get_struct_field_attrs(&cx
.tcx().sess
.cstore
, self.did
);
1746 let (name
, attrs
) = if self.name
== unnamed_field
.name
{
1749 (Some(self.name
), Some(attr_map
.get(&self.did
.node
).unwrap()))
1753 name
: name
.clean(cx
),
1754 attrs
: attrs
.unwrap_or(&Vec
::new()).clean(cx
),
1755 source
: Span
::empty(),
1756 visibility
: Some(self.vis
),
1757 stability
: get_stability(cx
, self.did
),
1759 inner
: StructFieldItem(TypedStructField(self.unsubst_ty().clean(cx
))),
1764 pub type Visibility
= hir
::Visibility
;
1766 impl Clean
<Option
<Visibility
>> for hir
::Visibility
{
1767 fn clean(&self, _
: &DocContext
) -> Option
<Visibility
> {
1772 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1774 pub struct_type
: doctree
::StructType
,
1775 pub generics
: Generics
,
1776 pub fields
: Vec
<Item
>,
1777 pub fields_stripped
: bool
,
1780 impl Clean
<Item
> for doctree
::Struct
{
1781 fn clean(&self, cx
: &DocContext
) -> Item
{
1783 name
: Some(self.name
.clean(cx
)),
1784 attrs
: self.attrs
.clean(cx
),
1785 source
: self.whence
.clean(cx
),
1786 def_id
: DefId
::local(self.id
),
1787 visibility
: self.vis
.clean(cx
),
1788 stability
: self.stab
.clean(cx
),
1789 inner
: StructItem(Struct
{
1790 struct_type
: self.struct_type
,
1791 generics
: self.generics
.clean(cx
),
1792 fields
: self.fields
.clean(cx
),
1793 fields_stripped
: false,
1799 /// This is a more limited form of the standard Struct, different in that
1800 /// it lacks the things most items have (name, id, parameterization). Found
1801 /// only as a variant in an enum.
1802 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1803 pub struct VariantStruct
{
1804 pub struct_type
: doctree
::StructType
,
1805 pub fields
: Vec
<Item
>,
1806 pub fields_stripped
: bool
,
1809 impl Clean
<VariantStruct
> for ::rustc_front
::hir
::StructDef
{
1810 fn clean(&self, cx
: &DocContext
) -> VariantStruct
{
1812 struct_type
: doctree
::struct_type_from_def(self),
1813 fields
: self.fields
.clean(cx
),
1814 fields_stripped
: false,
1819 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1821 pub variants
: Vec
<Item
>,
1822 pub generics
: Generics
,
1823 pub variants_stripped
: bool
,
1826 impl Clean
<Item
> for doctree
::Enum
{
1827 fn clean(&self, cx
: &DocContext
) -> Item
{
1829 name
: Some(self.name
.clean(cx
)),
1830 attrs
: self.attrs
.clean(cx
),
1831 source
: self.whence
.clean(cx
),
1832 def_id
: DefId
::local(self.id
),
1833 visibility
: self.vis
.clean(cx
),
1834 stability
: self.stab
.clean(cx
),
1835 inner
: EnumItem(Enum
{
1836 variants
: self.variants
.clean(cx
),
1837 generics
: self.generics
.clean(cx
),
1838 variants_stripped
: false,
1844 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1845 pub struct Variant
{
1846 pub kind
: VariantKind
,
1849 impl Clean
<Item
> for doctree
::Variant
{
1850 fn clean(&self, cx
: &DocContext
) -> Item
{
1852 name
: Some(self.name
.clean(cx
)),
1853 attrs
: self.attrs
.clean(cx
),
1854 source
: self.whence
.clean(cx
),
1855 visibility
: self.vis
.clean(cx
),
1856 stability
: self.stab
.clean(cx
),
1857 def_id
: DefId
::local(self.id
),
1858 inner
: VariantItem(Variant
{
1859 kind
: self.kind
.clean(cx
),
1865 impl<'tcx
> Clean
<Item
> for ty
::VariantDefData
<'tcx
, '
static> {
1866 fn clean(&self, cx
: &DocContext
) -> Item
{
1867 // use syntax::parse::token::special_idents::unnamed_field;
1868 let kind
= match self.kind() {
1869 ty
::VariantKind
::Unit
=> CLikeVariant
,
1870 ty
::VariantKind
::Tuple
=> {
1872 self.fields
.iter().map(|f
| f
.unsubst_ty().clean(cx
)).collect()
1875 ty
::VariantKind
::Dict
=> {
1876 StructVariant(VariantStruct
{
1877 struct_type
: doctree
::Plain
,
1878 fields_stripped
: false,
1879 fields
: self.fields
.iter().map(|field
| {
1881 source
: Span
::empty(),
1882 name
: Some(field
.name
.clean(cx
)),
1884 visibility
: Some(hir
::Public
),
1885 // FIXME: this is not accurate, we need an id for
1886 // the specific field but we're using the id
1887 // for the whole variant. Thus we read the
1888 // stability from the whole variant as well.
1889 // Struct variants are experimental and need
1890 // more infrastructure work before we can get
1891 // at the needed information here.
1893 stability
: get_stability(cx
, self.did
),
1894 inner
: StructFieldItem(
1895 TypedStructField(field
.unsubst_ty().clean(cx
))
1903 name
: Some(self.name
.clean(cx
)),
1904 attrs
: inline
::load_attrs(cx
, cx
.tcx(), self.did
),
1905 source
: Span
::empty(),
1906 visibility
: Some(hir
::Public
),
1908 inner
: VariantItem(Variant { kind: kind }
),
1909 stability
: get_stability(cx
, self.did
),
1914 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1915 pub enum VariantKind
{
1917 TupleVariant(Vec
<Type
>),
1918 StructVariant(VariantStruct
),
1921 impl Clean
<VariantKind
> for hir
::VariantKind
{
1922 fn clean(&self, cx
: &DocContext
) -> VariantKind
{
1924 &hir
::TupleVariantKind(ref args
) => {
1925 if args
.is_empty() {
1928 TupleVariant(args
.iter().map(|x
| x
.ty
.clean(cx
)).collect())
1931 &hir
::StructVariantKind(ref sd
) => StructVariant(sd
.clean(cx
)),
1936 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1938 pub filename
: String
,
1946 fn empty() -> Span
{
1948 filename
: "".to_string(),
1949 loline
: 0, locol
: 0,
1950 hiline
: 0, hicol
: 0,
1955 impl Clean
<Span
> for syntax
::codemap
::Span
{
1956 fn clean(&self, cx
: &DocContext
) -> Span
{
1957 if *self == DUMMY_SP
{
1958 return Span
::empty();
1961 let cm
= cx
.sess().codemap();
1962 let filename
= cm
.span_to_filename(*self);
1963 let lo
= cm
.lookup_char_pos(self.lo
);
1964 let hi
= cm
.lookup_char_pos(self.hi
);
1966 filename
: filename
.to_string(),
1968 locol
: lo
.col
.to_usize(),
1970 hicol
: hi
.col
.to_usize(),
1975 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
1978 pub segments
: Vec
<PathSegment
>,
1982 pub fn singleton(name
: String
) -> Path
{
1985 segments
: vec
![PathSegment
{
1987 params
: PathParameters
::AngleBracketed
{
1988 lifetimes
: Vec
::new(),
1990 bindings
: Vec
::new()
1997 impl Clean
<Path
> for hir
::Path
{
1998 fn clean(&self, cx
: &DocContext
) -> Path
{
2000 global
: self.global
,
2001 segments
: self.segments
.clean(cx
),
2006 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
2007 pub enum PathParameters
{
2009 lifetimes
: Vec
<Lifetime
>,
2011 bindings
: Vec
<TypeBinding
>
2015 output
: Option
<Type
>
2019 impl Clean
<PathParameters
> for hir
::PathParameters
{
2020 fn clean(&self, cx
: &DocContext
) -> PathParameters
{
2022 hir
::AngleBracketedParameters(ref data
) => {
2023 PathParameters
::AngleBracketed
{
2024 lifetimes
: data
.lifetimes
.clean(cx
),
2025 types
: data
.types
.clean(cx
),
2026 bindings
: data
.bindings
.clean(cx
)
2030 hir
::ParenthesizedParameters(ref data
) => {
2031 PathParameters
::Parenthesized
{
2032 inputs
: data
.inputs
.clean(cx
),
2033 output
: data
.output
.clean(cx
)
2040 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
2041 pub struct PathSegment
{
2043 pub params
: PathParameters
2046 impl Clean
<PathSegment
> for hir
::PathSegment
{
2047 fn clean(&self, cx
: &DocContext
) -> PathSegment
{
2049 name
: self.identifier
.clean(cx
),
2050 params
: self.parameters
.clean(cx
)
2055 fn path_to_string(p
: &hir
::Path
) -> String
{
2056 let mut s
= String
::new();
2057 let mut first
= true;
2058 for i
in p
.segments
.iter().map(|x
| x
.identifier
.name
.as_str()) {
2059 if !first
|| p
.global
{
2069 impl Clean
<String
> for ast
::Ident
{
2070 fn clean(&self, _
: &DocContext
) -> String
{
2075 impl Clean
<String
> for ast
::Name
{
2076 fn clean(&self, _
: &DocContext
) -> String
{
2081 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2082 pub struct Typedef
{
2084 pub generics
: Generics
,
2087 impl Clean
<Item
> for doctree
::Typedef
{
2088 fn clean(&self, cx
: &DocContext
) -> Item
{
2090 name
: Some(self.name
.clean(cx
)),
2091 attrs
: self.attrs
.clean(cx
),
2092 source
: self.whence
.clean(cx
),
2093 def_id
: DefId
::local(self.id
.clone()),
2094 visibility
: self.vis
.clean(cx
),
2095 stability
: self.stab
.clean(cx
),
2096 inner
: TypedefItem(Typedef
{
2097 type_
: self.ty
.clean(cx
),
2098 generics
: self.gen
.clean(cx
),
2104 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
2105 pub struct BareFunctionDecl
{
2106 pub unsafety
: hir
::Unsafety
,
2107 pub generics
: Generics
,
2112 impl Clean
<BareFunctionDecl
> for hir
::BareFnTy
{
2113 fn clean(&self, cx
: &DocContext
) -> BareFunctionDecl
{
2115 unsafety
: self.unsafety
,
2116 generics
: Generics
{
2117 lifetimes
: self.lifetimes
.clean(cx
),
2118 type_params
: Vec
::new(),
2119 where_predicates
: Vec
::new()
2121 decl
: self.decl
.clean(cx
),
2122 abi
: self.abi
.to_string(),
2127 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2130 pub mutability
: Mutability
,
2131 /// It's useful to have the value of a static documented, but I have no
2132 /// desire to represent expressions (that'd basically be all of the AST,
2133 /// which is huge!). So, have a string.
2137 impl Clean
<Item
> for doctree
::Static
{
2138 fn clean(&self, cx
: &DocContext
) -> Item
{
2139 debug
!("cleaning static {}: {:?}", self.name
.clean(cx
), self);
2141 name
: Some(self.name
.clean(cx
)),
2142 attrs
: self.attrs
.clean(cx
),
2143 source
: self.whence
.clean(cx
),
2144 def_id
: DefId
::local(self.id
),
2145 visibility
: self.vis
.clean(cx
),
2146 stability
: self.stab
.clean(cx
),
2147 inner
: StaticItem(Static
{
2148 type_
: self.type_
.clean(cx
),
2149 mutability
: self.mutability
.clean(cx
),
2150 expr
: self.expr
.span
.to_src(cx
),
2156 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2157 pub struct Constant
{
2162 impl Clean
<Item
> for doctree
::Constant
{
2163 fn clean(&self, cx
: &DocContext
) -> Item
{
2165 name
: Some(self.name
.clean(cx
)),
2166 attrs
: self.attrs
.clean(cx
),
2167 source
: self.whence
.clean(cx
),
2168 def_id
: DefId
::local(self.id
),
2169 visibility
: self.vis
.clean(cx
),
2170 stability
: self.stab
.clean(cx
),
2171 inner
: ConstantItem(Constant
{
2172 type_
: self.type_
.clean(cx
),
2173 expr
: self.expr
.span
.to_src(cx
),
2179 #[derive(Debug, Clone, RustcEncodable, RustcDecodable, PartialEq, Copy)]
2180 pub enum Mutability
{
2185 impl Clean
<Mutability
> for hir
::Mutability
{
2186 fn clean(&self, _
: &DocContext
) -> Mutability
{
2188 &hir
::MutMutable
=> Mutable
,
2189 &hir
::MutImmutable
=> Immutable
,
2194 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Copy, Debug)]
2195 pub enum ImplPolarity
{
2200 impl Clean
<ImplPolarity
> for hir
::ImplPolarity
{
2201 fn clean(&self, _
: &DocContext
) -> ImplPolarity
{
2203 &hir
::ImplPolarity
::Positive
=> ImplPolarity
::Positive
,
2204 &hir
::ImplPolarity
::Negative
=> ImplPolarity
::Negative
,
2209 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2211 pub unsafety
: hir
::Unsafety
,
2212 pub generics
: Generics
,
2213 pub trait_
: Option
<Type
>,
2215 pub items
: Vec
<Item
>,
2217 pub polarity
: Option
<ImplPolarity
>,
2220 fn detect_derived
<M
: AttrMetaMethods
>(attrs
: &[M
]) -> bool
{
2221 attr
::contains_name(attrs
, "automatically_derived")
2224 impl Clean
<Vec
<Item
>> for doctree
::Impl
{
2225 fn clean(&self, cx
: &DocContext
) -> Vec
<Item
> {
2226 let mut ret
= Vec
::new();
2227 let trait_
= self.trait_
.clean(cx
);
2228 let items
= self.items
.clean(cx
);
2230 // If this impl block is an implementation of the Deref trait, then we
2231 // need to try inlining the target's inherent impl blocks as well.
2232 if let Some(ResolvedPath { did, .. }
) = trait_
{
2233 if Some(did
) == cx
.deref_trait_did
.get() {
2234 build_deref_target_impls(cx
, &items
, &mut ret
);
2240 attrs
: self.attrs
.clean(cx
),
2241 source
: self.whence
.clean(cx
),
2242 def_id
: DefId
::local(self.id
),
2243 visibility
: self.vis
.clean(cx
),
2244 stability
: self.stab
.clean(cx
),
2245 inner
: ImplItem(Impl
{
2246 unsafety
: self.unsafety
,
2247 generics
: self.generics
.clean(cx
),
2249 for_
: self.for_
.clean(cx
),
2251 derived
: detect_derived(&self.attrs
),
2252 polarity
: Some(self.polarity
.clean(cx
)),
2259 fn build_deref_target_impls(cx
: &DocContext
,
2261 ret
: &mut Vec
<Item
>) {
2262 let tcx
= match cx
.tcx_opt() {
2268 let target
= match item
.inner
{
2269 TypedefItem(ref t
, true) => &t
.type_
,
2272 let primitive
= match *target
{
2273 ResolvedPath { did, .. }
if did
.is_local() => continue,
2274 ResolvedPath { did, .. }
=> {
2275 ret
.extend(inline
::build_impls(cx
, tcx
, did
));
2278 _
=> match target
.primitive_type() {
2283 let did
= match primitive
{
2284 Isize
=> tcx
.lang_items
.isize_impl(),
2285 I8
=> tcx
.lang_items
.i8_impl(),
2286 I16
=> tcx
.lang_items
.i16_impl(),
2287 I32
=> tcx
.lang_items
.i32_impl(),
2288 I64
=> tcx
.lang_items
.i64_impl(),
2289 Usize
=> tcx
.lang_items
.usize_impl(),
2290 U8
=> tcx
.lang_items
.u8_impl(),
2291 U16
=> tcx
.lang_items
.u16_impl(),
2292 U32
=> tcx
.lang_items
.u32_impl(),
2293 U64
=> tcx
.lang_items
.u64_impl(),
2294 F32
=> tcx
.lang_items
.f32_impl(),
2295 F64
=> tcx
.lang_items
.f64_impl(),
2296 Char
=> tcx
.lang_items
.char_impl(),
2298 Str
=> tcx
.lang_items
.str_impl(),
2299 Slice
=> tcx
.lang_items
.slice_impl(),
2300 Array
=> tcx
.lang_items
.slice_impl(),
2301 PrimitiveTuple
=> None
,
2302 PrimitiveRawPointer
=> tcx
.lang_items
.const_ptr_impl(),
2304 if let Some(did
) = did
{
2305 if !did
.is_local() {
2306 inline
::build_impl(cx
, tcx
, did
, ret
);
2312 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2313 pub struct DefaultImpl
{
2314 pub unsafety
: hir
::Unsafety
,
2318 impl Clean
<Item
> for doctree
::DefaultImpl
{
2319 fn clean(&self, cx
: &DocContext
) -> Item
{
2322 attrs
: self.attrs
.clean(cx
),
2323 source
: self.whence
.clean(cx
),
2324 def_id
: DefId
::local(self.id
),
2325 visibility
: Some(hir
::Public
),
2327 inner
: DefaultImplItem(DefaultImpl
{
2328 unsafety
: self.unsafety
,
2329 trait_
: self.trait_
.clean(cx
),
2335 impl Clean
<Item
> for doctree
::ExternCrate
{
2336 fn clean(&self, cx
: &DocContext
) -> Item
{
2339 attrs
: self.attrs
.clean(cx
),
2340 source
: self.whence
.clean(cx
),
2341 def_id
: DefId
::local(0),
2342 visibility
: self.vis
.clean(cx
),
2344 inner
: ExternCrateItem(self.name
.clean(cx
), self.path
.clone())
2349 impl Clean
<Vec
<Item
>> for doctree
::Import
{
2350 fn clean(&self, cx
: &DocContext
) -> Vec
<Item
> {
2351 // We consider inlining the documentation of `pub use` statements, but we
2352 // forcefully don't inline if this is not public or if the
2353 // #[doc(no_inline)] attribute is present.
2354 let denied
= self.vis
!= hir
::Public
|| self.attrs
.iter().any(|a
| {
2355 &a
.name()[..] == "doc" && match a
.meta_item_list() {
2356 Some(l
) => attr
::contains_name(l
, "no_inline"),
2360 let (mut ret
, inner
) = match self.node
{
2361 hir
::ViewPathGlob(ref p
) => {
2362 (vec
![], GlobImport(resolve_use_source(cx
, p
.clean(cx
), self.id
)))
2364 hir
::ViewPathList(ref p
, ref list
) => {
2365 // Attempt to inline all reexported items, but be sure
2366 // to keep any non-inlineable reexports so they can be
2367 // listed in the documentation.
2368 let mut ret
= vec
![];
2369 let remaining
= if !denied
{
2370 let mut remaining
= vec
![];
2372 match inline
::try_inline(cx
, path
.node
.id(), path
.node
.rename()) {
2377 remaining
.push(path
.clean(cx
));
2385 if remaining
.is_empty() {
2388 (ret
, ImportList(resolve_use_source(cx
, p
.clean(cx
), self.id
),
2391 hir
::ViewPathSimple(i
, ref p
) => {
2393 match inline
::try_inline(cx
, self.id
, Some(i
)) {
2394 Some(items
) => return items
,
2398 (vec
![], SimpleImport(i
.clean(cx
),
2399 resolve_use_source(cx
, p
.clean(cx
), self.id
)))
2404 attrs
: self.attrs
.clean(cx
),
2405 source
: self.whence
.clean(cx
),
2406 def_id
: DefId
::local(0),
2407 visibility
: self.vis
.clean(cx
),
2409 inner
: ImportItem(inner
)
2415 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2417 // use source as str;
2418 SimpleImport(String
, ImportSource
),
2420 GlobImport(ImportSource
),
2421 // use source::{a, b, c};
2422 ImportList(ImportSource
, Vec
<ViewListIdent
>),
2425 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2426 pub struct ImportSource
{
2428 pub did
: Option
<DefId
>,
2431 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2432 pub struct ViewListIdent
{
2434 pub rename
: Option
<String
>,
2435 pub source
: Option
<DefId
>,
2438 impl Clean
<ViewListIdent
> for hir
::PathListItem
{
2439 fn clean(&self, cx
: &DocContext
) -> ViewListIdent
{
2441 hir
::PathListIdent { id, name, rename }
=> ViewListIdent
{
2442 name
: name
.clean(cx
),
2443 rename
: rename
.map(|r
| r
.clean(cx
)),
2444 source
: resolve_def(cx
, id
)
2446 hir
::PathListMod { id, rename }
=> ViewListIdent
{
2447 name
: "self".to_string(),
2448 rename
: rename
.map(|r
| r
.clean(cx
)),
2449 source
: resolve_def(cx
, id
)
2455 impl Clean
<Vec
<Item
>> for hir
::ForeignMod
{
2456 fn clean(&self, cx
: &DocContext
) -> Vec
<Item
> {
2457 let mut items
= self.items
.clean(cx
);
2458 for item
in &mut items
{
2460 ForeignFunctionItem(ref mut f
) => f
.abi
= self.abi
,
2468 impl Clean
<Item
> for hir
::ForeignItem
{
2469 fn clean(&self, cx
: &DocContext
) -> Item
{
2470 let inner
= match self.node
{
2471 hir
::ForeignItemFn(ref decl
, ref generics
) => {
2472 ForeignFunctionItem(Function
{
2473 decl
: decl
.clean(cx
),
2474 generics
: generics
.clean(cx
),
2475 unsafety
: hir
::Unsafety
::Unsafe
,
2477 constness
: hir
::Constness
::NotConst
,
2480 hir
::ForeignItemStatic(ref ty
, mutbl
) => {
2481 ForeignStaticItem(Static
{
2482 type_
: ty
.clean(cx
),
2483 mutability
: if mutbl {Mutable}
else {Immutable}
,
2484 expr
: "".to_string(),
2489 name
: Some(self.ident
.clean(cx
)),
2490 attrs
: self.attrs
.clean(cx
),
2491 source
: self.span
.clean(cx
),
2492 def_id
: DefId
::local(self.id
),
2493 visibility
: self.vis
.clean(cx
),
2494 stability
: get_stability(cx
, DefId
::local(self.id
)),
2503 fn to_src(&self, cx
: &DocContext
) -> String
;
2506 impl ToSource
for syntax
::codemap
::Span
{
2507 fn to_src(&self, cx
: &DocContext
) -> String
{
2508 debug
!("converting span {:?} to snippet", self.clean(cx
));
2509 let sn
= match cx
.sess().codemap().span_to_snippet(*self) {
2510 Ok(x
) => x
.to_string(),
2511 Err(_
) => "".to_string()
2513 debug
!("got snippet {}", sn
);
2518 fn lit_to_string(lit
: &hir
::Lit
) -> String
{
2520 hir
::LitStr(ref st
, _
) => st
.to_string(),
2521 hir
::LitByteStr(ref data
) => format
!("{:?}", data
),
2522 hir
::LitByte(b
) => {
2523 let mut res
= String
::from("b'");
2524 for c
in (b
as char).escape_default() {
2530 hir
::LitChar(c
) => format
!("'{}'", c
),
2531 hir
::LitInt(i
, _t
) => i
.to_string(),
2532 hir
::LitFloat(ref f
, _t
) => f
.to_string(),
2533 hir
::LitFloatUnsuffixed(ref f
) => f
.to_string(),
2534 hir
::LitBool(b
) => b
.to_string(),
2538 fn name_from_pat(p
: &hir
::Pat
) -> String
{
2539 use rustc_front
::hir
::*;
2540 debug
!("Trying to get a name from pattern: {:?}", p
);
2543 PatWild(PatWildSingle
) => "_".to_string(),
2544 PatWild(PatWildMulti
) => "..".to_string(),
2545 PatIdent(_
, ref p
, _
) => p
.node
.to_string(),
2546 PatEnum(ref p
, _
) => path_to_string(p
),
2547 PatQPath(..) => panic
!("tried to get argument name from PatQPath, \
2548 which is not allowed in function arguments"),
2549 PatStruct(ref name
, ref fields
, etc
) => {
2550 format
!("{} {{ {}{} }}", path_to_string(name
),
2551 fields
.iter().map(|&Spanned { node: ref fp, .. }
|
2552 format
!("{}: {}", fp
.ident
, name_from_pat(&*fp
.pat
)))
2553 .collect
::<Vec
<String
>>().join(", "),
2554 if etc { ", ..." }
else { "" }
2557 PatTup(ref elts
) => format
!("({})", elts
.iter().map(|p
| name_from_pat(&**p
))
2558 .collect
::<Vec
<String
>>().join(", ")),
2559 PatBox(ref p
) => name_from_pat(&**p
),
2560 PatRegion(ref p
, _
) => name_from_pat(&**p
),
2562 warn
!("tried to get argument name from PatLit, \
2563 which is silly in function arguments");
2566 PatRange(..) => panic
!("tried to get argument name from PatRange, \
2567 which is not allowed in function arguments"),
2568 PatVec(ref begin
, ref mid
, ref end
) => {
2569 let begin
= begin
.iter().map(|p
| name_from_pat(&**p
));
2570 let mid
= mid
.as_ref().map(|p
| format
!("..{}", name_from_pat(&**p
))).into_iter();
2571 let end
= end
.iter().map(|p
| name_from_pat(&**p
));
2572 format
!("[{}]", begin
.chain(mid
).chain(end
).collect
::<Vec
<_
>>().join(", "))
2577 /// Given a Type, resolve it using the def_map
2578 fn resolve_type(cx
: &DocContext
,
2580 id
: ast
::NodeId
) -> Type
{
2581 let tcx
= match cx
.tcx_opt() {
2583 // If we're extracting tests, this return value doesn't matter.
2584 None
=> return Primitive(Bool
),
2586 debug
!("searching for {} in defmap", id
);
2587 let def
= match tcx
.def_map
.borrow().get(&id
) {
2588 Some(k
) => k
.full_def(),
2589 None
=> panic
!("unresolved id not in defmap")
2592 let is_generic
= match def
{
2593 def
::DefPrimTy(p
) => match p
{
2594 hir
::TyStr
=> return Primitive(Str
),
2595 hir
::TyBool
=> return Primitive(Bool
),
2596 hir
::TyChar
=> return Primitive(Char
),
2597 hir
::TyInt(hir
::TyIs
) => return Primitive(Isize
),
2598 hir
::TyInt(hir
::TyI8
) => return Primitive(I8
),
2599 hir
::TyInt(hir
::TyI16
) => return Primitive(I16
),
2600 hir
::TyInt(hir
::TyI32
) => return Primitive(I32
),
2601 hir
::TyInt(hir
::TyI64
) => return Primitive(I64
),
2602 hir
::TyUint(hir
::TyUs
) => return Primitive(Usize
),
2603 hir
::TyUint(hir
::TyU8
) => return Primitive(U8
),
2604 hir
::TyUint(hir
::TyU16
) => return Primitive(U16
),
2605 hir
::TyUint(hir
::TyU32
) => return Primitive(U32
),
2606 hir
::TyUint(hir
::TyU64
) => return Primitive(U64
),
2607 hir
::TyFloat(hir
::TyF32
) => return Primitive(F32
),
2608 hir
::TyFloat(hir
::TyF64
) => return Primitive(F64
),
2610 def
::DefSelfTy(..) if path
.segments
.len() == 1 => {
2611 return Generic(special_idents
::type_self
.name
.to_string());
2613 def
::DefSelfTy(..) | def
::DefTyParam(..) => true,
2616 let did
= register_def(&*cx
, def
);
2617 ResolvedPath { path: path, typarams: None, did: did, is_generic: is_generic }
2620 fn register_def(cx
: &DocContext
, def
: def
::Def
) -> DefId
{
2621 let (did
, kind
) = match def
{
2622 def
::DefFn(i
, _
) => (i
, TypeFunction
),
2623 def
::DefTy(i
, false) => (i
, TypeTypedef
),
2624 def
::DefTy(i
, true) => (i
, TypeEnum
),
2625 def
::DefTrait(i
) => (i
, TypeTrait
),
2626 def
::DefStruct(i
) => (i
, TypeStruct
),
2627 def
::DefMod(i
) => (i
, TypeModule
),
2628 def
::DefStatic(i
, _
) => (i
, TypeStatic
),
2629 def
::DefVariant(i
, _
, _
) => (i
, TypeEnum
),
2630 _
=> return def
.def_id()
2632 if did
.is_local() { return did }
2633 let tcx
= match cx
.tcx_opt() {
2637 inline
::record_extern_fqn(cx
, did
, kind
);
2638 if let TypeTrait
= kind
{
2639 let t
= inline
::build_external_trait(cx
, tcx
, did
);
2640 cx
.external_traits
.borrow_mut().as_mut().unwrap().insert(did
, t
);
2645 fn resolve_use_source(cx
: &DocContext
, path
: Path
, id
: ast
::NodeId
) -> ImportSource
{
2648 did
: resolve_def(cx
, id
),
2652 fn resolve_def(cx
: &DocContext
, id
: ast
::NodeId
) -> Option
<DefId
> {
2653 cx
.tcx_opt().and_then(|tcx
| {
2654 tcx
.def_map
.borrow().get(&id
).map(|d
| register_def(cx
, d
.full_def()))
2658 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2661 pub imported_from
: Option
<String
>,
2664 impl Clean
<Item
> for doctree
::Macro
{
2665 fn clean(&self, cx
: &DocContext
) -> Item
{
2667 name
: Some(format
!("{}!", self.name
.clean(cx
))),
2668 attrs
: self.attrs
.clean(cx
),
2669 source
: self.whence
.clean(cx
),
2670 visibility
: hir
::Public
.clean(cx
),
2671 stability
: self.stab
.clean(cx
),
2672 def_id
: DefId
::local(self.id
),
2673 inner
: MacroItem(Macro
{
2674 source
: self.whence
.to_src(cx
),
2675 imported_from
: self.imported_from
.clean(cx
),
2681 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2682 pub struct Stability
{
2683 pub level
: attr
::StabilityLevel
,
2684 pub feature
: String
,
2686 pub deprecated_since
: String
,
2688 pub issue
: Option
<u32>
2691 impl Clean
<Stability
> for attr
::Stability
{
2692 fn clean(&self, _
: &DocContext
) -> Stability
{
2695 feature
: self.feature
.to_string(),
2696 since
: self.since
.as_ref().map_or("".to_string(),
2697 |interned
| interned
.to_string()),
2698 deprecated_since
: self.deprecated_since
.as_ref().map_or("".to_string(),
2699 |istr
| istr
.to_string()),
2700 reason
: self.reason
.as_ref().map_or("".to_string(),
2701 |interned
| interned
.to_string()),
2707 impl<'a
> Clean
<Stability
> for &'a attr
::Stability
{
2708 fn clean(&self, _
: &DocContext
) -> Stability
{
2711 feature
: self.feature
.to_string(),
2712 since
: self.since
.as_ref().map_or("".to_string(),
2713 |interned
| interned
.to_string()),
2714 deprecated_since
: self.deprecated_since
.as_ref().map_or("".to_string(),
2715 |istr
| istr
.to_string()),
2716 reason
: self.reason
.as_ref().map_or("".to_string(),
2717 |interned
| interned
.to_string()),
2723 impl<'tcx
> Clean
<Item
> for ty
::AssociatedConst
<'tcx
> {
2724 fn clean(&self, cx
: &DocContext
) -> Item
{
2726 source
: DUMMY_SP
.clean(cx
),
2727 name
: Some(self.name
.clean(cx
)),
2729 inner
: AssociatedConstItem(self.ty
.clean(cx
), None
),
2731 def_id
: self.def_id
,
2737 impl<'tcx
> Clean
<Item
> for ty
::AssociatedType
<'tcx
> {
2738 fn clean(&self, cx
: &DocContext
) -> Item
{
2739 let my_name
= self.name
.clean(cx
);
2741 let mut bounds
= if let ty
::TraitContainer(did
) = self.container
{
2742 // When loading a cross-crate associated type, the bounds for this type
2743 // are actually located on the trait/impl itself, so we need to load
2744 // all of the generics from there and then look for bounds that are
2745 // applied to this associated type in question.
2746 let def
= cx
.tcx().lookup_trait_def(did
);
2747 let predicates
= cx
.tcx().lookup_predicates(did
);
2748 let generics
= (&def
.generics
, &predicates
, subst
::TypeSpace
).clean(cx
);
2749 generics
.where_predicates
.iter().filter_map(|pred
| {
2750 let (name
, self_type
, trait_
, bounds
) = match *pred
{
2751 WherePredicate
::BoundPredicate
{
2752 ty
: QPath { ref name, ref self_type, ref trait_ }
,
2754 } => (name
, self_type
, trait_
, bounds
),
2757 if *name
!= my_name { return None }
2759 ResolvedPath { did, .. }
if did
== self.container
.id() => {}
2763 Generic(ref s
) if *s
== "Self" => {}
2767 }).flat_map(|i
| i
.iter().cloned()).collect
::<Vec
<_
>>()
2772 // Our Sized/?Sized bound didn't get handled when creating the generics
2773 // because we didn't actually get our whole set of bounds until just now
2774 // (some of them may have come from the trait). If we do have a sized
2775 // bound, we remove it, and if we don't then we add the `?Sized` bound
2777 match bounds
.iter().position(|b
| b
.is_sized_bound(cx
)) {
2778 Some(i
) => { bounds.remove(i); }
2779 None
=> bounds
.push(TyParamBound
::maybe_sized(cx
)),
2783 source
: DUMMY_SP
.clean(cx
),
2784 name
: Some(self.name
.clean(cx
)),
2785 attrs
: inline
::load_attrs(cx
, cx
.tcx(), self.def_id
),
2786 inner
: AssociatedTypeItem(bounds
, self.ty
.clean(cx
)),
2787 visibility
: self.vis
.clean(cx
),
2788 def_id
: self.def_id
,
2789 stability
: stability
::lookup(cx
.tcx(), self.def_id
).clean(cx
),
2794 impl<'a
> Clean
<Typedef
> for (ty
::TypeScheme
<'a
>, ty
::GenericPredicates
<'a
>,
2796 fn clean(&self, cx
: &DocContext
) -> Typedef
{
2797 let (ref ty_scheme
, ref predicates
, ps
) = *self;
2799 type_
: ty_scheme
.ty
.clean(cx
),
2800 generics
: (&ty_scheme
.generics
, predicates
, ps
).clean(cx
)
2805 fn lang_struct(cx
: &DocContext
, did
: Option
<DefId
>,
2806 t
: ty
::Ty
, name
: &str,
2807 fallback
: fn(Box
<Type
>) -> Type
) -> Type
{
2808 let did
= match did
{
2810 None
=> return fallback(box t
.clean(cx
)),
2812 let fqn
= csearch
::get_item_path(cx
.tcx(), did
);
2813 let fqn
: Vec
<String
> = fqn
.into_iter().map(|i
| {
2816 cx
.external_paths
.borrow_mut().as_mut().unwrap().insert(did
, (fqn
, TypeStruct
));
2822 segments
: vec
![PathSegment
{
2823 name
: name
.to_string(),
2824 params
: PathParameters
::AngleBracketed
{
2826 types
: vec
![t
.clean(cx
)],
2835 /// An equality constraint on an associated type, e.g. `A=Bar` in `Foo<A=Bar>`
2836 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Debug)]
2837 pub struct TypeBinding
{
2842 impl Clean
<TypeBinding
> for hir
::TypeBinding
{
2843 fn clean(&self, cx
: &DocContext
) -> TypeBinding
{
2845 name
: self.ident
.clean(cx
),
2846 ty
: self.ty
.clean(cx
)