mod.rs 92.7 KB
Newer Older
C
Corey Richardson 已提交
1 2 3
//! This module contains the "cleaned" pieces of the AST, and the functions
//! that clean them.

4 5
mod auto_trait;
mod blanket_impl;
M
Mark Rousskov 已提交
6 7
pub mod cfg;
pub mod inline;
8 9
mod simplify;
pub mod types;
M
Mark Rousskov 已提交
10
pub mod utils;
S
Steven Fackler 已提交
11

12 13
use rustc::hir;
use rustc::hir::def::{CtorKind, DefKind, Res};
G
Guillaume Gomez 已提交
14
use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
M
Mark Rousskov 已提交
15 16 17 18
use rustc::infer::region_constraints::{Constraint, RegionConstraintData};
use rustc::middle::lang_items;
use rustc::middle::resolve_lifetime as rl;
use rustc::middle::stability;
19
use rustc::ty::fold::TypeFolder;
M
Mark Rousskov 已提交
20 21
use rustc::ty::subst::InternalSubsts;
use rustc::ty::{self, AdtKind, Lift, Ty, TyCtxt};
22
use rustc::util::nodemap::{FxHashMap, FxHashSet};
M
Mark Rousskov 已提交
23
use rustc_index::vec::{Idx, IndexVec};
24 25 26
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym};
use rustc_span::{self, Pos};
M
Mark Rousskov 已提交
27
use rustc_typeck::hir_ty_to_ty;
28
use syntax::ast::{self, Ident};
29
use syntax::attr;
30

31
use std::collections::hash_map::Entry;
32
use std::default::Default;
M
Mark Rousskov 已提交
33
use std::hash::Hash;
34
use std::rc::Rc;
35
use std::u32;
M
Mark Rousskov 已提交
36
use std::{mem, vec};
37

38
use crate::core::{self, DocContext, ImplTraitParam};
39 40
use crate::doctree;

G
Guillaume Gomez 已提交
41 42 43 44
use utils::*;

pub use utils::{get_auto_trait_and_blanket_impls, krate, register_res};

M
Mark Rousskov 已提交
45
pub use self::types::FunctionRetTy::*;
46 47
pub use self::types::ItemEnum::*;
pub use self::types::SelfTy::*;
M
Mark Rousskov 已提交
48 49 50
pub use self::types::Type::*;
pub use self::types::Visibility::{Inherited, Public};
pub use self::types::*;
51 52

const FN_OUTPUT_NAME: &'static str = "Output";
K
kennytm 已提交
53

C
Corey Richardson 已提交
54
pub trait Clean<T> {
55
    fn clean(&self, cx: &DocContext<'_>) -> T;
C
Corey Richardson 已提交
56 57
}

58
impl<T: Clean<U>, U> Clean<Vec<U>> for [T] {
59
    fn clean(&self, cx: &DocContext<'_>) -> Vec<U> {
60
        self.iter().map(|x| x.clean(cx)).collect()
61 62 63
    }
}

64
impl<T: Clean<U>, U, V: Idx> Clean<IndexVec<V, U>> for IndexVec<V, T> {
65
    fn clean(&self, cx: &DocContext<'_>) -> IndexVec<V, U> {
66 67 68 69
        self.iter().map(|x| x.clean(cx)).collect()
    }
}

C
Camille GILLOT 已提交
70 71 72 73 74 75
impl<T: Clean<U>, U> Clean<U> for &T {
    fn clean(&self, cx: &DocContext<'_>) -> U {
        (**self).clean(cx)
    }
}

76
impl<T: Clean<U>, U> Clean<U> for Rc<T> {
77
    fn clean(&self, cx: &DocContext<'_>) -> U {
78
        (**self).clean(cx)
79 80 81
    }
}

C
Corey Richardson 已提交
82
impl<T: Clean<U>, U> Clean<Option<U>> for Option<T> {
83
    fn clean(&self, cx: &DocContext<'_>) -> Option<U> {
M
mitaa 已提交
84
        self.as_ref().map(|v| v.clean(cx))
C
Corey Richardson 已提交
85 86 87
    }
}

M
Mark Rousskov 已提交
88 89 90 91
impl<T, U> Clean<U> for ty::Binder<T>
where
    T: Clean<U>,
{
92
    fn clean(&self, cx: &DocContext<'_>) -> U {
93
        self.skip_binder().clean(cx)
94 95 96
    }
}

A
Ariel Ben-Yehuda 已提交
97
impl Clean<ExternalCrate> for CrateNum {
98
    fn clean(&self, cx: &DocContext<'_>) -> ExternalCrate {
99 100
        let root = DefId { krate: *self, index: CRATE_DEF_INDEX };
        let krate_span = cx.tcx.def_span(root);
D
Donato Sciarra 已提交
101
        let krate_src = cx.sess().source_map().span_to_filename(krate_span);
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119

        // Collect all inner modules which are tagged as implementations of
        // primitives.
        //
        // Note that this loop only searches the top-level items of the crate,
        // and this is intentional. If we were to search the entire crate for an
        // item tagged with `#[doc(primitive)]` then we would also have to
        // search the entirety of external modules for items tagged
        // `#[doc(primitive)]`, which is a pretty inefficient process (decoding
        // all that metadata unconditionally).
        //
        // In order to keep the metadata load under control, the
        // `#[doc(primitive)]` feature is explicitly designed to only allow the
        // primitive tags to show up as the top level items in a crate.
        //
        // Also note that this does not attempt to deal with modules tagged
        // duplicately for the same primitive. This is handled later on when
        // rendering by delegating everything to a hash map.
120 121
        let as_primitive = |res: Res| {
            if let Res::Def(DefKind::Mod, def_id) = res {
122 123
                let attrs = cx.tcx.get_attrs(def_id).clean(cx);
                let mut prim = None;
124
                for attr in attrs.lists(sym::doc) {
125
                    if let Some(v) = attr.value_str() {
126
                        if attr.check_name(sym::primitive) {
127 128 129 130
                            prim = PrimitiveType::from_str(&v.as_str());
                            if prim.is_some() {
                                break;
                            }
131
                            // FIXME: should warn on unknown primitives?
132 133 134 135 136 137 138 139
                        }
                    }
                }
                return prim.map(|p| (def_id, p, attrs));
            }
            None
        };
        let primitives = if root.is_local() {
M
Mark Rousskov 已提交
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
            cx.tcx
                .hir()
                .krate()
                .module
                .item_ids
                .iter()
                .filter_map(|&id| {
                    let item = cx.tcx.hir().expect_item(id.id);
                    match item.kind {
                        hir::ItemKind::Mod(_) => {
                            as_primitive(Res::Def(DefKind::Mod, cx.tcx.hir().local_def_id(id.id)))
                        }
                        hir::ItemKind::Use(ref path, hir::UseKind::Single)
                            if item.vis.node.is_pub() =>
                        {
                            as_primitive(path.res).map(|(_, prim, attrs)| {
                                // Pretend the primitive is local.
                                (cx.tcx.hir().local_def_id(id.id), prim, attrs)
                            })
                        }
                        _ => None,
161
                    }
M
Mark Rousskov 已提交
162 163
                })
                .collect()
164
        } else {
M
Mark Rousskov 已提交
165 166 167 168 169 170
            cx.tcx
                .item_children(root)
                .iter()
                .map(|item| item.res)
                .filter_map(as_primitive)
                .collect()
171 172
        };

173 174
        let as_keyword = |res: Res| {
            if let Res::Def(DefKind::Mod, def_id) = res {
G
Guillaume Gomez 已提交
175 176
                let attrs = cx.tcx.get_attrs(def_id).clean(cx);
                let mut keyword = None;
177
                for attr in attrs.lists(sym::doc) {
G
Guillaume Gomez 已提交
178
                    if let Some(v) = attr.value_str() {
179
                        if attr.check_name(sym::keyword) {
180 181 182
                            if v.is_doc_keyword() {
                                keyword = Some(v.to_string());
                                break;
G
Guillaume Gomez 已提交
183 184 185 186 187 188 189 190 191 192
                            }
                            // FIXME: should warn on unknown keywords?
                        }
                    }
                }
                return keyword.map(|p| (def_id, p, attrs));
            }
            None
        };
        let keywords = if root.is_local() {
M
Mark Rousskov 已提交
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
            cx.tcx
                .hir()
                .krate()
                .module
                .item_ids
                .iter()
                .filter_map(|&id| {
                    let item = cx.tcx.hir().expect_item(id.id);
                    match item.kind {
                        hir::ItemKind::Mod(_) => {
                            as_keyword(Res::Def(DefKind::Mod, cx.tcx.hir().local_def_id(id.id)))
                        }
                        hir::ItemKind::Use(ref path, hir::UseKind::Single)
                            if item.vis.node.is_pub() =>
                        {
                            as_keyword(path.res).map(|(_, prim, attrs)| {
                                (cx.tcx.hir().local_def_id(id.id), prim, attrs)
                            })
                        }
                        _ => None,
G
Guillaume Gomez 已提交
213
                    }
M
Mark Rousskov 已提交
214 215
                })
                .collect()
G
Guillaume Gomez 已提交
216
        } else {
M
Mark Rousskov 已提交
217
            cx.tcx.item_children(root).iter().map(|item| item.res).filter_map(as_keyword).collect()
G
Guillaume Gomez 已提交
218 219
        };

220
        ExternalCrate {
221
            name: cx.tcx.crate_name(*self).to_string(),
222
            src: krate_src,
223
            attrs: cx.tcx.get_attrs(root).clean(cx),
224
            primitives,
G
Guillaume Gomez 已提交
225
            keywords,
C
Corey Richardson 已提交
226 227 228 229
        }
    }
}

230
impl Clean<Item> for doctree::Module<'_> {
231
    fn clean(&self, cx: &DocContext<'_>) -> Item {
C
Corey Richardson 已提交
232
        let name = if self.name.is_some() {
G
Guillaume Gomez 已提交
233
            self.name.expect("No name provided").clean(cx)
C
Corey Richardson 已提交
234
        } else {
235
            String::new()
C
Corey Richardson 已提交
236
        };
237

238 239 240
        // maintain a stack of mod ids, for doc comment path resolution
        // but we also need to resolve the module's own docs based on whether its docs were written
        // inside or outside the module, so check for that
241
        let attrs = self.attrs.clean(cx);
M
Manish Goregaokar 已提交
242

243
        let mut items: Vec<Item> = vec![];
D
DebugSteven 已提交
244
        items.extend(self.extern_crates.iter().flat_map(|x| x.clean(cx)));
245
        items.extend(self.imports.iter().flat_map(|x| x.clean(cx)));
246 247 248
        items.extend(self.structs.iter().map(|x| x.clean(cx)));
        items.extend(self.unions.iter().map(|x| x.clean(cx)));
        items.extend(self.enums.iter().map(|x| x.clean(cx)));
249
        items.extend(self.fns.iter().map(|x| x.clean(cx)));
250
        items.extend(self.foreigns.iter().map(|x| x.clean(cx)));
251 252
        items.extend(self.mods.iter().map(|x| x.clean(cx)));
        items.extend(self.typedefs.iter().map(|x| x.clean(cx)));
V
varkor 已提交
253
        items.extend(self.opaque_tys.iter().map(|x| x.clean(cx)));
254 255 256
        items.extend(self.statics.iter().map(|x| x.clean(cx)));
        items.extend(self.constants.iter().map(|x| x.clean(cx)));
        items.extend(self.traits.iter().map(|x| x.clean(cx)));
257
        items.extend(self.impls.iter().flat_map(|x| x.clean(cx)));
258
        items.extend(self.macros.iter().map(|x| x.clean(cx)));
259
        items.extend(self.proc_macros.iter().map(|x| x.clean(cx)));
260
        items.extend(self.trait_aliases.iter().map(|x| x.clean(cx)));
261 262 263

        // determine if we should display the inner contents or
        // the outer `mod` item for the source code.
264
        let whence = {
D
Donato Sciarra 已提交
265
            let cm = cx.sess().source_map();
266 267
            let outer = cm.lookup_char_pos(self.where_outer.lo());
            let inner = cm.lookup_char_pos(self.where_inner.lo());
268 269 270 271
            if outer.file.start_pos == inner.file.start_pos {
                // mod foo { ... }
                self.where_outer
            } else {
D
Donato Sciarra 已提交
272
                // mod foo; (and a separate SourceFile for the contents)
273 274 275 276
                self.where_inner
            }
        };

C
Corey Richardson 已提交
277 278
        Item {
            name: Some(name),
279
            attrs,
280 281
            source: whence.clean(cx),
            visibility: self.vis.clean(cx),
282 283 284
            stability: cx.stability(self.id).clean(cx),
            deprecation: cx.deprecation(self.id).clean(cx),
            def_id: cx.tcx.hir().local_def_id(self.id),
M
Mark Rousskov 已提交
285
            inner: ModuleItem(Module { is_crate: self.is_crate, items }),
C
Corey Richardson 已提交
286 287 288 289
        }
    }
}

290
impl Clean<Attributes> for [ast::Attribute] {
291
    fn clean(&self, cx: &DocContext<'_>) -> Attributes {
292
        Attributes::from_ast(cx.sess().diagnostic(), self)
C
Corey Richardson 已提交
293 294 295
    }
}

C
Camille GILLOT 已提交
296
impl Clean<GenericBound> for hir::GenericBound<'_> {
297
    fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
C
Corey Richardson 已提交
298
        match *self {
V
varkor 已提交
299 300 301 302
            hir::GenericBound::Outlives(lt) => GenericBound::Outlives(lt.clean(cx)),
            hir::GenericBound::Trait(ref t, modifier) => {
                GenericBound::TraitBound(t.clean(cx), modifier)
            }
C
Corey Richardson 已提交
303 304 305 306
        }
    }
}

