mod.rs 94.4 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
use rustc_ast::ast::{self, Ident};
13
use rustc_attr as attr;
14
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
15 16 17
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
M
Mark Rousskov 已提交
18
use rustc_index::vec::{Idx, IndexVec};
C
Camille GILLOT 已提交
19
use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
M
Mazdak Farrokhzad 已提交
20 21 22 23 24
use rustc_middle::middle::resolve_lifetime as rl;
use rustc_middle::middle::stability;
use rustc_middle::ty::fold::TypeFolder;
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::{self, AdtKind, Lift, Ty, TyCtxt};
25
use rustc_mir::const_eval::is_min_const_fn;
26 27 28
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym};
use rustc_span::{self, Pos};
M
Mark Rousskov 已提交
29
use rustc_typeck::hir_ty_to_ty;
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;
M
Mark Rousskov 已提交
35
use std::{mem, vec};
36

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

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

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

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

51
const FN_OUTPUT_NAME: &str = "Output";
K
kennytm 已提交
52

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

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

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

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

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

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

A
Ariel Ben-Yehuda 已提交
87
impl Clean<ExternalCrate> for CrateNum {
88
    fn clean(&self, cx: &DocContext<'_>) -> ExternalCrate {
89 90
        let root = DefId { krate: *self, index: CRATE_DEF_INDEX };
        let krate_span = cx.tcx.def_span(root);
D
Donato Sciarra 已提交
91
        let krate_src = cx.sess().source_map().span_to_filename(krate_span);
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109

        // 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.
110 111
        let as_primitive = |res: Res| {
            if let Res::Def(DefKind::Mod, def_id) = res {
112 113
                let attrs = cx.tcx.get_attrs(def_id).clean(cx);
                let mut prim = None;
114
                for attr in attrs.lists(sym::doc) {
115
                    if let Some(v) = attr.value_str() {
116
                        if attr.check_name(sym::primitive) {
117 118 119 120
                            prim = PrimitiveType::from_str(&v.as_str());
                            if prim.is_some() {
                                break;
                            }
121
                            // FIXME: should warn on unknown primitives?
122 123 124 125 126 127 128 129
                        }
                    }
                }
                return prim.map(|p| (def_id, p, attrs));
            }
            None
        };
        let primitives = if root.is_local() {
M
Mark Rousskov 已提交
130 131 132
            cx.tcx
                .hir()
                .krate()
133
                .item
M
Mark Rousskov 已提交
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
                .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,
152
                    }
M
Mark Rousskov 已提交
153 154
                })
                .collect()
155
        } else {
M
Mark Rousskov 已提交
156 157 158 159 160 161
            cx.tcx
                .item_children(root)
                .iter()
                .map(|item| item.res)
                .filter_map(as_primitive)
                .collect()
162 163
        };

164 165
        let as_keyword = |res: Res| {
            if let Res::Def(DefKind::Mod, def_id) = res {
G
Guillaume Gomez 已提交
166 167
                let attrs = cx.tcx.get_attrs(def_id).clean(cx);
                let mut keyword = None;
168
                for attr in attrs.lists(sym::doc) {
G
Guillaume Gomez 已提交
169
                    if let Some(v) = attr.value_str() {
170
                        if attr.check_name(sym::keyword) {
171 172 173
                            if v.is_doc_keyword() {
                                keyword = Some(v.to_string());
                                break;
G
Guillaume Gomez 已提交
174 175 176 177 178 179 180 181 182 183
                            }
                            // FIXME: should warn on unknown keywords?
                        }
                    }
                }
                return keyword.map(|p| (def_id, p, attrs));
            }
            None
        };
        let keywords = if root.is_local() {
M
Mark Rousskov 已提交
184 185 186
            cx.tcx
                .hir()
                .krate()
187
                .item
M
Mark Rousskov 已提交
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
                .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 已提交
205
                    }
M
Mark Rousskov 已提交
206 207
                })
                .collect()
G
Guillaume Gomez 已提交
208
        } else {
M
Mark Rousskov 已提交
209
            cx.tcx.item_children(root).iter().map(|item| item.res).filter_map(as_keyword).collect()
G
Guillaume Gomez 已提交
210 211
        };

212
        ExternalCrate {
213
            name: cx.tcx.crate_name(*self).to_string(),
214
            src: krate_src,
215
            attrs: cx.tcx.get_attrs(root).clean(cx),
216
            primitives,
G
Guillaume Gomez 已提交
217
            keywords,
C
Corey Richardson 已提交
218 219 220 221
        }
    }
}

222
impl Clean<Item> for doctree::Module<'_> {
223
    fn clean(&self, cx: &DocContext<'_>) -> Item {
C
Corey Richardson 已提交
224
        let name = if self.name.is_some() {
G
Guillaume Gomez 已提交
225
            self.name.expect("No name provided").clean(cx)
C
Corey Richardson 已提交
226
        } else {
227
            String::new()
C
Corey Richardson 已提交
228
        };
229

230 231 232
        // 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
233
        let attrs = self.attrs.clean(cx);
M
Manish Goregaokar 已提交
234

235
        let mut items: Vec<Item> = vec![];
D
DebugSteven 已提交
236
        items.extend(self.extern_crates.iter().flat_map(|x| x.clean(cx)));
237
        items.extend(self.imports.iter().flat_map(|x| x.clean(cx)));
238 239 240
        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)));
241
        items.extend(self.fns.iter().map(|x| x.clean(cx)));
242
        items.extend(self.foreigns.iter().map(|x| x.clean(cx)));
243 244
        items.extend(self.mods.iter().map(|x| x.clean(cx)));
        items.extend(self.typedefs.iter().map(|x| x.clean(cx)));
V
varkor 已提交
245
        items.extend(self.opaque_tys.iter().map(|x| x.clean(cx)));
246 247 248
        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)));
249
        items.extend(self.impls.iter().flat_map(|x| x.clean(cx)));
250
        items.extend(self.macros.iter().map(|x| x.clean(cx)));
251
        items.extend(self.proc_macros.iter().map(|x| x.clean(cx)));
252
        items.extend(self.trait_aliases.iter().map(|x| x.clean(cx)));
253 254 255

        // determine if we should display the inner contents or
        // the outer `mod` item for the source code.
256
        let whence = {
257 258 259
            let sm = cx.sess().source_map();
            let outer = sm.lookup_char_pos(self.where_outer.lo());
            let inner = sm.lookup_char_pos(self.where_inner.lo());
260 261 262 263
            if outer.file.start_pos == inner.file.start_pos {
                // mod foo { ... }
                self.where_outer
            } else {
D
Donato Sciarra 已提交
264
                // mod foo; (and a separate SourceFile for the contents)
265 266 267 268
                self.where_inner
            }
        };

C
Corey Richardson 已提交
269 270
        Item {
            name: Some(name),
271
            attrs,
272 273
            source: whence.clean(cx),
            visibility: self.vis.clean(cx),
274 275 276
            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 已提交
277
            inner: ModuleItem(Module { is_crate: self.is_crate, items }),
C
Corey Richardson 已提交
278 279 280 281
        }
    }
}

282
impl Clean<Attributes> for [ast::Attribute] {
283
    fn clean(&self, cx: &DocContext<'_>) -> Attributes {
284
        Attributes::from_ast(cx.sess().diagnostic(), self)
C
Corey Richardson 已提交
285 286 287
    }
}

C
Camille GILLOT 已提交
288
impl Clean<GenericBound> for hir::GenericBound<'_> {
289
    fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
C
Corey Richardson 已提交
290
        match *self {
V
varkor 已提交
291 292 293 294
            hir::GenericBound::Outlives(lt) => GenericBound::Outlives(lt.clean(cx)),
            hir::GenericBound::Trait(ref t, modifier) => {
                GenericBound::TraitBound(t.clean(cx), modifier)
            }
C
Corey Richardson 已提交
295 296 297 298
        }
    }
}

299 300 301
impl Clean<Type> for (ty::TraitRef<'_>, &[TypeBinding]) {
    fn clean(&self, cx: &DocContext<'_>) -> Type {
        let (trait_ref, bounds) = *self;
302
        inline::record_extern_fqn(cx, trait_ref.def_id, TypeKind::Trait);
M
Mark Rousskov 已提交
303 304 305 306 307
        let path = external_path(
            cx,
            cx.tcx.item_name(trait_ref.def_id),
            Some(trait_ref.def_id),
            true,
308
            bounds.to_vec(),
M
Mark Rousskov 已提交
309 310
            trait_ref.substs,
        );
311

312
        debug!("ty::TraitRef\n  subst: {:?}\n", trait_ref.substs);
313

314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
        ResolvedPath { path, param_names: None, did: trait_ref.def_id, is_generic: false }
    }
}

impl<'tcx> Clean<GenericBound> for ty::TraitRef<'tcx> {
    fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
        GenericBound::TraitBound(
            PolyTrait { trait_: (*self, &[][..]).clean(cx), generic_params: vec![] },
            hir::TraitBoundModifier::None,
        )
    }
}

