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