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