impl Clean<GenericBound> for (ty::PolyTraitRef<'_>, &[TypeBinding]) {
    fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
        let (poly_trait_ref, bounds) = *self;
        let poly_trait_ref = poly_trait_ref.lift_to_tcx(cx.tcx).unwrap();

332
        // collect any late bound regions
333 334 335 336 337 338 339 340 341 342 343 344
        let late_bound_regions: Vec<_> = cx
            .tcx
            .collect_referenced_late_bound_regions(&poly_trait_ref)
            .into_iter()
            .filter_map(|br| match br {
                ty::BrNamed(_, name) => Some(GenericParamDef {
                    name: name.to_string(),
                    kind: GenericParamDefKind::Lifetime,
                }),
                _ => None,
            })
            .collect();
345

V
varkor 已提交
346
        GenericBound::TraitBound(
347
            PolyTrait {
348 349
                trait_: (*poly_trait_ref.skip_binder(), bounds).clean(cx),
                generic_params: late_bound_regions,
350
            },
M
Mark Rousskov 已提交
351
            hir::TraitBoundModifier::None,
352
        )
353 354 355
    }
}

356
impl<'tcx> Clean<GenericBound> for ty::PolyTraitRef<'tcx> {
357
    fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
358
        (*self, &[][..]).clean(cx)
359 360 361
    }
}

C
csmoe 已提交
362
impl<'tcx> Clean<Option<Vec<GenericBound>>> for InternalSubsts<'tcx> {
363
    fn clean(&self, cx: &DocContext<'_>) -> Option<Vec<GenericBound>> {
364
        let mut v = Vec::new();
V
varkor 已提交
365
        v.extend(self.regions().filter_map(|r| r.clean(cx)).map(GenericBound::Outlives));
M
Mark Rousskov 已提交
366 367 368 369 370 371 372
        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 }
373 374 375
    }
}

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

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

V
varkor 已提交
419
impl Clean<Constant> for hir::ConstArg {
420
    fn clean(&self, cx: &DocContext<'_>) -> Constant {
V
varkor 已提交
421 422 423
        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),
424 425
            value: None,
            is_literal: is_literal_expr(cx, self.value.body.hir_id),
V
varkor 已提交
426 427 428 429
        }
    }
}

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

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

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

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

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

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

477
impl<'a> Clean<Option<WherePredicate>> for ty::Predicate<'a> {
478
    fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
M
Mazdak Farrokhzad 已提交
479
        use rustc_middle::ty::Predicate;
480 481

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

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

496
impl<'a> Clean<WherePredicate> for ty::PolyTraitPredicate<'a> {
497
    fn clean(&self, cx: &DocContext<'_>) -> WherePredicate {
498
        let poly_trait_ref = self.map_bound(|pred| pred.trait_ref);
499
        WherePredicate::BoundPredicate {
500 501
            ty: poly_trait_ref.self_ty().clean(cx),
            bounds: vec![poly_trait_ref.clean(cx)],
502 503 504 505
        }
    }
}

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

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

M
Matthias Krüger 已提交
521 522
        if let (ty::ReEmpty(_), ty::ReEmpty(_)) = (a, b) {
            return None;
523 524 525
        }

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

532
impl<'tcx> Clean<Option<WherePredicate>> for ty::PolyOutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>> {
533
    fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
534
        let ty::OutlivesPredicate(ty, lt) = self.skip_binder();
535

M
Matthias Krüger 已提交
536 537
        if let ty::ReEmpty(_) = lt {
            return None;
538 539 540
        }

        Some(WherePredicate::BoundPredicate {
541
            ty: ty.clean(cx),
M
Mark Rousskov 已提交
542
            bounds: vec![GenericBound::Outlives(lt.clean(cx).expect("failed to clean lifetimes"))],
543
        })
544 545 546
    }
}

547
impl<'tcx> Clean<WherePredicate> for ty::PolyProjectionPredicate<'tcx> {
548
    fn clean(&self, cx: &DocContext<'_>) -> WherePredicate {
549 550
        let ty::ProjectionPredicate { projection_ty, ty } = *self.skip_binder();
        WherePredicate::EqPredicate { lhs: projection_ty.clean(cx), rhs: ty.clean(cx) }
551 552 553 554
    }
}

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

569
impl Clean<GenericParamDef> for ty::GenericParamDef {
570
    fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef {
571 572 573 574
        let (name, kind) = match self.kind {
            ty::GenericParamDefKind::Lifetime => {
                (self.name.to_string(), GenericParamDefKind::Lifetime)
            }
575
            ty::GenericParamDefKind::Type { has_default, synthetic, .. } => {
M
Mark Rousskov 已提交
576 577 578 579 580 581 582 583 584 585 586
                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,
                    },
                )
587
            }
M
Mark Rousskov 已提交
588 589 590
            ty::GenericParamDefKind::Const { .. } => (
                self.name.clean(cx),
                GenericParamDefKind::Const {
591 592
                    did: self.def_id,
                    ty: cx.tcx.type_of(self.def_id).clean(cx),
M
Mark Rousskov 已提交
593 594
                },
            ),
595 596
        };

M
Mark Rousskov 已提交
597
        GenericParamDef { name, kind }
598 599 600
    }
}

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

M
Mark Rousskov 已提交
639
        GenericParamDef { name, kind }
640 641 642
    }
}

C
Camille GILLOT 已提交
643
impl Clean<Generics> for hir::Generics<'_> {
644
    fn clean(&self, cx: &DocContext<'_>) -> Generics {
645 646 647
        // 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 已提交
648
        fn is_impl_trait(param: &hir::GenericParam<'_>) -> bool {
V
varkor 已提交
649 650 651 652 653
            match param.kind {
                hir::GenericParamKind::Type { synthetic, .. } => {
                    synthetic == Some(hir::SyntheticTyParamKind::ImplTrait)
                }
                _ => false,
654 655
            }
        }
M
Mark Rousskov 已提交
656 657
        let impl_trait_params = self
            .params
658
            .iter()
659 660 661 662 663 664
            .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, .. } => {
665
                        cx.impl_trait_bounds.borrow_mut().insert(did.into(), bounds.clone());
666
                    }
V
varkor 已提交
667
                    GenericParamDefKind::Const { .. } => unreachable!(),
668
                }
669
                param
670 671 672
            })
            .collect::<Vec<_>>();

673
        let mut params = Vec::with_capacity(self.params.len());
674
        for p in self.params.iter().filter(|p| !is_impl_trait(p)) {
675 676 677
            let p = p.clean(cx);
            params.push(p);
        }
678 679
        params.extend(impl_trait_params);

M
Mark Rousskov 已提交
680 681
        let mut generics =
            Generics { params, where_predicates: self.where_clause.predicates.clean(cx) };
682 683 684 685

        // 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.
686
        for where_pred in &mut generics.where_predicates {
687 688 689
            match *where_pred {
                WherePredicate::BoundPredicate { ty: Generic(ref name), ref mut bounds } => {
                    if bounds.is_empty() {
690 691 692 693 694 695
                        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 已提交
696
                                        break;
697
                                    }
698
                                }
V
varkor 已提交
699
                                GenericParamDefKind::Const { .. } => {}
700 701 702 703 704 705
                            }
                        }
                    }
                }
                _ => continue,
            }
C
Corey Richardson 已提交
706
        }
707
        generics
C
Corey Richardson 已提交
708 709 710
    }
}

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

716
        let (gens, preds) = *self;
717

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

722 723 724
        // 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 已提交
725 726 727
        let stripped_typarams = gens
            .params
            .iter()
728 729 730
            .filter_map(|param| match param.kind {
                ty::GenericParamDefKind::Lifetime => None,
                ty::GenericParamDefKind::Type { synthetic, .. } => {
731
                    if param.name == kw::SelfUpper {
732 733 734 735 736 737 738 739
                        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 已提交
740
                }
741
                ty::GenericParamDefKind::Const { .. } => None,
M
Mark Rousskov 已提交
742 743
            })
            .collect::<Vec<GenericParamDef>>();
744

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

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

769
                    None
770
                })();
771

772 773
                if let Some(param_idx) = param_idx {
                    if let Some(b) = impl_trait.get_mut(&param_idx.into()) {
774 775
                        let p = p.clean(cx)?;

776 777 778 779 780
                        b.extend(
                            p.get_bounds()
                                .into_iter()
                                .flatten()
                                .cloned()
M
Mark Rousskov 已提交
781
                                .filter(|b| !b.is_sized_bound(cx)),
782 783
                        );

S
Shotaro Yamada 已提交
784 785 786 787 788
                        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 已提交
789 790 791 792 793
                            impl_trait_proj.entry(param_idx).or_default().push((
                                trait_did,
                                name.to_string(),
                                rhs,
                            ));
794 795 796 797
                        }

                        return None;
                    }
798 799 800 801
                }

                Some(p)
            })
802
            .collect::<Vec<_>>();
803

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

S
Shotaro Yamada 已提交
808 809 810
            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 已提交
