]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | //! This module contains the "cleaned" pieces of the AST, and the functions |
2 | //! that clean them. | |
3 | ||
0731742a XL |
4 | pub mod inline; |
5 | pub mod cfg; | |
60c5eb7d | 6 | pub mod utils; |
0731742a XL |
7 | mod auto_trait; |
8 | mod blanket_impl; | |
60c5eb7d XL |
9 | mod simplify; |
10 | pub mod types; | |
1a4d82fc | 11 | |
e74abb32 | 12 | use rustc_index::vec::{IndexVec, Idx}; |
0731742a XL |
13 | use rustc_typeck::hir_ty_to_ty; |
14 | use rustc::infer::region_constraints::{RegionConstraintData, Constraint}; | |
32a655c1 | 15 | use rustc::middle::resolve_lifetime as rl; |
476ff2be | 16 | use rustc::middle::lang_items; |
0731742a | 17 | use rustc::middle::stability; |
60c5eb7d | 18 | use rustc::mir::interpret::GlobalId; |
dc9dc135 XL |
19 | use rustc::hir; |
20 | use rustc::hir::def::{CtorKind, DefKind, Res}; | |
60c5eb7d | 21 | use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; |
416331ca | 22 | use rustc::hir::ptr::P; |
60c5eb7d XL |
23 | use rustc::ty::subst::InternalSubsts; |
24 | use rustc::ty::{self, TyCtxt, Ty, AdtKind}; | |
0731742a | 25 | use rustc::ty::fold::TypeFolder; |
476ff2be | 26 | use rustc::util::nodemap::{FxHashMap, FxHashSet}; |
60c5eb7d | 27 | use syntax::ast::{self, Ident}; |
0731742a | 28 | use syntax::attr; |
60c5eb7d | 29 | use syntax_pos::symbol::{kw, sym}; |
e74abb32 | 30 | use syntax_pos::hygiene::MacroKind; |
60c5eb7d | 31 | use syntax_pos::{self, Pos}; |
94b46f34 | 32 | |
0531ce1d | 33 | use std::collections::hash_map::Entry; |
60c5eb7d | 34 | use std::hash::Hash; |
ff7c6d11 | 35 | use std::default::Default; |
60c5eb7d | 36 | use std::{mem, vec}; |
1a4d82fc JJ |
37 | use std::rc::Rc; |
38 | use std::u32; | |
1a4d82fc | 39 | |
e1599b0c | 40 | use crate::core::{self, DocContext, ImplTraitParam}; |
9fa01778 | 41 | use crate::doctree; |
9fa01778 | 42 | |
60c5eb7d | 43 | use utils::*; |
1a4d82fc | 44 | |
60c5eb7d | 45 | pub use utils::{get_auto_trait_and_blanket_impls, krate, register_res}; |
0531ce1d | 46 | |
60c5eb7d XL |
47 | pub use self::types::*; |
48 | pub use self::types::Type::*; | |
49 | pub use self::types::Mutability::*; | |
50 | pub use self::types::ItemEnum::*; | |
51 | pub use self::types::SelfTy::*; | |
52 | pub use self::types::FunctionRetTy::*; | |
53 | pub use self::types::Visibility::{Public, Inherited}; | |
0531ce1d XL |
54 | |
55 | const FN_OUTPUT_NAME: &'static str = "Output"; | |
3b2f2976 | 56 | |
1a4d82fc | 57 | pub trait Clean<T> { |
532ac7d7 | 58 | fn clean(&self, cx: &DocContext<'_>) -> T; |
1a4d82fc JJ |
59 | } |
60 | ||
c34b1796 | 61 | impl<T: Clean<U>, U> Clean<Vec<U>> for [T] { |
532ac7d7 | 62 | fn clean(&self, cx: &DocContext<'_>) -> Vec<U> { |
1a4d82fc JJ |
63 | self.iter().map(|x| x.clean(cx)).collect() |
64 | } | |
65 | } | |
66 | ||
a1dfa0c6 | 67 | impl<T: Clean<U>, U, V: Idx> Clean<IndexVec<V, U>> for IndexVec<V, T> { |
532ac7d7 | 68 | fn clean(&self, cx: &DocContext<'_>) -> IndexVec<V, U> { |
a1dfa0c6 XL |
69 | self.iter().map(|x| x.clean(cx)).collect() |
70 | } | |
71 | } | |
72 | ||
1a4d82fc | 73 | impl<T: Clean<U>, U> Clean<U> for P<T> { |
532ac7d7 | 74 | fn clean(&self, cx: &DocContext<'_>) -> U { |
1a4d82fc JJ |
75 | (**self).clean(cx) |
76 | } | |
77 | } | |
78 | ||
79 | impl<T: Clean<U>, U> Clean<U> for Rc<T> { | |
532ac7d7 | 80 | fn clean(&self, cx: &DocContext<'_>) -> U { |
1a4d82fc JJ |
81 | (**self).clean(cx) |
82 | } | |
83 | } | |
84 | ||
85 | impl<T: Clean<U>, U> Clean<Option<U>> for Option<T> { | |
532ac7d7 | 86 | fn clean(&self, cx: &DocContext<'_>) -> Option<U> { |
54a0048b | 87 | self.as_ref().map(|v| v.clean(cx)) |
1a4d82fc JJ |
88 | } |
89 | } | |
90 | ||
85aaf69f | 91 | impl<T, U> Clean<U> for ty::Binder<T> where T: Clean<U> { |
532ac7d7 | 92 | fn clean(&self, cx: &DocContext<'_>) -> U { |
83c7162d | 93 | self.skip_binder().clean(cx) |
85aaf69f SL |
94 | } |
95 | } | |
96 | ||
9cc50fc6 | 97 | impl<T: Clean<U>, U> Clean<Vec<U>> for P<[T]> { |
532ac7d7 | 98 | fn clean(&self, cx: &DocContext<'_>) -> Vec<U> { |
1a4d82fc JJ |
99 | self.iter().map(|x| x.clean(cx)).collect() |
100 | } | |
101 | } | |
102 | ||
92a42be0 | 103 | impl Clean<ExternalCrate> for CrateNum { |
532ac7d7 | 104 | fn clean(&self, cx: &DocContext<'_>) -> ExternalCrate { |
476ff2be SL |
105 | let root = DefId { krate: *self, index: CRATE_DEF_INDEX }; |
106 | let krate_span = cx.tcx.def_span(root); | |
b7449926 | 107 | let krate_src = cx.sess().source_map().span_to_filename(krate_span); |
476ff2be SL |
108 | |
109 | // Collect all inner modules which are tagged as implementations of | |
110 | // primitives. | |
111 | // | |
112 | // Note that this loop only searches the top-level items of the crate, | |
113 | // and this is intentional. If we were to search the entire crate for an | |
114 | // item tagged with `#[doc(primitive)]` then we would also have to | |
115 | // search the entirety of external modules for items tagged | |
116 | // `#[doc(primitive)]`, which is a pretty inefficient process (decoding | |
117 | // all that metadata unconditionally). | |
118 | // | |
119 | // In order to keep the metadata load under control, the | |
120 | // `#[doc(primitive)]` feature is explicitly designed to only allow the | |
121 | // primitive tags to show up as the top level items in a crate. | |
122 | // | |
123 | // Also note that this does not attempt to deal with modules tagged | |
124 | // duplicately for the same primitive. This is handled later on when | |
125 | // rendering by delegating everything to a hash map. | |
48663c56 XL |
126 | let as_primitive = |res: Res| { |
127 | if let Res::Def(DefKind::Mod, def_id) = res { | |
476ff2be SL |
128 | let attrs = cx.tcx.get_attrs(def_id).clean(cx); |
129 | let mut prim = None; | |
48663c56 | 130 | for attr in attrs.lists(sym::doc) { |
476ff2be | 131 | if let Some(v) = attr.value_str() { |
48663c56 | 132 | if attr.check_name(sym::primitive) { |
476ff2be SL |
133 | prim = PrimitiveType::from_str(&v.as_str()); |
134 | if prim.is_some() { | |
135 | break; | |
136 | } | |
abe05a73 | 137 | // FIXME: should warn on unknown primitives? |
476ff2be SL |
138 | } |
139 | } | |
140 | } | |
141 | return prim.map(|p| (def_id, p, attrs)); | |
92a42be0 | 142 | } |
476ff2be SL |
143 | None |
144 | }; | |
145 | let primitives = if root.is_local() { | |
0731742a | 146 | cx.tcx.hir().krate().module.item_ids.iter().filter_map(|&id| { |
dc9dc135 | 147 | let item = cx.tcx.hir().expect_item(id.id); |
e74abb32 | 148 | match item.kind { |
8faf50e0 | 149 | hir::ItemKind::Mod(_) => { |
48663c56 XL |
150 | as_primitive(Res::Def( |
151 | DefKind::Mod, | |
416331ca | 152 | cx.tcx.hir().local_def_id(id.id), |
48663c56 | 153 | )) |
476ff2be | 154 | } |
8faf50e0 XL |
155 | hir::ItemKind::Use(ref path, hir::UseKind::Single) |
156 | if item.vis.node.is_pub() => { | |
48663c56 | 157 | as_primitive(path.res).map(|(_, prim, attrs)| { |
476ff2be | 158 | // Pretend the primitive is local. |
416331ca | 159 | (cx.tcx.hir().local_def_id(id.id), prim, attrs) |
476ff2be SL |
160 | }) |
161 | } | |
162 | _ => None | |
163 | } | |
164 | }).collect() | |
165 | } else { | |
48663c56 | 166 | cx.tcx.item_children(root).iter().map(|item| item.res) |
476ff2be SL |
167 | .filter_map(as_primitive).collect() |
168 | }; | |
169 | ||
48663c56 XL |
170 | let as_keyword = |res: Res| { |
171 | if let Res::Def(DefKind::Mod, def_id) = res { | |
94b46f34 XL |
172 | let attrs = cx.tcx.get_attrs(def_id).clean(cx); |
173 | let mut keyword = None; | |
48663c56 | 174 | for attr in attrs.lists(sym::doc) { |
94b46f34 | 175 | if let Some(v) = attr.value_str() { |
48663c56 | 176 | if attr.check_name(sym::keyword) { |
dc9dc135 XL |
177 | if v.is_doc_keyword() { |
178 | keyword = Some(v.to_string()); | |
179 | break; | |
94b46f34 XL |
180 | } |
181 | // FIXME: should warn on unknown keywords? | |
182 | } | |
183 | } | |
184 | } | |
185 | return keyword.map(|p| (def_id, p, attrs)); | |
186 | } | |
187 | None | |
188 | }; | |
189 | let keywords = if root.is_local() { | |
0731742a | 190 | cx.tcx.hir().krate().module.item_ids.iter().filter_map(|&id| { |
dc9dc135 | 191 | let item = cx.tcx.hir().expect_item(id.id); |
e74abb32 | 192 | match item.kind { |
8faf50e0 | 193 | hir::ItemKind::Mod(_) => { |
48663c56 XL |
194 | as_keyword(Res::Def( |
195 | DefKind::Mod, | |
416331ca | 196 | cx.tcx.hir().local_def_id(id.id), |
48663c56 | 197 | )) |
94b46f34 | 198 | } |
8faf50e0 XL |
199 | hir::ItemKind::Use(ref path, hir::UseKind::Single) |
200 | if item.vis.node.is_pub() => { | |
48663c56 | 201 | as_keyword(path.res).map(|(_, prim, attrs)| { |
416331ca | 202 | (cx.tcx.hir().local_def_id(id.id), prim, attrs) |
94b46f34 XL |
203 | }) |
204 | } | |
205 | _ => None | |
206 | } | |
207 | }).collect() | |
208 | } else { | |
48663c56 | 209 | cx.tcx.item_children(root).iter().map(|item| item.res) |
94b46f34 XL |
210 | .filter_map(as_keyword).collect() |
211 | }; | |
212 | ||
1a4d82fc | 213 | ExternalCrate { |
476ff2be | 214 | name: cx.tcx.crate_name(*self).to_string(), |
ff7c6d11 | 215 | src: krate_src, |
476ff2be | 216 | attrs: cx.tcx.get_attrs(root).clean(cx), |
3b2f2976 | 217 | primitives, |
94b46f34 | 218 | keywords, |
1a4d82fc JJ |
219 | } |
220 | } | |
221 | } | |
222 | ||
dc9dc135 | 223 | impl Clean<Item> for doctree::Module<'_> { |
532ac7d7 | 224 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
1a4d82fc | 225 | let name = if self.name.is_some() { |
b7449926 | 226 | self.name.expect("No name provided").clean(cx) |
1a4d82fc | 227 | } else { |
b7449926 | 228 | String::new() |
1a4d82fc | 229 | }; |
85aaf69f | 230 | |
2c00a5a8 XL |
231 | // maintain a stack of mod ids, for doc comment path resolution |
232 | // but we also need to resolve the module's own docs based on whether its docs were written | |
233 | // inside or outside the module, so check for that | |
b7449926 | 234 | let attrs = self.attrs.clean(cx); |
2c00a5a8 | 235 | |
85aaf69f | 236 | let mut items: Vec<Item> = vec![]; |
0731742a | 237 | items.extend(self.extern_crates.iter().flat_map(|x| x.clean(cx))); |
62682a34 | 238 | items.extend(self.imports.iter().flat_map(|x| x.clean(cx))); |
0bf4aa26 XL |
239 | items.extend(self.structs.iter().map(|x| x.clean(cx))); |
240 | items.extend(self.unions.iter().map(|x| x.clean(cx))); | |
241 | items.extend(self.enums.iter().map(|x| x.clean(cx))); | |
85aaf69f | 242 | items.extend(self.fns.iter().map(|x| x.clean(cx))); |
dc9dc135 | 243 | items.extend(self.foreigns.iter().map(|x| x.clean(cx))); |
85aaf69f SL |
244 | items.extend(self.mods.iter().map(|x| x.clean(cx))); |
245 | items.extend(self.typedefs.iter().map(|x| x.clean(cx))); | |
416331ca | 246 | items.extend(self.opaque_tys.iter().map(|x| x.clean(cx))); |
85aaf69f SL |
247 | items.extend(self.statics.iter().map(|x| x.clean(cx))); |
248 | items.extend(self.constants.iter().map(|x| x.clean(cx))); | |
249 | items.extend(self.traits.iter().map(|x| x.clean(cx))); | |
62682a34 | 250 | items.extend(self.impls.iter().flat_map(|x| x.clean(cx))); |
85aaf69f | 251 | items.extend(self.macros.iter().map(|x| x.clean(cx))); |
0bf4aa26 | 252 | items.extend(self.proc_macros.iter().map(|x| x.clean(cx))); |
9fa01778 | 253 | items.extend(self.trait_aliases.iter().map(|x| x.clean(cx))); |
2c00a5a8 | 254 | |
1a4d82fc JJ |
255 | // determine if we should display the inner contents or |
256 | // the outer `mod` item for the source code. | |
257 | let whence = { | |
b7449926 | 258 | let cm = cx.sess().source_map(); |
ea8adc8c XL |
259 | let outer = cm.lookup_char_pos(self.where_outer.lo()); |
260 | let inner = cm.lookup_char_pos(self.where_inner.lo()); | |
1a4d82fc JJ |
261 | if outer.file.start_pos == inner.file.start_pos { |
262 | // mod foo { ... } | |
263 | self.where_outer | |
264 | } else { | |
b7449926 | 265 | // mod foo; (and a separate SourceFile for the contents) |
1a4d82fc JJ |
266 | self.where_inner |
267 | } | |
268 | }; | |
269 | ||
270 | Item { | |
271 | name: Some(name), | |
2c00a5a8 | 272 | attrs, |
1a4d82fc JJ |
273 | source: whence.clean(cx), |
274 | visibility: self.vis.clean(cx), | |
416331ca XL |
275 | stability: cx.stability(self.id).clean(cx), |
276 | deprecation: cx.deprecation(self.id).clean(cx), | |
0731742a | 277 | def_id: cx.tcx.hir().local_def_id(self.id), |
1a4d82fc JJ |
278 | inner: ModuleItem(Module { |
279 | is_crate: self.is_crate, | |
3b2f2976 | 280 | items, |
1a4d82fc JJ |
281 | }) |
282 | } | |
283 | } | |
284 | } | |
285 | ||
476ff2be | 286 | impl Clean<Attributes> for [ast::Attribute] { |
532ac7d7 | 287 | fn clean(&self, cx: &DocContext<'_>) -> Attributes { |
b7449926 | 288 | Attributes::from_ast(cx.sess().diagnostic(), self) |
1a4d82fc JJ |
289 | } |
290 | } | |
291 | ||
8faf50e0 | 292 | impl Clean<GenericBound> for hir::GenericBound { |
532ac7d7 | 293 | fn clean(&self, cx: &DocContext<'_>) -> GenericBound { |
1a4d82fc | 294 | match *self { |
8faf50e0 XL |
295 | hir::GenericBound::Outlives(lt) => GenericBound::Outlives(lt.clean(cx)), |
296 | hir::GenericBound::Trait(ref t, modifier) => { | |
297 | GenericBound::TraitBound(t.clean(cx), modifier) | |
298 | } | |
1a4d82fc JJ |
299 | } |
300 | } | |
301 | } | |
302 | ||
8faf50e0 | 303 | impl<'a, 'tcx> Clean<GenericBound> for (&'a ty::TraitRef<'tcx>, Vec<TypeBinding>) { |
532ac7d7 | 304 | fn clean(&self, cx: &DocContext<'_>) -> GenericBound { |
0531ce1d XL |
305 | let (trait_ref, ref bounds) = *self; |
306 | inline::record_extern_fqn(cx, trait_ref.def_id, TypeKind::Trait); | |
e1599b0c | 307 | let path = external_path(cx, cx.tcx.item_name(trait_ref.def_id), |
0531ce1d | 308 | Some(trait_ref.def_id), true, bounds.clone(), trait_ref.substs); |
1a4d82fc | 309 | |
0531ce1d | 310 | debug!("ty::TraitRef\n subst: {:?}\n", trait_ref.substs); |
1a4d82fc JJ |
311 | |
312 | // collect any late bound regions | |
313 | let mut late_bounds = vec![]; | |
0531ce1d | 314 | for ty_s in trait_ref.input_types().skip(1) { |
e74abb32 | 315 | if let ty::Tuple(ts) = ty_s.kind { |
85aaf69f | 316 | for &ty_s in ts { |
e74abb32 | 317 | if let ty::Ref(ref reg, _, _) = ty_s.expect_ty().kind { |
7cac9316 | 318 | if let &ty::RegionKind::ReLateBound(..) = *reg { |
1a4d82fc | 319 | debug!(" hit an ReLateBound {:?}", reg); |
8faf50e0 XL |
320 | if let Some(Lifetime(name)) = reg.clean(cx) { |
321 | late_bounds.push(GenericParamDef { | |
322 | name, | |
323 | kind: GenericParamDefKind::Lifetime, | |
324 | }); | |
1a4d82fc JJ |
325 | } |
326 | } | |
327 | } | |
328 | } | |
329 | } | |
330 | } | |
331 | ||
8faf50e0 | 332 | GenericBound::TraitBound( |
54a0048b SL |
333 | PolyTrait { |
334 | trait_: ResolvedPath { | |
3b2f2976 | 335 | path, |
532ac7d7 | 336 | param_names: None, |
0531ce1d | 337 | did: trait_ref.def_id, |
54a0048b SL |
338 | is_generic: false, |
339 | }, | |
ff7c6d11 | 340 | generic_params: late_bounds, |
62682a34 | 341 | }, |
54a0048b SL |
342 | hir::TraitBoundModifier::None |
343 | ) | |
1a4d82fc JJ |
344 | } |
345 | } | |
346 | ||
8faf50e0 | 347 | impl<'tcx> Clean<GenericBound> for ty::TraitRef<'tcx> { |
532ac7d7 | 348 | fn clean(&self, cx: &DocContext<'_>) -> GenericBound { |
0531ce1d XL |
349 | (self, vec![]).clean(cx) |
350 | } | |
351 | } | |
352 | ||
532ac7d7 XL |
353 | impl<'tcx> Clean<Option<Vec<GenericBound>>> for InternalSubsts<'tcx> { |
354 | fn clean(&self, cx: &DocContext<'_>) -> Option<Vec<GenericBound>> { | |
1a4d82fc | 355 | let mut v = Vec::new(); |
8faf50e0 XL |
356 | v.extend(self.regions().filter_map(|r| r.clean(cx)).map(GenericBound::Outlives)); |
357 | v.extend(self.types().map(|t| GenericBound::TraitBound(PolyTrait { | |
1a4d82fc | 358 | trait_: t.clean(cx), |
ff7c6d11 | 359 | generic_params: Vec::new(), |
e9174d1e | 360 | }, hir::TraitBoundModifier::None))); |
9346a6ac | 361 | if !v.is_empty() {Some(v)} else {None} |
1a4d82fc JJ |
362 | } |
363 | } | |
364 | ||
e9174d1e | 365 | impl Clean<Lifetime> for hir::Lifetime { |
532ac7d7 XL |
366 | fn clean(&self, cx: &DocContext<'_>) -> Lifetime { |
367 | if self.hir_id != hir::DUMMY_HIR_ID { | |
9fa01778 | 368 | let def = cx.tcx.named_region(self.hir_id); |
0531ce1d XL |
369 | match def { |
370 | Some(rl::Region::EarlyBound(_, node_id, _)) | | |
371 | Some(rl::Region::LateBound(_, node_id, _)) | | |
372 | Some(rl::Region::Free(_, node_id)) => { | |
373 | if let Some(lt) = cx.lt_substs.borrow().get(&node_id).cloned() { | |
374 | return lt; | |
375 | } | |
9e0c209e | 376 | } |
0531ce1d | 377 | _ => {} |
9e0c209e SL |
378 | } |
379 | } | |
8faf50e0 | 380 | Lifetime(self.name.ident().to_string()) |
1a4d82fc JJ |
381 | } |
382 | } | |
383 | ||
8faf50e0 | 384 | impl Clean<Lifetime> for hir::GenericParam { |
532ac7d7 | 385 | fn clean(&self, _: &DocContext<'_>) -> Lifetime { |
8faf50e0 XL |
386 | match self.kind { |
387 | hir::GenericParamKind::Lifetime { .. } => { | |
388 | if self.bounds.len() > 0 { | |
389 | let mut bounds = self.bounds.iter().map(|bound| match bound { | |
390 | hir::GenericBound::Outlives(lt) => lt, | |
391 | _ => panic!(), | |
392 | }); | |
b7449926 | 393 | let name = bounds.next().expect("no more bounds").name.ident(); |
8faf50e0 XL |
394 | let mut s = format!("{}: {}", self.name.ident(), name); |
395 | for bound in bounds { | |
396 | s.push_str(&format!(" + {}", bound.name.ident())); | |
397 | } | |
398 | Lifetime(s) | |
399 | } else { | |
400 | Lifetime(self.name.ident().to_string()) | |
401 | } | |
a7813a04 | 402 | } |
8faf50e0 | 403 | _ => panic!(), |
a7813a04 | 404 | } |
1a4d82fc JJ |
405 | } |
406 | } | |
407 | ||
9fa01778 | 408 | impl Clean<Constant> for hir::ConstArg { |
532ac7d7 | 409 | fn clean(&self, cx: &DocContext<'_>) -> Constant { |
9fa01778 XL |
410 | Constant { |
411 | type_: cx.tcx.type_of(cx.tcx.hir().body_owner_def_id(self.value.body)).clean(cx), | |
412 | expr: print_const_expr(cx, self.value.body), | |
413 | } | |
414 | } | |
415 | } | |
416 | ||
dc9dc135 | 417 | impl Clean<Lifetime> for ty::GenericParamDef { |
532ac7d7 | 418 | fn clean(&self, _cx: &DocContext<'_>) -> Lifetime { |
c1a9b12d | 419 | Lifetime(self.name.to_string()) |
1a4d82fc JJ |
420 | } |
421 | } | |
422 | ||
7cac9316 | 423 | impl Clean<Option<Lifetime>> for ty::RegionKind { |
532ac7d7 | 424 | fn clean(&self, cx: &DocContext<'_>) -> Option<Lifetime> { |
1a4d82fc JJ |
425 | match *self { |
426 | ty::ReStatic => Some(Lifetime::statik()), | |
8bb4bdeb | 427 | ty::ReLateBound(_, ty::BrNamed(_, name)) => Some(Lifetime(name.to_string())), |
9346a6ac | 428 | ty::ReEarlyBound(ref data) => Some(Lifetime(data.name.clean(cx))), |
1a4d82fc JJ |
429 | |
430 | ty::ReLateBound(..) | | |
431 | ty::ReFree(..) | | |
432 | ty::ReScope(..) | | |
e9174d1e | 433 | ty::ReVar(..) | |
0bf4aa26 | 434 | ty::RePlaceholder(..) | |
3157f602 | 435 | ty::ReEmpty | |
ff7c6d11 | 436 | ty::ReClosureBound(_) | |
9fa01778 | 437 | ty::ReErased => { |
416331ca | 438 | debug!("cannot clean region {:?}", self); |
9fa01778 XL |
439 | None |
440 | } | |
1a4d82fc JJ |
441 | } |
442 | } | |
443 | } | |
444 | ||
e9174d1e | 445 | impl Clean<WherePredicate> for hir::WherePredicate { |
532ac7d7 | 446 | fn clean(&self, cx: &DocContext<'_>) -> WherePredicate { |
1a4d82fc | 447 | match *self { |
e9174d1e | 448 | hir::WherePredicate::BoundPredicate(ref wbp) => { |
1a4d82fc JJ |
449 | WherePredicate::BoundPredicate { |
450 | ty: wbp.bounded_ty.clean(cx), | |
451 | bounds: wbp.bounds.clean(cx) | |
452 | } | |
453 | } | |
454 | ||
e9174d1e | 455 | hir::WherePredicate::RegionPredicate(ref wrp) => { |
1a4d82fc JJ |
456 | WherePredicate::RegionPredicate { |
457 | lifetime: wrp.lifetime.clean(cx), | |
458 | bounds: wrp.bounds.clean(cx) | |
459 | } | |
460 | } | |
461 | ||
32a655c1 SL |
462 | hir::WherePredicate::EqPredicate(ref wrp) => { |
463 | WherePredicate::EqPredicate { | |
464 | lhs: wrp.lhs_ty.clean(cx), | |
465 | rhs: wrp.rhs_ty.clean(cx) | |
466 | } | |
1a4d82fc JJ |
467 | } |
468 | } | |
469 | } | |
470 | } | |
471 | ||
9fa01778 | 472 | impl<'a> Clean<Option<WherePredicate>> for ty::Predicate<'a> { |
532ac7d7 | 473 | fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> { |
54a0048b | 474 | use rustc::ty::Predicate; |
85aaf69f SL |
475 | |
476 | match *self { | |
9fa01778 XL |
477 | Predicate::Trait(ref pred) => Some(pred.clean(cx)), |
478 | Predicate::Subtype(ref pred) => Some(pred.clean(cx)), | |
85aaf69f SL |
479 | Predicate::RegionOutlives(ref pred) => pred.clean(cx), |
480 | Predicate::TypeOutlives(ref pred) => pred.clean(cx), | |
9fa01778 | 481 | Predicate::Projection(ref pred) => Some(pred.clean(cx)), |
a1dfa0c6 XL |
482 | |
483 | Predicate::WellFormed(..) | | |
484 | Predicate::ObjectSafe(..) | | |
485 | Predicate::ClosureKind(..) | | |
ea8adc8c | 486 | Predicate::ConstEvaluatable(..) => panic!("not user writable"), |
85aaf69f SL |
487 | } |
488 | } | |
489 | } | |
490 | ||
491 | impl<'a> Clean<WherePredicate> for ty::TraitPredicate<'a> { | |
532ac7d7 | 492 | fn clean(&self, cx: &DocContext<'_>) -> WherePredicate { |
85aaf69f | 493 | WherePredicate::BoundPredicate { |
9e0c209e | 494 | ty: self.trait_ref.self_ty().clean(cx), |
85aaf69f SL |
495 | bounds: vec![self.trait_ref.clean(cx)] |
496 | } | |
497 | } | |
498 | } | |
499 | ||
cc61c64b | 500 | impl<'tcx> Clean<WherePredicate> for ty::SubtypePredicate<'tcx> { |
532ac7d7 | 501 | fn clean(&self, _cx: &DocContext<'_>) -> WherePredicate { |
cc61c64b XL |
502 | panic!("subtype predicates are an internal rustc artifact \ |
503 | and should not be seen by rustdoc") | |
504 | } | |
505 | } | |
506 | ||
9fa01778 XL |
507 | impl<'tcx> Clean<Option<WherePredicate>> for |
508 | ty::OutlivesPredicate<ty::Region<'tcx>,ty::Region<'tcx>> { | |
509 | ||
532ac7d7 | 510 | fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> { |
85aaf69f | 511 | let ty::OutlivesPredicate(ref a, ref b) = *self; |
9fa01778 XL |
512 | |
513 | match (a, b) { | |
514 | (ty::ReEmpty, ty::ReEmpty) => { | |
515 | return None; | |
516 | }, | |
517 | _ => {} | |
518 | } | |
519 | ||
520 | Some(WherePredicate::RegionPredicate { | |
b7449926 XL |
521 | lifetime: a.clean(cx).expect("failed to clean lifetime"), |
522 | bounds: vec![GenericBound::Outlives(b.clean(cx).expect("failed to clean bounds"))] | |
9fa01778 | 523 | }) |
85aaf69f SL |
524 | } |
525 | } | |
526 | ||
9fa01778 | 527 | impl<'tcx> Clean<Option<WherePredicate>> for ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>> { |
532ac7d7 | 528 | fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> { |
85aaf69f SL |
529 | let ty::OutlivesPredicate(ref ty, ref lt) = *self; |
530 | ||
9fa01778 XL |
531 | match lt { |
532 | ty::ReEmpty => return None, | |
533 | _ => {} | |
534 | } | |
535 | ||
536 | Some(WherePredicate::BoundPredicate { | |
85aaf69f | 537 | ty: ty.clean(cx), |
b7449926 | 538 | bounds: vec![GenericBound::Outlives(lt.clean(cx).expect("failed to clean lifetimes"))] |
9fa01778 | 539 | }) |
85aaf69f SL |
540 | } |
541 | } | |
542 | ||
543 | impl<'tcx> Clean<WherePredicate> for ty::ProjectionPredicate<'tcx> { | |
532ac7d7 | 544 | fn clean(&self, cx: &DocContext<'_>) -> WherePredicate { |
85aaf69f SL |
545 | WherePredicate::EqPredicate { |
546 | lhs: self.projection_ty.clean(cx), | |
547 | rhs: self.ty.clean(cx) | |
548 | } | |
549 | } | |
550 | } | |
551 | ||
552 | impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> { | |
532ac7d7 | 553 | fn clean(&self, cx: &DocContext<'_>) -> Type { |
041b39d2 | 554 | let trait_ = match self.trait_ref(cx.tcx).clean(cx) { |
8faf50e0 XL |
555 | GenericBound::TraitBound(t, _) => t.trait_, |
556 | GenericBound::Outlives(_) => panic!("cleaning a trait got a lifetime"), | |
85aaf69f SL |
557 | }; |
558 | Type::QPath { | |
8faf50e0 | 559 | name: cx.tcx.associated_item(self.item_def_id).ident.name.clean(cx), |
041b39d2 | 560 | self_type: box self.self_ty().clean(cx), |
85aaf69f SL |
561 | trait_: box trait_ |
562 | } | |
563 | } | |
564 | } | |
565 | ||
532ac7d7 XL |
566 | impl Clean<GenericParamDef> for ty::GenericParamDef { |
567 | fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef { | |
8faf50e0 XL |
568 | let (name, kind) = match self.kind { |
569 | ty::GenericParamDefKind::Lifetime => { | |
570 | (self.name.to_string(), GenericParamDefKind::Lifetime) | |
571 | } | |
e1599b0c | 572 | ty::GenericParamDefKind::Type { has_default, synthetic, .. } => { |
8faf50e0 XL |
573 | let default = if has_default { |
574 | Some(cx.tcx.type_of(self.def_id).clean(cx)) | |
575 | } else { | |
576 | None | |
577 | }; | |
578 | (self.name.clean(cx), GenericParamDefKind::Type { | |
579 | did: self.def_id, | |
580 | bounds: vec![], // These are filled in from the where-clauses. | |
581 | default, | |
e1599b0c | 582 | synthetic, |
8faf50e0 XL |
583 | }) |
584 | } | |
532ac7d7 XL |
585 | ty::GenericParamDefKind::Const { .. } => { |
586 | (self.name.clean(cx), GenericParamDefKind::Const { | |
587 | did: self.def_id, | |
588 | ty: cx.tcx.type_of(self.def_id).clean(cx), | |
589 | }) | |
590 | } | |
8faf50e0 XL |
591 | }; |
592 | ||
593 | GenericParamDef { | |
594 | name, | |
595 | kind, | |
0531ce1d XL |
596 | } |
597 | } | |
598 | } | |
599 | ||
94b46f34 | 600 | impl Clean<GenericParamDef> for hir::GenericParam { |
532ac7d7 | 601 | fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef { |
8faf50e0 XL |
602 | let (name, kind) = match self.kind { |
603 | hir::GenericParamKind::Lifetime { .. } => { | |
604 | let name = if self.bounds.len() > 0 { | |
605 | let mut bounds = self.bounds.iter().map(|bound| match bound { | |
606 | hir::GenericBound::Outlives(lt) => lt, | |
607 | _ => panic!(), | |
608 | }); | |
b7449926 | 609 | let name = bounds.next().expect("no more bounds").name.ident(); |
8faf50e0 XL |
610 | let mut s = format!("{}: {}", self.name.ident(), name); |
611 | for bound in bounds { | |
612 | s.push_str(&format!(" + {}", bound.name.ident())); | |
613 | } | |
614 | s | |
615 | } else { | |
616 | self.name.ident().to_string() | |
617 | }; | |
618 | (name, GenericParamDefKind::Lifetime) | |
619 | } | |
9fa01778 | 620 | hir::GenericParamKind::Type { ref default, synthetic } => { |
8faf50e0 | 621 | (self.name.ident().name.clean(cx), GenericParamDefKind::Type { |
416331ca | 622 | did: cx.tcx.hir().local_def_id(self.hir_id), |
8faf50e0 XL |
623 | bounds: self.bounds.clean(cx), |
624 | default: default.clean(cx), | |
e74abb32 | 625 | synthetic, |
8faf50e0 XL |
626 | }) |
627 | } | |
9fa01778 XL |
628 | hir::GenericParamKind::Const { ref ty } => { |
629 | (self.name.ident().name.clean(cx), GenericParamDefKind::Const { | |
416331ca | 630 | did: cx.tcx.hir().local_def_id(self.hir_id), |
9fa01778 XL |
631 | ty: ty.clean(cx), |
632 | }) | |
633 | } | |
8faf50e0 XL |
634 | }; |
635 | ||
636 | GenericParamDef { | |
637 | name, | |
638 | kind, | |
ff7c6d11 XL |
639 | } |
640 | } | |
641 | } | |
642 | ||
e9174d1e | 643 | impl Clean<Generics> for hir::Generics { |
532ac7d7 | 644 | fn clean(&self, cx: &DocContext<'_>) -> Generics { |
94b46f34 XL |
645 | // Synthetic type-parameters are inserted after normal ones. |
646 | // In order for normal parameters to be able to refer to synthetic ones, | |
647 | // scans them first. | |
648 | fn is_impl_trait(param: &hir::GenericParam) -> bool { | |
8faf50e0 XL |
649 | match param.kind { |
650 | hir::GenericParamKind::Type { synthetic, .. } => { | |
651 | synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) | |
652 | } | |
653 | _ => false, | |
94b46f34 XL |
654 | } |
655 | } | |
656 | let impl_trait_params = self.params | |
657 | .iter() | |
8faf50e0 XL |
658 | .filter(|param| is_impl_trait(param)) |
659 | .map(|param| { | |
660 | let param: GenericParamDef = param.clean(cx); | |
661 | match param.kind { | |
662 | GenericParamDefKind::Lifetime => unreachable!(), | |
663 | GenericParamDefKind::Type { did, ref bounds, .. } => { | |
e1599b0c | 664 | cx.impl_trait_bounds.borrow_mut().insert(did.into(), bounds.clone()); |
8faf50e0 | 665 | } |
9fa01778 | 666 | GenericParamDefKind::Const { .. } => unreachable!(), |
94b46f34 | 667 | } |
8faf50e0 | 668 | param |
94b46f34 XL |
669 | }) |
670 | .collect::<Vec<_>>(); | |
671 | ||
0531ce1d | 672 | let mut params = Vec::with_capacity(self.params.len()); |
94b46f34 | 673 | for p in self.params.iter().filter(|p| !is_impl_trait(p)) { |
0531ce1d | 674 | let p = p.clean(cx); |
0531ce1d XL |
675 | params.push(p); |
676 | } | |
94b46f34 XL |
677 | params.extend(impl_trait_params); |
678 | ||
8faf50e0 | 679 | let mut generics = Generics { |
0531ce1d | 680 | params, |
8faf50e0 | 681 | where_predicates: self.where_clause.predicates.clean(cx), |
ff7c6d11 XL |
682 | }; |
683 | ||
684 | // Some duplicates are generated for ?Sized bounds between type params and where | |
685 | // predicates. The point in here is to move the bounds definitions from type params | |
686 | // to where predicates when such cases occur. | |
8faf50e0 | 687 | for where_pred in &mut generics.where_predicates { |
ff7c6d11 XL |
688 | match *where_pred { |
689 | WherePredicate::BoundPredicate { ty: Generic(ref name), ref mut bounds } => { | |
690 | if bounds.is_empty() { | |
8faf50e0 XL |
691 | for param in &mut generics.params { |
692 | match param.kind { | |
693 | GenericParamDefKind::Lifetime => {} | |
694 | GenericParamDefKind::Type { bounds: ref mut ty_bounds, .. } => { | |
695 | if ¶m.name == name { | |
696 | mem::swap(bounds, ty_bounds); | |
697 | break | |
698 | } | |
ff7c6d11 | 699 | } |
9fa01778 | 700 | GenericParamDefKind::Const { .. } => {} |
ff7c6d11 XL |
701 | } |
702 | } | |
703 | } | |
704 | } | |
705 | _ => continue, | |
706 | } | |
1a4d82fc | 707 | } |
8faf50e0 | 708 | generics |
1a4d82fc JJ |
709 | } |
710 | } | |
711 | ||
e74abb32 | 712 | impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx>) { |
532ac7d7 | 713 | fn clean(&self, cx: &DocContext<'_>) -> Generics { |
85aaf69f | 714 | use self::WherePredicate as WP; |
e1599b0c | 715 | use std::collections::BTreeMap; |
85aaf69f | 716 | |
9e0c209e | 717 | let (gens, preds) = *self; |
85aaf69f | 718 | |
e1599b0c XL |
719 | // Don't populate `cx.impl_trait_bounds` before `clean`ning `where` clauses, |
720 | // since `Clean for ty::Predicate` would consume them. | |
721 | let mut impl_trait = BTreeMap::<ImplTraitParam, Vec<GenericBound>>::default(); | |
722 | ||
9346a6ac AL |
723 | // Bounds in the type_params and lifetimes fields are repeated in the |
724 | // predicates field (see rustc_typeck::collect::ty_generics), so remove | |
725 | // them. | |
e1599b0c XL |
726 | let stripped_typarams = gens.params.iter() |
727 | .filter_map(|param| match param.kind { | |
728 | ty::GenericParamDefKind::Lifetime => None, | |
729 | ty::GenericParamDefKind::Type { synthetic, .. } => { | |
e74abb32 | 730 | if param.name == kw::SelfUpper { |
e1599b0c XL |
731 | assert_eq!(param.index, 0); |
732 | return None; | |
733 | } | |
734 | if synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) { | |
735 | impl_trait.insert(param.index.into(), vec![]); | |
736 | return None; | |
737 | } | |
738 | Some(param.clean(cx)) | |
739 | } | |
740 | ty::GenericParamDefKind::Const { .. } => None, | |
741 | }).collect::<Vec<GenericParamDef>>(); | |
742 | ||
743 | // param index -> [(DefId of trait, associated type name, type)] | |
744 | let mut impl_trait_proj = | |
745 | FxHashMap::<u32, Vec<(DefId, String, Ty<'tcx>)>>::default(); | |
746 | ||
747 | let where_predicates = preds.predicates.iter() | |
748 | .flat_map(|(p, _)| { | |
749 | let mut projection = None; | |
750 | let param_idx = (|| { | |
751 | if let Some(trait_ref) = p.to_opt_poly_trait_ref() { | |
e74abb32 | 752 | if let ty::Param(param) = trait_ref.self_ty().kind { |
e1599b0c XL |
753 | return Some(param.index); |
754 | } | |
755 | } else if let Some(outlives) = p.to_opt_type_outlives() { | |
e74abb32 | 756 | if let ty::Param(param) = outlives.skip_binder().0.kind { |
e1599b0c XL |
757 | return Some(param.index); |
758 | } | |
759 | } else if let ty::Predicate::Projection(p) = p { | |
e74abb32 | 760 | if let ty::Param(param) = p.skip_binder().projection_ty.self_ty().kind { |
e1599b0c XL |
761 | projection = Some(p); |
762 | return Some(param.index); | |
763 | } | |
764 | } | |
765 | ||
766 | None | |
767 | })(); | |
768 | ||
769 | if let Some(param_idx) = param_idx { | |
770 | if let Some(b) = impl_trait.get_mut(¶m_idx.into()) { | |
771 | let p = p.clean(cx)?; | |
772 | ||
773 | b.extend( | |
774 | p.get_bounds() | |
775 | .into_iter() | |
776 | .flatten() | |
777 | .cloned() | |
778 | .filter(|b| !b.is_sized_bound(cx)) | |
779 | ); | |
780 | ||
781 | let proj = projection | |
782 | .map(|p| (p.skip_binder().projection_ty.clean(cx), p.skip_binder().ty)); | |
783 | if let Some(((_, trait_did, name), rhs)) = | |
784 | proj.as_ref().and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs))) | |
785 | { | |
786 | impl_trait_proj | |
787 | .entry(param_idx) | |
788 | .or_default() | |
789 | .push((trait_did, name.to_string(), rhs)); | |
790 | } | |
791 | ||
792 | return None; | |
793 | } | |
794 | } | |
795 | ||
796 | Some(p) | |
797 | }) | |
798 | .collect::<Vec<_>>(); | |
799 | ||
800 | for (param, mut bounds) in impl_trait { | |
801 | // Move trait bounds to the front. | |
802 | bounds.sort_by_key(|b| if let GenericBound::TraitBound(..) = b { | |
803 | false | |
804 | } else { | |
805 | true | |
806 | }); | |
807 | ||
808 | if let crate::core::ImplTraitParam::ParamIndex(idx) = param { | |
809 | if let Some(proj) = impl_trait_proj.remove(&idx) { | |
810 | for (trait_did, name, rhs) in proj { | |
811 | simplify::merge_bounds( | |
812 | cx, | |
813 | &mut bounds, | |
814 | trait_did, | |
815 | &name, | |
816 | &rhs.clean(cx), | |
817 | ); | |
818 | } | |
94b46f34 | 819 | } |
e1599b0c XL |
820 | } else { |
821 | unreachable!(); | |
9e0c209e | 822 | } |
85aaf69f | 823 | |
e1599b0c XL |
824 | cx.impl_trait_bounds.borrow_mut().insert(param, bounds); |
825 | } | |
826 | ||
827 | // Now that `cx.impl_trait_bounds` is populated, we can process | |
828 | // remaining predicates which could contain `impl Trait`. | |
829 | let mut where_predicates = where_predicates | |
830 | .into_iter() | |
831 | .flat_map(|p| p.clean(cx)) | |
0bf4aa26 | 832 | .collect::<Vec<_>>(); |
85aaf69f | 833 | |
9346a6ac | 834 | // Type parameters and have a Sized bound by default unless removed with |
ff7c6d11 | 835 | // ?Sized. Scan through the predicates and mark any type parameter with |
9346a6ac AL |
836 | // a Sized bound, removing the bounds as we find them. |
837 | // | |
838 | // Note that associated types also have a sized bound by default, but we | |
d9579d0f | 839 | // don't actually know the set of associated types right here so that's |
9346a6ac | 840 | // handled in cleaning associated types |
0bf4aa26 | 841 | let mut sized_params = FxHashSet::default(); |
9346a6ac AL |
842 | where_predicates.retain(|pred| { |
843 | match *pred { | |
844 | WP::BoundPredicate { ty: Generic(ref g), ref bounds } => { | |
845 | if bounds.iter().any(|b| b.is_sized_bound(cx)) { | |
846 | sized_params.insert(g.clone()); | |
847 | false | |
848 | } else { | |
849 | true | |
850 | } | |
85aaf69f | 851 | } |
9346a6ac | 852 | _ => true, |
85aaf69f | 853 | } |
9346a6ac | 854 | }); |
85aaf69f | 855 | |
9346a6ac AL |
856 | // Run through the type parameters again and insert a ?Sized |
857 | // unbound for any we didn't find to be Sized. | |
85aaf69f SL |
858 | for tp in &stripped_typarams { |
859 | if !sized_params.contains(&tp.name) { | |
85aaf69f SL |
860 | where_predicates.push(WP::BoundPredicate { |
861 | ty: Type::Generic(tp.name.clone()), | |
8faf50e0 | 862 | bounds: vec![GenericBound::maybe_sized(cx)], |
85aaf69f SL |
863 | }) |
864 | } | |
865 | } | |
866 | ||
867 | // It would be nice to collect all of the bounds on a type and recombine | |
0731742a | 868 | // them if possible, to avoid e.g., `where T: Foo, T: Bar, T: Sized, T: 'a` |
85aaf69f SL |
869 | // and instead see `where T: Foo + Bar + Sized + 'a` |
870 | ||
1a4d82fc | 871 | Generics { |
94b46f34 XL |
872 | params: gens.params |
873 | .iter() | |
8faf50e0 XL |
874 | .flat_map(|param| match param.kind { |
875 | ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)), | |
876 | ty::GenericParamDefKind::Type { .. } => None, | |
532ac7d7 | 877 | ty::GenericParamDefKind::Const { .. } => Some(param.clean(cx)), |
8faf50e0 | 878 | }).chain(simplify::ty_params(stripped_typarams).into_iter()) |
94b46f34 | 879 | .collect(), |
9346a6ac | 880 | where_predicates: simplify::where_clauses(cx, where_predicates), |
1a4d82fc JJ |
881 | } |
882 | } | |
883 | } | |
884 | ||
60c5eb7d | 885 | impl<'a> Clean<Method> for (&'a hir::FnSig, &'a hir::Generics, hir::BodyId, |
532ac7d7 XL |
886 | Option<hir::Defaultness>) { |
887 | fn clean(&self, cx: &DocContext<'_>) -> Method { | |
0531ce1d XL |
888 | let (generics, decl) = enter_impl_trait(cx, || { |
889 | (self.1.clean(cx), (&*self.0.decl, self.2).clean(cx)) | |
890 | }); | |
532ac7d7 | 891 | let (all_types, ret_types) = get_all_types(&generics, &decl, cx); |
c34b1796 | 892 | Method { |
0531ce1d XL |
893 | decl, |
894 | generics, | |
8faf50e0 | 895 | header: self.0.header, |
532ac7d7 XL |
896 | defaultness: self.3, |
897 | all_types, | |
898 | ret_types, | |
1a4d82fc JJ |
899 | } |
900 | } | |
901 | } | |
902 | ||
dc9dc135 | 903 | impl Clean<Item> for doctree::Function<'_> { |
532ac7d7 | 904 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
0531ce1d | 905 | let (generics, decl) = enter_impl_trait(cx, || { |
dc9dc135 | 906 | (self.generics.clean(cx), (self.decl, self.body).clean(cx)) |
0531ce1d | 907 | }); |
8faf50e0 | 908 | |
416331ca | 909 | let did = cx.tcx.hir().local_def_id(self.id); |
0731742a XL |
910 | let constness = if cx.tcx.is_min_const_fn(did) { |
911 | hir::Constness::Const | |
912 | } else { | |
913 | hir::Constness::NotConst | |
914 | }; | |
532ac7d7 | 915 | let (all_types, ret_types) = get_all_types(&generics, &decl, cx); |
1a4d82fc JJ |
916 | Item { |
917 | name: Some(self.name.clean(cx)), | |
918 | attrs: self.attrs.clean(cx), | |
919 | source: self.whence.clean(cx), | |
920 | visibility: self.vis.clean(cx), | |
416331ca XL |
921 | stability: cx.stability(self.id).clean(cx), |
922 | deprecation: cx.deprecation(self.id).clean(cx), | |
0731742a | 923 | def_id: did, |
1a4d82fc | 924 | inner: FunctionItem(Function { |
0531ce1d XL |
925 | decl, |
926 | generics, | |
0731742a | 927 | header: hir::FnHeader { constness, ..self.header }, |
532ac7d7 XL |
928 | all_types, |
929 | ret_types, | |
1a4d82fc JJ |
930 | }), |
931 | } | |
60c5eb7d | 932 | } |
1a4d82fc JJ |
933 | } |
934 | ||
8faf50e0 | 935 | impl<'a> Clean<Arguments> for (&'a [hir::Ty], &'a [ast::Ident]) { |
532ac7d7 | 936 | fn clean(&self, cx: &DocContext<'_>) -> Arguments { |
32a655c1 SL |
937 | Arguments { |
938 | values: self.0.iter().enumerate().map(|(i, ty)| { | |
8faf50e0 | 939 | let mut name = self.1.get(i).map(|ident| ident.to_string()) |
32a655c1 SL |
940 | .unwrap_or(String::new()); |
941 | if name.is_empty() { | |
942 | name = "_".to_string(); | |
943 | } | |
944 | Argument { | |
3b2f2976 | 945 | name, |
32a655c1 SL |
946 | type_: ty.clean(cx), |
947 | } | |
948 | }).collect() | |
949 | } | |
950 | } | |
951 | } | |
952 | ||
8faf50e0 | 953 | impl<'a> Clean<Arguments> for (&'a [hir::Ty], hir::BodyId) { |
532ac7d7 | 954 | fn clean(&self, cx: &DocContext<'_>) -> Arguments { |
0731742a | 955 | let body = cx.tcx.hir().body(self.1); |
32a655c1 SL |
956 | |
957 | Arguments { | |
958 | values: self.0.iter().enumerate().map(|(i, ty)| { | |
959 | Argument { | |
e1599b0c | 960 | name: name_from_pat(&body.params[i].pat), |
32a655c1 SL |
961 | type_: ty.clean(cx), |
962 | } | |
963 | }).collect() | |
964 | } | |
965 | } | |
966 | } | |
967 | ||
968 | impl<'a, A: Copy> Clean<FnDecl> for (&'a hir::FnDecl, A) | |
8faf50e0 | 969 | where (&'a [hir::Ty], A): Clean<Arguments> |
32a655c1 | 970 | { |
532ac7d7 | 971 | fn clean(&self, cx: &DocContext<'_>) -> FnDecl { |
1a4d82fc | 972 | FnDecl { |
32a655c1 SL |
973 | inputs: (&self.0.inputs[..], self.1).clean(cx), |
974 | output: self.0.output.clean(cx), | |
e74abb32 | 975 | c_variadic: self.0.c_variadic, |
532ac7d7 | 976 | attrs: Attributes::default(), |
1a4d82fc JJ |
977 | } |
978 | } | |
979 | } | |
980 | ||
dc9dc135 | 981 | impl<'tcx> Clean<FnDecl> for (DefId, ty::PolyFnSig<'tcx>) { |
532ac7d7 | 982 | fn clean(&self, cx: &DocContext<'_>) -> FnDecl { |
1a4d82fc | 983 | let (did, sig) = *self; |
532ac7d7 | 984 | let mut names = if cx.tcx.hir().as_local_hir_id(did).is_some() { |
b039eaaf | 985 | vec![].into_iter() |
1a4d82fc | 986 | } else { |
7cac9316 | 987 | cx.tcx.fn_arg_names(did).into_iter() |
0531ce1d XL |
988 | }; |
989 | ||
1a4d82fc | 990 | FnDecl { |
476ff2be SL |
991 | output: Return(sig.skip_binder().output().clean(cx)), |
992 | attrs: Attributes::default(), | |
e74abb32 | 993 | c_variadic: sig.skip_binder().c_variadic, |
1a4d82fc | 994 | inputs: Arguments { |
476ff2be | 995 | values: sig.skip_binder().inputs().iter().map(|t| { |
1a4d82fc JJ |
996 | Argument { |
997 | type_: t.clean(cx), | |
b7449926 | 998 | name: names.next().map_or(String::new(), |name| name.to_string()), |
1a4d82fc JJ |
999 | } |
1000 | }).collect(), | |
1001 | }, | |
1002 | } | |
1003 | } | |
1004 | } | |
1005 | ||
e9174d1e | 1006 | impl Clean<FunctionRetTy> for hir::FunctionRetTy { |
532ac7d7 | 1007 | fn clean(&self, cx: &DocContext<'_>) -> FunctionRetTy { |
1a4d82fc | 1008 | match *self { |
e9174d1e SL |
1009 | hir::Return(ref typ) => Return(typ.clean(cx)), |
1010 | hir::DefaultReturn(..) => DefaultReturn, | |
1a4d82fc JJ |
1011 | } |
1012 | } | |
1013 | } | |
1014 | ||
dc9dc135 | 1015 | impl Clean<Item> for doctree::Trait<'_> { |
532ac7d7 | 1016 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
ff7c6d11 | 1017 | let attrs = self.attrs.clean(cx); |
48663c56 | 1018 | let is_spotlight = attrs.has_doc_flag(sym::spotlight); |
1a4d82fc JJ |
1019 | Item { |
1020 | name: Some(self.name.clean(cx)), | |
e74abb32 | 1021 | attrs, |
1a4d82fc | 1022 | source: self.whence.clean(cx), |
416331ca | 1023 | def_id: cx.tcx.hir().local_def_id(self.id), |
1a4d82fc | 1024 | visibility: self.vis.clean(cx), |
416331ca XL |
1025 | stability: cx.stability(self.id).clean(cx), |
1026 | deprecation: cx.deprecation(self.id).clean(cx), | |
1a4d82fc | 1027 | inner: TraitItem(Trait { |
0531ce1d | 1028 | auto: self.is_auto.clean(cx), |
1a4d82fc | 1029 | unsafety: self.unsafety, |
dc9dc135 | 1030 | items: self.items.iter().map(|ti| ti.clean(cx)).collect(), |
1a4d82fc JJ |
1031 | generics: self.generics.clean(cx), |
1032 | bounds: self.bounds.clean(cx), | |
9fa01778 | 1033 | is_spotlight, |
2c00a5a8 | 1034 | is_auto: self.is_auto.clean(cx), |
1a4d82fc JJ |
1035 | }), |
1036 | } | |
1037 | } | |
1038 | } | |
1039 | ||
dc9dc135 | 1040 | impl Clean<Item> for doctree::TraitAlias<'_> { |
532ac7d7 | 1041 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
9fa01778 XL |
1042 | let attrs = self.attrs.clean(cx); |
1043 | Item { | |
1044 | name: Some(self.name.clean(cx)), | |
1045 | attrs, | |
1046 | source: self.whence.clean(cx), | |
416331ca | 1047 | def_id: cx.tcx.hir().local_def_id(self.id), |
9fa01778 | 1048 | visibility: self.vis.clean(cx), |
416331ca XL |
1049 | stability: cx.stability(self.id).clean(cx), |
1050 | deprecation: cx.deprecation(self.id).clean(cx), | |
9fa01778 XL |
1051 | inner: TraitAliasItem(TraitAlias { |
1052 | generics: self.generics.clean(cx), | |
1053 | bounds: self.bounds.clean(cx), | |
1054 | }), | |
1055 | } | |
1056 | } | |
1057 | } | |
1058 | ||
2c00a5a8 | 1059 | impl Clean<bool> for hir::IsAuto { |
532ac7d7 | 1060 | fn clean(&self, _: &DocContext<'_>) -> bool { |
2c00a5a8 XL |
1061 | match *self { |
1062 | hir::IsAuto::Yes => true, | |
1063 | hir::IsAuto::No => false, | |
1064 | } | |
1065 | } | |
1066 | } | |
1067 | ||
e9174d1e | 1068 | impl Clean<Type> for hir::TraitRef { |
532ac7d7 XL |
1069 | fn clean(&self, cx: &DocContext<'_>) -> Type { |
1070 | resolve_type(cx, self.path.clean(cx), self.hir_ref_id) | |
1a4d82fc JJ |
1071 | } |
1072 | } | |
1073 | ||
e9174d1e | 1074 | impl Clean<PolyTrait> for hir::PolyTraitRef { |
532ac7d7 | 1075 | fn clean(&self, cx: &DocContext<'_>) -> PolyTrait { |
1a4d82fc JJ |
1076 | PolyTrait { |
1077 | trait_: self.trait_ref.clean(cx), | |
ff7c6d11 | 1078 | generic_params: self.bound_generic_params.clean(cx) |
1a4d82fc JJ |
1079 | } |
1080 | } | |
1081 | } | |
1082 | ||
e9174d1e | 1083 | impl Clean<Item> for hir::TraitItem { |
532ac7d7 | 1084 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
e74abb32 | 1085 | let inner = match self.kind { |
32a655c1 | 1086 | hir::TraitItemKind::Const(ref ty, default) => { |
dc9dc135 | 1087 | AssocConstItem(ty.clean(cx), |
32a655c1 | 1088 | default.map(|e| print_const_expr(cx, e))) |
d9579d0f | 1089 | } |
32a655c1 | 1090 | hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => { |
532ac7d7 | 1091 | MethodItem((sig, &self.generics, body, None).clean(cx)) |
c34b1796 | 1092 | } |
32a655c1 | 1093 | hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref names)) => { |
0531ce1d XL |
1094 | let (generics, decl) = enter_impl_trait(cx, || { |
1095 | (self.generics.clean(cx), (&*sig.decl, &names[..]).clean(cx)) | |
1096 | }); | |
532ac7d7 | 1097 | let (all_types, ret_types) = get_all_types(&generics, &decl, cx); |
32a655c1 | 1098 | TyMethodItem(TyMethod { |
8faf50e0 | 1099 | header: sig.header, |
0531ce1d XL |
1100 | decl, |
1101 | generics, | |
532ac7d7 XL |
1102 | all_types, |
1103 | ret_types, | |
32a655c1 | 1104 | }) |
c34b1796 | 1105 | } |
32a655c1 | 1106 | hir::TraitItemKind::Type(ref bounds, ref default) => { |
dc9dc135 | 1107 | AssocTypeItem(bounds.clean(cx), default.clean(cx)) |
c34b1796 AL |
1108 | } |
1109 | }; | |
416331ca | 1110 | let local_did = cx.tcx.hir().local_def_id(self.hir_id); |
c34b1796 | 1111 | Item { |
8faf50e0 | 1112 | name: Some(self.ident.name.clean(cx)), |
c34b1796 AL |
1113 | attrs: self.attrs.clean(cx), |
1114 | source: self.span.clean(cx), | |
532ac7d7 | 1115 | def_id: local_did, |
e74abb32 | 1116 | visibility: Visibility::Inherited, |
532ac7d7 XL |
1117 | stability: get_stability(cx, local_did), |
1118 | deprecation: get_deprecation(cx, local_did), | |
3b2f2976 | 1119 | inner, |
1a4d82fc JJ |
1120 | } |
1121 | } | |
1122 | } | |
1123 | ||
e9174d1e | 1124 | impl Clean<Item> for hir::ImplItem { |
532ac7d7 | 1125 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
e74abb32 | 1126 | let inner = match self.kind { |
32a655c1 | 1127 | hir::ImplItemKind::Const(ref ty, expr) => { |
dc9dc135 | 1128 | AssocConstItem(ty.clean(cx), |
32a655c1 | 1129 | Some(print_const_expr(cx, expr))) |
d9579d0f | 1130 | } |
32a655c1 | 1131 | hir::ImplItemKind::Method(ref sig, body) => { |
532ac7d7 | 1132 | MethodItem((sig, &self.generics, body, Some(self.defaultness)).clean(cx)) |
c34b1796 | 1133 | } |
416331ca | 1134 | hir::ImplItemKind::TyAlias(ref ty) => TypedefItem(Typedef { |
c34b1796 | 1135 | type_: ty.clean(cx), |
ff7c6d11 | 1136 | generics: Generics::default(), |
62682a34 | 1137 | }, true), |
416331ca | 1138 | hir::ImplItemKind::OpaqueTy(ref bounds) => OpaqueTyItem(OpaqueTy { |
8faf50e0 XL |
1139 | bounds: bounds.clean(cx), |
1140 | generics: Generics::default(), | |
1141 | }, true), | |
c34b1796 | 1142 | }; |
416331ca | 1143 | let local_did = cx.tcx.hir().local_def_id(self.hir_id); |
c34b1796 | 1144 | Item { |
8faf50e0 | 1145 | name: Some(self.ident.name.clean(cx)), |
c34b1796 AL |
1146 | source: self.span.clean(cx), |
1147 | attrs: self.attrs.clean(cx), | |
532ac7d7 | 1148 | def_id: local_did, |
c34b1796 | 1149 | visibility: self.vis.clean(cx), |
532ac7d7 XL |
1150 | stability: get_stability(cx, local_did), |
1151 | deprecation: get_deprecation(cx, local_did), | |
3b2f2976 | 1152 | inner, |
1a4d82fc JJ |
1153 | } |
1154 | } | |
1155 | } | |
1156 | ||
dc9dc135 | 1157 | impl Clean<Item> for ty::AssocItem { |
532ac7d7 | 1158 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
476ff2be | 1159 | let inner = match self.kind { |
dc9dc135 | 1160 | ty::AssocKind::Const => { |
7cac9316 | 1161 | let ty = cx.tcx.type_of(self.def_id); |
ff7c6d11 XL |
1162 | let default = if self.defaultness.has_value() { |
1163 | Some(inline::print_inlined_const(cx, self.def_id)) | |
1164 | } else { | |
1165 | None | |
1166 | }; | |
dc9dc135 | 1167 | AssocConstItem(ty.clean(cx), default) |
a7813a04 | 1168 | } |
dc9dc135 | 1169 | ty::AssocKind::Method => { |
7cac9316 | 1170 | let generics = (cx.tcx.generics_of(self.def_id), |
e74abb32 | 1171 | cx.tcx.explicit_predicates_of(self.def_id)).clean(cx); |
041b39d2 | 1172 | let sig = cx.tcx.fn_sig(self.def_id); |
8bb4bdeb | 1173 | let mut decl = (self.def_id, sig).clean(cx); |
476ff2be SL |
1174 | |
1175 | if self.method_has_self_argument { | |
1176 | let self_ty = match self.container { | |
1177 | ty::ImplContainer(def_id) => { | |
7cac9316 | 1178 | cx.tcx.type_of(def_id) |
476ff2be | 1179 | } |
e1599b0c | 1180 | ty::TraitContainer(_) => cx.tcx.types.self_param, |
476ff2be | 1181 | }; |
8bb4bdeb | 1182 | let self_arg_ty = *sig.input(0).skip_binder(); |
476ff2be | 1183 | if self_arg_ty == self_ty { |
32a655c1 | 1184 | decl.inputs.values[0].type_ = Generic(String::from("Self")); |
e74abb32 | 1185 | } else if let ty::Ref(_, ty, _) = self_arg_ty.kind { |
94b46f34 | 1186 | if ty == self_ty { |
476ff2be | 1187 | match decl.inputs.values[0].type_ { |
32a655c1 SL |
1188 | BorrowedRef{ref mut type_, ..} => { |
1189 | **type_ = Generic(String::from("Self")) | |
1190 | } | |
476ff2be SL |
1191 | _ => unreachable!(), |
1192 | } | |
1193 | } | |
1194 | } | |
1195 | } | |
1196 | ||
1197 | let provided = match self.container { | |
ff7c6d11 | 1198 | ty::ImplContainer(_) => true, |
476ff2be SL |
1199 | ty::TraitContainer(_) => self.defaultness.has_value() |
1200 | }; | |
532ac7d7 | 1201 | let (all_types, ret_types) = get_all_types(&generics, &decl, cx); |
476ff2be | 1202 | if provided { |
0731742a | 1203 | let constness = if cx.tcx.is_min_const_fn(self.def_id) { |
ff7c6d11 XL |
1204 | hir::Constness::Const |
1205 | } else { | |
1206 | hir::Constness::NotConst | |
1207 | }; | |
e1599b0c | 1208 | let asyncness = cx.tcx.asyncness(self.def_id); |
532ac7d7 XL |
1209 | let defaultness = match self.container { |
1210 | ty::ImplContainer(_) => Some(self.defaultness), | |
1211 | ty::TraitContainer(_) => None, | |
1212 | }; | |
476ff2be | 1213 | MethodItem(Method { |
3b2f2976 XL |
1214 | generics, |
1215 | decl, | |
8faf50e0 XL |
1216 | header: hir::FnHeader { |
1217 | unsafety: sig.unsafety(), | |
1218 | abi: sig.abi(), | |
1219 | constness, | |
e1599b0c | 1220 | asyncness, |
532ac7d7 XL |
1221 | }, |
1222 | defaultness, | |
1223 | all_types, | |
1224 | ret_types, | |
476ff2be SL |
1225 | }) |
1226 | } else { | |
1227 | TyMethodItem(TyMethod { | |
3b2f2976 XL |
1228 | generics, |
1229 | decl, | |
8faf50e0 XL |
1230 | header: hir::FnHeader { |
1231 | unsafety: sig.unsafety(), | |
1232 | abi: sig.abi(), | |
1233 | constness: hir::Constness::NotConst, | |
1234 | asyncness: hir::IsAsync::NotAsync, | |
532ac7d7 XL |
1235 | }, |
1236 | all_types, | |
1237 | ret_types, | |
476ff2be | 1238 | }) |
a7813a04 XL |
1239 | } |
1240 | } | |
dc9dc135 | 1241 | ty::AssocKind::Type => { |
8faf50e0 | 1242 | let my_name = self.ident.name.clean(cx); |
476ff2be | 1243 | |
ff7c6d11 | 1244 | if let ty::TraitContainer(did) = self.container { |
476ff2be SL |
1245 | // When loading a cross-crate associated type, the bounds for this type |
1246 | // are actually located on the trait/impl itself, so we need to load | |
1247 | // all of the generics from there and then look for bounds that are | |
1248 | // applied to this associated type in question. | |
532ac7d7 | 1249 | let predicates = cx.tcx.explicit_predicates_of(did); |
e74abb32 | 1250 | let generics = (cx.tcx.generics_of(did), predicates).clean(cx); |
ff7c6d11 | 1251 | let mut bounds = generics.where_predicates.iter().filter_map(|pred| { |
476ff2be SL |
1252 | let (name, self_type, trait_, bounds) = match *pred { |
1253 | WherePredicate::BoundPredicate { | |
1254 | ty: QPath { ref name, ref self_type, ref trait_ }, | |
1255 | ref bounds | |
1256 | } => (name, self_type, trait_, bounds), | |
1257 | _ => return None, | |
1258 | }; | |
1259 | if *name != my_name { return None } | |
1260 | match **trait_ { | |
1261 | ResolvedPath { did, .. } if did == self.container.id() => {} | |
1262 | _ => return None, | |
1263 | } | |
1264 | match **self_type { | |
1265 | Generic(ref s) if *s == "Self" => {} | |
1266 | _ => return None, | |
1267 | } | |
1268 | Some(bounds) | |
ff7c6d11 XL |
1269 | }).flat_map(|i| i.iter().cloned()).collect::<Vec<_>>(); |
1270 | // Our Sized/?Sized bound didn't get handled when creating the generics | |
1271 | // because we didn't actually get our whole set of bounds until just now | |
1272 | // (some of them may have come from the trait). If we do have a sized | |
1273 | // bound, we remove it, and if we don't then we add the `?Sized` bound | |
1274 | // at the end. | |
1275 | match bounds.iter().position(|b| b.is_sized_bound(cx)) { | |
1276 | Some(i) => { bounds.remove(i); } | |
8faf50e0 | 1277 | None => bounds.push(GenericBound::maybe_sized(cx)), |
ff7c6d11 | 1278 | } |
476ff2be | 1279 | |
ff7c6d11 XL |
1280 | let ty = if self.defaultness.has_value() { |
1281 | Some(cx.tcx.type_of(self.def_id)) | |
1282 | } else { | |
1283 | None | |
1284 | }; | |
476ff2be | 1285 | |
dc9dc135 | 1286 | AssocTypeItem(bounds, ty.clean(cx)) |
476ff2be | 1287 | } else { |
ff7c6d11 XL |
1288 | TypedefItem(Typedef { |
1289 | type_: cx.tcx.type_of(self.def_id).clean(cx), | |
1290 | generics: Generics { | |
1291 | params: Vec::new(), | |
1292 | where_predicates: Vec::new(), | |
1293 | }, | |
1294 | }, true) | |
1295 | } | |
9346a6ac | 1296 | } |
416331ca | 1297 | ty::AssocKind::OpaqueTy => unimplemented!(), |
9346a6ac | 1298 | }; |
9346a6ac | 1299 | |
ff7c6d11 XL |
1300 | let visibility = match self.container { |
1301 | ty::ImplContainer(_) => self.vis.clean(cx), | |
e74abb32 | 1302 | ty::TraitContainer(_) => Inherited, |
ff7c6d11 XL |
1303 | }; |
1304 | ||
1a4d82fc | 1305 | Item { |
8faf50e0 | 1306 | name: Some(self.ident.name.clean(cx)), |
ff7c6d11 | 1307 | visibility, |
1a4d82fc | 1308 | stability: get_stability(cx, self.def_id), |
9cc50fc6 | 1309 | deprecation: get_deprecation(cx, self.def_id), |
1a4d82fc | 1310 | def_id: self.def_id, |
416331ca | 1311 | attrs: inline::load_attrs(cx, self.def_id).clean(cx), |
476ff2be | 1312 | source: cx.tcx.def_span(self.def_id).clean(cx), |
3b2f2976 | 1313 | inner, |
1a4d82fc JJ |
1314 | } |
1315 | } | |
1316 | } | |
1317 | ||
e9174d1e | 1318 | impl Clean<Type> for hir::Ty { |
532ac7d7 | 1319 | fn clean(&self, cx: &DocContext<'_>) -> Type { |
54a0048b | 1320 | use rustc::hir::*; |
b7449926 | 1321 | |
e74abb32 | 1322 | match self.kind { |
8faf50e0 XL |
1323 | TyKind::Never => Never, |
1324 | TyKind::Ptr(ref m) => RawPointer(m.mutbl.clean(cx), box m.ty.clean(cx)), | |
1325 | TyKind::Rptr(ref l, ref m) => { | |
32a655c1 SL |
1326 | let lifetime = if l.is_elided() { |
1327 | None | |
1328 | } else { | |
1329 | Some(l.clean(cx)) | |
5bcae85e | 1330 | }; |
e74abb32 | 1331 | BorrowedRef {lifetime, mutability: m.mutbl.clean(cx), |
32a655c1 SL |
1332 | type_: box m.ty.clean(cx)} |
1333 | } | |
8faf50e0 XL |
1334 | TyKind::Slice(ref ty) => Slice(box ty.clean(cx)), |
1335 | TyKind::Array(ref ty, ref length) => { | |
416331ca | 1336 | let def_id = cx.tcx.hir().local_def_id(length.hir_id); |
ff7c6d11 | 1337 | let param_env = cx.tcx.param_env(def_id); |
532ac7d7 | 1338 | let substs = InternalSubsts::identity_for_item(cx.tcx, def_id); |
0531ce1d XL |
1339 | let cid = GlobalId { |
1340 | instance: ty::Instance::new(def_id, substs), | |
1341 | promoted: None | |
1342 | }; | |
0731742a | 1343 | let length = match cx.tcx.const_eval(param_env.and(cid)) { |
532ac7d7 | 1344 | Ok(length) => print_const(cx, length), |
dc9dc135 XL |
1345 | Err(_) => cx.sess() |
1346 | .source_map() | |
1347 | .span_to_snippet(cx.tcx.def_span(def_id)) | |
1348 | .unwrap_or_else(|_| "_".to_string()), | |
0731742a | 1349 | }; |
94b46f34 | 1350 | Array(box ty.clean(cx), length) |
5bcae85e | 1351 | }, |
8faf50e0 | 1352 | TyKind::Tup(ref tys) => Tuple(tys.clean(cx)), |
0bf4aa26 | 1353 | TyKind::Def(item_id, _) => { |
dc9dc135 | 1354 | let item = cx.tcx.hir().expect_item(item_id.id); |
e74abb32 | 1355 | if let hir::ItemKind::OpaqueTy(ref ty) = item.kind { |
0bf4aa26 XL |
1356 | ImplTrait(ty.bounds.clean(cx)) |
1357 | } else { | |
1358 | unreachable!() | |
1359 | } | |
1360 | } | |
8faf50e0 | 1361 | TyKind::Path(hir::QPath::Resolved(None, ref path)) => { |
48663c56 XL |
1362 | if let Res::Def(DefKind::TyParam, did) = path.res { |
1363 | if let Some(new_ty) = cx.ty_substs.borrow().get(&did).cloned() { | |
1364 | return new_ty; | |
1365 | } | |
e1599b0c | 1366 | if let Some(bounds) = cx.impl_trait_bounds.borrow_mut().remove(&did.into()) { |
0531ce1d XL |
1367 | return ImplTrait(bounds); |
1368 | } | |
1369 | } | |
1370 | ||
476ff2be | 1371 | let mut alias = None; |
48663c56 | 1372 | if let Res::Def(DefKind::TyAlias, def_id) = path.res { |
476ff2be | 1373 | // Substitute private type aliases |
9fa01778 | 1374 | if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(def_id) { |
0bf4aa26 | 1375 | if !cx.renderinfo.borrow().access_levels.is_exported(def_id) { |
e74abb32 | 1376 | alias = Some(&cx.tcx.hir().expect_item(hir_id).kind); |
476ff2be | 1377 | } |
9e0c209e | 1378 | } |
476ff2be SL |
1379 | }; |
1380 | ||
416331ca | 1381 | if let Some(&hir::ItemKind::TyAlias(ref ty, ref generics)) = alias { |
b7449926 | 1382 | let provided_params = &path.segments.last().expect("segments were empty"); |
0bf4aa26 XL |
1383 | let mut ty_substs = FxHashMap::default(); |
1384 | let mut lt_substs = FxHashMap::default(); | |
48663c56 | 1385 | let mut ct_substs = FxHashMap::default(); |
dc9dc135 XL |
1386 | let generic_args = provided_params.generic_args(); |
1387 | { | |
b7449926 | 1388 | let mut indices: GenericParamCount = Default::default(); |
94b46f34 | 1389 | for param in generics.params.iter() { |
8faf50e0 XL |
1390 | match param.kind { |
1391 | hir::GenericParamKind::Lifetime { .. } => { | |
1392 | let mut j = 0; | |
1393 | let lifetime = generic_args.args.iter().find_map(|arg| { | |
1394 | match arg { | |
9fa01778 | 1395 | hir::GenericArg::Lifetime(lt) => { |
8faf50e0 XL |
1396 | if indices.lifetimes == j { |
1397 | return Some(lt); | |
1398 | } | |
1399 | j += 1; | |
1400 | None | |
1401 | } | |
1402 | _ => None, | |
1403 | } | |
1404 | }); | |
1405 | if let Some(lt) = lifetime.cloned() { | |
94b46f34 XL |
1406 | if !lt.is_elided() { |
1407 | let lt_def_id = | |
416331ca | 1408 | cx.tcx.hir().local_def_id(param.hir_id); |
94b46f34 XL |
1409 | lt_substs.insert(lt_def_id, lt.clean(cx)); |
1410 | } | |
1411 | } | |
1412 | indices.lifetimes += 1; | |
1413 | } | |
8faf50e0 | 1414 | hir::GenericParamKind::Type { ref default, .. } => { |
48663c56 | 1415 | let ty_param_def_id = |
416331ca | 1416 | cx.tcx.hir().local_def_id(param.hir_id); |
8faf50e0 XL |
1417 | let mut j = 0; |
1418 | let type_ = generic_args.args.iter().find_map(|arg| { | |
1419 | match arg { | |
9fa01778 | 1420 | hir::GenericArg::Type(ty) => { |
8faf50e0 XL |
1421 | if indices.types == j { |
1422 | return Some(ty); | |
1423 | } | |
1424 | j += 1; | |
1425 | None | |
1426 | } | |
1427 | _ => None, | |
1428 | } | |
1429 | }); | |
dc9dc135 | 1430 | if let Some(ty) = type_ { |
48663c56 | 1431 | ty_substs.insert(ty_param_def_id, ty.clean(cx)); |
8faf50e0 | 1432 | } else if let Some(default) = default.clone() { |
48663c56 | 1433 | ty_substs.insert(ty_param_def_id, |
dc9dc135 | 1434 | default.clean(cx)); |
94b46f34 XL |
1435 | } |
1436 | indices.types += 1; | |
ea8adc8c | 1437 | } |
9fa01778 | 1438 | hir::GenericParamKind::Const { .. } => { |
48663c56 | 1439 | let const_param_def_id = |
416331ca | 1440 | cx.tcx.hir().local_def_id(param.hir_id); |
9fa01778 XL |
1441 | let mut j = 0; |
1442 | let const_ = generic_args.args.iter().find_map(|arg| { | |
1443 | match arg { | |
1444 | hir::GenericArg::Const(ct) => { | |
1445 | if indices.consts == j { | |
1446 | return Some(ct); | |
1447 | } | |
1448 | j += 1; | |
1449 | None | |
1450 | } | |
1451 | _ => None, | |
1452 | } | |
1453 | }); | |
dc9dc135 | 1454 | if let Some(ct) = const_ { |
48663c56 | 1455 | ct_substs.insert(const_param_def_id, ct.clean(cx)); |
9fa01778 XL |
1456 | } |
1457 | // FIXME(const_generics:defaults) | |
1458 | indices.consts += 1; | |
1459 | } | |
32a655c1 | 1460 | } |
9e0c209e | 1461 | } |
dc9dc135 | 1462 | } |
48663c56 | 1463 | return cx.enter_alias(ty_substs, lt_substs, ct_substs, || ty.clean(cx)); |
5bcae85e | 1464 | } |
532ac7d7 | 1465 | resolve_type(cx, path.clean(cx), self.hir_id) |
c34b1796 | 1466 | } |
8faf50e0 | 1467 | TyKind::Path(hir::QPath::Resolved(Some(ref qself), ref p)) => { |
dc9dc135 XL |
1468 | let segments = if p.is_global() { &p.segments[1..] } else { &p.segments }; |
1469 | let trait_segments = &segments[..segments.len() - 1]; | |
1470 | let trait_path = self::Path { | |
1471 | global: p.is_global(), | |
48663c56 XL |
1472 | res: Res::Def( |
1473 | DefKind::Trait, | |
1474 | cx.tcx.associated_item(p.res.def_id()).container.id(), | |
1475 | ), | |
dc9dc135 | 1476 | segments: trait_segments.clean(cx), |
9cc50fc6 | 1477 | }; |
c34b1796 | 1478 | Type::QPath { |
b7449926 | 1479 | name: p.segments.last().expect("segments were empty").ident.name.clean(cx), |
476ff2be | 1480 | self_type: box qself.clean(cx), |
dc9dc135 | 1481 | trait_: box resolve_type(cx, trait_path, self.hir_id) |
476ff2be SL |
1482 | } |
1483 | } | |
8faf50e0 | 1484 | TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => { |
48663c56 | 1485 | let mut res = Res::Err; |
7cac9316 | 1486 | let ty = hir_ty_to_ty(cx.tcx, self); |
e74abb32 | 1487 | if let ty::Projection(proj) = ty.kind { |
48663c56 | 1488 | res = Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id); |
476ff2be SL |
1489 | } |
1490 | let trait_path = hir::Path { | |
1491 | span: self.span, | |
48663c56 | 1492 | res, |
476ff2be SL |
1493 | segments: vec![].into(), |
1494 | }; | |
1495 | Type::QPath { | |
8faf50e0 | 1496 | name: segment.ident.name.clean(cx), |
476ff2be | 1497 | self_type: box qself.clean(cx), |
532ac7d7 | 1498 | trait_: box resolve_type(cx, trait_path.clean(cx), self.hir_id) |
c34b1796 | 1499 | } |
1a4d82fc | 1500 | } |
8faf50e0 | 1501 | TyKind::TraitObject(ref bounds, ref lifetime) => { |
32a655c1 | 1502 | match bounds[0].clean(cx).trait_ { |
532ac7d7 | 1503 | ResolvedPath { path, param_names: None, did, is_generic } => { |
8faf50e0 XL |
1504 | let mut bounds: Vec<self::GenericBound> = bounds[1..].iter().map(|bound| { |
1505 | self::GenericBound::TraitBound(bound.clean(cx), | |
1506 | hir::TraitBoundModifier::None) | |
32a655c1 SL |
1507 | }).collect(); |
1508 | if !lifetime.is_elided() { | |
8faf50e0 | 1509 | bounds.push(self::GenericBound::Outlives(lifetime.clean(cx))); |
62682a34 | 1510 | } |
532ac7d7 | 1511 | ResolvedPath { path, param_names: Some(bounds), did, is_generic, } |
1a4d82fc | 1512 | } |
dc9dc135 | 1513 | _ => Infer, // shouldn't happen |
1a4d82fc JJ |
1514 | } |
1515 | } | |
8faf50e0 XL |
1516 | TyKind::BareFn(ref barefn) => BareFunction(box barefn.clean(cx)), |
1517 | TyKind::Infer | TyKind::Err => Infer, | |
e74abb32 | 1518 | TyKind::Typeof(..) => panic!("unimplemented type {:?}", self.kind), |
1a4d82fc JJ |
1519 | } |
1520 | } | |
1521 | } | |
1522 | ||
ea8adc8c | 1523 | impl<'tcx> Clean<Type> for Ty<'tcx> { |
532ac7d7 | 1524 | fn clean(&self, cx: &DocContext<'_>) -> Type { |
48663c56 | 1525 | debug!("cleaning type: {:?}", self); |
e74abb32 | 1526 | match self.kind { |
b7449926 XL |
1527 | ty::Never => Never, |
1528 | ty::Bool => Primitive(PrimitiveType::Bool), | |
1529 | ty::Char => Primitive(PrimitiveType::Char), | |
1530 | ty::Int(int_ty) => Primitive(int_ty.into()), | |
1531 | ty::Uint(uint_ty) => Primitive(uint_ty.into()), | |
1532 | ty::Float(float_ty) => Primitive(float_ty.into()), | |
1533 | ty::Str => Primitive(PrimitiveType::Str), | |
1534 | ty::Slice(ty) => Slice(box ty.clean(cx)), | |
1535 | ty::Array(ty, n) => { | |
dc9dc135 | 1536 | let mut n = cx.tcx.lift(&n).expect("array lift failed"); |
60c5eb7d | 1537 | if let ty::ConstKind::Unevaluated(def_id, substs) = n.val { |
ff7c6d11 | 1538 | let param_env = cx.tcx.param_env(def_id); |
0531ce1d XL |
1539 | let cid = GlobalId { |
1540 | instance: ty::Instance::new(def_id, substs), | |
1541 | promoted: None | |
1542 | }; | |
1543 | if let Ok(new_n) = cx.tcx.const_eval(param_env.and(cid)) { | |
532ac7d7 | 1544 | n = new_n; |
2c00a5a8 | 1545 | } |
ff7c6d11 | 1546 | }; |
0531ce1d | 1547 | let n = print_const(cx, n); |
ea8adc8c XL |
1548 | Array(box ty.clean(cx), n) |
1549 | } | |
b7449926 XL |
1550 | ty::RawPtr(mt) => RawPointer(mt.mutbl.clean(cx), box mt.ty.clean(cx)), |
1551 | ty::Ref(r, ty, mutbl) => BorrowedRef { | |
1a4d82fc | 1552 | lifetime: r.clean(cx), |
94b46f34 XL |
1553 | mutability: mutbl.clean(cx), |
1554 | type_: box ty.clean(cx), | |
1a4d82fc | 1555 | }, |
b7449926 XL |
1556 | ty::FnDef(..) | |
1557 | ty::FnPtr(_) => { | |
1558 | let ty = cx.tcx.lift(self).expect("FnPtr lift failed"); | |
041b39d2 | 1559 | let sig = ty.fn_sig(cx.tcx); |
416331ca | 1560 | let local_def_id = cx.tcx.hir().local_def_id_from_node_id(ast::CRATE_NODE_ID); |
041b39d2 XL |
1561 | BareFunction(box BareFunctionDecl { |
1562 | unsafety: sig.unsafety(), | |
ff7c6d11 | 1563 | generic_params: Vec::new(), |
416331ca | 1564 | decl: (local_def_id, sig).clean(cx), |
041b39d2 XL |
1565 | abi: sig.abi(), |
1566 | }) | |
1567 | } | |
b7449926 | 1568 | ty::Adt(def, substs) => { |
e9174d1e | 1569 | let did = def.did; |
9e0c209e | 1570 | let kind = match def.adt_kind() { |
c30ab7b3 SL |
1571 | AdtKind::Struct => TypeKind::Struct, |
1572 | AdtKind::Union => TypeKind::Union, | |
1573 | AdtKind::Enum => TypeKind::Enum, | |
1a4d82fc | 1574 | }; |
92a42be0 | 1575 | inline::record_extern_fqn(cx, did, kind); |
e1599b0c | 1576 | let path = external_path(cx, cx.tcx.item_name(did), None, false, vec![], substs); |
1a4d82fc | 1577 | ResolvedPath { |
3b2f2976 | 1578 | path, |
532ac7d7 | 1579 | param_names: None, |
3b2f2976 | 1580 | did, |
62682a34 | 1581 | is_generic: false, |
1a4d82fc JJ |
1582 | } |
1583 | } | |
b7449926 | 1584 | ty::Foreign(did) => { |
abe05a73 | 1585 | inline::record_extern_fqn(cx, did, TypeKind::Foreign); |
e1599b0c | 1586 | let path = external_path(cx, cx.tcx.item_name(did), |
532ac7d7 | 1587 | None, false, vec![], InternalSubsts::empty()); |
abe05a73 | 1588 | ResolvedPath { |
e74abb32 | 1589 | path, |
532ac7d7 | 1590 | param_names: None, |
e74abb32 | 1591 | did, |
abe05a73 XL |
1592 | is_generic: false, |
1593 | } | |
1594 | } | |
b7449926 | 1595 | ty::Dynamic(ref obj, ref reg) => { |
0731742a XL |
1596 | // HACK: pick the first `did` as the `did` of the trait object. Someone |
1597 | // might want to implement "native" support for marker-trait-only | |
1598 | // trait objects. | |
1599 | let mut dids = obj.principal_def_id().into_iter().chain(obj.auto_traits()); | |
1600 | let did = dids.next().unwrap_or_else(|| { | |
1601 | panic!("found trait object `{:?}` with no traits?", self) | |
1602 | }); | |
1603 | let substs = match obj.principal() { | |
1604 | Some(principal) => principal.skip_binder().substs, | |
1605 | // marker traits have no substs. | |
1606 | _ => cx.tcx.intern_substs(&[]) | |
1607 | }; | |
1608 | ||
0bf4aa26 XL |
1609 | inline::record_extern_fqn(cx, did, TypeKind::Trait); |
1610 | ||
532ac7d7 XL |
1611 | let mut param_names = vec![]; |
1612 | reg.clean(cx).map(|b| param_names.push(GenericBound::Outlives(b))); | |
0731742a | 1613 | for did in dids { |
0bf4aa26 | 1614 | let empty = cx.tcx.intern_substs(&[]); |
e1599b0c | 1615 | let path = external_path(cx, cx.tcx.item_name(did), |
0bf4aa26 | 1616 | Some(did), false, vec![], empty); |
476ff2be | 1617 | inline::record_extern_fqn(cx, did, TypeKind::Trait); |
0bf4aa26 XL |
1618 | let bound = GenericBound::TraitBound(PolyTrait { |
1619 | trait_: ResolvedPath { | |
1620 | path, | |
532ac7d7 | 1621 | param_names: None, |
0bf4aa26 XL |
1622 | did, |
1623 | is_generic: false, | |
1624 | }, | |
1625 | generic_params: Vec::new(), | |
1626 | }, hir::TraitBoundModifier::None); | |
532ac7d7 | 1627 | param_names.push(bound); |
0bf4aa26 | 1628 | } |
476ff2be | 1629 | |
0bf4aa26 XL |
1630 | let mut bindings = vec![]; |
1631 | for pb in obj.projection_bounds() { | |
1632 | bindings.push(TypeBinding { | |
1633 | name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx), | |
dc9dc135 XL |
1634 | kind: TypeBindingKind::Equality { |
1635 | ty: pb.skip_binder().ty.clean(cx) | |
1636 | }, | |
0bf4aa26 XL |
1637 | }); |
1638 | } | |
9e0c209e | 1639 | |
e1599b0c | 1640 | let path = external_path(cx, cx.tcx.item_name(did), Some(did), |
0731742a | 1641 | false, bindings, substs); |
0bf4aa26 XL |
1642 | ResolvedPath { |
1643 | path, | |
532ac7d7 | 1644 | param_names: Some(param_names), |
0bf4aa26 XL |
1645 | did, |
1646 | is_generic: false, | |
1a4d82fc JJ |
1647 | } |
1648 | } | |
48663c56 XL |
1649 | ty::Tuple(ref t) => { |
1650 | Tuple(t.iter().map(|t| t.expect_ty()).collect::<Vec<_>>().clean(cx)) | |
1651 | } | |
1a4d82fc | 1652 | |
b7449926 | 1653 | ty::Projection(ref data) => data.clean(cx), |
1a4d82fc | 1654 | |
e1599b0c XL |
1655 | ty::Param(ref p) => { |
1656 | if let Some(bounds) = cx.impl_trait_bounds.borrow_mut().remove(&p.index.into()) { | |
1657 | ImplTrait(bounds) | |
1658 | } else { | |
1659 | Generic(p.name.to_string()) | |
1660 | } | |
1661 | } | |
1a4d82fc | 1662 | |
b7449926 | 1663 | ty::Opaque(def_id, substs) => { |
5bcae85e SL |
1664 | // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, |
1665 | // by looking up the projections associated with the def_id. | |
532ac7d7 | 1666 | let predicates_of = cx.tcx.explicit_predicates_of(def_id); |
b7449926 | 1667 | let substs = cx.tcx.lift(&substs).expect("Opaque lift failed"); |
7cac9316 | 1668 | let bounds = predicates_of.instantiate(cx.tcx, substs); |
0531ce1d XL |
1669 | let mut regions = vec![]; |
1670 | let mut has_sized = false; | |
1671 | let mut bounds = bounds.predicates.iter().filter_map(|predicate| { | |
1672 | let trait_ref = if let Some(tr) = predicate.to_opt_poly_trait_ref() { | |
1673 | tr | |
1674 | } else if let ty::Predicate::TypeOutlives(pred) = *predicate { | |
1675 | // these should turn up at the end | |
8faf50e0 XL |
1676 | pred.skip_binder().1.clean(cx).map(|r| { |
1677 | regions.push(GenericBound::Outlives(r)) | |
1678 | }); | |
0531ce1d XL |
1679 | return None; |
1680 | } else { | |
1681 | return None; | |
1682 | }; | |
1683 | ||
1684 | if let Some(sized) = cx.tcx.lang_items().sized_trait() { | |
1685 | if trait_ref.def_id() == sized { | |
1686 | has_sized = true; | |
1687 | return None; | |
1688 | } | |
1689 | } | |
1690 | ||
0531ce1d XL |
1691 | let bounds = bounds.predicates.iter().filter_map(|pred| |
1692 | if let ty::Predicate::Projection(proj) = *pred { | |
1693 | let proj = proj.skip_binder(); | |
1694 | if proj.projection_ty.trait_ref(cx.tcx) == *trait_ref.skip_binder() { | |
1695 | Some(TypeBinding { | |
1696 | name: cx.tcx.associated_item(proj.projection_ty.item_def_id) | |
8faf50e0 | 1697 | .ident.name.clean(cx), |
dc9dc135 XL |
1698 | kind: TypeBindingKind::Equality { |
1699 | ty: proj.ty.clean(cx), | |
1700 | }, | |
0531ce1d XL |
1701 | }) |
1702 | } else { | |
1703 | None | |
1704 | } | |
1705 | } else { | |
1706 | None | |
1707 | } | |
1708 | ).collect(); | |
1709 | ||
1710 | Some((trait_ref.skip_binder(), bounds).clean(cx)) | |
1711 | }).collect::<Vec<_>>(); | |
1712 | bounds.extend(regions); | |
1713 | if !has_sized && !bounds.is_empty() { | |
8faf50e0 | 1714 | bounds.insert(0, GenericBound::maybe_sized(cx)); |
0531ce1d XL |
1715 | } |
1716 | ImplTrait(bounds) | |
5bcae85e SL |
1717 | } |
1718 | ||
b7449926 | 1719 | ty::Closure(..) | ty::Generator(..) => Tuple(vec![]), // FIXME(pcwalton) |
1a4d82fc | 1720 | |
a1dfa0c6 XL |
1721 | ty::Bound(..) => panic!("Bound"), |
1722 | ty::Placeholder(..) => panic!("Placeholder"), | |
0bf4aa26 | 1723 | ty::UnnormalizedProjection(..) => panic!("UnnormalizedProjection"), |
b7449926 XL |
1724 | ty::GeneratorWitness(..) => panic!("GeneratorWitness"), |
1725 | ty::Infer(..) => panic!("Infer"), | |
1726 | ty::Error => panic!("Error"), | |
1a4d82fc JJ |
1727 | } |
1728 | } | |
1729 | } | |
1730 | ||
532ac7d7 XL |
1731 | impl<'tcx> Clean<Constant> for ty::Const<'tcx> { |
1732 | fn clean(&self, cx: &DocContext<'_>) -> Constant { | |
1733 | Constant { | |
1734 | type_: self.ty.clean(cx), | |
dc9dc135 | 1735 | expr: format!("{}", self), |
532ac7d7 XL |
1736 | } |
1737 | } | |
1738 | } | |
1739 | ||
e9174d1e | 1740 | impl Clean<Item> for hir::StructField { |
532ac7d7 | 1741 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
416331ca | 1742 | let local_did = cx.tcx.hir().local_def_id(self.hir_id); |
532ac7d7 | 1743 | |
1a4d82fc | 1744 | Item { |
94b46f34 | 1745 | name: Some(self.ident.name).clean(cx), |
54a0048b | 1746 | attrs: self.attrs.clean(cx), |
1a4d82fc | 1747 | source: self.span.clean(cx), |
54a0048b | 1748 | visibility: self.vis.clean(cx), |
532ac7d7 XL |
1749 | stability: get_stability(cx, local_did), |
1750 | deprecation: get_deprecation(cx, local_did), | |
1751 | def_id: local_did, | |
54a0048b | 1752 | inner: StructFieldItem(self.ty.clean(cx)), |
1a4d82fc JJ |
1753 | } |
1754 | } | |
1755 | } | |
1756 | ||
dc9dc135 | 1757 | impl Clean<Item> for ty::FieldDef { |
532ac7d7 | 1758 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
1a4d82fc | 1759 | Item { |
94b46f34 | 1760 | name: Some(self.ident.name).clean(cx), |
476ff2be SL |
1761 | attrs: cx.tcx.get_attrs(self.did).clean(cx), |
1762 | source: cx.tcx.def_span(self.did).clean(cx), | |
54a0048b | 1763 | visibility: self.vis.clean(cx), |
e9174d1e | 1764 | stability: get_stability(cx, self.did), |
9cc50fc6 | 1765 | deprecation: get_deprecation(cx, self.did), |
e9174d1e | 1766 | def_id: self.did, |
7cac9316 | 1767 | inner: StructFieldItem(cx.tcx.type_of(self.did).clean(cx)), |
1a4d82fc JJ |
1768 | } |
1769 | } | |
1770 | } | |
1771 | ||
e74abb32 XL |
1772 | impl Clean<Visibility> for hir::Visibility { |
1773 | fn clean(&self, cx: &DocContext<'_>) -> Visibility { | |
1774 | match self.node { | |
8faf50e0 XL |
1775 | hir::VisibilityKind::Public => Visibility::Public, |
1776 | hir::VisibilityKind::Inherited => Visibility::Inherited, | |
1777 | hir::VisibilityKind::Crate(_) => Visibility::Crate, | |
1778 | hir::VisibilityKind::Restricted { ref path, .. } => { | |
94b46f34 | 1779 | let path = path.clean(cx); |
48663c56 | 1780 | let did = register_res(cx, path.res); |
94b46f34 XL |
1781 | Visibility::Restricted(did, path) |
1782 | } | |
e74abb32 | 1783 | } |
54a0048b SL |
1784 | } |
1785 | } | |
1786 | ||
e74abb32 XL |
1787 | impl Clean<Visibility> for ty::Visibility { |
1788 | fn clean(&self, _: &DocContext<'_>) -> Visibility { | |
1789 | if *self == ty::Visibility::Public { Public } else { Inherited } | |
1a4d82fc JJ |
1790 | } |
1791 | } | |
1792 | ||
dc9dc135 | 1793 | impl Clean<Item> for doctree::Struct<'_> { |
532ac7d7 | 1794 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
0bf4aa26 XL |
1795 | Item { |
1796 | name: Some(self.name.clean(cx)), | |
1a4d82fc JJ |
1797 | attrs: self.attrs.clean(cx), |
1798 | source: self.whence.clean(cx), | |
416331ca | 1799 | def_id: cx.tcx.hir().local_def_id(self.id), |
1a4d82fc | 1800 | visibility: self.vis.clean(cx), |
416331ca XL |
1801 | stability: cx.stability(self.id).clean(cx), |
1802 | deprecation: cx.deprecation(self.id).clean(cx), | |
1a4d82fc JJ |
1803 | inner: StructItem(Struct { |
1804 | struct_type: self.struct_type, | |
1805 | generics: self.generics.clean(cx), | |
1806 | fields: self.fields.clean(cx), | |
1807 | fields_stripped: false, | |
1808 | }), | |
0bf4aa26 | 1809 | } |
1a4d82fc JJ |
1810 | } |
1811 | } | |
1812 | ||
dc9dc135 | 1813 | impl Clean<Item> for doctree::Union<'_> { |
532ac7d7 | 1814 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
0bf4aa26 XL |
1815 | Item { |
1816 | name: Some(self.name.clean(cx)), | |
9e0c209e SL |
1817 | attrs: self.attrs.clean(cx), |
1818 | source: self.whence.clean(cx), | |
416331ca | 1819 | def_id: cx.tcx.hir().local_def_id(self.id), |
9e0c209e | 1820 | visibility: self.vis.clean(cx), |
416331ca XL |
1821 | stability: cx.stability(self.id).clean(cx), |
1822 | deprecation: cx.deprecation(self.id).clean(cx), | |
9e0c209e SL |
1823 | inner: UnionItem(Union { |
1824 | struct_type: self.struct_type, | |
1825 | generics: self.generics.clean(cx), | |
1826 | fields: self.fields.clean(cx), | |
1827 | fields_stripped: false, | |
1828 | }), | |
0bf4aa26 | 1829 | } |
9e0c209e SL |
1830 | } |
1831 | } | |
1832 | ||
54a0048b | 1833 | impl Clean<VariantStruct> for ::rustc::hir::VariantData { |
532ac7d7 | 1834 | fn clean(&self, cx: &DocContext<'_>) -> VariantStruct { |
1a4d82fc JJ |
1835 | VariantStruct { |
1836 | struct_type: doctree::struct_type_from_def(self), | |
b039eaaf | 1837 | fields: self.fields().iter().map(|x| x.clean(cx)).collect(), |
1a4d82fc JJ |
1838 | fields_stripped: false, |
1839 | } | |
1840 | } | |
1841 | } | |
1842 | ||
dc9dc135 | 1843 | impl Clean<Item> for doctree::Enum<'_> { |
532ac7d7 | 1844 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
0bf4aa26 XL |
1845 | Item { |
1846 | name: Some(self.name.clean(cx)), | |
1a4d82fc JJ |
1847 | attrs: self.attrs.clean(cx), |
1848 | source: self.whence.clean(cx), | |
416331ca | 1849 | def_id: cx.tcx.hir().local_def_id(self.id), |
1a4d82fc | 1850 | visibility: self.vis.clean(cx), |
416331ca XL |
1851 | stability: cx.stability(self.id).clean(cx), |
1852 | deprecation: cx.deprecation(self.id).clean(cx), | |
1a4d82fc | 1853 | inner: EnumItem(Enum { |
a1dfa0c6 | 1854 | variants: self.variants.iter().map(|v| v.clean(cx)).collect(), |
1a4d82fc JJ |
1855 | generics: self.generics.clean(cx), |
1856 | variants_stripped: false, | |
1857 | }), | |
0bf4aa26 | 1858 | } |
1a4d82fc JJ |
1859 | } |
1860 | } | |
1861 | ||
dc9dc135 | 1862 | impl Clean<Item> for doctree::Variant<'_> { |
532ac7d7 | 1863 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
1a4d82fc JJ |
1864 | Item { |
1865 | name: Some(self.name.clean(cx)), | |
1866 | attrs: self.attrs.clean(cx), | |
1867 | source: self.whence.clean(cx), | |
e74abb32 | 1868 | visibility: Inherited, |
416331ca XL |
1869 | stability: cx.stability(self.id).clean(cx), |
1870 | deprecation: cx.deprecation(self.id).clean(cx), | |
1871 | def_id: cx.tcx.hir().local_def_id(self.id), | |
1a4d82fc | 1872 | inner: VariantItem(Variant { |
c30ab7b3 | 1873 | kind: self.def.clean(cx), |
1a4d82fc JJ |
1874 | }), |
1875 | } | |
1876 | } | |
1877 | } | |
1878 | ||
dc9dc135 | 1879 | impl Clean<Item> for ty::VariantDef { |
532ac7d7 | 1880 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
c30ab7b3 SL |
1881 | let kind = match self.ctor_kind { |
1882 | CtorKind::Const => VariantKind::CLike, | |
1883 | CtorKind::Fn => { | |
1884 | VariantKind::Tuple( | |
7cac9316 | 1885 | self.fields.iter().map(|f| cx.tcx.type_of(f.did).clean(cx)).collect() |
e9174d1e | 1886 | ) |
1a4d82fc | 1887 | } |
c30ab7b3 SL |
1888 | CtorKind::Fictive => { |
1889 | VariantKind::Struct(VariantStruct { | |
1a4d82fc JJ |
1890 | struct_type: doctree::Plain, |
1891 | fields_stripped: false, | |
e9174d1e | 1892 | fields: self.fields.iter().map(|field| { |
1a4d82fc | 1893 | Item { |
476ff2be | 1894 | source: cx.tcx.def_span(field.did).clean(cx), |
94b46f34 | 1895 | name: Some(field.ident.name.clean(cx)), |
476ff2be | 1896 | attrs: cx.tcx.get_attrs(field.did).clean(cx), |
54a0048b SL |
1897 | visibility: field.vis.clean(cx), |
1898 | def_id: field.did, | |
1899 | stability: get_stability(cx, field.did), | |
1900 | deprecation: get_deprecation(cx, field.did), | |
7cac9316 | 1901 | inner: StructFieldItem(cx.tcx.type_of(field.did).clean(cx)) |
1a4d82fc JJ |
1902 | } |
1903 | }).collect() | |
1904 | }) | |
1905 | } | |
1906 | }; | |
1907 | Item { | |
0731742a | 1908 | name: Some(self.ident.clean(cx)), |
416331ca | 1909 | attrs: inline::load_attrs(cx, self.def_id).clean(cx), |
532ac7d7 | 1910 | source: cx.tcx.def_span(self.def_id).clean(cx), |
e74abb32 | 1911 | visibility: Inherited, |
532ac7d7 | 1912 | def_id: self.def_id, |
a1dfa0c6 | 1913 | inner: VariantItem(Variant { kind }), |
532ac7d7 XL |
1914 | stability: get_stability(cx, self.def_id), |
1915 | deprecation: get_deprecation(cx, self.def_id), | |
1a4d82fc JJ |
1916 | } |
1917 | } | |
1918 | } | |
1919 | ||
c30ab7b3 | 1920 | impl Clean<VariantKind> for hir::VariantData { |
532ac7d7 XL |
1921 | fn clean(&self, cx: &DocContext<'_>) -> VariantKind { |
1922 | match self { | |
1923 | hir::VariantData::Struct(..) => VariantKind::Struct(self.clean(cx)), | |
1924 | hir::VariantData::Tuple(..) => | |
1925 | VariantKind::Tuple(self.fields().iter().map(|x| x.ty.clean(cx)).collect()), | |
1926 | hir::VariantData::Unit(..) => VariantKind::CLike, | |
c30ab7b3 | 1927 | } |
1a4d82fc JJ |
1928 | } |
1929 | } | |
1930 | ||
3157f602 | 1931 | impl Clean<Span> for syntax_pos::Span { |
532ac7d7 | 1932 | fn clean(&self, cx: &DocContext<'_>) -> Span { |
8faf50e0 | 1933 | if self.is_dummy() { |
c1a9b12d SL |
1934 | return Span::empty(); |
1935 | } | |
1936 | ||
b7449926 | 1937 | let cm = cx.sess().source_map(); |
1a4d82fc | 1938 | let filename = cm.span_to_filename(*self); |
ea8adc8c XL |
1939 | let lo = cm.lookup_char_pos(self.lo()); |
1940 | let hi = cm.lookup_char_pos(self.hi()); | |
1a4d82fc | 1941 | Span { |
ff7c6d11 | 1942 | filename, |
1a4d82fc | 1943 | loline: lo.line, |
85aaf69f | 1944 | locol: lo.col.to_usize(), |
1a4d82fc | 1945 | hiline: hi.line, |
85aaf69f | 1946 | hicol: hi.col.to_usize(), |
48663c56 | 1947 | original: *self, |
1a4d82fc JJ |
1948 | } |
1949 | } | |
1950 | } | |
1951 | ||
e9174d1e | 1952 | impl Clean<Path> for hir::Path { |
532ac7d7 | 1953 | fn clean(&self, cx: &DocContext<'_>) -> Path { |
1a4d82fc | 1954 | Path { |
32a655c1 | 1955 | global: self.is_global(), |
48663c56 | 1956 | res: self.res, |
32a655c1 | 1957 | segments: if self.is_global() { &self.segments[1..] } else { &self.segments }.clean(cx), |
1a4d82fc JJ |
1958 | } |
1959 | } | |
1960 | } | |
1961 | ||
8faf50e0 | 1962 | impl Clean<GenericArgs> for hir::GenericArgs { |
532ac7d7 | 1963 | fn clean(&self, cx: &DocContext<'_>) -> GenericArgs { |
3b2f2976 | 1964 | if self.parenthesized { |
dc9dc135 | 1965 | let output = self.bindings[0].ty().clean(cx); |
8faf50e0 | 1966 | GenericArgs::Parenthesized { |
3b2f2976 XL |
1967 | inputs: self.inputs().clean(cx), |
1968 | output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None } | |
1a4d82fc | 1969 | } |
3b2f2976 | 1970 | } else { |
532ac7d7 XL |
1971 | let elide_lifetimes = self.args.iter().all(|arg| match arg { |
1972 | hir::GenericArg::Lifetime(lt) => lt.is_elided(), | |
1973 | _ => true, | |
1974 | }); | |
8faf50e0 | 1975 | GenericArgs::AngleBracketed { |
532ac7d7 XL |
1976 | args: self.args.iter().filter_map(|arg| match arg { |
1977 | hir::GenericArg::Lifetime(lt) if !elide_lifetimes => { | |
1978 | Some(GenericArg::Lifetime(lt.clean(cx))) | |
1979 | } | |
1980 | hir::GenericArg::Lifetime(_) => None, | |
1981 | hir::GenericArg::Type(ty) => Some(GenericArg::Type(ty.clean(cx))), | |
1982 | hir::GenericArg::Const(ct) => Some(GenericArg::Const(ct.clean(cx))), | |
1983 | }).collect(), | |
3b2f2976 | 1984 | bindings: self.bindings.clean(cx), |
1a4d82fc JJ |
1985 | } |
1986 | } | |
1987 | } | |
1988 | } | |
1989 | ||
e9174d1e | 1990 | impl Clean<PathSegment> for hir::PathSegment { |
532ac7d7 | 1991 | fn clean(&self, cx: &DocContext<'_>) -> PathSegment { |
1a4d82fc | 1992 | PathSegment { |
8faf50e0 | 1993 | name: self.ident.name.clean(cx), |
dc9dc135 | 1994 | args: self.generic_args().clean(cx), |
1a4d82fc JJ |
1995 | } |
1996 | } | |
1997 | } | |
1998 | ||
0731742a XL |
1999 | impl Clean<String> for Ident { |
2000 | #[inline] | |
532ac7d7 | 2001 | fn clean(&self, cx: &DocContext<'_>) -> String { |
0731742a XL |
2002 | self.name.clean(cx) |
2003 | } | |
2004 | } | |
2005 | ||
1a4d82fc | 2006 | impl Clean<String> for ast::Name { |
0731742a | 2007 | #[inline] |
532ac7d7 | 2008 | fn clean(&self, _: &DocContext<'_>) -> String { |
c1a9b12d | 2009 | self.to_string() |
1a4d82fc JJ |
2010 | } |
2011 | } | |
2012 | ||
dc9dc135 | 2013 | impl Clean<Item> for doctree::Typedef<'_> { |
532ac7d7 | 2014 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
1a4d82fc JJ |
2015 | Item { |
2016 | name: Some(self.name.clean(cx)), | |
2017 | attrs: self.attrs.clean(cx), | |
2018 | source: self.whence.clean(cx), | |
416331ca | 2019 | def_id: cx.tcx.hir().local_def_id(self.id), |
1a4d82fc | 2020 | visibility: self.vis.clean(cx), |
416331ca XL |
2021 | stability: cx.stability(self.id).clean(cx), |
2022 | deprecation: cx.deprecation(self.id).clean(cx), | |
1a4d82fc JJ |
2023 | inner: TypedefItem(Typedef { |
2024 | type_: self.ty.clean(cx), | |
2025 | generics: self.gen.clean(cx), | |
62682a34 | 2026 | }, false), |
1a4d82fc JJ |
2027 | } |
2028 | } | |
2029 | } | |
2030 | ||
416331ca | 2031 | impl Clean<Item> for doctree::OpaqueTy<'_> { |
532ac7d7 | 2032 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
8faf50e0 XL |
2033 | Item { |
2034 | name: Some(self.name.clean(cx)), | |
2035 | attrs: self.attrs.clean(cx), | |
2036 | source: self.whence.clean(cx), | |
416331ca | 2037 | def_id: cx.tcx.hir().local_def_id(self.id), |
8faf50e0 | 2038 | visibility: self.vis.clean(cx), |
416331ca XL |
2039 | stability: cx.stability(self.id).clean(cx), |
2040 | deprecation: cx.deprecation(self.id).clean(cx), | |
2041 | inner: OpaqueTyItem(OpaqueTy { | |
2042 | bounds: self.opaque_ty.bounds.clean(cx), | |
2043 | generics: self.opaque_ty.generics.clean(cx), | |
8faf50e0 XL |
2044 | }, false), |
2045 | } | |
2046 | } | |
2047 | } | |
2048 | ||
e9174d1e | 2049 | impl Clean<BareFunctionDecl> for hir::BareFnTy { |
532ac7d7 | 2050 | fn clean(&self, cx: &DocContext<'_>) -> BareFunctionDecl { |
0531ce1d | 2051 | let (generic_params, decl) = enter_impl_trait(cx, || { |
e1599b0c | 2052 | (self.generic_params.clean(cx), (&*self.decl, &self.param_names[..]).clean(cx)) |
0531ce1d | 2053 | }); |
1a4d82fc JJ |
2054 | BareFunctionDecl { |
2055 | unsafety: self.unsafety, | |
8faf50e0 | 2056 | abi: self.abi, |
0531ce1d XL |
2057 | decl, |
2058 | generic_params, | |
1a4d82fc JJ |
2059 | } |
2060 | } | |
2061 | } | |
2062 | ||
dc9dc135 | 2063 | impl Clean<Item> for doctree::Static<'_> { |
532ac7d7 | 2064 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
1a4d82fc JJ |
2065 | debug!("cleaning static {}: {:?}", self.name.clean(cx), self); |
2066 | Item { | |
2067 | name: Some(self.name.clean(cx)), | |
2068 | attrs: self.attrs.clean(cx), | |
2069 | source: self.whence.clean(cx), | |
416331ca | 2070 | def_id: cx.tcx.hir().local_def_id(self.id), |
1a4d82fc | 2071 | visibility: self.vis.clean(cx), |
416331ca XL |
2072 | stability: cx.stability(self.id).clean(cx), |
2073 | deprecation: cx.deprecation(self.id).clean(cx), | |
1a4d82fc JJ |
2074 | inner: StaticItem(Static { |
2075 | type_: self.type_.clean(cx), | |
2076 | mutability: self.mutability.clean(cx), | |
32a655c1 | 2077 | expr: print_const_expr(cx, self.expr), |
1a4d82fc JJ |
2078 | }), |
2079 | } | |
2080 | } | |
2081 | } | |
2082 | ||
dc9dc135 | 2083 | impl Clean<Item> for doctree::Constant<'_> { |
532ac7d7 | 2084 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
1a4d82fc JJ |
2085 | Item { |
2086 | name: Some(self.name.clean(cx)), | |
2087 | attrs: self.attrs.clean(cx), | |
2088 | source: self.whence.clean(cx), | |
416331ca | 2089 | def_id: cx.tcx.hir().local_def_id(self.id), |
1a4d82fc | 2090 | visibility: self.vis.clean(cx), |
416331ca XL |
2091 | stability: cx.stability(self.id).clean(cx), |
2092 | deprecation: cx.deprecation(self.id).clean(cx), | |
1a4d82fc JJ |
2093 | inner: ConstantItem(Constant { |
2094 | type_: self.type_.clean(cx), | |
32a655c1 | 2095 | expr: print_const_expr(cx, self.expr), |
1a4d82fc JJ |
2096 | }), |
2097 | } | |
2098 | } | |
2099 | } | |
2100 | ||
e9174d1e | 2101 | impl Clean<Mutability> for hir::Mutability { |
532ac7d7 | 2102 | fn clean(&self, _: &DocContext<'_>) -> Mutability { |
1a4d82fc | 2103 | match self { |
60c5eb7d XL |
2104 | &hir::Mutability::Mutable => Mutable, |
2105 | &hir::Mutability::Immutable => Immutable, | |
1a4d82fc JJ |
2106 | } |
2107 | } | |
2108 | } | |
2109 | ||
e74abb32 | 2110 | impl Clean<ImplPolarity> for ty::ImplPolarity { |
532ac7d7 | 2111 | fn clean(&self, _: &DocContext<'_>) -> ImplPolarity { |
85aaf69f | 2112 | match self { |
e74abb32 XL |
2113 | &ty::ImplPolarity::Positive | |
2114 | // FIXME: do we want to do something else here? | |
2115 | &ty::ImplPolarity::Reservation => ImplPolarity::Positive, | |
2116 | &ty::ImplPolarity::Negative => ImplPolarity::Negative, | |
85aaf69f SL |
2117 | } |
2118 | } | |
2119 | } | |
2120 | ||
dc9dc135 | 2121 | impl Clean<Vec<Item>> for doctree::Impl<'_> { |
532ac7d7 | 2122 | fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> { |
d9579d0f AL |
2123 | let mut ret = Vec::new(); |
2124 | let trait_ = self.trait_.clean(cx); | |
dc9dc135 | 2125 | let items = self.items.iter().map(|ii| ii.clean(cx)).collect::<Vec<_>>(); |
e74abb32 | 2126 | let def_id = cx.tcx.hir().local_def_id(self.id); |
d9579d0f AL |
2127 | |
2128 | // If this impl block is an implementation of the Deref trait, then we | |
2129 | // need to try inlining the target's inherent impl blocks as well. | |
ea8adc8c | 2130 | if trait_.def_id() == cx.tcx.lang_items().deref_trait() { |
54a0048b | 2131 | build_deref_target_impls(cx, &items, &mut ret); |
d9579d0f AL |
2132 | } |
2133 | ||
476ff2be SL |
2134 | let provided = trait_.def_id().map(|did| { |
2135 | cx.tcx.provided_trait_methods(did) | |
2136 | .into_iter() | |
8faf50e0 | 2137 | .map(|meth| meth.ident.to_string()) |
476ff2be | 2138 | .collect() |
0bf4aa26 | 2139 | }).unwrap_or_default(); |
54a0048b | 2140 | |
d9579d0f | 2141 | ret.push(Item { |
1a4d82fc JJ |
2142 | name: None, |
2143 | attrs: self.attrs.clean(cx), | |
2144 | source: self.whence.clean(cx), | |
e74abb32 | 2145 | def_id, |
1a4d82fc | 2146 | visibility: self.vis.clean(cx), |
416331ca XL |
2147 | stability: cx.stability(self.id).clean(cx), |
2148 | deprecation: cx.deprecation(self.id).clean(cx), | |
1a4d82fc | 2149 | inner: ImplItem(Impl { |
c34b1796 | 2150 | unsafety: self.unsafety, |
1a4d82fc | 2151 | generics: self.generics.clean(cx), |
54a0048b | 2152 | provided_trait_methods: provided, |
3b2f2976 | 2153 | trait_, |
1a4d82fc | 2154 | for_: self.for_.clean(cx), |
3b2f2976 | 2155 | items, |
e74abb32 | 2156 | polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), |
0531ce1d | 2157 | synthetic: false, |
8faf50e0 | 2158 | blanket_impl: None, |
0531ce1d | 2159 | }) |
d9579d0f | 2160 | }); |
54a0048b | 2161 | ret |
d9579d0f AL |
2162 | } |
2163 | } | |
2164 | ||
dc9dc135 | 2165 | impl Clean<Vec<Item>> for doctree::ExternCrate<'_> { |
532ac7d7 | 2166 | fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> { |
0731742a XL |
2167 | |
2168 | let please_inline = self.vis.node.is_pub() && self.attrs.iter().any(|a| { | |
48663c56 XL |
2169 | a.check_name(sym::doc) && match a.meta_item_list() { |
2170 | Some(l) => attr::list_contains_name(&l, sym::inline), | |
0731742a XL |
2171 | None => false, |
2172 | } | |
2173 | }); | |
2174 | ||
2175 | if please_inline { | |
2176 | let mut visited = FxHashSet::default(); | |
2177 | ||
48663c56 XL |
2178 | let res = Res::Def( |
2179 | DefKind::Mod, | |
2180 | DefId { | |
2181 | krate: self.cnum, | |
2182 | index: CRATE_DEF_INDEX, | |
2183 | }, | |
2184 | ); | |
0731742a | 2185 | |
416331ca XL |
2186 | if let Some(items) = inline::try_inline( |
2187 | cx, res, self.name, | |
2188 | Some(rustc::ty::Attributes::Borrowed(self.attrs)), | |
2189 | &mut visited | |
2190 | ) { | |
0731742a XL |
2191 | return items; |
2192 | } | |
2193 | } | |
2194 | ||
2195 | vec![Item { | |
85aaf69f SL |
2196 | name: None, |
2197 | attrs: self.attrs.clean(cx), | |
2198 | source: self.whence.clean(cx), | |
a7813a04 | 2199 | def_id: DefId { krate: self.cnum, index: CRATE_DEF_INDEX }, |
85aaf69f SL |
2200 | visibility: self.vis.clean(cx), |
2201 | stability: None, | |
9cc50fc6 | 2202 | deprecation: None, |
85aaf69f | 2203 | inner: ExternCrateItem(self.name.clean(cx), self.path.clone()) |
0731742a | 2204 | }] |
85aaf69f | 2205 | } |
1a4d82fc JJ |
2206 | } |
2207 | ||
dc9dc135 | 2208 | impl Clean<Vec<Item>> for doctree::Import<'_> { |
532ac7d7 | 2209 | fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> { |
1a4d82fc JJ |
2210 | // We consider inlining the documentation of `pub use` statements, but we |
2211 | // forcefully don't inline if this is not public or if the | |
2212 | // #[doc(no_inline)] attribute is present. | |
3157f602 | 2213 | // Don't inline doc(hidden) imports so they can be stripped at a later stage. |
13cf67c4 | 2214 | let mut denied = !self.vis.node.is_pub() || self.attrs.iter().any(|a| { |
48663c56 XL |
2215 | a.check_name(sym::doc) && match a.meta_item_list() { |
2216 | Some(l) => attr::list_contains_name(&l, sym::no_inline) || | |
2217 | attr::list_contains_name(&l, sym::hidden), | |
1a4d82fc JJ |
2218 | None => false, |
2219 | } | |
2220 | }); | |
13cf67c4 XL |
2221 | // Also check whether imports were asked to be inlined, in case we're trying to re-export a |
2222 | // crate in Rust 2018+ | |
48663c56 | 2223 | let please_inline = self.attrs.lists(sym::doc).has_word(sym::inline); |
476ff2be SL |
2224 | let path = self.path.clean(cx); |
2225 | let inner = if self.glob { | |
94b46f34 | 2226 | if !denied { |
0bf4aa26 | 2227 | let mut visited = FxHashSet::default(); |
48663c56 | 2228 | if let Some(items) = inline::try_inline_glob(cx, path.res, &mut visited) { |
94b46f34 XL |
2229 | return items; |
2230 | } | |
2231 | } | |
2232 | ||
476ff2be SL |
2233 | Import::Glob(resolve_use_source(cx, path)) |
2234 | } else { | |
2235 | let name = self.name; | |
13cf67c4 | 2236 | if !please_inline { |
48663c56 XL |
2237 | match path.res { |
2238 | Res::Def(DefKind::Mod, did) => { | |
2239 | if !did.is_local() && did.index == CRATE_DEF_INDEX { | |
2240 | // if we're `pub use`ing an extern crate root, don't inline it unless we | |
2241 | // were specifically asked for it | |
2242 | denied = true; | |
2243 | } | |
13cf67c4 XL |
2244 | } |
2245 | _ => {} | |
2246 | } | |
2247 | } | |
476ff2be | 2248 | if !denied { |
0bf4aa26 | 2249 | let mut visited = FxHashSet::default(); |
416331ca XL |
2250 | if let Some(items) = inline::try_inline( |
2251 | cx, path.res, name, | |
2252 | Some(rustc::ty::Attributes::Borrowed(self.attrs)), | |
2253 | &mut visited | |
2254 | ) { | |
476ff2be | 2255 | return items; |
85aaf69f | 2256 | } |
1a4d82fc | 2257 | } |
476ff2be | 2258 | Import::Simple(name.clean(cx), resolve_use_source(cx, path)) |
85aaf69f | 2259 | }; |
8faf50e0 | 2260 | |
476ff2be | 2261 | vec![Item { |
85aaf69f SL |
2262 | name: None, |
2263 | attrs: self.attrs.clean(cx), | |
2264 | source: self.whence.clean(cx), | |
416331ca | 2265 | def_id: cx.tcx.hir().local_def_id_from_node_id(ast::CRATE_NODE_ID), |
85aaf69f SL |
2266 | visibility: self.vis.clean(cx), |
2267 | stability: None, | |
9cc50fc6 | 2268 | deprecation: None, |
85aaf69f | 2269 | inner: ImportItem(inner) |
476ff2be | 2270 | }] |
1a4d82fc JJ |
2271 | } |
2272 | } | |
2273 | ||
dc9dc135 | 2274 | impl Clean<Item> for doctree::ForeignItem<'_> { |
532ac7d7 | 2275 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
dc9dc135 | 2276 | let inner = match self.kind { |
8faf50e0 | 2277 | hir::ForeignItemKind::Fn(ref decl, ref names, ref generics) => { |
dc9dc135 | 2278 | let abi = cx.tcx.hir().get_foreign_abi(self.id); |
0531ce1d XL |
2279 | let (generics, decl) = enter_impl_trait(cx, || { |
2280 | (generics.clean(cx), (&**decl, &names[..]).clean(cx)) | |
2281 | }); | |
532ac7d7 | 2282 | let (all_types, ret_types) = get_all_types(&generics, &decl, cx); |
1a4d82fc | 2283 | ForeignFunctionItem(Function { |
0531ce1d XL |
2284 | decl, |
2285 | generics, | |
8faf50e0 XL |
2286 | header: hir::FnHeader { |
2287 | unsafety: hir::Unsafety::Unsafe, | |
dc9dc135 | 2288 | abi, |
8faf50e0 XL |
2289 | constness: hir::Constness::NotConst, |
2290 | asyncness: hir::IsAsync::NotAsync, | |
2291 | }, | |
532ac7d7 XL |
2292 | all_types, |
2293 | ret_types, | |
1a4d82fc JJ |
2294 | }) |
2295 | } | |
8faf50e0 | 2296 | hir::ForeignItemKind::Static(ref ty, mutbl) => { |
1a4d82fc JJ |
2297 | ForeignStaticItem(Static { |
2298 | type_: ty.clean(cx), | |
48663c56 | 2299 | mutability: mutbl.clean(cx), |
b7449926 | 2300 | expr: String::new(), |
1a4d82fc JJ |
2301 | }) |
2302 | } | |
8faf50e0 | 2303 | hir::ForeignItemKind::Type => { |
abe05a73 XL |
2304 | ForeignTypeItem |
2305 | } | |
1a4d82fc | 2306 | }; |
8faf50e0 | 2307 | |
1a4d82fc | 2308 | Item { |
dc9dc135 | 2309 | name: Some(self.name.clean(cx)), |
1a4d82fc | 2310 | attrs: self.attrs.clean(cx), |
dc9dc135 | 2311 | source: self.whence.clean(cx), |
416331ca | 2312 | def_id: cx.tcx.hir().local_def_id(self.id), |
1a4d82fc | 2313 | visibility: self.vis.clean(cx), |
416331ca XL |
2314 | stability: cx.stability(self.id).clean(cx), |
2315 | deprecation: cx.deprecation(self.id).clean(cx), | |
3b2f2976 | 2316 | inner, |
1a4d82fc JJ |
2317 | } |
2318 | } | |
2319 | } | |
2320 | ||
dc9dc135 | 2321 | impl Clean<Item> for doctree::Macro<'_> { |
532ac7d7 | 2322 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
9e0c209e | 2323 | let name = self.name.clean(cx); |
1a4d82fc | 2324 | Item { |
92a42be0 | 2325 | name: Some(name.clone()), |
1a4d82fc JJ |
2326 | attrs: self.attrs.clean(cx), |
2327 | source: self.whence.clean(cx), | |
e74abb32 | 2328 | visibility: Public, |
416331ca XL |
2329 | stability: cx.stability(self.hid).clean(cx), |
2330 | deprecation: cx.deprecation(self.hid).clean(cx), | |
32a655c1 | 2331 | def_id: self.def_id, |
1a4d82fc | 2332 | inner: MacroItem(Macro { |
92a42be0 | 2333 | source: format!("macro_rules! {} {{\n{}}}", |
9e0c209e SL |
2334 | name, |
2335 | self.matchers.iter().map(|span| { | |
2336 | format!(" {} => {{ ... }};\n", span.to_src(cx)) | |
2337 | }).collect::<String>()), | |
d9579d0f | 2338 | imported_from: self.imported_from.clean(cx), |
1a4d82fc JJ |
2339 | }), |
2340 | } | |
2341 | } | |
2342 | } | |
2343 | ||
dc9dc135 | 2344 | impl Clean<Item> for doctree::ProcMacro<'_> { |
532ac7d7 | 2345 | fn clean(&self, cx: &DocContext<'_>) -> Item { |
0bf4aa26 XL |
2346 | Item { |
2347 | name: Some(self.name.clean(cx)), | |
2348 | attrs: self.attrs.clean(cx), | |
2349 | source: self.whence.clean(cx), | |
e74abb32 | 2350 | visibility: Public, |
416331ca XL |
2351 | stability: cx.stability(self.id).clean(cx), |
2352 | deprecation: cx.deprecation(self.id).clean(cx), | |
2353 | def_id: cx.tcx.hir().local_def_id(self.id), | |
0bf4aa26 XL |
2354 | inner: ProcMacroItem(ProcMacro { |
2355 | kind: self.kind, | |
2356 | helpers: self.helpers.clean(cx), | |
2357 | }), | |
2358 | } | |
2359 | } | |
2360 | } | |
2361 | ||
1a4d82fc | 2362 | impl Clean<Stability> for attr::Stability { |
532ac7d7 | 2363 | fn clean(&self, _: &DocContext<'_>) -> Stability { |
1a4d82fc | 2364 | Stability { |
b039eaaf | 2365 | level: stability::StabilityLevel::from_attr_level(&self.level), |
0731742a | 2366 | feature: Some(self.feature.to_string()).filter(|f| !f.is_empty()), |
b039eaaf SL |
2367 | since: match self.level { |
2368 | attr::Stable {ref since} => since.to_string(), | |
b7449926 | 2369 | _ => String::new(), |
b039eaaf | 2370 | }, |
0731742a XL |
2371 | deprecation: self.rustc_depr.as_ref().map(|d| { |
2372 | Deprecation { | |
2373 | note: Some(d.reason.to_string()).filter(|r| !r.is_empty()), | |
2374 | since: Some(d.since.to_string()).filter(|d| !d.is_empty()), | |
2375 | } | |
2376 | }), | |
476ff2be | 2377 | unstable_reason: match self.level { |
0731742a XL |
2378 | attr::Unstable { reason: Some(ref reason), .. } => Some(reason.to_string()), |
2379 | _ => None, | |
b039eaaf SL |
2380 | }, |
2381 | issue: match self.level { | |
60c5eb7d | 2382 | attr::Unstable {issue, ..} => issue, |
b039eaaf SL |
2383 | _ => None, |
2384 | } | |
1a4d82fc JJ |
2385 | } |
2386 | } | |
2387 | } | |
2388 | ||
62682a34 | 2389 | impl<'a> Clean<Stability> for &'a attr::Stability { |
532ac7d7 | 2390 | fn clean(&self, dc: &DocContext<'_>) -> Stability { |
b039eaaf | 2391 | (**self).clean(dc) |
62682a34 SL |
2392 | } |
2393 | } | |
2394 | ||
9cc50fc6 | 2395 | impl Clean<Deprecation> for attr::Deprecation { |
532ac7d7 | 2396 | fn clean(&self, _: &DocContext<'_>) -> Deprecation { |
9cc50fc6 | 2397 | Deprecation { |
0731742a XL |
2398 | since: self.since.map(|s| s.to_string()).filter(|s| !s.is_empty()), |
2399 | note: self.note.map(|n| n.to_string()).filter(|n| !n.is_empty()), | |
9cc50fc6 SL |
2400 | } |
2401 | } | |
2402 | } | |
2403 | ||
e9174d1e | 2404 | impl Clean<TypeBinding> for hir::TypeBinding { |
532ac7d7 | 2405 | fn clean(&self, cx: &DocContext<'_>) -> TypeBinding { |
1a4d82fc | 2406 | TypeBinding { |
8faf50e0 | 2407 | name: self.ident.name.clean(cx), |
dc9dc135 XL |
2408 | kind: self.kind.clean(cx), |
2409 | } | |
2410 | } | |
2411 | } | |
2412 | ||
2413 | impl Clean<TypeBindingKind> for hir::TypeBindingKind { | |
2414 | fn clean(&self, cx: &DocContext<'_>) -> TypeBindingKind { | |
2415 | match *self { | |
2416 | hir::TypeBindingKind::Equality { ref ty } => | |
2417 | TypeBindingKind::Equality { | |
2418 | ty: ty.clean(cx), | |
2419 | }, | |
2420 | hir::TypeBindingKind::Constraint { ref bounds } => | |
2421 | TypeBindingKind::Constraint { | |
2422 | bounds: bounds.into_iter().map(|b| b.clean(cx)).collect(), | |
2423 | }, | |
1a4d82fc JJ |
2424 | } |
2425 | } | |
2426 | } | |
0531ce1d | 2427 | |
0531ce1d | 2428 | enum SimpleBound { |
8faf50e0 XL |
2429 | TraitBound(Vec<PathSegment>, Vec<SimpleBound>, Vec<GenericParamDef>, hir::TraitBoundModifier), |
2430 | Outlives(Lifetime), | |
0531ce1d XL |
2431 | } |
2432 | ||
8faf50e0 XL |
2433 | impl From<GenericBound> for SimpleBound { |
2434 | fn from(bound: GenericBound) -> Self { | |
0531ce1d | 2435 | match bound.clone() { |
8faf50e0 XL |
2436 | GenericBound::Outlives(l) => SimpleBound::Outlives(l), |
2437 | GenericBound::TraitBound(t, mod_) => match t.trait_ { | |
532ac7d7 | 2438 | Type::ResolvedPath { path, param_names, .. } => { |
0531ce1d | 2439 | SimpleBound::TraitBound(path.segments, |
532ac7d7 | 2440 | param_names |
0531ce1d XL |
2441 | .map_or_else(|| Vec::new(), |v| v.iter() |
2442 | .map(|p| SimpleBound::from(p.clone())) | |
2443 | .collect()), | |
2444 | t.generic_params, | |
2445 | mod_) | |
2446 | } | |
2447 | _ => panic!("Unexpected bound {:?}", bound), | |
2448 | } | |
2449 | } | |
2450 | } | |
2451 | } |