V
varkor 已提交
307
impl<'a, 'tcx> Clean<GenericBound> for (&'a ty::TraitRef<'tcx>, Vec<TypeBinding>) {
308
    fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
309 310
        let (trait_ref, ref bounds) = *self;
        inline::record_extern_fqn(cx, trait_ref.def_id, TypeKind::Trait);
M
Mark Rousskov 已提交
311 312 313 314 315 316 317 318
        let path = external_path(
            cx,
            cx.tcx.item_name(trait_ref.def_id),
            Some(trait_ref.def_id),
            true,
            bounds.clone(),
            trait_ref.substs,
        );
319

320
        debug!("ty::TraitRef\n  subst: {:?}\n", trait_ref.substs);
321 322 323

        // collect any late bound regions
        let mut late_bounds = vec![];
324
        for ty_s in trait_ref.input_types().skip(1) {
V
varkor 已提交
325
            if let ty::Tuple(ts) = ty_s.kind {
326
                for &ty_s in ts {
V
varkor 已提交
327
                    if let ty::Ref(ref reg, _, _) = ty_s.expect_ty().kind {
N
Niko Matsakis 已提交
328
                        if let &ty::RegionKind::ReLateBound(..) = *reg {
329
                            debug!("  hit an ReLateBound {:?}", reg);
330 331 332 333 334
                            if let Some(Lifetime(name)) = reg.clean(cx) {
                                late_bounds.push(GenericParamDef {
                                    name,
                                    kind: GenericParamDefKind::Lifetime,
                                });
335 336 337 338 339 340 341
                            }
                        }
                    }
                }
            }
        }

V
varkor 已提交
342
        GenericBound::TraitBound(
343 344
            PolyTrait {
                trait_: ResolvedPath {
345
                    path,
V
varkor 已提交
346
                    param_names: None,
347
                    did: trait_ref.def_id,
348 349
                    is_generic: false,
                },
350
                generic_params: late_bounds,
351
            },
M
Mark Rousskov 已提交
352
            hir::TraitBoundModifier::None,
353
        )
354 355 356
    }
}

V
varkor 已提交
357
impl<'tcx> Clean<GenericBound> for ty::TraitRef<'tcx> {
358
    fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
359 360 361 362
        (self, vec![]).clean(cx)
    }
}

C
csmoe 已提交
363
impl<'tcx> Clean<Option<Vec<GenericBound>>> for InternalSubsts<'tcx> {
364
    fn clean(&self, cx: &DocContext<'_>) -> Option<Vec<GenericBound>> {
365
        let mut v = Vec::new();
V
varkor 已提交
366
        v.extend(self.regions().filter_map(|r| r.clean(cx)).map(GenericBound::Outlives));
M
Mark Rousskov 已提交
367 368 369 370 371 372 373
        v.extend(self.types().map(|t| {
            GenericBound::TraitBound(
                PolyTrait { trait_: t.clean(cx), generic_params: Vec::new() },
                hir::TraitBoundModifier::None,
            )
        }));
        if !v.is_empty() { Some(v) } else { None }
374 375 376
    }
}

377
impl Clean<Lifetime> for hir::Lifetime {
378
    fn clean(&self, cx: &DocContext<'_>) -> Lifetime {
L
ljedrz 已提交
379
        if self.hir_id != hir::DUMMY_HIR_ID {
380
            let def = cx.tcx.named_region(self.hir_id);
381
            match def {
M
Mark Rousskov 已提交
382 383 384
                Some(rl::Region::EarlyBound(_, node_id, _))
                | Some(rl::Region::LateBound(_, node_id, _))
                | Some(rl::Region::Free(_, node_id)) => {
385 386 387
                    if let Some(lt) = cx.lt_substs.borrow().get(&node_id).cloned() {
                        return lt;
                    }
E
Eduard Burtescu 已提交
388
                }
389
                _ => {}
E
Eduard Burtescu 已提交
390 391
            }
        }
392
        Lifetime(self.name.ident().to_string())
C
Corey Richardson 已提交
393 394 395
    }
}

C
Camille GILLOT 已提交
396
impl Clean<Lifetime> for hir::GenericParam<'_> {
397
    fn clean(&self, _: &DocContext<'_>) -> Lifetime {
V
varkor 已提交
398
        match self.kind {
V
varkor 已提交
399 400 401
            hir::GenericParamKind::Lifetime { .. } => {
                if self.bounds.len() > 0 {
                    let mut bounds = self.bounds.iter().map(|bound| match bound {
V
varkor 已提交
402
                        hir::GenericBound::Outlives(lt) => lt,
V
varkor 已提交
403 404
                        _ => panic!(),
                    });
G
Guillaume Gomez 已提交
405
                    let name = bounds.next().expect("no more bounds").name.ident();
406
                    let mut s = format!("{}: {}", self.name.ident(), name);
V
varkor 已提交
407
                    for bound in bounds {
408
                        s.push_str(&format!(" + {}", bound.name.ident()));
V
varkor 已提交
409 410 411
                    }
                    Lifetime(s)
                } else {
412
                    Lifetime(self.name.ident().to_string())
V
varkor 已提交
413
                }
414
            }
V
varkor 已提交
415
            _ => panic!(),
416
        }
417 418 419
    }
}

V
varkor 已提交
420
impl Clean<Constant> for hir::ConstArg {
421
    fn clean(&self, cx: &DocContext<'_>) -> Constant {
V
varkor 已提交
422 423 424
        Constant {
            type_: cx.tcx.type_of(cx.tcx.hir().body_owner_def_id(self.value.body)).clean(cx),
            expr: print_const_expr(cx, self.value.body),
425 426
            value: None,
            is_literal: is_literal_expr(cx, self.value.body.hir_id),
V
varkor 已提交
427 428 429 430
        }
    }
}

431
impl Clean<Lifetime> for ty::GenericParamDef {
432
    fn clean(&self, _cx: &DocContext<'_>) -> Lifetime {
433
        Lifetime(self.name.to_string())
434 435 436
    }
}

437
impl Clean<Option<Lifetime>> for ty::RegionKind {
438
    fn clean(&self, cx: &DocContext<'_>) -> Option<Lifetime> {
439
        match *self {
440
            ty::ReStatic => Some(Lifetime::statik()),
441
            ty::ReLateBound(_, ty::BrNamed(_, name)) => Some(Lifetime(name.to_string())),
N
Niko Matsakis 已提交
442
            ty::ReEarlyBound(ref data) => Some(Lifetime(data.name.clean(cx))),
443

M
Mark Rousskov 已提交
444 445 446 447 448 449 450 451
            ty::ReLateBound(..)
            | ty::ReFree(..)
            | ty::ReScope(..)
            | ty::ReVar(..)
            | ty::RePlaceholder(..)
            | ty::ReEmpty
            | ty::ReClosureBound(_)
            | ty::ReErased => {
452
                debug!("cannot clean region {:?}", self);
453 454
                None
            }
455 456 457 458
        }
    }
}

C
Camille GILLOT 已提交
459
impl Clean<WherePredicate> for hir::WherePredicate<'_> {
460
    fn clean(&self, cx: &DocContext<'_>) -> WherePredicate {
N
Nick Cameron 已提交
461
        match *self {
M
Mark Rousskov 已提交
462 463 464 465
            hir::WherePredicate::BoundPredicate(ref wbp) => WherePredicate::BoundPredicate {
                ty: wbp.bounded_ty.clean(cx),
                bounds: wbp.bounds.clean(cx),
            },
466

M
Mark Rousskov 已提交
467 468 469 470
            hir::WherePredicate::RegionPredicate(ref wrp) => WherePredicate::RegionPredicate {
                lifetime: wrp.lifetime.clean(cx),
                bounds: wrp.bounds.clean(cx),
            },
471

472
            hir::WherePredicate::EqPredicate(ref wrp) => {
M
Mark Rousskov 已提交
473
                WherePredicate::EqPredicate { lhs: wrp.lhs_ty.clean(cx), rhs: wrp.rhs_ty.clean(cx) }
N
Nick Cameron 已提交
474
            }
475 476 477 478
        }
    }
}

479
impl<'a> Clean<Option<WherePredicate>> for ty::Predicate<'a> {
480
    fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
481
        use rustc::ty::Predicate;
482 483

        match *self {
484 485
            Predicate::Trait(ref pred) => Some(pred.clean(cx)),
            Predicate::Subtype(ref pred) => Some(pred.clean(cx)),
486 487
            Predicate::RegionOutlives(ref pred) => pred.clean(cx),
            Predicate::TypeOutlives(ref pred) => pred.clean(cx),
488
            Predicate::Projection(ref pred) => Some(pred.clean(cx)),
489

M
Mark Rousskov 已提交
490 491 492 493
            Predicate::WellFormed(..)
            | Predicate::ObjectSafe(..)
            | Predicate::ClosureKind(..)
            | Predicate::ConstEvaluatable(..) => panic!("not user writable"),
494 495 496 497 498
        }
    }
}

impl<'a> Clean<WherePredicate> for ty::TraitPredicate<'a> {
499
    fn clean(&self, cx: &DocContext<'_>) -> WherePredicate {
500
        WherePredicate::BoundPredicate {
501
            ty: self.trait_ref.self_ty().clean(cx),
M
Mark Rousskov 已提交
502
            bounds: vec![self.trait_ref.clean(cx)],
503 504 505 506
        }
    }
}

N
Niko Matsakis 已提交
507
impl<'tcx> Clean<WherePredicate> for ty::SubtypePredicate<'tcx> {
508
    fn clean(&self, _cx: &DocContext<'_>) -> WherePredicate {
M
Mark Rousskov 已提交
509 510 511 512
        panic!(
            "subtype predicates are an internal rustc artifact \
                and should not be seen by rustdoc"
        )
N
Niko Matsakis 已提交
513 514 515
    }
}

M
Mark Rousskov 已提交
516 517 518
impl<'tcx> Clean<Option<WherePredicate>>
    for ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>
{
519
    fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
520
        let ty::OutlivesPredicate(ref a, ref b) = *self;
521 522 523 524

        match (a, b) {
            (ty::ReEmpty, ty::ReEmpty) => {
                return None;
M
Mark Rousskov 已提交
525
            }
526 527 528 529
            _ => {}
        }

        Some(WherePredicate::RegionPredicate {
G
Guillaume Gomez 已提交
530
            lifetime: a.clean(cx).expect("failed to clean lifetime"),
M
Mark Rousskov 已提交
531
            bounds: vec![GenericBound::Outlives(b.clean(cx).expect("failed to clean bounds"))],
532
        })
533 534 535
    }
}

536
impl<'tcx> Clean<Option<WherePredicate>> for ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>> {
537
    fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
538 539
        let ty::OutlivesPredicate(ref ty, ref lt) = *self;

540 541 542 543 544 545
        match lt {
            ty::ReEmpty => return None,
            _ => {}
        }

        Some(WherePredicate::BoundPredicate {
546
            ty: ty.clean(cx),
M
Mark Rousskov 已提交
547
            bounds: vec![GenericBound::Outlives(lt.clean(cx).expect("failed to clean lifetimes"))],
548
        })
549 550 551 552
    }
}

impl<'tcx> Clean<WherePredicate> for ty::ProjectionPredicate<'tcx> {
553
    fn clean(&self, cx: &DocContext<'_>) -> WherePredicate {
M
Mark Rousskov 已提交
554
        WherePredicate::EqPredicate { lhs: self.projection_ty.clean(cx), rhs: self.ty.clean(cx) }
555 556 557 558
    }
}

impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
559
    fn clean(&self, cx: &DocContext<'_>) -> Type {
M
Matthew Jasper 已提交
560 561
        let lifted = self.lift_to_tcx(cx.tcx).unwrap();
        let trait_ = match lifted.trait_ref(cx.tcx).clean(cx) {
V
varkor 已提交
562 563
            GenericBound::TraitBound(t, _) => t.trait_,
            GenericBound::Outlives(_) => panic!("cleaning a trait got a lifetime"),
564 565
        };
        Type::QPath {
566
            name: cx.tcx.associated_item(self.item_def_id).ident.name.clean(cx),
567
            self_type: box self.self_ty().clean(cx),
M
Mark Rousskov 已提交
568
            trait_: box trait_,
569 570 571 572
        }
    }
}

573
impl Clean<GenericParamDef> for ty::GenericParamDef {
574
    fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef {
575 576 577 578
        let (name, kind) = match self.kind {
            ty::GenericParamDefKind::Lifetime => {
                (self.name.to_string(), GenericParamDefKind::Lifetime)
            }
579
            ty::GenericParamDefKind::Type { has_default, synthetic, .. } => {
M
Mark Rousskov 已提交
580 581 582 583 584 585 586 587 588 589 590
                let default =
                    if has_default { Some(cx.tcx.type_of(self.def_id).clean(cx)) } else { None };
                (
                    self.name.clean(cx),
                    GenericParamDefKind::Type {
                        did: self.def_id,
                        bounds: vec![], // These are filled in from the where-clauses.
                        default,
                        synthetic,
                    },
                )
591
            }
M
Mark Rousskov 已提交
592 593 594
            ty::GenericParamDefKind::Const { .. } => (
                self.name.clean(cx),
                GenericParamDefKind::Const {
595 596
                    did: self.def_id,
                    ty: cx.tcx.type_of(self.def_id).clean(cx),
M
Mark Rousskov 已提交
597 598
                },
            ),
599 600
        };

M
Mark Rousskov 已提交
601
        GenericParamDef { name, kind }
602 603 604
    }
}