811
                        simplify::merge_bounds(cx, &mut bounds, trait_did, &name, &rhs.clean(cx));
S
Shotaro Yamada 已提交
812 813 814 815 816 817 818 819
                    }
                }
            } else {
                unreachable!();
            }

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

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

826
        // Type parameters and have a Sized bound by default unless removed with
827
        // ?Sized. Scan through the predicates and mark any type parameter with
828
        // a Sized bound, removing the bounds as we find them.
829 830
        //
        // Note that associated types also have a sized bound by default, but we
831
        // don't actually know the set of associated types right here so that's
832
        // handled in cleaning associated types
833
        let mut sized_params = FxHashSet::default();
M
Mark Rousskov 已提交
834 835 836 837 838 839 840
        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
841 842
                }
            }
M
Mark Rousskov 已提交
843
            _ => true,
844
        });
845

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

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

861
        Generics {
M
Mark Rousskov 已提交
862 863 864 865 866 867 868 869 870 871
            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(),
872
            where_predicates: simplify::where_clauses(cx, where_predicates),
873 874 875 876
        }
    }
}

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

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

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

C
Camille GILLOT 已提交
919
impl<'a> Clean<Arguments> for (&'a [hir::Ty<'a>], &'a [ast::Ident]) {
920
    fn clean(&self, cx: &DocContext<'_>) -> Arguments {
921
        Arguments {
M
Mark Rousskov 已提交
922 923 924 925 926 927 928 929 930 931 932 933 934
            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(),
935 936 937 938
        }
    }
}

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

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

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

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

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

999 1000
impl Clean<FnRetTy> for hir::FnRetTy<'_> {
    fn clean(&self, cx: &DocContext<'_>) -> FnRetTy {
C
Corey Richardson 已提交
1001
        match *self {
1002 1003
            Self::Return(ref typ) => Return(typ.clean(cx)),
            Self::DefaultReturn(..) => DefaultReturn,
C
Corey Richardson 已提交
1004 1005 1006 1007
        }
    }
}

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

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

1050
impl Clean<bool> for hir::IsAuto {
1051
    fn clean(&self, _: &DocContext<'_>) -> bool {
1052 1053 1054 1055 1056 1057 1058
        match *self {
            hir::IsAuto::Yes => true,
            hir::IsAuto::No => false,
        }
    }
}

C
Camille GILLOT 已提交
1059
impl Clean<Type> for hir::TraitRef<'_> {
1060
    fn clean(&self, cx: &DocContext<'_>) -> Type {
L
ljedrz 已提交
1061
        resolve_type(cx, self.path.clean(cx), self.hir_ref_id)
C
Corey Richardson 已提交
1062 1063 1064
    }
}

C
Camille GILLOT 已提交
1065
impl Clean<PolyTrait> for hir::PolyTraitRef<'_> {
1066
    fn clean(&self, cx: &DocContext<'_>) -> PolyTrait {
1067 1068
        PolyTrait {
            trait_: self.trait_ref.clean(cx),
M
Mark Rousskov 已提交
1069
            generic_params: self.bound_generic_params.clean(cx),
1070
        }
N
Niko Matsakis 已提交
1071 1072 1073
    }
}

1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093
impl Clean<TypeKind> for hir::def::DefKind {
    fn clean(&self, _: &DocContext<'_>) -> TypeKind {
        match *self {
            hir::def::DefKind::Mod => TypeKind::Module,
            hir::def::DefKind::Struct => TypeKind::Struct,
            hir::def::DefKind::Union => TypeKind::Union,
            hir::def::DefKind::Enum => TypeKind::Enum,
            hir::def::DefKind::Trait => TypeKind::Trait,
            hir::def::DefKind::TyAlias => TypeKind::Typedef,
            hir::def::DefKind::ForeignTy => TypeKind::Foreign,
            hir::def::DefKind::TraitAlias => TypeKind::TraitAlias,
            hir::def::DefKind::Fn => TypeKind::Function,
            hir::def::DefKind::Const => TypeKind::Const,
            hir::def::DefKind::Static => TypeKind::Static,
            hir::def::DefKind::Macro(_) => TypeKind::Macro,
            _ => TypeKind::Foreign,
        }
    }
}

C
Camille GILLOT 已提交
1094
impl Clean<Item> for hir::TraitItem<'_> {
1095
    fn clean(&self, cx: &DocContext<'_>) -> Item {
1096
        let inner = match self.kind {
1097
            hir::TraitItemKind::Const(ref ty, default) => {
M
Mark Rousskov 已提交
1098
                AssocConstItem(ty.clean(cx), default.map(|e| print_const_expr(cx, e)))
1099
            }
M
Mark Mansi 已提交
1100
            hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
1101
                MethodItem((sig, &self.generics, body, None).clean(cx))
1102
            }
M
Mark Mansi 已提交
1103
            hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(ref names)) => {
1104 1105 1106
                let (generics, decl) = enter_impl_trait(cx, || {
                    (self.generics.clean(cx), (&*sig.decl, &names[..]).clean(cx))
                });
1107
                let (all_types, ret_types) = get_all_types(&generics, &decl, cx);
M
Mark Rousskov 已提交
1108
                TyMethodItem(TyMethod { header: sig.header, decl, generics, all_types, ret_types })
1109
            }
1110
            hir::TraitItemKind::Type(ref bounds, ref default) => {
A
Andrew Xu 已提交
1111
                AssocTypeItem(bounds.clean(cx), default.clean(cx))
1112 1113
            }
        };
1114
        let local_did = cx.tcx.hir().local_def_id(self.hir_id);
1115
        Item {
1116
            name: Some(self.ident.name.clean(cx)),
1117 1118
            attrs: self.attrs.clean(cx),
            source: self.span.clean(cx),
L
ljedrz 已提交
1119
            def_id: local_did,
M
Mark Rousskov 已提交
1120
            visibility: Visibility::Inherited,
L
ljedrz 已提交
1121 1122
            stability: get_stability(cx, local_did),
            deprecation: get_deprecation(cx, local_did),
1123
            inner,
1124 1125 1126 1127
        }
    }
}

C
Camille GILLOT 已提交
1128
impl Clean<Item> for hir::ImplItem<'_> {
1129
    fn clean(&self, cx: &DocContext<'_>) -> Item {
1130
        let inner = match self.kind {
1131
            hir::ImplItemKind::Const(ref ty, expr) => {
M
Mark Rousskov 已提交
1132
                AssocConstItem(ty.clean(cx), Some(print_const_expr(cx, expr)))
1133
            }
M
Mark Mansi 已提交
1134
            hir::ImplItemKind::Fn(ref sig, body) => {
1135
                MethodItem((sig, &self.generics, body, Some(self.defaultness)).clean(cx))
1136
            }
M
Mark Rousskov 已提交
1137
            hir::ImplItemKind::TyAlias(ref ty) => {
G
Guillaume Gomez 已提交
1138 1139
                let type_ = ty.clean(cx);
                let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did));
G
Guillaume Gomez 已提交
1140
                TypedefItem(Typedef { type_, generics: Generics::default(), item_type }, true)
M
Mark Rousskov 已提交
1141 1142 1143 1144 1145
            }
            hir::ImplItemKind::OpaqueTy(ref bounds) => OpaqueTyItem(
                OpaqueTy { bounds: bounds.clean(cx), generics: Generics::default() },
                true,
            ),
1146
        };
1147
        let local_did = cx.tcx.hir().local_def_id(self.hir_id);
1148
        Item {
1149
            name: Some(self.ident.name.clean(cx)),
1150 1151
            source: self.span.clean(cx),
            attrs: self.attrs.clean(cx),
L
ljedrz 已提交
1152
            def_id: local_did,
1153
            visibility: self.vis.clean(cx),
L
ljedrz 已提交
1154 1155
            stability: get_stability(cx, local_did),
            deprecation: get_deprecation(cx, local_did),
1156
            inner,
C
Corey Richardson 已提交
1157 1158 1159 1160
        }
    }
}

1161
impl Clean<Item> for ty::AssocItem {
1162
    fn clean(&self, cx: &DocContext<'_>) -> Item {
1163
        let inner = match self.kind {
A
Andrew Xu 已提交
1164
            ty::AssocKind::Const => {
1165
                let ty = cx.tcx.type_of(self.def_id);
1166 1167 1168 1169 1170
                let default = if self.defaultness.has_value() {
                    Some(inline::print_inlined_const(cx, self.def_id))
                } else {
                    None
                };
A
Andrew Xu 已提交
1171
                AssocConstItem(ty.clean(cx), default)
1172
            }
A
Andrew Xu 已提交
1173
            ty::AssocKind::Method => {
M
Mark Rousskov 已提交
1174 1175 1176
                let generics =
                    (cx.tcx.generics_of(self.def_id), cx.tcx.explicit_predicates_of(self.def_id))
                        .clean(cx);
1177
                let sig = cx.tcx.fn_sig(self.def_id);
1178
                let mut decl = (self.def_id, sig).clean(cx);
1179 1180 1181

                if self.method_has_self_argument {
                    let self_ty = match self.container {
M
Mark Rousskov 已提交
1182
                        ty::ImplContainer(def_id) => cx.tcx.type_of(def_id),
1183
                        ty::TraitContainer(_) => cx.tcx.types.self_param,
1184
                    };
1185
                    let self_arg_ty = *sig.input(0).skip_binder();
1186
                    if self_arg_ty == self_ty {
1187
                        decl.inputs.values[0].type_ = Generic(String::from("Self"));
V
varkor 已提交
1188
                    } else if let ty::Ref(_, ty, _) = self_arg_ty.kind {
1189
                        if ty == self_ty {
1190
                            match decl.inputs.values[0].type_ {
M
Mark Rousskov 已提交
1191
                                BorrowedRef { ref mut type_, .. } => {
1192 1193
                                    **type_ = Generic(String::from("Self"))
                                }
1194 1195 1196 1197 1198
                                _ => unreachable!(),
                            }
                        }
                    }
                }
1199

1200
                let provided = match self.container {
1201
                    ty::ImplContainer(_) => true,
M
Mark Rousskov 已提交
1202
                    ty::TraitContainer(_) => self.defaultness.has_value(),
1203
                };
1204
                let (all_types, ret_types) = get_all_types(&generics, &decl, cx);
1205
                if provided {
1206
                    let constness = if is_min_const_fn(cx.tcx, self.def_id) {
1207 1208 1209 1210
                        hir::Constness::Const
                    } else {
                        hir::Constness::NotConst
                    };
C
csmoe 已提交
1211
                    let asyncness = cx.tcx.asyncness(self.def_id);
1212 1213 1214 1215
                    let defaultness = match self.container {
                        ty::ImplContainer(_) => Some(self.defaultness),
                        ty::TraitContainer(_) => None,
                    };
1216
                    MethodItem(Method {
1217 1218
                        generics,
                        decl,
W
Without Boats 已提交
1219 1220 1221 1222
                        header: hir::FnHeader {
                            unsafety: sig.unsafety(),
                            abi: sig.abi(),
                            constness,
C
csmoe 已提交
1223
                            asyncness,
1224
                        },
1225
                        defaultness,
1226
                        all_types,
1227
                        ret_types,
1228 1229 1230
                    })
                } else {
                    TyMethodItem(TyMethod {
1231 1232
                        generics,
                        decl,
W
Without Boats 已提交
1233 1234 1235
                        header: hir::FnHeader {
                            unsafety: sig.unsafety(),
                            abi: sig.abi(),
1236 1237
                            constness: hir::Constness::NotConst,
                            asyncness: hir::IsAsync::NotAsync,
1238 1239
                        },
                        all_types,
1240
                        ret_types,
1241
                    })
1242 1243
                }
            }
A
Andrew Xu 已提交
1244
            ty::AssocKind::Type => {
1245
                let my_name = self.ident.name.clean(cx);
1246

1247
                if let ty::TraitContainer(did) = self.container {
1248 1249 1250 1251
                    // 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.
1252
                    let predicates = cx.tcx.explicit_predicates_of(did);
1253
                    let generics = (cx.tcx.generics_of(did), predicates).clean(cx);
M
Mark Rousskov 已提交
1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279
                    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<_>>();
1280 1281 1282 1283 1284 1285
                    // 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 已提交
1286 1287 1288
                        Some(i) => {
                            bounds.remove(i);
                        }
V
varkor 已提交
1289
                        None => bounds.push(GenericBound::maybe_sized(cx)),
1290
                    }
1291

1292 1293 1294 1295 1296
                    let ty = if self.defaultness.has_value() {
                        Some(cx.tcx.type_of(self.def_id))
                    } else {
                        None
                    };
1297

A
Andrew Xu 已提交
1298
                    AssocTypeItem(bounds, ty.clean(cx))
1299
                } else {
G
Guillaume Gomez 已提交
1300 1301
                    let type_ = cx.tcx.type_of(self.def_id).clean(cx);
                    let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did));
M
Mark Rousskov 已提交
1302 1303
                    TypedefItem(
                        Typedef {
G
Guillaume Gomez 已提交
1304
                            type_,
M
Mark Rousskov 已提交
1305
                            generics: Generics { params: Vec::new(), where_predicates: Vec::new() },
G
Guillaume Gomez 已提交
1306
                            item_type,
1307
                        },
M
Mark Rousskov 已提交
1308 1309
                        true,
                    )
1310
                }
1311
            }
V
varkor 已提交
1312
            ty::AssocKind::OpaqueTy => unimplemented!(),
1313 1314
        };

1315 1316
        let visibility = match self.container {
            ty::ImplContainer(_) => self.vis.clean(cx),
M
Mark Rousskov 已提交
1317
            ty::TraitContainer(_) => Inherited,
1318 1319
        };

1320
        Item {
1321
            name: Some(self.ident.name.clean(cx)),
1322
            visibility,
1323
            stability: get_stability(cx, self.def_id),
1324
            deprecation: get_deprecation(cx, self.def_id),
1325
            def_id: self.def_id,
1326
            attrs: inline::load_attrs(cx, self.def_id).clean(cx),
1327
            source: cx.tcx.def_span(self.def_id).clean(cx),
1328
            inner,
1329
        }
1330 1331 1332
    }
}