C
Camille GILLOT 已提交
605
impl Clean<GenericParamDef> for hir::GenericParam<'_> {
606
    fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef {
607
        let (name, kind) = match self.kind {
V
varkor 已提交
608 609 610
            hir::GenericParamKind::Lifetime { .. } => {
                let name = if self.bounds.len() > 0 {
                    let mut bounds = self.bounds.iter().map(|bound| match bound {
V
varkor 已提交
611
                        hir::GenericBound::Outlives(lt) => lt,
V
varkor 已提交
612 613
                        _ => panic!(),
                    });
G
Guillaume Gomez 已提交
614
                    let name = bounds.next().expect("no more bounds").name.ident();
V
Vadim Petrochenkov 已提交
615
                    let mut s = format!("{}: {}", self.name.ident(), name);
V
varkor 已提交
616
                    for bound in bounds {
V
Vadim Petrochenkov 已提交
617
                        s.push_str(&format!(" + {}", bound.name.ident()));
618 619 620
                    }
                    s
                } else {
V
Vadim Petrochenkov 已提交
621
                    self.name.ident().to_string()
622 623 624
                };
                (name, GenericParamDefKind::Lifetime)
            }
M
Mark Rousskov 已提交
625 626 627
            hir::GenericParamKind::Type { ref default, synthetic } => (
                self.name.ident().name.clean(cx),
                GenericParamDefKind::Type {
628
                    did: cx.tcx.hir().local_def_id(self.hir_id),
V
varkor 已提交
629
                    bounds: self.bounds.clean(cx),
630
                    default: default.clean(cx),
631
                    synthetic,
M
Mark Rousskov 已提交
632 633 634 635 636
                },
            ),
            hir::GenericParamKind::Const { ref ty } => (
                self.name.ident().name.clean(cx),
                GenericParamDefKind::Const {
637
                    did: cx.tcx.hir().local_def_id(self.hir_id),
V
varkor 已提交
638
                    ty: ty.clean(cx),
M
Mark Rousskov 已提交
639 640
                },
            ),
641 642
        };

M
Mark Rousskov 已提交
643
        GenericParamDef { name, kind }
644 645 646
    }
}

C
Camille GILLOT 已提交
647
impl Clean<Generics> for hir::Generics<'_> {
648
    fn clean(&self, cx: &DocContext<'_>) -> Generics {
649 650 651
        // Synthetic type-parameters are inserted after normal ones.
        // In order for normal parameters to be able to refer to synthetic ones,
        // scans them first.
C
Camille GILLOT 已提交
652
        fn is_impl_trait(param: &hir::GenericParam<'_>) -> bool {
V
varkor 已提交
653 654 655 656 657
            match param.kind {
                hir::GenericParamKind::Type { synthetic, .. } => {
                    synthetic == Some(hir::SyntheticTyParamKind::ImplTrait)
                }
                _ => false,
658 659
            }
        }
M
Mark Rousskov 已提交
660 661
        let impl_trait_params = self
            .params
662
            .iter()
663 664 665 666 667 668
            .filter(|param| is_impl_trait(param))
            .map(|param| {
                let param: GenericParamDef = param.clean(cx);
                match param.kind {
                    GenericParamDefKind::Lifetime => unreachable!(),
                    GenericParamDefKind::Type { did, ref bounds, .. } => {
669
                        cx.impl_trait_bounds.borrow_mut().insert(did.into(), bounds.clone());
670
                    }
V
varkor 已提交
671
                    GenericParamDefKind::Const { .. } => unreachable!(),
672
                }
673
                param
674 675 676
            })
            .collect::<Vec<_>>();

677
        let mut params = Vec::with_capacity(self.params.len());
678
        for p in self.params.iter().filter(|p| !is_impl_trait(p)) {
679 680 681
            let p = p.clean(cx);
            params.push(p);
        }
682 683
        params.extend(impl_trait_params);

M
Mark Rousskov 已提交
684 685
        let mut generics =
            Generics { params, where_predicates: self.where_clause.predicates.clean(cx) };
686 687 688 689

        // Some duplicates are generated for ?Sized bounds between type params and where
        // predicates. The point in here is to move the bounds definitions from type params
        // to where predicates when such cases occur.
690
        for where_pred in &mut generics.where_predicates {
691 692 693
            match *where_pred {
                WherePredicate::BoundPredicate { ty: Generic(ref name), ref mut bounds } => {
                    if bounds.is_empty() {
694 695 696 697 698 699
                        for param in &mut generics.params {
                            match param.kind {
                                GenericParamDefKind::Lifetime => {}
                                GenericParamDefKind::Type { bounds: ref mut ty_bounds, .. } => {
                                    if &param.name == name {
                                        mem::swap(bounds, ty_bounds);
M
Mark Rousskov 已提交
700
                                        break;
701
                                    }
702
                                }
V
varkor 已提交
703
                                GenericParamDefKind::Const { .. } => {}
704 705 706 707 708 709
                            }
                        }
                    }
                }
                _ => continue,
            }
C
Corey Richardson 已提交
710
        }
711
        generics
C
Corey Richardson 已提交
712 713 714
    }
}

715
impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx>) {
716
    fn clean(&self, cx: &DocContext<'_>) -> Generics {
717
        use self::WherePredicate as WP;
718
        use std::collections::BTreeMap;
719

720
        let (gens, preds) = *self;
721

722 723
        // Don't populate `cx.impl_trait_bounds` before `clean`ning `where` clauses,
        // since `Clean for ty::Predicate` would consume them.
724
        let mut impl_trait = BTreeMap::<ImplTraitParam, Vec<GenericBound>>::default();
725

726 727 728
        // Bounds in the type_params and lifetimes fields are repeated in the
        // predicates field (see rustc_typeck::collect::ty_generics), so remove
        // them.
M
Mark Rousskov 已提交
729 730 731
        let stripped_typarams = gens
            .params
            .iter()
732 733 734
            .filter_map(|param| match param.kind {
                ty::GenericParamDefKind::Lifetime => None,
                ty::GenericParamDefKind::Type { synthetic, .. } => {
735
                    if param.name == kw::SelfUpper {
736 737 738 739 740 741 742 743
                        assert_eq!(param.index, 0);
                        return None;
                    }
                    if synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) {
                        impl_trait.insert(param.index.into(), vec![]);
                        return None;
                    }
                    Some(param.clean(cx))
V
varkor 已提交
744
                }
745
                ty::GenericParamDefKind::Const { .. } => None,
M
Mark Rousskov 已提交
746 747
            })
            .collect::<Vec<GenericParamDef>>();
748

S
Shotaro Yamada 已提交
749
        // param index -> [(DefId of trait, associated type name, type)]
M
Mark Rousskov 已提交
750
        let mut impl_trait_proj = FxHashMap::<u32, Vec<(DefId, String, Ty<'tcx>)>>::default();
751

M
Mark Rousskov 已提交
752 753 754
        let where_predicates = preds
            .predicates
            .iter()
755
            .flat_map(|(p, _)| {
S
Shotaro Yamada 已提交
756
                let mut projection = None;
757 758
                let param_idx = (|| {
                    if let Some(trait_ref) = p.to_opt_poly_trait_ref() {
V
varkor 已提交
759
                        if let ty::Param(param) = trait_ref.self_ty().kind {
760 761 762
                            return Some(param.index);
                        }
                    } else if let Some(outlives) = p.to_opt_type_outlives() {
V
varkor 已提交
763
                        if let ty::Param(param) = outlives.skip_binder().0.kind {
764 765
                            return Some(param.index);
                        }
S
Shotaro Yamada 已提交
766
                    } else if let ty::Predicate::Projection(p) = p {
V
varkor 已提交
767
                        if let ty::Param(param) = p.skip_binder().projection_ty.self_ty().kind {
S
Shotaro Yamada 已提交
768
                            projection = Some(p);
769 770
                            return Some(param.index);
                        }
771
                    }
772

773
                    None
774
                })();
775

776 777
                if let Some(param_idx) = param_idx {
                    if let Some(b) = impl_trait.get_mut(&param_idx.into()) {
778 779
                        let p = p.clean(cx)?;

780 781 782 783 784
                        b.extend(
                            p.get_bounds()
                                .into_iter()
                                .flatten()
                                .cloned()
M
Mark Rousskov 已提交
785
                                .filter(|b| !b.is_sized_bound(cx)),
786 787
                        );

S
Shotaro Yamada 已提交
788 789 790 791 792
                        let proj = projection
                            .map(|p| (p.skip_binder().projection_ty.clean(cx), p.skip_binder().ty));
                        if let Some(((_, trait_did, name), rhs)) =
                            proj.as_ref().and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs)))
                        {
M
Mark Rousskov 已提交
793 794 795 796 797
                            impl_trait_proj.entry(param_idx).or_default().push((
                                trait_did,
                                name.to_string(),
                                rhs,
                            ));
798 799 800 801
                        }

                        return None;
                    }
802 803 804 805
                }

                Some(p)
            })
806
            .collect::<Vec<_>>();
807

808 809
        for (param, mut bounds) in impl_trait {
            // Move trait bounds to the front.
M
Mark Rousskov 已提交
810
            bounds.sort_by_key(|b| if let GenericBound::TraitBound(..) = b { false } else { true });
811

S
Shotaro Yamada 已提交
812 813 814
            if let crate::core::ImplTraitParam::ParamIndex(idx) = param {
                if let Some(proj) = impl_trait_proj.remove(&idx) {
                    for (trait_did, name, rhs) in proj {
M
Mark Rousskov 已提交
815
                        simplify::merge_bounds(cx, &mut bounds, trait_did, &name, &rhs.clean(cx));
S
Shotaro Yamada 已提交
816 817 818 819 820 821 822 823
                    }
                }
            } else {
                unreachable!();
            }

            cx.impl_trait_bounds.borrow_mut().insert(param, bounds);
        }
824

825 826
        // Now that `cx.impl_trait_bounds` is populated, we can process
        // remaining predicates which could contain `impl Trait`.
M
Mark Rousskov 已提交
827 828
        let mut where_predicates =
            where_predicates.into_iter().flat_map(|p| p.clean(cx)).collect::<Vec<_>>();
829

830
        // Type parameters and have a Sized bound by default unless removed with
831
        // ?Sized. Scan through the predicates and mark any type parameter with
832
        // a Sized bound, removing the bounds as we find them.
833 834
        //
        // Note that associated types also have a sized bound by default, but we
835
        // don't actually know the set of associated types right here so that's
836
        // handled in cleaning associated types
837
        let mut sized_params = FxHashSet::default();
M
Mark Rousskov 已提交
838 839 840 841 842 843 844
        where_predicates.retain(|pred| match *pred {
            WP::BoundPredicate { ty: Generic(ref g), ref bounds } => {
                if bounds.iter().any(|b| b.is_sized_bound(cx)) {
                    sized_params.insert(g.clone());
                    false
                } else {
                    true
845 846
                }
            }
M
Mark Rousskov 已提交
847
            _ => true,
848
        });
849

850
        // Run through the type parameters again and insert a ?Sized
851
        // unbound for any we didn't find to be Sized.
852
        for tp in &stripped_typarams {
853 854 855
            if !sized_params.contains(&tp.name) {
                where_predicates.push(WP::BoundPredicate {
                    ty: Type::Generic(tp.name.clone()),
V
varkor 已提交
856
                    bounds: vec![GenericBound::maybe_sized(cx)],
857 858 859 860 861
                })
            }
        }

        // It would be nice to collect all of the bounds on a type and recombine
862
        // them if possible, to avoid e.g., `where T: Foo, T: Bar, T: Sized, T: 'a`
863 864
        // and instead see `where T: Foo + Bar + Sized + 'a`

865
        Generics {
M
Mark Rousskov 已提交
866 867 868 869 870 871 872 873 874 875
            params: gens
                .params
                .iter()
                .flat_map(|param| match param.kind {
                    ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)),
                    ty::GenericParamDefKind::Type { .. } => None,
                    ty::GenericParamDefKind::Const { .. } => Some(param.clean(cx)),
                })
                .chain(simplify::ty_params(stripped_typarams).into_iter())
                .collect(),
876
            where_predicates: simplify::where_clauses(cx, where_predicates),
877 878 879 880
        }
    }
}

M
Mark Rousskov 已提交
881
impl<'a> Clean<Method>
C
Camille GILLOT 已提交
882
    for (&'a hir::FnSig<'a>, &'a hir::Generics<'a>, hir::BodyId, Option<hir::Defaultness>)
M
Mark Rousskov 已提交
883
{
884
    fn clean(&self, cx: &DocContext<'_>) -> Method {
M
Mark Rousskov 已提交
885 886
        let (generics, decl) =
            enter_impl_trait(cx, || (self.1.clean(cx), (&*self.0.decl, self.2).clean(cx)));
887
        let (all_types, ret_types) = get_all_types(&generics, &decl, cx);
M
Mark Rousskov 已提交
888
        Method { decl, generics, header: self.0.header, defaultness: self.3, all_types, ret_types }
C
Corey Richardson 已提交
889 890 891
    }
}

892
impl Clean<Item> for doctree::Function<'_> {
893
    fn clean(&self, cx: &DocContext<'_>) -> Item {
M
Mark Rousskov 已提交
894 895
        let (generics, decl) =
            enter_impl_trait(cx, || (self.generics.clean(cx), (self.decl, self.body).clean(cx)));
G
Guillaume Gomez 已提交
896

897
        let did = cx.tcx.hir().local_def_id(self.id);
G
Guillaume Gomez 已提交
898 899 900 901 902
        let constness = if cx.tcx.is_min_const_fn(did) {
            hir::Constness::Const
        } else {
            hir::Constness::NotConst
        };
903
        let (all_types, ret_types) = get_all_types(&generics, &decl, cx);
C
Corey Richardson 已提交
904
        Item {
905 906 907 908
            name: Some(self.name.clean(cx)),
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
            visibility: self.vis.clean(cx),
909
            stability: cx.stability(self.id).clean(cx),
910
            deprecation: cx.deprecation(self.id).clean(cx),
G
Guillaume Gomez 已提交
911
            def_id: did,
C
Corey Richardson 已提交
912
            inner: FunctionItem(Function {
913 914
                decl,
                generics,
G
Guillaume Gomez 已提交
915
                header: hir::FnHeader { constness, ..self.header },
916
                all_types,
917
                ret_types,
C
Corey Richardson 已提交
918 919 920 921 922
            }),
        }
    }
}

C
Camille GILLOT 已提交
923
impl<'a> Clean<Arguments> for (&'a [hir::Ty<'a>], &'a [ast::Ident]) {
924
    fn clean(&self, cx: &DocContext<'_>) -> Arguments {
925
        Arguments {
M
Mark Rousskov 已提交
926 927 928 929 930 931 932 933 934 935 936 937 938
            values: self
                .0
                .iter()
                .enumerate()
                .map(|(i, ty)| {
                    let mut name =
                        self.1.get(i).map(|ident| ident.to_string()).unwrap_or(String::new());
                    if name.is_empty() {
                        name = "_".to_string();
                    }
                    Argument { name, type_: ty.clean(cx) }
                })
                .collect(),
939 940 941 942
        }
    }
}

C
Camille GILLOT 已提交
943
impl<'a> Clean<Arguments> for (&'a [hir::Ty<'a>], hir::BodyId) {
944
    fn clean(&self, cx: &DocContext<'_>) -> Arguments {
945
        let body = cx.tcx.hir().body(self.1);
946 947

        Arguments {
M
Mark Rousskov 已提交
948 949 950 951 952
            values: self
                .0
                .iter()
                .enumerate()
                .map(|(i, ty)| Argument {
953
                    name: name_from_pat(&body.params[i].pat),
954
                    type_: ty.clean(cx),
M
Mark Rousskov 已提交
955 956
                })
                .collect(),
957 958 959 960
        }
    }
}

C
Camille GILLOT 已提交
961
impl<'a, A: Copy> Clean<FnDecl> for (&'a hir::FnDecl<'a>, A)
M
Mark Rousskov 已提交
962
where
C
Camille GILLOT 已提交
963
    (&'a [hir::Ty<'a>], A): Clean<Arguments>,
964
{
965
    fn clean(&self, cx: &DocContext<'_>) -> FnDecl {
C
Corey Richardson 已提交
966
        FnDecl {
967 968
            inputs: (&self.0.inputs[..], self.1).clean(cx),
            output: self.0.output.clean(cx),
969
            c_variadic: self.0.c_variadic,
970
            attrs: Attributes::default(),
C
Corey Richardson 已提交
971 972 973 974
        }
    }
}

975
impl<'tcx> Clean<FnDecl> for (DefId, ty::PolyFnSig<'tcx>) {
976
    fn clean(&self, cx: &DocContext<'_>) -> FnDecl {
977
        let (did, sig) = *self;
978
        let mut names = if cx.tcx.hir().as_local_hir_id(did).is_some() {
979
            vec![].into_iter()
980
        } else {
A
achernyak 已提交
981
            cx.tcx.fn_arg_names(did).into_iter()
S
Cleanup  
Shotaro Yamada 已提交
982 983
        };

984
        FnDecl {
985
            output: Return(sig.skip_binder().output().clean(cx)),
986
            attrs: Attributes::default(),
987
            c_variadic: sig.skip_binder().c_variadic,
988
            inputs: Arguments {
M
Mark Rousskov 已提交
989 990 991 992 993
                values: sig
                    .skip_binder()
                    .inputs()
                    .iter()
                    .map(|t| Argument {
994
                        type_: t.clean(cx),
995
                        name: names.next().map_or(String::new(), |name| name.to_string()),
M
Mark Rousskov 已提交
996 997
                    })
                    .collect(),
998 999 1000 1001 1002
            },
        }
    }
}

C
Camille GILLOT 已提交
1003
impl Clean<FunctionRetTy> for hir::FunctionRetTy<'_> {
1004
    fn clean(&self, cx: &DocContext<'_>) -> FunctionRetTy {
C
Corey Richardson 已提交
1005
        match *self {
1006 1007
            hir::Return(ref typ) => Return(typ.clean(cx)),
            hir::DefaultReturn(..) => DefaultReturn,
C
Corey Richardson 已提交
1008 1009 1010 1011
        }
    }
}

1012
impl Clean<Item> for doctree::Trait<'_> {
1013
    fn clean(&self, cx: &DocContext<'_>) -> Item {
1014
        let attrs = self.attrs.clean(cx);
1015
        let is_spotlight = attrs.has_doc_flag(sym::spotlight);
C
Corey Richardson 已提交
1016
        Item {
1017
            name: Some(self.name.clean(cx)),
1018
            attrs,
1019
            source: self.whence.clean(cx),
1020
            def_id: cx.tcx.hir().local_def_id(self.id),
1021
            visibility: self.vis.clean(cx),
1022
            stability: cx.stability(self.id).clean(cx),
1023
            deprecation: cx.deprecation(self.id).clean(cx),
C
Corey Richardson 已提交
1024
            inner: TraitItem(Trait {
1025
                auto: self.is_auto.clean(cx),
1026
                unsafety: self.unsafety,
1027
                items: self.items.iter().map(|ti| ti.clean(cx)).collect(),
1028 1029
                generics: self.generics.clean(cx),
                bounds: self.bounds.clean(cx),
1030
                is_spotlight,
1031
                is_auto: self.is_auto.clean(cx),
C
Corey Richardson 已提交
1032 1033 1034 1035 1036
            }),
        }
    }
}

1037
impl Clean<Item> for doctree::TraitAlias<'_> {
1038
    fn clean(&self, cx: &DocContext<'_>) -> Item {
1039 1040 1041 1042 1043
        let attrs = self.attrs.clean(cx);
        Item {
            name: Some(self.name.clean(cx)),
            attrs,
            source: self.whence.clean(cx),
1044
            def_id: cx.tcx.hir().local_def_id(self.id),
1045
            visibility: self.vis.clean(cx),
1046
            stability: cx.stability(self.id).clean(cx),
1047
            deprecation: cx.deprecation(self.id).clean(cx),
1048 1049 1050 1051 1052 1053 1054 1055
            inner: TraitAliasItem(TraitAlias {
                generics: self.generics.clean(cx),
                bounds: self.bounds.clean(cx),
            }),
        }
    }
}

1056
impl Clean<bool> for hir::IsAuto {
1057
    fn clean(&self, _: &DocContext<'_>) -> bool {
1058 1059 1060 1061 1062 1063 1064
        match *self {
            hir::IsAuto::Yes => true,
            hir::IsAuto::No => false,
        }
    }
}

C
Camille GILLOT 已提交
1065
impl Clean<Type> for hir::TraitRef<'_> {
1066
    fn clean(&self, cx: &DocContext<'_>) -> Type {
L
ljedrz 已提交
1067
        resolve_type(cx, self.path.clean(cx), self.hir_ref_id)
C
Corey Richardson 已提交
1068 1069 1070
    }
}

C
Camille GILLOT 已提交
1071
impl Clean<PolyTrait> for hir::PolyTraitRef<'_> {
1072
    fn clean(&self, cx: &DocContext<'_>) -> PolyTrait {
1073 1074
        PolyTrait {
            trait_: self.trait_ref.clean(cx),
M
Mark Rousskov 已提交
1075
            generic_params: self.bound_generic_params.clean(cx),
1076
        }
N
Niko Matsakis 已提交
1077 1078 1079
    }
}

C
Camille GILLOT 已提交
1080
impl Clean<Item> for hir::TraitItem<'_> {
1081
    fn clean(&self, cx: &DocContext<'_>) -> Item {
1082
        let inner = match self.kind {
1083
            hir::TraitItemKind::Const(ref ty, default) => {
M
Mark Rousskov 已提交
1084
                AssocConstItem(ty.clean(cx), default.map(|e| print_const_expr(cx, e)))
1085
            }
1086
            hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => {
1087
                MethodItem((sig, &self.generics, body, None).clean(cx))
1088
            }
1089
            hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref names)) => {
1090 1091 1092
                let (generics, decl) = enter_impl_trait(cx, || {
                    (self.generics.clean(cx), (&*sig.decl, &names[..]).clean(cx))
                });
1093
                let (all_types, ret_types) = get_all_types(&generics, &decl, cx);
M
Mark Rousskov 已提交
1094
                TyMethodItem(TyMethod { header: sig.header, decl, generics, all_types, ret_types })
1095
            }
1096
            hir::TraitItemKind::Type(ref bounds, ref default) => {
A
Andrew Xu 已提交
1097
                AssocTypeItem(bounds.clean(cx), default.clean(cx))
1098 1099
            }
        };
1100
        let local_did = cx.tcx.hir().local_def_id(self.hir_id);
1101
        Item {
1102
            name: Some(self.ident.name.clean(cx)),
1103 1104
            attrs: self.attrs.clean(cx),
            source: self.span.clean(cx),
L
ljedrz 已提交
1105
            def_id: local_did,
M
Mark Rousskov 已提交
1106
            visibility: Visibility::Inherited,
L
ljedrz 已提交
1107 1108
            stability: get_stability(cx, local_did),
            deprecation: get_deprecation(cx, local_did),
1109
            inner,
1110 1111 1112 1113
        }
    }
}

C
Camille GILLOT 已提交
1114
impl Clean<Item> for hir::ImplItem<'_> {
1115
    fn clean(&self, cx: &DocContext<'_>) -> Item {
1116
        let inner = match self.kind {
1117
            hir::ImplItemKind::Const(ref ty, expr) => {
M
Mark Rousskov 已提交
1118
                AssocConstItem(ty.clean(cx), Some(print_const_expr(cx, expr)))
1119
            }
1120
            hir::ImplItemKind::Method(ref sig, body) => {
1121
                MethodItem((sig, &self.generics, body, Some(self.defaultness)).clean(cx))
1122
            }
M
Mark Rousskov 已提交
1123 1124 1125 1126 1127 1128 1129
            hir::ImplItemKind::TyAlias(ref ty) => {
                TypedefItem(Typedef { type_: ty.clean(cx), generics: Generics::default() }, true)
            }
            hir::ImplItemKind::OpaqueTy(ref bounds) => OpaqueTyItem(
                OpaqueTy { bounds: bounds.clean(cx), generics: Generics::default() },
                true,
            ),
1130
        };
1131
        let local_did = cx.tcx.hir().local_def_id(self.hir_id);
1132
        Item {
1133
            name: Some(self.ident.name.clean(cx)),
1134 1135
            source: self.span.clean(cx),
            attrs: self.attrs.clean(cx),
L
ljedrz 已提交
1136
            def_id: local_did,
1137
            visibility: self.vis.clean(cx),
L
ljedrz 已提交
1138 1139
            stability: get_stability(cx, local_did),
            deprecation: get_deprecation(cx, local_did),
1140
            inner,
C
Corey Richardson 已提交
1141 1142 1143 1144
        }
    }
}

1145
impl Clean<Item> for ty::AssocItem {
1146
    fn clean(&self, cx: &DocContext<'_>) -> Item {
1147
        let inner = match self.kind {
A
Andrew Xu 已提交
1148
            ty::AssocKind::Const => {
1149
                let ty = cx.tcx.type_of(self.def_id);
1150 1151 1152 1153 1154
                let default = if self.defaultness.has_value() {
                    Some(inline::print_inlined_const(cx, self.def_id))
                } else {
                    None
                };
A
Andrew Xu 已提交
1155
                AssocConstItem(ty.clean(cx), default)
1156
            }
A
Andrew Xu 已提交
1157
            ty::AssocKind::Method => {
M
Mark Rousskov 已提交
1158 1159 1160
                let generics =
                    (cx.tcx.generics_of(self.def_id), cx.tcx.explicit_predicates_of(self.def_id))
                        .clean(cx);
1161
                let sig = cx.tcx.fn_sig(self.def_id);
1162
                let mut decl = (self.def_id, sig).clean(cx);
1163 1164 1165

                if self.method_has_self_argument {
                    let self_ty = match self.container {
M
Mark Rousskov 已提交
1166
                        ty::ImplContainer(def_id) => cx.tcx.type_of(def_id),
1167
                        ty::TraitContainer(_) => cx.tcx.types.self_param,
1168
                    };
1169
                    let self_arg_ty = *sig.input(0).skip_binder();
1170
                    if self_arg_ty == self_ty {
1171
                        decl.inputs.values[0].type_ = Generic(String::from("Self"));
V
varkor 已提交
1172
                    } else if let ty::Ref(_, ty, _) = self_arg_ty.kind {
1173
                        if ty == self_ty {
1174
                            match decl.inputs.values[0].type_ {
M
Mark Rousskov 已提交
1175
                                BorrowedRef { ref mut type_, .. } => {
1176 1177
                                    **type_ = Generic(String::from("Self"))
                                }
1178 1179 1180 1181 1182
                                _ => unreachable!(),
                            }
                        }
                    }
                }
1183

1184
                let provided = match self.container {
1185
                    ty::ImplContainer(_) => true,
M
Mark Rousskov 已提交
1186
                    ty::TraitContainer(_) => self.defaultness.has_value(),
1187
                };
1188
                let (all_types, ret_types) = get_all_types(&generics, &decl, cx);
1189
                if provided {
1190
                    let constness = if cx.tcx.is_min_const_fn(self.def_id) {
1191 1192 1193 1194
                        hir::Constness::Const
                    } else {
                        hir::Constness::NotConst
                    };
C
csmoe 已提交
1195
                    let asyncness = cx.tcx.asyncness(self.def_id);
1196 1197 1198 1199
                    let defaultness = match self.container {
                        ty::ImplContainer(_) => Some(self.defaultness),
                        ty::TraitContainer(_) => None,
                    };
1200
                    MethodItem(Method {
1201 1202
                        generics,
                        decl,
W
Without Boats 已提交
1203 1204 1205 1206
                        header: hir::FnHeader {
                            unsafety: sig.unsafety(),
                            abi: sig.abi(),
                            constness,
C
csmoe 已提交
1207
                            asyncness,
1208
                        },
1209
                        defaultness,
1210
                        all_types,
1211
                        ret_types,
1212 1213 1214
                    })
                } else {
                    TyMethodItem(TyMethod {
1215 1216
                        generics,
                        decl,
W
Without Boats 已提交
1217 1218 1219
                        header: hir::FnHeader {
                            unsafety: sig.unsafety(),
                            abi: sig.abi(),
1220 1221
                            constness: hir::Constness::NotConst,
                            asyncness: hir::IsAsync::NotAsync,
1222 1223
                        },
                        all_types,
1224
                        ret_types,
1225
                    })
1226 1227
                }
            }
A
Andrew Xu 已提交
1228
            ty::AssocKind::Type => {
1229
                let my_name = self.ident.name.clean(cx);
1230

1231
                if let ty::TraitContainer(did) = self.container {
1232 1233 1234 1235
                    // When loading a cross-crate associated type, the bounds for this type
                    // are actually located on the trait/impl itself, so we need to load
                    // all of the generics from there and then look for bounds that are
                    // applied to this associated type in question.
1236
                    let predicates = cx.tcx.explicit_predicates_of(did);
1237
                    let generics = (cx.tcx.generics_of(did), predicates).clean(cx);
M
Mark Rousskov 已提交
1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263
                    let mut bounds = generics
                        .where_predicates
                        .iter()
                        .filter_map(|pred| {
                            let (name, self_type, trait_, bounds) = match *pred {
                                WherePredicate::BoundPredicate {
                                    ty: QPath { ref name, ref self_type, ref trait_ },
                                    ref bounds,
                                } => (name, self_type, trait_, bounds),
                                _ => return None,
                            };
                            if *name != my_name {
                                return None;
                            }
                            match **trait_ {
                                ResolvedPath { did, .. } if did == self.container.id() => {}
                                _ => return None,
                            }
                            match **self_type {
                                Generic(ref s) if *s == "Self" => {}
                                _ => return None,
                            }
                            Some(bounds)
                        })
                        .flat_map(|i| i.iter().cloned())
                        .collect::<Vec<_>>();
1264 1265 1266 1267 1268 1269
                    // Our Sized/?Sized bound didn't get handled when creating the generics
                    // because we didn't actually get our whole set of bounds until just now
                    // (some of them may have come from the trait). If we do have a sized
                    // bound, we remove it, and if we don't then we add the `?Sized` bound
                    // at the end.
                    match bounds.iter().position(|b| b.is_sized_bound(cx)) {
M
Mark Rousskov 已提交
1270 1271 1272
                        Some(i) => {
                            bounds.remove(i);
                        }
V
varkor 已提交
1273
                        None => bounds.push(GenericBound::maybe_sized(cx)),
1274
                    }
1275

1276 1277 1278 1279 1280
                    let ty = if self.defaultness.has_value() {
                        Some(cx.tcx.type_of(self.def_id))
                    } else {
                        None
                    };
1281

A
Andrew Xu 已提交
1282
                    AssocTypeItem(bounds, ty.clean(cx))
1283
                } else {
M
Mark Rousskov 已提交
1284 1285 1286 1287
                    TypedefItem(
                        Typedef {
                            type_: cx.tcx.type_of(self.def_id).clean(cx),
                            generics: Generics { params: Vec::new(), where_predicates: Vec::new() },
1288
                        },
M
Mark Rousskov 已提交
1289 1290
                        true,
                    )
1291
                }
1292
            }
V
varkor 已提交
1293
            ty::AssocKind::OpaqueTy => unimplemented!(),
1294 1295
        };

1296 1297
        let visibility = match self.container {
            ty::ImplContainer(_) => self.vis.clean(cx),
M
Mark Rousskov 已提交
1298
            ty::TraitContainer(_) => Inherited,
1299 1300
        };

1301
        Item {
1302
            name: Some(self.ident.name.clean(cx)),
1303
            visibility,
1304
            stability: get_stability(cx, self.def_id),
1305
            deprecation: get_deprecation(cx, self.def_id),
1306
            def_id: self.def_id,
1307
            attrs: inline::load_attrs(cx, self.def_id).clean(cx),
1308
            source: cx.tcx.def_span(self.def_id).clean(cx),
1309
            inner,
1310
        }
1311 1312 1313
    }
}