C
Camille GILLOT 已提交
1333
impl Clean<Type> for hir::Ty<'_> {
1334
    fn clean(&self, cx: &DocContext<'_>) -> Type {
1335
        use rustc_hir::*;
1336

V
varkor 已提交
1337
        match self.kind {
C
csmoe 已提交
1338
            TyKind::Never => Never,
G
Guillaume Gomez 已提交
1339
            TyKind::Ptr(ref m) => RawPointer(m.mutbl, box m.ty.clean(cx)),
C
csmoe 已提交
1340
            TyKind::Rptr(ref l, ref m) => {
M
Mark Rousskov 已提交
1341 1342
                let lifetime = if l.is_elided() { None } else { Some(l.clean(cx)) };
                BorrowedRef { lifetime, mutability: m.mutbl, type_: box m.ty.clean(cx) }
1343
            }
C
csmoe 已提交
1344 1345
            TyKind::Slice(ref ty) => Slice(box ty.clean(cx)),
            TyKind::Array(ref ty, ref length) => {
1346
                let def_id = cx.tcx.hir().local_def_id(length.hir_id);
1347
                let length = match cx.tcx.const_eval_poly(def_id) {
1348
                    Ok(length) => {
B
Ben Lewis 已提交
1349
                        print_const(cx, ty::Const::from_value(cx.tcx, length, cx.tcx.types.usize))
1350
                    }
M
Mark Rousskov 已提交
1351 1352 1353 1354 1355
                    Err(_) => cx
                        .sess()
                        .source_map()
                        .span_to_snippet(cx.tcx.def_span(def_id))
                        .unwrap_or_else(|_| "_".to_string()),
1356
                };
1357
                Array(box ty.clean(cx), length)
M
Mark Rousskov 已提交
1358
            }
C
csmoe 已提交
1359
            TyKind::Tup(ref tys) => Tuple(tys.clean(cx)),
O
Oliver Schneider 已提交
1360
            TyKind::Def(item_id, _) => {
1361
                let item = cx.tcx.hir().expect_item(item_id.id);
V
varkor 已提交
1362
                if let hir::ItemKind::OpaqueTy(ref ty) = item.kind {
O
Oliver Schneider 已提交
1363 1364 1365 1366 1367
                    ImplTrait(ty.bounds.clean(cx))
                } else {
                    unreachable!()
                }
            }
C
csmoe 已提交
1368
            TyKind::Path(hir::QPath::Resolved(None, ref path)) => {
1369
                if let Res::Def(DefKind::TyParam, did) = path.res {
1370 1371 1372
                    if let Some(new_ty) = cx.ty_substs.borrow().get(&did).cloned() {
                        return new_ty;
                    }
1373
                    if let Some(bounds) = cx.impl_trait_bounds.borrow_mut().remove(&did.into()) {
1374 1375 1376 1377
                        return ImplTrait(bounds);
                    }
                }

1378
                let mut alias = None;
1379
                if let Res::Def(DefKind::TyAlias, def_id) = path.res {
1380
                    // Substitute private type aliases
1381
                    if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(def_id) {
1382
                        if !cx.renderinfo.borrow().access_levels.is_exported(def_id) {
V
varkor 已提交
1383
                            alias = Some(&cx.tcx.hir().expect_item(hir_id).kind);
1384
                        }
E
Eduard Burtescu 已提交
1385
                    }
1386 1387
                };

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

D
Douglas Campos 已提交
1525
impl<'tcx> Clean<Type> for Ty<'tcx> {
1526
    fn clean(&self, cx: &DocContext<'_>) -> Type {
1527
        debug!("cleaning type: {:?}", self);
V
varkor 已提交
1528
        match self.kind {
V
varkor 已提交
1529
            ty::Never => Never,
1530 1531 1532 1533 1534 1535
            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 已提交
1536 1537
            ty::Slice(ty) => Slice(box ty.clean(cx)),
            ty::Array(ty, n) => {
1538
                let mut n = cx.tcx.lift(&n).expect("array lift failed");
1539
                n = n.eval(cx.tcx, ty::ParamEnv::reveal_all());
O
Oliver Schneider 已提交
1540
                let n = print_const(cx, n);
1541 1542
                Array(box ty.clean(cx), n)
            }
G
Guillaume Gomez 已提交
1543
            ty::RawPtr(mt) => RawPointer(mt.mutbl, box mt.ty.clean(cx)),
M
Mark Rousskov 已提交
1544 1545 1546 1547
            ty::Ref(r, ty, mutbl) => {
                BorrowedRef { lifetime: r.clean(cx), mutability: mutbl, type_: box ty.clean(cx) }
            }
            ty::FnDef(..) | ty::FnPtr(_) => {
V
varkor 已提交
1548
                let ty = cx.tcx.lift(self).expect("FnPtr lift failed");
1549
                let sig = ty.fn_sig(cx.tcx);
1550
                let local_def_id = cx.tcx.hir().local_def_id_from_node_id(ast::CRATE_NODE_ID);
1551 1552
                BareFunction(box BareFunctionDecl {
                    unsafety: sig.unsafety(),
1553
                    generic_params: Vec::new(),
1554
                    decl: (local_def_id, sig).clean(cx),
1555 1556 1557
                    abi: sig.abi(),
                })
            }
V
varkor 已提交
1558
            ty::Adt(def, substs) => {
1559
                let did = def.did;
1560
                let kind = match def.adt_kind() {
1561 1562 1563
                    AdtKind::Struct => TypeKind::Struct,
                    AdtKind::Union => TypeKind::Union,
                    AdtKind::Enum => TypeKind::Enum,
1564
                };
M
mitaa 已提交
1565
                inline::record_extern_fqn(cx, did, kind);
1566
                let path = external_path(cx, cx.tcx.item_name(did), None, false, vec![], substs);
M
Mark Rousskov 已提交
1567
                ResolvedPath { path, param_names: None, did, is_generic: false }
1568
            }
V
varkor 已提交
1569
            ty::Foreign(did) => {
P
Paul Lietar 已提交
1570
                inline::record_extern_fqn(cx, did, TypeKind::Foreign);
M
Mark Rousskov 已提交
1571 1572 1573 1574 1575 1576 1577 1578 1579
                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 已提交
1580
            }
V
varkor 已提交
1581
            ty::Dynamic(ref obj, ref reg) => {
A
Ariel Ben-Yehuda 已提交
1582 1583 1584 1585
                // 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 已提交
1586 1587 1588
                let did = dids
                    .next()
                    .unwrap_or_else(|| panic!("found trait object `{:?}` with no traits?", self));
A
Ariel Ben-Yehuda 已提交
1589 1590 1591
                let substs = match obj.principal() {
                    Some(principal) => principal.skip_binder().substs,
                    // marker traits have no substs.
M
Mark Rousskov 已提交
1592
                    _ => cx.tcx.intern_substs(&[]),
A
Ariel Ben-Yehuda 已提交
1593 1594
                };

1595 1596
                inline::record_extern_fqn(cx, did, TypeKind::Trait);

V
varkor 已提交
1597 1598
                let mut param_names = vec![];
                reg.clean(cx).map(|b| param_names.push(GenericBound::Outlives(b)));
A
Ariel Ben-Yehuda 已提交
1599
                for did in dids {
1600
                    let empty = cx.tcx.intern_substs(&[]);
M
Mark Rousskov 已提交
1601 1602
                    let path =
                        external_path(cx, cx.tcx.item_name(did), Some(did), false, vec![], empty);
1603
                    inline::record_extern_fqn(cx, did, TypeKind::Trait);
M
Mark Rousskov 已提交
1604 1605 1606 1607 1608 1609 1610 1611 1612
                    let bound = GenericBound::TraitBound(
                        PolyTrait {
                            trait_: ResolvedPath {
                                path,
                                param_names: None,
                                did,
                                is_generic: false,
                            },
                            generic_params: Vec::new(),
1613
                        },
M
Mark Rousskov 已提交
1614 1615
                        hir::TraitBoundModifier::None,
                    );
V
varkor 已提交
1616
                    param_names.push(bound);
1617
                }
1618

1619 1620 1621 1622
                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 已提交
1623
                        kind: TypeBindingKind::Equality { ty: pb.skip_binder().ty.clean(cx) },
1624 1625
                    });
                }
1626

M
Mark Rousskov 已提交
1627 1628 1629
                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 }
1630
            }
V
varkor 已提交
1631 1632 1633
            ty::Tuple(ref t) => {
                Tuple(t.iter().map(|t| t.expect_ty()).collect::<Vec<_>>().clean(cx))
            }
1634

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

1637 1638 1639 1640 1641 1642 1643
            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())
                }
            }
1644

1645
            ty::Opaque(def_id, substs) => {
1646 1647
                // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
                // by looking up the projections associated with the def_id.
1648
                let predicates_of = cx.tcx.explicit_predicates_of(def_id);
1649
                let substs = cx.tcx.lift(&substs).expect("Opaque lift failed");
1650
                let bounds = predicates_of.instantiate(cx.tcx, substs);
1651 1652
                let mut regions = vec![];
                let mut has_sized = false;
M
Mark Rousskov 已提交
1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664
                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)));
1665
                            return None;
M
Mark Rousskov 已提交
1666 1667 1668
                        } else {
                            return None;
                        };
1669

M
Mark Rousskov 已提交
1670 1671 1672 1673
                        if let Some(sized) = cx.tcx.lang_items().sized_trait() {
                            if trait_ref.def_id() == sized {
                                has_sized = true;
                                return None;
1674 1675 1676
                            }
                        }

1677
                        let bounds: Vec<_> = bounds
M
Mark Rousskov 已提交
1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705
                            .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();

1706
                        Some((trait_ref, &bounds[..]).clean(cx))
M
Mark Rousskov 已提交
1707 1708
                    })
                    .collect::<Vec<_>>();
1709 1710
                bounds.extend(regions);
                if !has_sized && !bounds.is_empty() {
V
varkor 已提交
1711
                    bounds.insert(0, GenericBound::maybe_sized(cx));
1712 1713
                }
                ImplTrait(bounds)
1714 1715
            }

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

S
scalexm 已提交
1718
            ty::Bound(..) => panic!("Bound"),
S
scalexm 已提交
1719
            ty::Placeholder(..) => panic!("Placeholder"),
1720
            ty::UnnormalizedProjection(..) => panic!("UnnormalizedProjection"),
V
varkor 已提交
1721 1722 1723
            ty::GeneratorWitness(..) => panic!("GeneratorWitness"),
            ty::Infer(..) => panic!("Infer"),
            ty::Error => panic!("Error"),
1724 1725 1726 1727
        }
    }
}

V
varkor 已提交
1728 1729
impl<'tcx> Clean<Constant> for ty::Const<'tcx> {
    fn clean(&self, cx: &DocContext<'_>) -> Constant {
1730 1731 1732 1733 1734 1735
        Constant {
            type_: self.ty.clean(cx),
            expr: format!("{}", self),
            value: None,
            is_literal: false,
        }
V
varkor 已提交
1736 1737 1738
    }
}

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

C
Corey Richardson 已提交
1743
        Item {
1744
            name: Some(self.ident.name).clean(cx),
1745
            attrs: self.attrs.clean(cx),
1746
            source: self.span.clean(cx),
1747
            visibility: self.vis.clean(cx),
L
ljedrz 已提交
1748 1749 1750
            stability: get_stability(cx, local_did),
            deprecation: get_deprecation(cx, local_did),
            def_id: local_did,
1751
            inner: StructFieldItem(self.ty.clean(cx)),
C
Corey Richardson 已提交
1752 1753 1754 1755
        }
    }
}

1756
impl Clean<Item> for ty::FieldDef {
1757
    fn clean(&self, cx: &DocContext<'_>) -> Item {
1758
        Item {
1759
            name: Some(self.ident.name).clean(cx),
1760
            attrs: cx.tcx.get_attrs(self.did).clean(cx),
1761
            source: cx.tcx.def_span(self.did).clean(cx),
1762
            visibility: self.vis.clean(cx),
1763
            stability: get_stability(cx, self.did),
1764
            deprecation: get_deprecation(cx, self.did),
1765
            def_id: self.did,
1766
            inner: StructFieldItem(cx.tcx.type_of(self.did).clean(cx)),
1767 1768 1769 1770
        }
    }
}