C
Camille GILLOT 已提交
1314
impl Clean<Type> for hir::Ty<'_> {
1315
    fn clean(&self, cx: &DocContext<'_>) -> Type {
1316
        use rustc::hir::*;
1317

V
varkor 已提交
1318
        match self.kind {
C
csmoe 已提交
1319
            TyKind::Never => Never,
G
Guillaume Gomez 已提交
1320
            TyKind::Ptr(ref m) => RawPointer(m.mutbl, box m.ty.clean(cx)),
C
csmoe 已提交
1321
            TyKind::Rptr(ref l, ref m) => {
M
Mark Rousskov 已提交
1322 1323
                let lifetime = if l.is_elided() { None } else { Some(l.clean(cx)) };
                BorrowedRef { lifetime, mutability: m.mutbl, type_: box m.ty.clean(cx) }
1324
            }
C
csmoe 已提交
1325 1326
            TyKind::Slice(ref ty) => Slice(box ty.clean(cx)),
            TyKind::Array(ref ty, ref length) => {
1327
                let def_id = cx.tcx.hir().local_def_id(length.hir_id);
1328
                let length = match cx.tcx.const_eval_poly(def_id) {
O
Oliver Scherer 已提交
1329
                    Ok(length) => print_const(cx, length),
M
Mark Rousskov 已提交
1330 1331 1332 1333 1334
                    Err(_) => cx
                        .sess()
                        .source_map()
                        .span_to_snippet(cx.tcx.def_span(def_id))
                        .unwrap_or_else(|_| "_".to_string()),
1335
                };
1336
                Array(box ty.clean(cx), length)
M
Mark Rousskov 已提交
1337
            }
C
csmoe 已提交
1338
            TyKind::Tup(ref tys) => Tuple(tys.clean(cx)),
O
Oliver Schneider 已提交
1339
            TyKind::Def(item_id, _) => {
1340
                let item = cx.tcx.hir().expect_item(item_id.id);
V
varkor 已提交
1341
                if let hir::ItemKind::OpaqueTy(ref ty) = item.kind {
O
Oliver Schneider 已提交
1342 1343 1344 1345 1346
                    ImplTrait(ty.bounds.clean(cx))
                } else {
                    unreachable!()
                }
            }
C
csmoe 已提交
1347
            TyKind::Path(hir::QPath::Resolved(None, ref path)) => {
1348
                if let Res::Def(DefKind::TyParam, did) = path.res {
1349 1350 1351
                    if let Some(new_ty) = cx.ty_substs.borrow().get(&did).cloned() {
                        return new_ty;
                    }
1352
                    if let Some(bounds) = cx.impl_trait_bounds.borrow_mut().remove(&did.into()) {
1353 1354 1355 1356
                        return ImplTrait(bounds);
                    }
                }

1357
                let mut alias = None;
1358
                if let Res::Def(DefKind::TyAlias, def_id) = path.res {
1359
                    // Substitute private type aliases
1360
                    if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(def_id) {
1361
                        if !cx.renderinfo.borrow().access_levels.is_exported(def_id) {
V
varkor 已提交
1362
                            alias = Some(&cx.tcx.hir().expect_item(hir_id).kind);
1363
                        }
E
Eduard Burtescu 已提交
1364
                    }
1365 1366
                };

1367
                if let Some(&hir::ItemKind::TyAlias(ref ty, ref generics)) = alias {
G
Guillaume Gomez 已提交
1368
                    let provided_params = &path.segments.last().expect("segments were empty");
1369 1370
                    let mut ty_substs = FxHashMap::default();
                    let mut lt_substs = FxHashMap::default();
1371
                    let mut ct_substs = FxHashMap::default();
1372 1373
                    let generic_args = provided_params.generic_args();
                    {
V
varkor 已提交
1374
                        let mut indices: GenericParamCount = Default::default();
1375
                        for param in generics.params.iter() {
V
varkor 已提交
1376 1377
                            match param.kind {
                                hir::GenericParamKind::Lifetime { .. } => {
1378
                                    let mut j = 0;
M
Mark Rousskov 已提交
1379 1380
                                    let lifetime =
                                        generic_args.args.iter().find_map(|arg| match arg {
V
varkor 已提交
1381
                                            hir::GenericArg::Lifetime(lt) => {
1382 1383 1384 1385 1386 1387 1388
                                                if indices.lifetimes == j {
                                                    return Some(lt);
                                                }
                                                j += 1;
                                                None
                                            }
                                            _ => None,
M
Mark Rousskov 已提交
1389
                                        });
1390
                                    if let Some(lt) = lifetime.cloned() {
1391
                                        if !lt.is_elided() {
M
Mark Rousskov 已提交
1392
                                            let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
1393 1394 1395 1396 1397
                                            lt_substs.insert(lt_def_id, lt.clean(cx));
                                        }
                                    }
                                    indices.lifetimes += 1;
                                }
V
varkor 已提交
1398
                                hir::GenericParamKind::Type { ref default, .. } => {
M
Mark Rousskov 已提交
1399
                                    let ty_param_def_id = cx.tcx.hir().local_def_id(param.hir_id);
1400
                                    let mut j = 0;
M
Mark Rousskov 已提交
1401 1402
                                    let type_ =
                                        generic_args.args.iter().find_map(|arg| match arg {
V
varkor 已提交
1403
                                            hir::GenericArg::Type(ty) => {
1404 1405 1406 1407 1408 1409 1410
                                                if indices.types == j {
                                                    return Some(ty);
                                                }
                                                j += 1;
                                                None
                                            }
                                            _ => None,
M
Mark Rousskov 已提交
1411
                                        });
1412
                                    if let Some(ty) = type_ {
1413
                                        ty_substs.insert(ty_param_def_id, ty.clean(cx));
V
varkor 已提交
1414
                                    } else if let Some(default) = default.clone() {
M
Mark Rousskov 已提交
1415
                                        ty_substs.insert(ty_param_def_id, default.clean(cx));
1416
                                    }
1417
                                    indices.types += 1;
1418
                                }
V
varkor 已提交
1419
                                hir::GenericParamKind::Const { .. } => {
1420
                                    let const_param_def_id =
1421
                                        cx.tcx.hir().local_def_id(param.hir_id);
V
varkor 已提交
1422
                                    let mut j = 0;
M
Mark Rousskov 已提交
1423 1424
                                    let const_ =
                                        generic_args.args.iter().find_map(|arg| match arg {
V
varkor 已提交
1425 1426 1427 1428 1429 1430 1431 1432
                                            hir::GenericArg::Const(ct) => {
                                                if indices.consts == j {
                                                    return Some(ct);
                                                }
                                                j += 1;
                                                None
                                            }
                                            _ => None,
M
Mark Rousskov 已提交
1433
                                        });
1434
                                    if let Some(ct) = const_ {
1435
                                        ct_substs.insert(const_param_def_id, ct.clean(cx));
V
varkor 已提交
1436 1437 1438 1439
                                    }
                                    // FIXME(const_generics:defaults)
                                    indices.consts += 1;
                                }
1440
                            }
1441
                        }
1442
                    }
1443
                    return cx.enter_alias(ty_substs, lt_substs, ct_substs, || ty.clean(cx));
1444
                }
L
ljedrz 已提交
1445
                resolve_type(cx, path.clean(cx), self.hir_id)
N
Niko Matsakis 已提交
1446
            }
C
csmoe 已提交
1447
            TyKind::Path(hir::QPath::Resolved(Some(ref qself), ref p)) => {
1448 1449 1450 1451
                let segments = if p.is_global() { &p.segments[1..] } else { &p.segments };
                let trait_segments = &segments[..segments.len() - 1];
                let trait_path = self::Path {
                    global: p.is_global(),
1452
                    res: Res::Def(
1453
                        DefKind::Trait,
1454
                        cx.tcx.associated_item(p.res.def_id()).container.id(),
1455
                    ),
1456
                    segments: trait_segments.clean(cx),
1457
                };
1458
                Type::QPath {
G
Guillaume Gomez 已提交
1459
                    name: p.segments.last().expect("segments were empty").ident.name.clean(cx),
1460
                    self_type: box qself.clean(cx),
M
Mark Rousskov 已提交
1461
                    trait_: box resolve_type(cx, trait_path, self.hir_id),
1462 1463
                }
            }
C
csmoe 已提交
1464
            TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => {
1465
                let mut res = Res::Err;
1466
                let ty = hir_ty_to_ty(cx.tcx, self);
V
varkor 已提交
1467
                if let ty::Projection(proj) = ty.kind {
1468
                    res = Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id);
1469
                }
C
Camille GILLOT 已提交
1470
                let trait_path = hir::Path { span: self.span, res, segments: &[] };
1471
                Type::QPath {
1472
                    name: segment.ident.name.clean(cx),
1473
                    self_type: box qself.clean(cx),
M
Mark Rousskov 已提交
1474
                    trait_: box resolve_type(cx, trait_path.clean(cx), self.hir_id),
1475 1476
                }
            }
C
csmoe 已提交
1477
            TyKind::TraitObject(ref bounds, ref lifetime) => {
1478
                match bounds[0].clean(cx).trait_ {
V
varkor 已提交
1479
                    ResolvedPath { path, param_names: None, did, is_generic } => {
M
Mark Rousskov 已提交
1480 1481 1482 1483 1484 1485 1486 1487 1488
                        let mut bounds: Vec<self::GenericBound> = bounds[1..]
                            .iter()
                            .map(|bound| {
                                self::GenericBound::TraitBound(
                                    bound.clean(cx),
                                    hir::TraitBoundModifier::None,
                                )
                            })
                            .collect();
1489
                        if !lifetime.is_elided() {
V
varkor 已提交
1490
                            bounds.push(self::GenericBound::Outlives(lifetime.clean(cx)));
1491
                        }
M
Mark Rousskov 已提交
1492
                        ResolvedPath { path, param_names: Some(bounds), did, is_generic }
N
Niko Matsakis 已提交
1493
                    }
1494
                    _ => Infer, // shouldn't happen
N
Niko Matsakis 已提交
1495
                }
1496
            }
C
csmoe 已提交
1497 1498
            TyKind::BareFn(ref barefn) => BareFunction(box barefn.clean(cx)),
            TyKind::Infer | TyKind::Err => Infer,
V
varkor 已提交
1499
            TyKind::Typeof(..) => panic!("unimplemented type {:?}", self.kind),
1500
        }
C
Corey Richardson 已提交
1501 1502 1503
    }
}