C
Camille GILLOT 已提交
1771
impl Clean<Visibility> for hir::Visibility<'_> {
M
Mark Rousskov 已提交
1772 1773
    fn clean(&self, cx: &DocContext<'_>) -> Visibility {
        match self.node {
1774 1775 1776 1777
            hir::VisibilityKind::Public => Visibility::Public,
            hir::VisibilityKind::Inherited => Visibility::Inherited,
            hir::VisibilityKind::Crate(_) => Visibility::Crate,
            hir::VisibilityKind::Restricted { ref path, .. } => {
1778
                let path = path.clean(cx);
1779
                let did = register_res(cx, path.res);
1780 1781
                Visibility::Restricted(did, path)
            }
M
Mark Rousskov 已提交
1782
        }
1783 1784 1785
    }
}

M
Mark Rousskov 已提交
1786 1787 1788
impl Clean<Visibility> for ty::Visibility {
    fn clean(&self, _: &DocContext<'_>) -> Visibility {
        if *self == ty::Visibility::Public { Public } else { Inherited }
C
Corey Richardson 已提交
1789 1790 1791
    }
}

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

1812
impl Clean<Item> for doctree::Union<'_> {
1813
    fn clean(&self, cx: &DocContext<'_>) -> Item {
1814 1815
        Item {
            name: Some(self.name.clean(cx)),
V
Vadim Petrochenkov 已提交
1816 1817
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
1818
            def_id: cx.tcx.hir().local_def_id(self.id),
V
Vadim Petrochenkov 已提交
1819
            visibility: self.vis.clean(cx),
1820
            stability: cx.stability(self.id).clean(cx),
1821
            deprecation: cx.deprecation(self.id).clean(cx),
V
Vadim Petrochenkov 已提交
1822 1823 1824 1825 1826 1827
            inner: UnionItem(Union {
                struct_type: self.struct_type,
                generics: self.generics.clean(cx),
                fields: self.fields.clean(cx),
                fields_stripped: false,
            }),
1828
        }
V
Vadim Petrochenkov 已提交
1829 1830 1831
    }
}

1832
impl Clean<VariantStruct> for rustc_hir::VariantData<'_> {
1833
    fn clean(&self, cx: &DocContext<'_>) -> VariantStruct {
C
Corey Richardson 已提交
1834 1835
        VariantStruct {
            struct_type: doctree::struct_type_from_def(self),
1836
            fields: self.fields().iter().map(|x| x.clean(cx)).collect(),
S
Steven Fackler 已提交
1837
            fields_stripped: false,
C
Corey Richardson 已提交
1838 1839 1840 1841
        }
    }
}

1842
impl Clean<Item> for doctree::Enum<'_> {
1843
    fn clean(&self, cx: &DocContext<'_>) -> Item {
1844 1845
        Item {
            name: Some(self.name.clean(cx)),
1846 1847
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
1848
            def_id: cx.tcx.hir().local_def_id(self.id),
1849
            visibility: self.vis.clean(cx),
1850
            stability: cx.stability(self.id).clean(cx),
1851
            deprecation: cx.deprecation(self.id).clean(cx),
C
Corey Richardson 已提交
1852
            inner: EnumItem(Enum {
1853
                variants: self.variants.iter().map(|v| v.clean(cx)).collect(),
1854
                generics: self.generics.clean(cx),
S
Steven Fackler 已提交
1855
                variants_stripped: false,
C
Corey Richardson 已提交
1856
            }),
1857
        }
C
Corey Richardson 已提交
1858 1859 1860
    }
}

1861
impl Clean<Item> for doctree::Variant<'_> {
1862
    fn clean(&self, cx: &DocContext<'_>) -> Item {
C
Corey Richardson 已提交
1863
        Item {
1864 1865 1866
            name: Some(self.name.clean(cx)),
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
M
Mark Rousskov 已提交
1867
            visibility: Inherited,
1868
            stability: cx.stability(self.id).clean(cx),
1869
            deprecation: cx.deprecation(self.id).clean(cx),
1870
            def_id: cx.tcx.hir().local_def_id(self.id),
M
Mark Rousskov 已提交
1871
            inner: VariantItem(Variant { kind: self.def.clean(cx) }),
C
Corey Richardson 已提交
1872 1873 1874 1875
        }
    }
}

1876
impl Clean<Item> for ty::VariantDef {
1877
    fn clean(&self, cx: &DocContext<'_>) -> Item {
1878 1879
        let kind = match self.ctor_kind {
            CtorKind::Const => VariantKind::CLike,
M
Mark Rousskov 已提交
1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900
            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(),
            }),
1901 1902
        };
        Item {
1903
            name: Some(self.ident.clean(cx)),
1904
            attrs: inline::load_attrs(cx, self.def_id).clean(cx),
1905
            source: cx.tcx.def_span(self.def_id).clean(cx),
M
Mark Rousskov 已提交
1906
            visibility: Inherited,
1907
            def_id: self.def_id,
T
teresy 已提交
1908
            inner: VariantItem(Variant { kind }),
1909 1910
            stability: get_stability(cx, self.def_id),
            deprecation: get_deprecation(cx, self.def_id),
1911 1912 1913 1914
        }
    }
}

C
Camille GILLOT 已提交
1915
impl Clean<VariantKind> for hir::VariantData<'_> {
1916
    fn clean(&self, cx: &DocContext<'_>) -> VariantKind {
1917 1918
        match self {
            hir::VariantData::Struct(..) => VariantKind::Struct(self.clean(cx)),
M
Mark Rousskov 已提交
1919 1920 1921
            hir::VariantData::Tuple(..) => {
                VariantKind::Tuple(self.fields().iter().map(|x| x.ty.clean(cx)).collect())
            }
1922
            hir::VariantData::Unit(..) => VariantKind::CLike,
1923
        }
1924 1925 1926
    }
}

1927
impl Clean<Span> for rustc_span::Span {
1928
    fn clean(&self, cx: &DocContext<'_>) -> Span {
V
Vadim Petrochenkov 已提交
1929
        if self.is_dummy() {
1930 1931 1932
            return Span::empty();
        }

1933 1934 1935 1936
        let sm = cx.sess().source_map();
        let filename = sm.span_to_filename(*self);
        let lo = sm.lookup_char_pos(self.lo());
        let hi = sm.lookup_char_pos(self.hi());
1937
        Span {
1938
            filename,
1939
            cnum: lo.file.cnum,
1940
            loline: lo.line,
1941
            locol: lo.col.to_usize(),
1942
            hiline: hi.line,
1943
            hicol: hi.col.to_usize(),
G
Guillaume Gomez 已提交
1944
            original: *self,
1945
        }
C
Corey Richardson 已提交
1946 1947 1948
    }
}

C
Camille GILLOT 已提交
1949
impl Clean<Path> for hir::Path<'_> {
1950
    fn clean(&self, cx: &DocContext<'_>) -> Path {
C
Corey Richardson 已提交
1951
        Path {
1952
            global: self.is_global(),
1953
            res: self.res,
1954
            segments: if self.is_global() { &self.segments[1..] } else { &self.segments }.clean(cx),
1955 1956 1957 1958
        }
    }
}

C
Camille GILLOT 已提交
1959
impl Clean<GenericArgs> for hir::GenericArgs<'_> {
1960
    fn clean(&self, cx: &DocContext<'_>) -> GenericArgs {
1961
        if self.parenthesized {
1962
            let output = self.bindings[0].ty().clean(cx);
1963
            GenericArgs::Parenthesized {
1964
                inputs: self.inputs().clean(cx),
M
Mark Rousskov 已提交
1965
                output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None },
1966
            }
1967
        } else {
1968 1969 1970 1971
            let elide_lifetimes = self.args.iter().all(|arg| match arg {
                hir::GenericArg::Lifetime(lt) => lt.is_elided(),
                _ => true,
            });
1972
            GenericArgs::AngleBracketed {
M
Mark Rousskov 已提交
1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984
                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(),
1985
                bindings: self.bindings.clean(cx),
1986
            }
1987 1988 1989
        }
    }
}
1990

C
Camille GILLOT 已提交
1991
impl Clean<PathSegment> for hir::PathSegment<'_> {
1992
    fn clean(&self, cx: &DocContext<'_>) -> PathSegment {
M
Mark Rousskov 已提交
1993
        PathSegment { name: self.ident.name.clean(cx), args: self.generic_args().clean(cx) }
C
Corey Richardson 已提交
1994 1995 1996
    }
}

1997 1998
impl Clean<String> for Ident {
    #[inline]
1999
    fn clean(&self, cx: &DocContext<'_>) -> String {
2000 2001 2002 2003
        self.name.clean(cx)
    }
}

2004
impl Clean<String> for ast::Name {
2005
    #[inline]
2006
    fn clean(&self, _: &DocContext<'_>) -> String {
2007
        self.to_string()
2008 2009 2010
    }
}

2011
impl Clean<Item> for doctree::Typedef<'_> {
2012
    fn clean(&self, cx: &DocContext<'_>) -> Item {
G
Guillaume Gomez 已提交
2013 2014
        let type_ = self.ty.clean(cx);
        let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did));
C
Corey Richardson 已提交
2015
        Item {
2016 2017 2018
            name: Some(self.name.clean(cx)),
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
2019
            def_id: cx.tcx.hir().local_def_id(self.id),
2020
            visibility: self.vis.clean(cx),
2021
            stability: cx.stability(self.id).clean(cx),
2022
            deprecation: cx.deprecation(self.id).clean(cx),
G
Guillaume Gomez 已提交
2023
            inner: TypedefItem(Typedef { type_, generics: self.gen.clean(cx), item_type }, false),
C
Corey Richardson 已提交
2024 2025 2026 2027
        }
    }
}

V
varkor 已提交
2028
impl Clean<Item> for doctree::OpaqueTy<'_> {
2029
    fn clean(&self, cx: &DocContext<'_>) -> Item {
O
Oliver Schneider 已提交
2030 2031 2032 2033
        Item {
            name: Some(self.name.clean(cx)),
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
2034
            def_id: cx.tcx.hir().local_def_id(self.id),
O
Oliver Schneider 已提交
2035
            visibility: self.vis.clean(cx),
2036
            stability: cx.stability(self.id).clean(cx),
2037
            deprecation: cx.deprecation(self.id).clean(cx),
M
Mark Rousskov 已提交
2038 2039 2040 2041 2042 2043 2044
            inner: OpaqueTyItem(
                OpaqueTy {
                    bounds: self.opaque_ty.bounds.clean(cx),
                    generics: self.opaque_ty.generics.clean(cx),
                },
                false,
            ),
O
Oliver Schneider 已提交
2045 2046 2047 2048
        }
    }
}

C
Camille GILLOT 已提交
2049
impl Clean<BareFunctionDecl> for hir::BareFnTy<'_> {
2050
    fn clean(&self, cx: &DocContext<'_>) -> BareFunctionDecl {
2051
        let (generic_params, decl) = enter_impl_trait(cx, || {
2052
            (self.generic_params.clean(cx), (&*self.decl, &self.param_names[..]).clean(cx))
2053
        });
M
Mark Rousskov 已提交
2054
        BareFunctionDecl { unsafety: self.unsafety, abi: self.abi, decl, generic_params }
C
Corey Richardson 已提交
2055 2056 2057
    }
}

2058
impl Clean<Item> for doctree::Static<'_> {
2059
    fn clean(&self, cx: &DocContext<'_>) -> Item {
2060
        debug!("cleaning static {}: {:?}", self.name.clean(cx), self);
C
Corey Richardson 已提交
2061
        Item {
2062 2063 2064
            name: Some(self.name.clean(cx)),
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
2065
            def_id: cx.tcx.hir().local_def_id(self.id),
2066
            visibility: self.vis.clean(cx),
2067
            stability: cx.stability(self.id).clean(cx),
2068
            deprecation: cx.deprecation(self.id).clean(cx),
C
Corey Richardson 已提交
2069
            inner: StaticItem(Static {
2070
                type_: self.type_.clean(cx),
G
Guillaume Gomez 已提交
2071
                mutability: self.mutability,
2072
                expr: print_const_expr(cx, self.expr),
C
Corey Richardson 已提交
2073 2074 2075 2076 2077
            }),
        }
    }
}

2078
impl Clean<Item> for doctree::Constant<'_> {
2079
    fn clean(&self, cx: &DocContext<'_>) -> Item {
2080 2081
        let def_id = cx.tcx.hir().local_def_id(self.id);

2082 2083 2084 2085
        Item {
            name: Some(self.name.clean(cx)),
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
2086
            def_id,
2087
            visibility: self.vis.clean(cx),
2088
            stability: cx.stability(self.id).clean(cx),
2089
            deprecation: cx.deprecation(self.id).clean(cx),
2090 2091
            inner: ConstantItem(Constant {
                type_: self.type_.clean(cx),
2092
                expr: print_const_expr(cx, self.expr),
2093 2094
                value: print_evaluated_const(cx, def_id),
                is_literal: is_literal_expr(cx, self.expr.hir_id),
2095 2096 2097 2098 2099
            }),
        }
    }
}

2100
impl Clean<ImplPolarity> for ty::ImplPolarity {
2101
    fn clean(&self, _: &DocContext<'_>) -> ImplPolarity {
2102
        match self {
2103 2104 2105 2106
            &ty::ImplPolarity::Positive |
            // FIXME: do we want to do something else here?
            &ty::ImplPolarity::Reservation => ImplPolarity::Positive,
            &ty::ImplPolarity::Negative => ImplPolarity::Negative,
2107 2108 2109 2110
        }
    }
}

2111
impl Clean<Vec<Item>> for doctree::Impl<'_> {
2112
    fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
2113 2114
        let mut ret = Vec::new();
        let trait_ = self.trait_.clean(cx);
2115
        let items = self.items.iter().map(|ii| ii.clean(cx)).collect::<Vec<_>>();
2116
        let def_id = cx.tcx.hir().local_def_id(self.id);
2117 2118 2119

        // 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.
2120
        if trait_.def_id() == cx.tcx.lang_items().deref_trait() {
2121
            build_deref_target_impls(cx, &items, &mut ret);
2122 2123
        }

2124
        let provided: FxHashSet<String> = trait_
M
Mark Rousskov 已提交
2125 2126
            .def_id()
            .map(|did| {
2127
                cx.tcx.provided_trait_methods(did).map(|meth| meth.ident.to_string()).collect()
M
Mark Rousskov 已提交
2128 2129
            })
            .unwrap_or_default();
2130

2131 2132 2133 2134 2135
        let for_ = self.for_.clean(cx);
        let type_alias = for_.def_id().and_then(|did| match cx.tcx.def_kind(did) {
            Some(DefKind::TyAlias) => Some(cx.tcx.type_of(did).clean(cx)),
            _ => None,
        });
G
Guillaume Gomez 已提交
2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154
        let make_item = |trait_: Option<Type>, for_: Type, items: Vec<Item>| Item {
            name: None,
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
            def_id,
            visibility: self.vis.clean(cx),
            stability: cx.stability(self.id).clean(cx),
            deprecation: cx.deprecation(self.id).clean(cx),
            inner: ImplItem(Impl {
                unsafety: self.unsafety,
                generics: self.generics.clean(cx),
                provided_trait_methods: provided.clone(),
                trait_,
                for_,
                items,
                polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)),
                synthetic: false,
                blanket_impl: None,
            }),
G
Guillaume Gomez 已提交
2155 2156 2157
        };
        if let Some(type_alias) = type_alias {
            ret.push(make_item(trait_.clone(), type_alias, items.clone()));
2158
        }
G
Guillaume Gomez 已提交
2159
        ret.push(make_item(trait_, for_, items));
M
mitaa 已提交
2160
        ret
2161 2162 2163
    }
}

2164
impl Clean<Vec<Item>> for doctree::ExternCrate<'_> {
2165
    fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
M
Mark Rousskov 已提交
2166 2167 2168 2169 2170 2171 2172 2173
        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 已提交
2174 2175 2176 2177

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

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

2180
            if let Some(items) = inline::try_inline(
M
Mark Rousskov 已提交
2181 2182 2183
                cx,
                res,
                self.name,
M
Mazdak Farrokhzad 已提交
2184
                Some(rustc_middle::ty::Attributes::Borrowed(self.attrs)),
M
Mark Rousskov 已提交
2185
                &mut visited,
2186
            ) {
D
DebugSteven 已提交
2187 2188 2189 2190 2191
                return items;
            }
        }

        vec![Item {
2192 2193 2194
            name: None,
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
M
mitaa 已提交
2195
            def_id: DefId { krate: self.cnum, index: CRATE_DEF_INDEX },
2196 2197
            visibility: self.vis.clean(cx),
            stability: None,
2198
            deprecation: None,
M
Mark Rousskov 已提交
2199
            inner: ExternCrateItem(self.name.clean(cx), self.path.clone()),
D
DebugSteven 已提交
2200
        }]
2201
    }
C
Corey Richardson 已提交
2202 2203
}

2204
impl Clean<Vec<Item>> for doctree::Import<'_> {
2205
    fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
J
Joseph Crail 已提交
2206
        // We consider inlining the documentation of `pub use` statements, but we
2207 2208
        // forcefully don't inline if this is not public or if the
        // #[doc(no_inline)] attribute is present.
2209
        // Don't inline doc(hidden) imports so they can be stripped at a later stage.
M
Mark Rousskov 已提交
2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220
        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,
                    }
            });
2221 2222
        // Also check whether imports were asked to be inlined, in case we're trying to re-export a
        // crate in Rust 2018+
2223
        let please_inline = self.attrs.lists(sym::doc).has_word(sym::inline);
2224 2225
        let path = self.path.clean(cx);
        let inner = if self.glob {
2226
            if !denied {
2227
                let mut visited = FxHashSet::default();
2228
                if let Some(items) = inline::try_inline_glob(cx, path.res, &mut visited) {
2229 2230 2231 2232
                    return items;
                }
            }

2233
            Import::Glob(resolve_use_source(cx, path))
2234 2235
        } else {
            let name = self.name;
2236
            if !please_inline {
M
Matthias Krüger 已提交
2237 2238 2239 2240 2241
                if let Res::Def(DefKind::Mod, did) = path.res {
                    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;
2242 2243 2244
                    }
                }
            }