D
Douglas Campos 已提交
1504
impl<'tcx> Clean<Type> for Ty<'tcx> {
1505
    fn clean(&self, cx: &DocContext<'_>) -> Type {
1506
        debug!("cleaning type: {:?}", self);
V
varkor 已提交
1507
        match self.kind {
V
varkor 已提交
1508
            ty::Never => Never,
1509 1510 1511 1512 1513 1514
            ty::Bool => Primitive(PrimitiveType::Bool),
            ty::Char => Primitive(PrimitiveType::Char),
            ty::Int(int_ty) => Primitive(int_ty.into()),
            ty::Uint(uint_ty) => Primitive(uint_ty.into()),
            ty::Float(float_ty) => Primitive(float_ty.into()),
            ty::Str => Primitive(PrimitiveType::Str),
V
varkor 已提交
1515 1516
            ty::Slice(ty) => Slice(box ty.clean(cx)),
            ty::Array(ty, n) => {
1517
                let mut n = cx.tcx.lift(&n).expect("array lift failed");
1518
                n = n.eval(cx.tcx, ty::ParamEnv::reveal_all());
O
Oliver Schneider 已提交
1519
                let n = print_const(cx, n);
1520 1521
                Array(box ty.clean(cx), n)
            }
G
Guillaume Gomez 已提交
1522
            ty::RawPtr(mt) => RawPointer(mt.mutbl, box mt.ty.clean(cx)),
M
Mark Rousskov 已提交
1523 1524 1525 1526
            ty::Ref(r, ty, mutbl) => {
                BorrowedRef { lifetime: r.clean(cx), mutability: mutbl, type_: box ty.clean(cx) }
            }
            ty::FnDef(..) | ty::FnPtr(_) => {
V
varkor 已提交
1527
                let ty = cx.tcx.lift(self).expect("FnPtr lift failed");
1528
                let sig = ty.fn_sig(cx.tcx);
1529
                let local_def_id = cx.tcx.hir().local_def_id_from_node_id(ast::CRATE_NODE_ID);
1530 1531
                BareFunction(box BareFunctionDecl {
                    unsafety: sig.unsafety(),
1532
                    generic_params: Vec::new(),
1533
                    decl: (local_def_id, sig).clean(cx),
1534 1535 1536
                    abi: sig.abi(),
                })
            }
V
varkor 已提交
1537
            ty::Adt(def, substs) => {
1538
                let did = def.did;
1539
                let kind = match def.adt_kind() {
1540 1541 1542
                    AdtKind::Struct => TypeKind::Struct,
                    AdtKind::Union => TypeKind::Union,
                    AdtKind::Enum => TypeKind::Enum,
1543
                };
M
mitaa 已提交
1544
                inline::record_extern_fqn(cx, did, kind);
1545
                let path = external_path(cx, cx.tcx.item_name(did), None, false, vec![], substs);
M
Mark Rousskov 已提交
1546
                ResolvedPath { path, param_names: None, did, is_generic: false }
1547
            }
V
varkor 已提交
1548
            ty::Foreign(did) => {
P
Paul Lietar 已提交
1549
                inline::record_extern_fqn(cx, did, TypeKind::Foreign);
M
Mark Rousskov 已提交
1550 1551 1552 1553 1554 1555 1556 1557 1558
                let path = external_path(
                    cx,
                    cx.tcx.item_name(did),
                    None,
                    false,
                    vec![],
                    InternalSubsts::empty(),
                );
                ResolvedPath { path, param_names: None, did, is_generic: false }
P
Paul Lietar 已提交
1559
            }
V
varkor 已提交
1560
            ty::Dynamic(ref obj, ref reg) => {
A
Ariel Ben-Yehuda 已提交
1561 1562 1563 1564
                // HACK: pick the first `did` as the `did` of the trait object. Someone
                // might want to implement "native" support for marker-trait-only
                // trait objects.
                let mut dids = obj.principal_def_id().into_iter().chain(obj.auto_traits());
M
Mark Rousskov 已提交
1565 1566 1567
                let did = dids
                    .next()
                    .unwrap_or_else(|| panic!("found trait object `{:?}` with no traits?", self));
A
Ariel Ben-Yehuda 已提交
1568 1569 1570
                let substs = match obj.principal() {
                    Some(principal) => principal.skip_binder().substs,
                    // marker traits have no substs.
M
Mark Rousskov 已提交
1571
                    _ => cx.tcx.intern_substs(&[]),
A
Ariel Ben-Yehuda 已提交
1572 1573
                };

1574 1575
                inline::record_extern_fqn(cx, did, TypeKind::Trait);

V
varkor 已提交
1576 1577
                let mut param_names = vec![];
                reg.clean(cx).map(|b| param_names.push(GenericBound::Outlives(b)));
A
Ariel Ben-Yehuda 已提交
1578
                for did in dids {
1579
                    let empty = cx.tcx.intern_substs(&[]);
M
Mark Rousskov 已提交
1580 1581
                    let path =
                        external_path(cx, cx.tcx.item_name(did), Some(did), false, vec![], empty);
1582
                    inline::record_extern_fqn(cx, did, TypeKind::Trait);
M
Mark Rousskov 已提交
1583 1584 1585 1586 1587 1588 1589 1590 1591
                    let bound = GenericBound::TraitBound(
                        PolyTrait {
                            trait_: ResolvedPath {
                                path,
                                param_names: None,
                                did,
                                is_generic: false,
                            },
                            generic_params: Vec::new(),
1592
                        },
M
Mark Rousskov 已提交
1593 1594
                        hir::TraitBoundModifier::None,
                    );
V
varkor 已提交
1595
                    param_names.push(bound);
1596
                }
1597

1598 1599 1600 1601
                let mut bindings = vec![];
                for pb in obj.projection_bounds() {
                    bindings.push(TypeBinding {
                        name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx),
M
Mark Rousskov 已提交
1602
                        kind: TypeBindingKind::Equality { ty: pb.skip_binder().ty.clean(cx) },
1603 1604
                    });
                }
1605

M
Mark Rousskov 已提交
1606 1607 1608
                let path =
                    external_path(cx, cx.tcx.item_name(did), Some(did), false, bindings, substs);
                ResolvedPath { path, param_names: Some(param_names), did, is_generic: false }
1609
            }
V
varkor 已提交
1610 1611 1612
            ty::Tuple(ref t) => {
                Tuple(t.iter().map(|t| t.expect_ty()).collect::<Vec<_>>().clean(cx))
            }
1613

V
varkor 已提交
1614
            ty::Projection(ref data) => data.clean(cx),
1615

1616 1617 1618 1619 1620 1621 1622
            ty::Param(ref p) => {
                if let Some(bounds) = cx.impl_trait_bounds.borrow_mut().remove(&p.index.into()) {
                    ImplTrait(bounds)
                } else {
                    Generic(p.name.to_string())
                }
            }
1623

1624
            ty::Opaque(def_id, substs) => {
1625 1626
                // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
                // by looking up the projections associated with the def_id.
1627
                let predicates_of = cx.tcx.explicit_predicates_of(def_id);
1628
                let substs = cx.tcx.lift(&substs).expect("Opaque lift failed");
1629
                let bounds = predicates_of.instantiate(cx.tcx, substs);
1630 1631
                let mut regions = vec![];
                let mut has_sized = false;
M
Mark Rousskov 已提交
1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643
                let mut bounds = bounds
                    .predicates
                    .iter()
                    .filter_map(|predicate| {
                        let trait_ref = if let Some(tr) = predicate.to_opt_poly_trait_ref() {
                            tr
                        } else if let ty::Predicate::TypeOutlives(pred) = *predicate {
                            // these should turn up at the end
                            pred.skip_binder()
                                .1
                                .clean(cx)
                                .map(|r| regions.push(GenericBound::Outlives(r)));
1644
                            return None;
M
Mark Rousskov 已提交
1645 1646 1647
                        } else {
                            return None;
                        };
1648

M
Mark Rousskov 已提交
1649 1650 1651 1652
                        if let Some(sized) = cx.tcx.lang_items().sized_trait() {
                            if trait_ref.def_id() == sized {
                                has_sized = true;
                                return None;
1653 1654 1655
                            }
                        }

M
Mark Rousskov 已提交
1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687
                        let bounds = bounds
                            .predicates
                            .iter()
                            .filter_map(|pred| {
                                if let ty::Predicate::Projection(proj) = *pred {
                                    let proj = proj.skip_binder();
                                    if proj.projection_ty.trait_ref(cx.tcx)
                                        == *trait_ref.skip_binder()
                                    {
                                        Some(TypeBinding {
                                            name: cx
                                                .tcx
                                                .associated_item(proj.projection_ty.item_def_id)
                                                .ident
                                                .name
                                                .clean(cx),
                                            kind: TypeBindingKind::Equality {
                                                ty: proj.ty.clean(cx),
                                            },
                                        })
                                    } else {
                                        None
                                    }
                                } else {
                                    None
                                }
                            })
                            .collect();

                        Some((trait_ref.skip_binder(), bounds).clean(cx))
                    })
                    .collect::<Vec<_>>();
1688 1689
                bounds.extend(regions);
                if !has_sized && !bounds.is_empty() {
V
varkor 已提交
1690
                    bounds.insert(0, GenericBound::maybe_sized(cx));
1691 1692
                }
                ImplTrait(bounds)
1693 1694
            }

V
varkor 已提交
1695
            ty::Closure(..) | ty::Generator(..) => Tuple(vec![]), // FIXME(pcwalton)
1696

S
scalexm 已提交
1697
            ty::Bound(..) => panic!("Bound"),
S
scalexm 已提交
1698
            ty::Placeholder(..) => panic!("Placeholder"),
1699
            ty::UnnormalizedProjection(..) => panic!("UnnormalizedProjection"),
V
varkor 已提交
1700 1701 1702
            ty::GeneratorWitness(..) => panic!("GeneratorWitness"),
            ty::Infer(..) => panic!("Infer"),
            ty::Error => panic!("Error"),
1703 1704 1705 1706
        }
    }
}

V
varkor 已提交
1707 1708
impl<'tcx> Clean<Constant> for ty::Const<'tcx> {
    fn clean(&self, cx: &DocContext<'_>) -> Constant {
1709 1710 1711 1712 1713 1714
        Constant {
            type_: self.ty.clean(cx),
            expr: format!("{}", self),
            value: None,
            is_literal: false,
        }
V
varkor 已提交
1715 1716 1717
    }
}

1718
impl Clean<Item> for hir::StructField<'_> {
1719
    fn clean(&self, cx: &DocContext<'_>) -> Item {
1720
        let local_did = cx.tcx.hir().local_def_id(self.hir_id);
L
ljedrz 已提交
1721

C
Corey Richardson 已提交
1722
        Item {
1723
            name: Some(self.ident.name).clean(cx),
1724
            attrs: self.attrs.clean(cx),
1725
            source: self.span.clean(cx),
1726
            visibility: self.vis.clean(cx),
L
ljedrz 已提交
1727 1728 1729
            stability: get_stability(cx, local_did),
            deprecation: get_deprecation(cx, local_did),
            def_id: local_did,
1730
            inner: StructFieldItem(self.ty.clean(cx)),
C
Corey Richardson 已提交
1731 1732 1733 1734
        }
    }
}

1735
impl Clean<Item> for ty::FieldDef {
1736
    fn clean(&self, cx: &DocContext<'_>) -> Item {
1737
        Item {
1738
            name: Some(self.ident.name).clean(cx),
1739
            attrs: cx.tcx.get_attrs(self.did).clean(cx),
1740
            source: cx.tcx.def_span(self.did).clean(cx),
1741
            visibility: self.vis.clean(cx),
1742
            stability: get_stability(cx, self.did),
1743
            deprecation: get_deprecation(cx, self.did),
1744
            def_id: self.did,
1745
            inner: StructFieldItem(cx.tcx.type_of(self.did).clean(cx)),
1746 1747 1748 1749
        }
    }
}

C
Camille GILLOT 已提交
1750
impl Clean<Visibility> for hir::Visibility<'_> {
M
Mark Rousskov 已提交
1751 1752
    fn clean(&self, cx: &DocContext<'_>) -> Visibility {
        match self.node {
1753 1754 1755 1756
            hir::VisibilityKind::Public => Visibility::Public,
            hir::VisibilityKind::Inherited => Visibility::Inherited,
            hir::VisibilityKind::Crate(_) => Visibility::Crate,
            hir::VisibilityKind::Restricted { ref path, .. } => {
1757
                let path = path.clean(cx);
1758
                let did = register_res(cx, path.res);
1759 1760
                Visibility::Restricted(did, path)
            }
M
Mark Rousskov 已提交
1761
        }
1762 1763 1764
    }
}

M
Mark Rousskov 已提交
1765 1766 1767
impl Clean<Visibility> for ty::Visibility {
    fn clean(&self, _: &DocContext<'_>) -> Visibility {
        if *self == ty::Visibility::Public { Public } else { Inherited }
C
Corey Richardson 已提交
1768 1769 1770
    }
}

1771
impl Clean<Item> for doctree::Struct<'_> {
1772
    fn clean(&self, cx: &DocContext<'_>) -> Item {
1773 1774
        Item {
            name: Some(self.name.clean(cx)),
1775 1776
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
1777
            def_id: cx.tcx.hir().local_def_id(self.id),
1778
            visibility: self.vis.clean(cx),
1779
            stability: cx.stability(self.id).clean(cx),
1780
            deprecation: cx.deprecation(self.id).clean(cx),
C
Corey Richardson 已提交
1781 1782
            inner: StructItem(Struct {
                struct_type: self.struct_type,
1783 1784
                generics: self.generics.clean(cx),
                fields: self.fields.clean(cx),
S
Steven Fackler 已提交
1785
                fields_stripped: false,
C
Corey Richardson 已提交
1786
            }),
1787
        }
C
Corey Richardson 已提交
1788 1789 1790
    }
}