2245
            if !denied {
2246
                let mut visited = FxHashSet::default();
2247
                if let Some(items) = inline::try_inline(
M
Mark Rousskov 已提交
2248 2249 2250
                    cx,
                    path.res,
                    name,
M
Mazdak Farrokhzad 已提交
2251
                    Some(rustc_middle::ty::Attributes::Borrowed(self.attrs)),
M
Mark Rousskov 已提交
2252
                    &mut visited,
2253
                ) {
2254
                    return items;
2255
                }
2256
            }
2257
            Import::Simple(name.clean(cx), resolve_use_source(cx, path))
2258
        };
G
Guillaume Gomez 已提交
2259

2260
        vec![Item {
2261 2262 2263
            name: None,
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
2264
            def_id: cx.tcx.hir().local_def_id_from_node_id(ast::CRATE_NODE_ID),
2265 2266
            visibility: self.vis.clean(cx),
            stability: None,
2267
            deprecation: None,
M
Mark Rousskov 已提交
2268
            inner: ImportItem(inner),
2269
        }]
C
Corey Richardson 已提交
2270 2271 2272
    }
}

2273
impl Clean<Item> for doctree::ForeignItem<'_> {
2274
    fn clean(&self, cx: &DocContext<'_>) -> Item {
2275
        let inner = match self.kind {
C
csmoe 已提交
2276
            hir::ForeignItemKind::Fn(ref decl, ref names, ref generics) => {
2277
                let abi = cx.tcx.hir().get_foreign_abi(self.id);
M
Mark Rousskov 已提交
2278 2279
                let (generics, decl) =
                    enter_impl_trait(cx, || (generics.clean(cx), (&**decl, &names[..]).clean(cx)));
2280
                let (all_types, ret_types) = get_all_types(&generics, &decl, cx);
2281
                ForeignFunctionItem(Function {
2282
                    decl,
2283
                    generics,
2284 2285
                    header: hir::FnHeader {
                        unsafety: hir::Unsafety::Unsafe,
2286
                        abi,
2287 2288 2289
                        constness: hir::Constness::NotConst,
                        asyncness: hir::IsAsync::NotAsync,
                    },
2290
                    all_types,
2291
                    ret_types,
2292 2293
                })
            }
M
Mark Rousskov 已提交
2294 2295 2296 2297 2298 2299
            hir::ForeignItemKind::Static(ref ty, mutbl) => ForeignStaticItem(Static {
                type_: ty.clean(cx),
                mutability: *mutbl,
                expr: String::new(),
            }),
            hir::ForeignItemKind::Type => ForeignTypeItem,
2300
        };
G
Guillaume Gomez 已提交
2301

2302
        Item {
2303
            name: Some(self.name.clean(cx)),
2304
            attrs: self.attrs.clean(cx),
2305
            source: self.whence.clean(cx),
2306
            def_id: cx.tcx.hir().local_def_id(self.id),
2307
            visibility: self.vis.clean(cx),
2308
            stability: cx.stability(self.id).clean(cx),
2309
            deprecation: cx.deprecation(self.id).clean(cx),
2310
            inner,
2311 2312 2313 2314
        }
    }
}

2315
impl Clean<Item> for doctree::Macro<'_> {
2316
    fn clean(&self, cx: &DocContext<'_>) -> Item {
2317
        let name = self.name.clean(cx);
2318
        Item {
2319
            name: Some(name.clone()),
2320 2321
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
M
Mark Rousskov 已提交
2322
            visibility: Public,
2323
            stability: cx.stability(self.hid).clean(cx),
2324
            deprecation: cx.deprecation(self.hid).clean(cx),
2325
            def_id: self.def_id,
2326
            inner: MacroItem(Macro {
M
Mark Rousskov 已提交
2327 2328 2329 2330 2331 2332 2333 2334
                source: format!(
                    "macro_rules! {} {{\n{}}}",
                    name,
                    self.matchers
                        .iter()
                        .map(|span| { format!("    {} => {{ ... }};\n", span.to_src(cx)) })
                        .collect::<String>()
                ),
2335
                imported_from: self.imported_from.clean(cx),
2336 2337 2338 2339
            }),
        }
    }
}
2340

2341
impl Clean<Item> for doctree::ProcMacro<'_> {
2342
    fn clean(&self, cx: &DocContext<'_>) -> Item {
2343 2344 2345 2346
        Item {
            name: Some(self.name.clean(cx)),
            attrs: self.attrs.clean(cx),
            source: self.whence.clean(cx),
M
Mark Rousskov 已提交
2347
            visibility: Public,
2348
            stability: cx.stability(self.id).clean(cx),
2349
            deprecation: cx.deprecation(self.id).clean(cx),
2350
            def_id: cx.tcx.hir().local_def_id(self.id),
M
Mark Rousskov 已提交
2351
            inner: ProcMacroItem(ProcMacro { kind: self.kind, helpers: self.helpers.clean(cx) }),
2352 2353 2354 2355
        }
    }
}

2356
impl Clean<Stability> for attr::Stability {
2357
    fn clean(&self, _: &DocContext<'_>) -> Stability {
2358
        Stability {
V
Vadim Petrochenkov 已提交
2359
            level: stability::StabilityLevel::from_attr_level(&self.level),
2360
            feature: Some(self.feature.to_string()).filter(|f| !f.is_empty()),
V
Vadim Petrochenkov 已提交
2361
            since: match self.level {
M
Mark Rousskov 已提交
2362
                attr::Stable { ref since } => since.to_string(),
2363
                _ => String::new(),
V
Vadim Petrochenkov 已提交
2364
            },
M
Mark Rousskov 已提交
2365 2366 2367
            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()),
2368
            }),
2369
            unstable_reason: match self.level {
2370 2371
                attr::Unstable { reason: Some(ref reason), .. } => Some(reason.to_string()),
                _ => None,
V
Vadim Petrochenkov 已提交
2372 2373
            },
            issue: match self.level {
M
Mark Rousskov 已提交
2374
                attr::Unstable { issue, .. } => issue,
V
Vadim Petrochenkov 已提交
2375
                _ => None,
M
Mark Rousskov 已提交
2376
            },
2377 2378 2379 2380
        }
    }
}

2381
impl Clean<Deprecation> for attr::Deprecation {
2382
    fn clean(&self, _: &DocContext<'_>) -> Deprecation {
2383
        Deprecation {
2384 2385
            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()),
2386 2387 2388 2389
        }
    }
}

C
Camille GILLOT 已提交
2390
impl Clean<TypeBinding> for hir::TypeBinding<'_> {
2391
    fn clean(&self, cx: &DocContext<'_>) -> TypeBinding {
M
Mark Rousskov 已提交
2392
        TypeBinding { name: self.ident.name.clean(cx), kind: self.kind.clean(cx) }
2393 2394 2395
    }
}

C
Camille GILLOT 已提交
2396
impl Clean<TypeBindingKind> for hir::TypeBindingKind<'_> {
2397 2398
    fn clean(&self, cx: &DocContext<'_>) -> TypeBindingKind {
        match *self {
M
Mark Rousskov 已提交
2399 2400 2401
            hir::TypeBindingKind::Equality { ref ty } => {
                TypeBindingKind::Equality { ty: ty.clean(cx) }
            }
2402 2403 2404
            hir::TypeBindingKind::Constraint { ref bounds } => {
                TypeBindingKind::Constraint { bounds: bounds.iter().map(|b| b.clean(cx)).collect() }
            }
2405 2406 2407
        }
    }
}
2408 2409

enum SimpleBound {
V
varkor 已提交
2410 2411
    TraitBound(Vec<PathSegment>, Vec<SimpleBound>, Vec<GenericParamDef>, hir::TraitBoundModifier),
    Outlives(Lifetime),
2412 2413
}

V
varkor 已提交
2414 2415
impl From<GenericBound> for SimpleBound {
    fn from(bound: GenericBound) -> Self {
2416
        match bound.clone() {
V
varkor 已提交
2417 2418
            GenericBound::Outlives(l) => SimpleBound::Outlives(l),
            GenericBound::TraitBound(t, mod_) => match t.trait_ {
M
Mark Rousskov 已提交
2419 2420
                Type::ResolvedPath { path, param_names, .. } => SimpleBound::TraitBound(
                    path.segments,
M
Matthias Krüger 已提交
2421 2422 2423
                    param_names.map_or_else(Vec::new, |v| {
                        v.iter().map(|p| SimpleBound::from(p.clone())).collect()
                    }),
M
Mark Rousskov 已提交
2424 2425 2426
                    t.generic_params,
                    mod_,
                ),
A
Aaron Hill 已提交
2427
                _ => panic!("Unexpected bound {:?}", bound),
M
Mark Rousskov 已提交
2428
            },
2429 2430 2431
        }
    }
}