1791
impl Clean<Item> for doctree::Union<'_> {
1792
    fn clean(&self, cx: &DocContext<'_>) -> Item {
1793 1794
        Item {
            name: Some(self.name.clean(cx)),
V
Vadim Petrochenkov 已提交
1795 1796
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
1797
            def_id: cx.tcx.hir().local_def_id(self.id),
V
Vadim Petrochenkov 已提交
1798
            visibility: self.vis.clean(cx),
1799
            stability: cx.stability(self.id).clean(cx),
1800
            deprecation: cx.deprecation(self.id).clean(cx),
V
Vadim Petrochenkov 已提交
1801 1802 1803 1804 1805 1806
            inner: UnionItem(Union {
                struct_type: self.struct_type,
                generics: self.generics.clean(cx),
                fields: self.fields.clean(cx),
                fields_stripped: false,
            }),
1807
        }
V
Vadim Petrochenkov 已提交
1808 1809 1810
    }
}

C
Camille GILLOT 已提交
1811
impl Clean<VariantStruct> for ::rustc::hir::VariantData<'_> {
1812
    fn clean(&self, cx: &DocContext<'_>) -> VariantStruct {
C
Corey Richardson 已提交
1813 1814
        VariantStruct {
            struct_type: doctree::struct_type_from_def(self),
1815
            fields: self.fields().iter().map(|x| x.clean(cx)).collect(),
S
Steven Fackler 已提交
1816
            fields_stripped: false,
C
Corey Richardson 已提交
1817 1818 1819 1820
        }
    }
}

1821
impl Clean<Item> for doctree::Enum<'_> {
1822
    fn clean(&self, cx: &DocContext<'_>) -> Item {
1823 1824
        Item {
            name: Some(self.name.clean(cx)),
1825 1826
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
1827
            def_id: cx.tcx.hir().local_def_id(self.id),
1828
            visibility: self.vis.clean(cx),
1829
            stability: cx.stability(self.id).clean(cx),
1830
            deprecation: cx.deprecation(self.id).clean(cx),
C
Corey Richardson 已提交
1831
            inner: EnumItem(Enum {
1832
                variants: self.variants.iter().map(|v| v.clean(cx)).collect(),
1833
                generics: self.generics.clean(cx),
S
Steven Fackler 已提交
1834
                variants_stripped: false,
C
Corey Richardson 已提交
1835
            }),
1836
        }
C
Corey Richardson 已提交
1837 1838 1839
    }
}

1840
impl Clean<Item> for doctree::Variant<'_> {
1841
    fn clean(&self, cx: &DocContext<'_>) -> Item {
C
Corey Richardson 已提交
1842
        Item {
1843 1844 1845
            name: Some(self.name.clean(cx)),
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
M
Mark Rousskov 已提交
1846
            visibility: Inherited,
1847
            stability: cx.stability(self.id).clean(cx),
1848
            deprecation: cx.deprecation(self.id).clean(cx),
1849
            def_id: cx.tcx.hir().local_def_id(self.id),
M
Mark Rousskov 已提交
1850
            inner: VariantItem(Variant { kind: self.def.clean(cx) }),
C
Corey Richardson 已提交
1851 1852 1853 1854
        }
    }
}

1855
impl Clean<Item> for ty::VariantDef {
1856
    fn clean(&self, cx: &DocContext<'_>) -> Item {
1857 1858
        let kind = match self.ctor_kind {
            CtorKind::Const => VariantKind::CLike,
M
Mark Rousskov 已提交
1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879
            CtorKind::Fn => VariantKind::Tuple(
                self.fields.iter().map(|f| cx.tcx.type_of(f.did).clean(cx)).collect(),
            ),
            CtorKind::Fictive => VariantKind::Struct(VariantStruct {
                struct_type: doctree::Plain,
                fields_stripped: false,
                fields: self
                    .fields
                    .iter()
                    .map(|field| Item {
                        source: cx.tcx.def_span(field.did).clean(cx),
                        name: Some(field.ident.name.clean(cx)),
                        attrs: cx.tcx.get_attrs(field.did).clean(cx),
                        visibility: field.vis.clean(cx),
                        def_id: field.did,
                        stability: get_stability(cx, field.did),
                        deprecation: get_deprecation(cx, field.did),
                        inner: StructFieldItem(cx.tcx.type_of(field.did).clean(cx)),
                    })
                    .collect(),
            }),
1880 1881
        };
        Item {
1882
            name: Some(self.ident.clean(cx)),
1883
            attrs: inline::load_attrs(cx, self.def_id).clean(cx),
1884
            source: cx.tcx.def_span(self.def_id).clean(cx),
M
Mark Rousskov 已提交
1885
            visibility: Inherited,
1886
            def_id: self.def_id,
T
teresy 已提交
1887
            inner: VariantItem(Variant { kind }),
1888 1889
            stability: get_stability(cx, self.def_id),
            deprecation: get_deprecation(cx, self.def_id),
1890 1891 1892 1893
        }
    }
}

C
Camille GILLOT 已提交
1894
impl Clean<VariantKind> for hir::VariantData<'_> {
1895
    fn clean(&self, cx: &DocContext<'_>) -> VariantKind {
1896 1897
        match self {
            hir::VariantData::Struct(..) => VariantKind::Struct(self.clean(cx)),
M
Mark Rousskov 已提交
1898 1899 1900
            hir::VariantData::Tuple(..) => {
                VariantKind::Tuple(self.fields().iter().map(|x| x.ty.clean(cx)).collect())
            }
1901
            hir::VariantData::Unit(..) => VariantKind::CLike,
1902
        }
1903 1904 1905
    }
}

1906
impl Clean<Span> for rustc_span::Span {
1907
    fn clean(&self, cx: &DocContext<'_>) -> Span {
V
Vadim Petrochenkov 已提交
1908
        if self.is_dummy() {
1909 1910 1911
            return Span::empty();
        }

D
Donato Sciarra 已提交
1912
        let cm = cx.sess().source_map();
1913
        let filename = cm.span_to_filename(*self);
1914 1915
        let lo = cm.lookup_char_pos(self.lo());
        let hi = cm.lookup_char_pos(self.hi());
1916
        Span {
1917
            filename,
1918
            loline: lo.line,
1919
            locol: lo.col.to_usize(),
1920
            hiline: hi.line,
1921
            hicol: hi.col.to_usize(),
G
Guillaume Gomez 已提交
1922
            original: *self,
1923
        }
C
Corey Richardson 已提交
1924 1925 1926
    }
}

C
Camille GILLOT 已提交
1927
impl Clean<Path> for hir::Path<'_> {
1928
    fn clean(&self, cx: &DocContext<'_>) -> Path {
C
Corey Richardson 已提交
1929
        Path {
1930
            global: self.is_global(),
1931
            res: self.res,
1932
            segments: if self.is_global() { &self.segments[1..] } else { &self.segments }.clean(cx),
1933 1934 1935 1936
        }
    }
}

C
Camille GILLOT 已提交
1937
impl Clean<GenericArgs> for hir::GenericArgs<'_> {
1938
    fn clean(&self, cx: &DocContext<'_>) -> GenericArgs {
1939
        if self.parenthesized {
1940
            let output = self.bindings[0].ty().clean(cx);
1941
            GenericArgs::Parenthesized {
1942
                inputs: self.inputs().clean(cx),
M
Mark Rousskov 已提交
1943
                output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None },
1944
            }
1945
        } else {
1946 1947 1948 1949
            let elide_lifetimes = self.args.iter().all(|arg| match arg {
                hir::GenericArg::Lifetime(lt) => lt.is_elided(),
                _ => true,
            });
1950
            GenericArgs::AngleBracketed {
M
Mark Rousskov 已提交
1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962
                args: self
                    .args
                    .iter()
                    .filter_map(|arg| match arg {
                        hir::GenericArg::Lifetime(lt) if !elide_lifetimes => {
                            Some(GenericArg::Lifetime(lt.clean(cx)))
                        }
                        hir::GenericArg::Lifetime(_) => None,
                        hir::GenericArg::Type(ty) => Some(GenericArg::Type(ty.clean(cx))),
                        hir::GenericArg::Const(ct) => Some(GenericArg::Const(ct.clean(cx))),
                    })
                    .collect(),
1963
                bindings: self.bindings.clean(cx),
1964
            }
1965 1966 1967
        }
    }
}
1968

C
Camille GILLOT 已提交
1969
impl Clean<PathSegment> for hir::PathSegment<'_> {
1970
    fn clean(&self, cx: &DocContext<'_>) -> PathSegment {
M
Mark Rousskov 已提交
1971
        PathSegment { name: self.ident.name.clean(cx), args: self.generic_args().clean(cx) }
C
Corey Richardson 已提交
1972 1973 1974
    }
}

1975 1976
impl Clean<String> for Ident {
    #[inline]
1977
    fn clean(&self, cx: &DocContext<'_>) -> String {
1978 1979 1980 1981
        self.name.clean(cx)
    }
}

1982
impl Clean<String> for ast::Name {
1983
    #[inline]
1984
    fn clean(&self, _: &DocContext<'_>) -> String {
1985
        self.to_string()
1986 1987 1988
    }
}

1989
impl Clean<Item> for doctree::Typedef<'_> {
1990
    fn clean(&self, cx: &DocContext<'_>) -> Item {
C
Corey Richardson 已提交
1991
        Item {
1992 1993 1994
            name: Some(self.name.clean(cx)),
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
1995
            def_id: cx.tcx.hir().local_def_id(self.id),
1996
            visibility: self.vis.clean(cx),
1997
            stability: cx.stability(self.id).clean(cx),
1998
            deprecation: cx.deprecation(self.id).clean(cx),
M
Mark Rousskov 已提交
1999 2000 2001 2002
            inner: TypedefItem(
                Typedef { type_: self.ty.clean(cx), generics: self.gen.clean(cx) },
                false,
            ),
C
Corey Richardson 已提交
2003 2004 2005 2006
        }
    }
}

V
varkor 已提交
2007
impl Clean<Item> for doctree::OpaqueTy<'_> {
2008
    fn clean(&self, cx: &DocContext<'_>) -> Item {
O
Oliver Schneider 已提交
2009 2010 2011 2012
        Item {
            name: Some(self.name.clean(cx)),
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
2013
            def_id: cx.tcx.hir().local_def_id(self.id),
O
Oliver Schneider 已提交
2014
            visibility: self.vis.clean(cx),
2015
            stability: cx.stability(self.id).clean(cx),
2016
            deprecation: cx.deprecation(self.id).clean(cx),
M
Mark Rousskov 已提交
2017 2018 2019 2020 2021 2022 2023
            inner: OpaqueTyItem(
                OpaqueTy {
                    bounds: self.opaque_ty.bounds.clean(cx),
                    generics: self.opaque_ty.generics.clean(cx),
                },
                false,
            ),
O
Oliver Schneider 已提交
2024 2025 2026 2027
        }
    }
}

C
Camille GILLOT 已提交
2028
impl Clean<BareFunctionDecl> for hir::BareFnTy<'_> {
2029
    fn clean(&self, cx: &DocContext<'_>) -> BareFunctionDecl {
2030
        let (generic_params, decl) = enter_impl_trait(cx, || {
2031
            (self.generic_params.clean(cx), (&*self.decl, &self.param_names[..]).clean(cx))
2032
        });
M
Mark Rousskov 已提交
2033
        BareFunctionDecl { unsafety: self.unsafety, abi: self.abi, decl, generic_params }
C
Corey Richardson 已提交
2034 2035 2036
    }
}

2037
impl Clean<Item> for doctree::Static<'_> {
2038
    fn clean(&self, cx: &DocContext<'_>) -> Item {
2039
        debug!("cleaning static {}: {:?}", self.name.clean(cx), self);
C
Corey Richardson 已提交
2040
        Item {
2041 2042 2043
            name: Some(self.name.clean(cx)),
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
2044
            def_id: cx.tcx.hir().local_def_id(self.id),
2045
            visibility: self.vis.clean(cx),
2046
            stability: cx.stability(self.id).clean(cx),
2047
            deprecation: cx.deprecation(self.id).clean(cx),
C
Corey Richardson 已提交
2048
            inner: StaticItem(Static {
2049
                type_: self.type_.clean(cx),
G
Guillaume Gomez 已提交
2050
                mutability: self.mutability,
2051
                expr: print_const_expr(cx, self.expr),
C
Corey Richardson 已提交
2052 2053 2054 2055 2056
            }),
        }
    }
}

2057
impl Clean<Item> for doctree::Constant<'_> {
2058
    fn clean(&self, cx: &DocContext<'_>) -> Item {
2059 2060
        let def_id = cx.tcx.hir().local_def_id(self.id);

2061 2062 2063 2064
        Item {
            name: Some(self.name.clean(cx)),
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
2065
            def_id,
2066
            visibility: self.vis.clean(cx),
2067
            stability: cx.stability(self.id).clean(cx),
2068
            deprecation: cx.deprecation(self.id).clean(cx),
2069 2070
            inner: ConstantItem(Constant {
                type_: self.type_.clean(cx),
2071
                expr: print_const_expr(cx, self.expr),
2072 2073
                value: print_evaluated_const(cx, def_id),
                is_literal: is_literal_expr(cx, self.expr.hir_id),
2074 2075 2076 2077 2078
            }),
        }
    }
}

2079
impl Clean<ImplPolarity> for ty::ImplPolarity {
2080
    fn clean(&self, _: &DocContext<'_>) -> ImplPolarity {
2081
        match self {
2082 2083 2084 2085
            &ty::ImplPolarity::Positive |
            // FIXME: do we want to do something else here?
            &ty::ImplPolarity::Reservation => ImplPolarity::Positive,
            &ty::ImplPolarity::Negative => ImplPolarity::Negative,
2086 2087 2088 2089
        }
    }
}

2090
impl Clean<Vec<Item>> for doctree::Impl<'_> {
2091
    fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
2092 2093
        let mut ret = Vec::new();
        let trait_ = self.trait_.clean(cx);
2094
        let items = self.items.iter().map(|ii| ii.clean(cx)).collect::<Vec<_>>();
2095
        let def_id = cx.tcx.hir().local_def_id(self.id);
2096 2097 2098

        // If this impl block is an implementation of the Deref trait, then we
        // need to try inlining the target's inherent impl blocks as well.
2099
        if trait_.def_id() == cx.tcx.lang_items().deref_trait() {
2100
            build_deref_target_impls(cx, &items, &mut ret);
2101 2102
        }

M
Mark Rousskov 已提交
2103 2104 2105 2106 2107 2108 2109 2110 2111 2112
        let provided = trait_
            .def_id()
            .map(|did| {
                cx.tcx
                    .provided_trait_methods(did)
                    .into_iter()
                    .map(|meth| meth.ident.to_string())
                    .collect()
            })
            .unwrap_or_default();
2113

2114
        ret.push(Item {
C
Corey Richardson 已提交
2115
            name: None,
2116 2117
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
2118
            def_id,
2119
            visibility: self.vis.clean(cx),
2120
            stability: cx.stability(self.id).clean(cx),
2121
            deprecation: cx.deprecation(self.id).clean(cx),
C
Corey Richardson 已提交
2122
            inner: ImplItem(Impl {
2123
                unsafety: self.unsafety,
2124
                generics: self.generics.clean(cx),
2125
                provided_trait_methods: provided,
2126
                trait_,
2127
                for_: self.for_.clean(cx),
2128
                items,
2129
                polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)),
A
Aaron Hill 已提交
2130
                synthetic: false,
2131
                blanket_impl: None,
M
Mark Rousskov 已提交
2132
            }),
2133
        });
M
mitaa 已提交
2134
        ret
2135 2136 2137
    }
}

2138
impl Clean<Vec<Item>> for doctree::ExternCrate<'_> {
2139
    fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
M
Mark Rousskov 已提交
2140 2141 2142 2143 2144 2145 2146 2147
        let please_inline = self.vis.node.is_pub()
            && self.attrs.iter().any(|a| {
                a.check_name(sym::doc)
                    && match a.meta_item_list() {
                        Some(l) => attr::list_contains_name(&l, sym::inline),
                        None => false,
                    }
            });
D
DebugSteven 已提交
2148 2149 2150 2151

        if please_inline {
            let mut visited = FxHashSet::default();

M
Mark Rousskov 已提交
2152
            let res = Res::Def(DefKind::Mod, DefId { krate: self.cnum, index: CRATE_DEF_INDEX });
D
DebugSteven 已提交
2153

2154
            if let Some(items) = inline::try_inline(
M
Mark Rousskov 已提交
2155 2156 2157
                cx,
                res,
                self.name,
2158
                Some(rustc::ty::Attributes::Borrowed(self.attrs)),
M
Mark Rousskov 已提交
2159
                &mut visited,
2160
            ) {
D
DebugSteven 已提交
2161 2162 2163 2164 2165
                return items;
            }
        }

        vec![Item {
2166 2167 2168
            name: None,
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
M
mitaa 已提交
2169
            def_id: DefId { krate: self.cnum, index: CRATE_DEF_INDEX },
2170 2171
            visibility: self.vis.clean(cx),
            stability: None,
2172
            deprecation: None,
M
Mark Rousskov 已提交
2173
            inner: ExternCrateItem(self.name.clean(cx), self.path.clone()),
D
DebugSteven 已提交
2174
        }]
2175
    }
C
Corey Richardson 已提交
2176 2177
}

2178
impl Clean<Vec<Item>> for doctree::Import<'_> {
2179
    fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
J
Joseph Crail 已提交
2180
        // We consider inlining the documentation of `pub use` statements, but we
2181 2182
        // forcefully don't inline if this is not public or if the
        // #[doc(no_inline)] attribute is present.
2183
        // Don't inline doc(hidden) imports so they can be stripped at a later stage.
M
Mark Rousskov 已提交
2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194
        let mut denied = !self.vis.node.is_pub()
            || self.attrs.iter().any(|a| {
                a.check_name(sym::doc)
                    && match a.meta_item_list() {
                        Some(l) => {
                            attr::list_contains_name(&l, sym::no_inline)
                                || attr::list_contains_name(&l, sym::hidden)
                        }
                        None => false,
                    }
            });
2195 2196
        // Also check whether imports were asked to be inlined, in case we're trying to re-export a
        // crate in Rust 2018+
2197
        let please_inline = self.attrs.lists(sym::doc).has_word(sym::inline);
2198 2199
        let path = self.path.clean(cx);
        let inner = if self.glob {
2200
            if !denied {
2201
                let mut visited = FxHashSet::default();
2202
                if let Some(items) = inline::try_inline_glob(cx, path.res, &mut visited) {
2203 2204 2205 2206
                    return items;
                }
            }

2207
            Import::Glob(resolve_use_source(cx, path))
2208 2209
        } else {
            let name = self.name;
2210
            if !please_inline {
2211 2212
                match path.res {
                    Res::Def(DefKind::Mod, did) => {
2213 2214 2215 2216 2217
                        if !did.is_local() && did.index == CRATE_DEF_INDEX {
                            // if we're `pub use`ing an extern crate root, don't inline it unless we
                            // were specifically asked for it
                            denied = true;
                        }
2218 2219 2220 2221
                    }
                    _ => {}
                }
            }
2222
            if !denied {
2223
                let mut visited = FxHashSet::default();
2224
                if let Some(items) = inline::try_inline(
M
Mark Rousskov 已提交
2225 2226 2227
                    cx,
                    path.res,
                    name,
2228
                    Some(rustc::ty::Attributes::Borrowed(self.attrs)),
M
Mark Rousskov 已提交
2229
                    &mut visited,
2230
                ) {
2231
                    return items;
2232
                }
2233
            }
2234
            Import::Simple(name.clean(cx), resolve_use_source(cx, path))
2235
        };
G
Guillaume Gomez 已提交
2236

2237
        vec![Item {
2238 2239 2240
            name: None,
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
2241
            def_id: cx.tcx.hir().local_def_id_from_node_id(ast::CRATE_NODE_ID),
2242 2243
            visibility: self.vis.clean(cx),
            stability: None,
2244
            deprecation: None,
M
Mark Rousskov 已提交
2245
            inner: ImportItem(inner),
2246
        }]
C
Corey Richardson 已提交
2247 2248 2249
    }
}

2250
impl Clean<Item> for doctree::ForeignItem<'_> {
2251
    fn clean(&self, cx: &DocContext<'_>) -> Item {
2252
        let inner = match self.kind {
C
csmoe 已提交
2253
            hir::ForeignItemKind::Fn(ref decl, ref names, ref generics) => {
2254
                let abi = cx.tcx.hir().get_foreign_abi(self.id);
M
Mark Rousskov 已提交
2255 2256
                let (generics, decl) =
                    enter_impl_trait(cx, || (generics.clean(cx), (&**decl, &names[..]).clean(cx)));
2257
                let (all_types, ret_types) = get_all_types(&generics, &decl, cx);
2258
                ForeignFunctionItem(Function {
2259
                    decl,
2260
                    generics,
2261 2262
                    header: hir::FnHeader {
                        unsafety: hir::Unsafety::Unsafe,
2263
                        abi,
2264 2265 2266
                        constness: hir::Constness::NotConst,
                        asyncness: hir::IsAsync::NotAsync,
                    },
2267
                    all_types,
2268
                    ret_types,
2269 2270
                })
            }
M
Mark Rousskov 已提交
2271 2272 2273 2274 2275 2276
            hir::ForeignItemKind::Static(ref ty, mutbl) => ForeignStaticItem(Static {
                type_: ty.clean(cx),
                mutability: *mutbl,
                expr: String::new(),
            }),
            hir::ForeignItemKind::Type => ForeignTypeItem,
2277
        };
G
Guillaume Gomez 已提交
2278

2279
        Item {
2280
            name: Some(self.name.clean(cx)),
2281
            attrs: self.attrs.clean(cx),
2282
            source: self.whence.clean(cx),
2283
            def_id: cx.tcx.hir().local_def_id(self.id),
2284
            visibility: self.vis.clean(cx),
2285
            stability: cx.stability(self.id).clean(cx),
2286
            deprecation: cx.deprecation(self.id).clean(cx),
2287
            inner,
2288 2289 2290 2291
        }
    }
}

2292
impl Clean<Item> for doctree::Macro<'_> {
2293
    fn clean(&self, cx: &DocContext<'_>) -> Item {
2294
        let name = self.name.clean(cx);
2295
        Item {
2296
            name: Some(name.clone()),
2297 2298
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
M
Mark Rousskov 已提交
2299
            visibility: Public,
2300
            stability: cx.stability(self.hid).clean(cx),
2301
            deprecation: cx.deprecation(self.hid).clean(cx),
2302
            def_id: self.def_id,
2303
            inner: MacroItem(Macro {
M
Mark Rousskov 已提交
2304 2305 2306 2307 2308 2309 2310 2311
                source: format!(
                    "macro_rules! {} {{\n{}}}",
                    name,
                    self.matchers
                        .iter()
                        .map(|span| { format!("    {} => {{ ... }};\n", span.to_src(cx)) })
                        .collect::<String>()
                ),
2312
                imported_from: self.imported_from.clean(cx),
2313 2314 2315 2316
            }),
        }
    }
}
2317

2318
impl Clean<Item> for doctree::ProcMacro<'_> {
2319
    fn clean(&self, cx: &DocContext<'_>) -> Item {
2320 2321 2322 2323
        Item {
            name: Some(self.name.clean(cx)),
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
M
Mark Rousskov 已提交
2324
            visibility: Public,
2325
            stability: cx.stability(self.id).clean(cx),
2326
            deprecation: cx.deprecation(self.id).clean(cx),
2327
            def_id: cx.tcx.hir().local_def_id(self.id),
M
Mark Rousskov 已提交
2328
            inner: ProcMacroItem(ProcMacro { kind: self.kind, helpers: self.helpers.clean(cx) }),
2329 2330 2331 2332
        }
    }
}

2333
impl Clean<Stability> for attr::Stability {
2334
    fn clean(&self, _: &DocContext<'_>) -> Stability {
2335
        Stability {
V
Vadim Petrochenkov 已提交
2336
            level: stability::StabilityLevel::from_attr_level(&self.level),
2337
            feature: Some(self.feature.to_string()).filter(|f| !f.is_empty()),
V
Vadim Petrochenkov 已提交
2338
            since: match self.level {
M
Mark Rousskov 已提交
2339
                attr::Stable { ref since } => since.to_string(),
2340
                _ => String::new(),
V
Vadim Petrochenkov 已提交
2341
            },
M
Mark Rousskov 已提交
2342 2343 2344
            deprecation: self.rustc_depr.as_ref().map(|d| Deprecation {
                note: Some(d.reason.to_string()).filter(|r| !r.is_empty()),
                since: Some(d.since.to_string()).filter(|d| !d.is_empty()),
2345
            }),
2346
            unstable_reason: match self.level {
2347 2348
                attr::Unstable { reason: Some(ref reason), .. } => Some(reason.to_string()),
                _ => None,
V
Vadim Petrochenkov 已提交
2349 2350
            },
            issue: match self.level {
M
Mark Rousskov 已提交
2351
                attr::Unstable { issue, .. } => issue,
V
Vadim Petrochenkov 已提交
2352
                _ => None,
M
Mark Rousskov 已提交
2353
            },
2354 2355 2356 2357
        }
    }
}

2358
impl Clean<Deprecation> for attr::Deprecation {
2359
    fn clean(&self, _: &DocContext<'_>) -> Deprecation {
2360
        Deprecation {
2361 2362
            since: self.since.map(|s| s.to_string()).filter(|s| !s.is_empty()),
            note: self.note.map(|n| n.to_string()).filter(|n| !n.is_empty()),
2363 2364 2365 2366
        }
    }
}

C
Camille GILLOT 已提交
2367
impl Clean<TypeBinding> for hir::TypeBinding<'_> {
2368
    fn clean(&self, cx: &DocContext<'_>) -> TypeBinding {
M
Mark Rousskov 已提交
2369
        TypeBinding { name: self.ident.name.clean(cx), kind: self.kind.clean(cx) }
2370 2371 2372
    }
}

C
Camille GILLOT 已提交
2373
impl Clean<TypeBindingKind> for hir::TypeBindingKind<'_> {
2374 2375
    fn clean(&self, cx: &DocContext<'_>) -> TypeBindingKind {
        match *self {
M
Mark Rousskov 已提交
2376 2377 2378 2379 2380 2381
            hir::TypeBindingKind::Equality { ref ty } => {
                TypeBindingKind::Equality { ty: ty.clean(cx) }
            }
            hir::TypeBindingKind::Constraint { ref bounds } => TypeBindingKind::Constraint {
                bounds: bounds.into_iter().map(|b| b.clean(cx)).collect(),
            },
2382 2383 2384
        }
    }
}
2385 2386

enum SimpleBound {
V
varkor 已提交
2387 2388
    TraitBound(Vec<PathSegment>, Vec<SimpleBound>, Vec<GenericParamDef>, hir::TraitBoundModifier),
    Outlives(Lifetime),
2389 2390
}

V
varkor 已提交
2391 2392
impl From<GenericBound> for SimpleBound {
    fn from(bound: GenericBound) -> Self {
2393
        match bound.clone() {
V
varkor 已提交
2394 2395
            GenericBound::Outlives(l) => SimpleBound::Outlives(l),
            GenericBound::TraitBound(t, mod_) => match t.trait_ {
M
Mark Rousskov 已提交
2396 2397 2398 2399 2400 2401 2402 2403 2404
                Type::ResolvedPath { path, param_names, .. } => SimpleBound::TraitBound(
                    path.segments,
                    param_names.map_or_else(
                        || Vec::new(),
                        |v| v.iter().map(|p| SimpleBound::from(p.clone())).collect(),
                    ),
                    t.generic_params,
                    mod_,
                ),
A
Aaron Hill 已提交
2405
                _ => panic!("Unexpected bound {:?}", bound),
M
Mark Rousskov 已提交
2406
            },
2407 2408 2409
        }
    }
}