]> git.proxmox.com Git - rustc.git/blob - src/librustdoc/clean/types.rs
New upstream version 1.42.0+dfsg1
[rustc.git] / src / librustdoc / clean / types.rs
1 use std::cell::RefCell;
2 use std::default::Default;
3 use std::fmt;
4 use std::hash::{Hash, Hasher};
5 use std::iter::FromIterator;
6 use std::num::NonZeroU32;
7 use std::rc::Rc;
8 use std::sync::Arc;
9 use std::{slice, vec};
10
11 use rustc::middle::lang_items;
12 use rustc::middle::stability;
13 use rustc::ty::layout::VariantIdx;
14 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
15 use rustc_hir as hir;
16 use rustc_hir::def::Res;
17 use rustc_hir::def_id::{CrateNum, DefId};
18 use rustc_hir::Mutability;
19 use rustc_index::vec::IndexVec;
20 use rustc_span::hygiene::MacroKind;
21 use rustc_span::source_map::DUMMY_SP;
22 use rustc_span::symbol::{sym, Symbol};
23 use rustc_span::{self, FileName};
24 use rustc_target::spec::abi::Abi;
25 use syntax::ast::{self, AttrStyle, Ident};
26 use syntax::attr;
27 use syntax::util::comments::strip_doc_comment_decoration;
28
29 use crate::clean::cfg::Cfg;
30 use crate::clean::external_path;
31 use crate::clean::inline;
32 use crate::clean::types::Type::{QPath, ResolvedPath};
33 use crate::core::DocContext;
34 use crate::doctree;
35 use crate::html::item_type::ItemType;
36 use crate::html::render::{cache, ExternalLocation};
37
38 use self::FunctionRetTy::*;
39 use self::ItemEnum::*;
40 use self::SelfTy::*;
41 use self::Type::*;
42
43 thread_local!(pub static MAX_DEF_ID: RefCell<FxHashMap<CrateNum, DefId>> = Default::default());
44
45 #[derive(Clone, Debug)]
46 pub struct Crate {
47 pub name: String,
48 pub version: Option<String>,
49 pub src: FileName,
50 pub module: Option<Item>,
51 pub externs: Vec<(CrateNum, ExternalCrate)>,
52 pub primitives: Vec<(DefId, PrimitiveType, Attributes)>,
53 // These are later on moved into `CACHEKEY`, leaving the map empty.
54 // Only here so that they can be filtered through the rustdoc passes.
55 pub external_traits: Rc<RefCell<FxHashMap<DefId, Trait>>>,
56 pub masked_crates: FxHashSet<CrateNum>,
57 pub collapsed: bool,
58 }
59
60 #[derive(Clone, Debug)]
61 pub struct ExternalCrate {
62 pub name: String,
63 pub src: FileName,
64 pub attrs: Attributes,
65 pub primitives: Vec<(DefId, PrimitiveType, Attributes)>,
66 pub keywords: Vec<(DefId, String, Attributes)>,
67 }
68
69 /// Anything with a source location and set of attributes and, optionally, a
70 /// name. That is, anything that can be documented. This doesn't correspond
71 /// directly to the AST's concept of an item; it's a strict superset.
72 #[derive(Clone)]
73 pub struct Item {
74 /// Stringified span
75 pub source: Span,
76 /// Not everything has a name. E.g., impls
77 pub name: Option<String>,
78 pub attrs: Attributes,
79 pub inner: ItemEnum,
80 pub visibility: Visibility,
81 pub def_id: DefId,
82 pub stability: Option<Stability>,
83 pub deprecation: Option<Deprecation>,
84 }
85
86 impl fmt::Debug for Item {
87 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
88 let fake = MAX_DEF_ID.with(|m| {
89 m.borrow().get(&self.def_id.krate).map(|id| self.def_id >= *id).unwrap_or(false)
90 });
91 let def_id: &dyn fmt::Debug = if fake { &"**FAKE**" } else { &self.def_id };
92
93 fmt.debug_struct("Item")
94 .field("source", &self.source)
95 .field("name", &self.name)
96 .field("attrs", &self.attrs)
97 .field("inner", &self.inner)
98 .field("visibility", &self.visibility)
99 .field("def_id", def_id)
100 .field("stability", &self.stability)
101 .field("deprecation", &self.deprecation)
102 .finish()
103 }
104 }
105
106 impl Item {
107 /// Finds the `doc` attribute as a NameValue and returns the corresponding
108 /// value found.
109 pub fn doc_value(&self) -> Option<&str> {
110 self.attrs.doc_value()
111 }
112
113 /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
114 /// with newlines.
115 pub fn collapsed_doc_value(&self) -> Option<String> {
116 self.attrs.collapsed_doc_value()
117 }
118
119 pub fn links(&self) -> Vec<(String, String)> {
120 self.attrs.links(&self.def_id.krate)
121 }
122
123 pub fn is_crate(&self) -> bool {
124 match self.inner {
125 StrippedItem(box ModuleItem(Module { is_crate: true, .. }))
126 | ModuleItem(Module { is_crate: true, .. }) => true,
127 _ => false,
128 }
129 }
130 pub fn is_mod(&self) -> bool {
131 self.type_() == ItemType::Module
132 }
133 pub fn is_trait(&self) -> bool {
134 self.type_() == ItemType::Trait
135 }
136 pub fn is_struct(&self) -> bool {
137 self.type_() == ItemType::Struct
138 }
139 pub fn is_enum(&self) -> bool {
140 self.type_() == ItemType::Enum
141 }
142 pub fn is_variant(&self) -> bool {
143 self.type_() == ItemType::Variant
144 }
145 pub fn is_associated_type(&self) -> bool {
146 self.type_() == ItemType::AssocType
147 }
148 pub fn is_associated_const(&self) -> bool {
149 self.type_() == ItemType::AssocConst
150 }
151 pub fn is_method(&self) -> bool {
152 self.type_() == ItemType::Method
153 }
154 pub fn is_ty_method(&self) -> bool {
155 self.type_() == ItemType::TyMethod
156 }
157 pub fn is_typedef(&self) -> bool {
158 self.type_() == ItemType::Typedef
159 }
160 pub fn is_primitive(&self) -> bool {
161 self.type_() == ItemType::Primitive
162 }
163 pub fn is_union(&self) -> bool {
164 self.type_() == ItemType::Union
165 }
166 pub fn is_import(&self) -> bool {
167 self.type_() == ItemType::Import
168 }
169 pub fn is_extern_crate(&self) -> bool {
170 self.type_() == ItemType::ExternCrate
171 }
172 pub fn is_keyword(&self) -> bool {
173 self.type_() == ItemType::Keyword
174 }
175 pub fn is_stripped(&self) -> bool {
176 match self.inner {
177 StrippedItem(..) => true,
178 _ => false,
179 }
180 }
181 pub fn has_stripped_fields(&self) -> Option<bool> {
182 match self.inner {
183 StructItem(ref _struct) => Some(_struct.fields_stripped),
184 UnionItem(ref union) => Some(union.fields_stripped),
185 VariantItem(Variant { kind: VariantKind::Struct(ref vstruct) }) => {
186 Some(vstruct.fields_stripped)
187 }
188 _ => None,
189 }
190 }
191
192 pub fn stability_class(&self) -> Option<String> {
193 self.stability.as_ref().and_then(|ref s| {
194 let mut classes = Vec::with_capacity(2);
195
196 if s.level == stability::Unstable {
197 classes.push("unstable");
198 }
199
200 if s.deprecation.is_some() {
201 classes.push("deprecated");
202 }
203
204 if classes.len() != 0 { Some(classes.join(" ")) } else { None }
205 })
206 }
207
208 pub fn stable_since(&self) -> Option<&str> {
209 self.stability.as_ref().map(|s| &s.since[..])
210 }
211
212 pub fn is_non_exhaustive(&self) -> bool {
213 self.attrs.other_attrs.iter().any(|a| a.check_name(sym::non_exhaustive))
214 }
215
216 /// Returns a documentation-level item type from the item.
217 pub fn type_(&self) -> ItemType {
218 ItemType::from(self)
219 }
220
221 /// Returns the info in the item's `#[deprecated]` or `#[rustc_deprecated]` attributes.
222 ///
223 /// If the item is not deprecated, returns `None`.
224 pub fn deprecation(&self) -> Option<&Deprecation> {
225 self.deprecation
226 .as_ref()
227 .or_else(|| self.stability.as_ref().and_then(|s| s.deprecation.as_ref()))
228 }
229 pub fn is_default(&self) -> bool {
230 match self.inner {
231 ItemEnum::MethodItem(ref meth) => {
232 if let Some(defaultness) = meth.defaultness {
233 defaultness.has_value() && !defaultness.is_final()
234 } else {
235 false
236 }
237 }
238 _ => false,
239 }
240 }
241 }
242
243 #[derive(Clone, Debug)]
244 pub enum ItemEnum {
245 ExternCrateItem(String, Option<String>),
246 ImportItem(Import),
247 StructItem(Struct),
248 UnionItem(Union),
249 EnumItem(Enum),
250 FunctionItem(Function),
251 ModuleItem(Module),
252 TypedefItem(Typedef, bool /* is associated type */),
253 OpaqueTyItem(OpaqueTy, bool /* is associated type */),
254 StaticItem(Static),
255 ConstantItem(Constant),
256 TraitItem(Trait),
257 TraitAliasItem(TraitAlias),
258 ImplItem(Impl),
259 /// A method signature only. Used for required methods in traits (ie,
260 /// non-default-methods).
261 TyMethodItem(TyMethod),
262 /// A method with a body.
263 MethodItem(Method),
264 StructFieldItem(Type),
265 VariantItem(Variant),
266 /// `fn`s from an extern block
267 ForeignFunctionItem(Function),
268 /// `static`s from an extern block
269 ForeignStaticItem(Static),
270 /// `type`s from an extern block
271 ForeignTypeItem,
272 MacroItem(Macro),
273 ProcMacroItem(ProcMacro),
274 PrimitiveItem(PrimitiveType),
275 AssocConstItem(Type, Option<String>),
276 AssocTypeItem(Vec<GenericBound>, Option<Type>),
277 /// An item that has been stripped by a rustdoc pass
278 StrippedItem(Box<ItemEnum>),
279 KeywordItem(String),
280 }
281
282 impl ItemEnum {
283 pub fn is_associated(&self) -> bool {
284 match *self {
285 ItemEnum::TypedefItem(_, _) | ItemEnum::AssocTypeItem(_, _) => true,
286 _ => false,
287 }
288 }
289 }
290
291 #[derive(Clone, Debug)]
292 pub struct Module {
293 pub items: Vec<Item>,
294 pub is_crate: bool,
295 }
296
297 pub struct ListAttributesIter<'a> {
298 attrs: slice::Iter<'a, ast::Attribute>,
299 current_list: vec::IntoIter<ast::NestedMetaItem>,
300 name: Symbol,
301 }
302
303 impl<'a> Iterator for ListAttributesIter<'a> {
304 type Item = ast::NestedMetaItem;
305
306 fn next(&mut self) -> Option<Self::Item> {
307 if let Some(nested) = self.current_list.next() {
308 return Some(nested);
309 }
310
311 for attr in &mut self.attrs {
312 if let Some(list) = attr.meta_item_list() {
313 if attr.check_name(self.name) {
314 self.current_list = list.into_iter();
315 if let Some(nested) = self.current_list.next() {
316 return Some(nested);
317 }
318 }
319 }
320 }
321
322 None
323 }
324
325 fn size_hint(&self) -> (usize, Option<usize>) {
326 let lower = self.current_list.len();
327 (lower, None)
328 }
329 }
330
331 pub trait AttributesExt {
332 /// Finds an attribute as List and returns the list of attributes nested inside.
333 fn lists(&self, name: Symbol) -> ListAttributesIter<'_>;
334 }
335
336 impl AttributesExt for [ast::Attribute] {
337 fn lists(&self, name: Symbol) -> ListAttributesIter<'_> {
338 ListAttributesIter { attrs: self.iter(), current_list: Vec::new().into_iter(), name }
339 }
340 }
341
342 pub trait NestedAttributesExt {
343 /// Returns `true` if the attribute list contains a specific `Word`
344 fn has_word(self, word: Symbol) -> bool;
345 }
346
347 impl<I: IntoIterator<Item = ast::NestedMetaItem>> NestedAttributesExt for I {
348 fn has_word(self, word: Symbol) -> bool {
349 self.into_iter().any(|attr| attr.is_word() && attr.check_name(word))
350 }
351 }
352
353 /// A portion of documentation, extracted from a `#[doc]` attribute.
354 ///
355 /// Each variant contains the line number within the complete doc-comment where the fragment
356 /// starts, as well as the Span where the corresponding doc comment or attribute is located.
357 ///
358 /// Included files are kept separate from inline doc comments so that proper line-number
359 /// information can be given when a doctest fails. Sugared doc comments and "raw" doc comments are
360 /// kept separate because of issue #42760.
361 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
362 pub enum DocFragment {
363 /// A doc fragment created from a `///` or `//!` doc comment.
364 SugaredDoc(usize, rustc_span::Span, String),
365 /// A doc fragment created from a "raw" `#[doc=""]` attribute.
366 RawDoc(usize, rustc_span::Span, String),
367 /// A doc fragment created from a `#[doc(include="filename")]` attribute. Contains both the
368 /// given filename and the file contents.
369 Include(usize, rustc_span::Span, String, String),
370 }
371
372 impl DocFragment {
373 pub fn as_str(&self) -> &str {
374 match *self {
375 DocFragment::SugaredDoc(_, _, ref s) => &s[..],
376 DocFragment::RawDoc(_, _, ref s) => &s[..],
377 DocFragment::Include(_, _, _, ref s) => &s[..],
378 }
379 }
380
381 pub fn span(&self) -> rustc_span::Span {
382 match *self {
383 DocFragment::SugaredDoc(_, span, _)
384 | DocFragment::RawDoc(_, span, _)
385 | DocFragment::Include(_, span, _, _) => span,
386 }
387 }
388 }
389
390 impl<'a> FromIterator<&'a DocFragment> for String {
391 fn from_iter<T>(iter: T) -> Self
392 where
393 T: IntoIterator<Item = &'a DocFragment>,
394 {
395 iter.into_iter().fold(String::new(), |mut acc, frag| {
396 if !acc.is_empty() {
397 acc.push('\n');
398 }
399 match *frag {
400 DocFragment::SugaredDoc(_, _, ref docs)
401 | DocFragment::RawDoc(_, _, ref docs)
402 | DocFragment::Include(_, _, _, ref docs) => acc.push_str(docs),
403 }
404
405 acc
406 })
407 }
408 }
409
410 #[derive(Clone, Debug, Default)]
411 pub struct Attributes {
412 pub doc_strings: Vec<DocFragment>,
413 pub other_attrs: Vec<ast::Attribute>,
414 pub cfg: Option<Arc<Cfg>>,
415 pub span: Option<rustc_span::Span>,
416 /// map from Rust paths to resolved defs and potential URL fragments
417 pub links: Vec<(String, Option<DefId>, Option<String>)>,
418 pub inner_docs: bool,
419 }
420
421 impl Attributes {
422 /// Extracts the content from an attribute `#[doc(cfg(content))]`.
423 pub fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> {
424 use syntax::ast::NestedMetaItem::MetaItem;
425
426 if let ast::MetaItemKind::List(ref nmis) = mi.kind {
427 if nmis.len() == 1 {
428 if let MetaItem(ref cfg_mi) = nmis[0] {
429 if cfg_mi.check_name(sym::cfg) {
430 if let ast::MetaItemKind::List(ref cfg_nmis) = cfg_mi.kind {
431 if cfg_nmis.len() == 1 {
432 if let MetaItem(ref content_mi) = cfg_nmis[0] {
433 return Some(content_mi);
434 }
435 }
436 }
437 }
438 }
439 }
440 }
441
442 None
443 }
444
445 /// Reads a `MetaItem` from within an attribute, looks for whether it is a
446 /// `#[doc(include="file")]`, and returns the filename and contents of the file as loaded from
447 /// its expansion.
448 pub fn extract_include(mi: &ast::MetaItem) -> Option<(String, String)> {
449 mi.meta_item_list().and_then(|list| {
450 for meta in list {
451 if meta.check_name(sym::include) {
452 // the actual compiled `#[doc(include="filename")]` gets expanded to
453 // `#[doc(include(file="filename", contents="file contents")]` so we need to
454 // look for that instead
455 return meta.meta_item_list().and_then(|list| {
456 let mut filename: Option<String> = None;
457 let mut contents: Option<String> = None;
458
459 for it in list {
460 if it.check_name(sym::file) {
461 if let Some(name) = it.value_str() {
462 filename = Some(name.to_string());
463 }
464 } else if it.check_name(sym::contents) {
465 if let Some(docs) = it.value_str() {
466 contents = Some(docs.to_string());
467 }
468 }
469 }
470
471 if let (Some(filename), Some(contents)) = (filename, contents) {
472 Some((filename, contents))
473 } else {
474 None
475 }
476 });
477 }
478 }
479
480 None
481 })
482 }
483
484 pub fn has_doc_flag(&self, flag: Symbol) -> bool {
485 for attr in &self.other_attrs {
486 if !attr.check_name(sym::doc) {
487 continue;
488 }
489
490 if let Some(items) = attr.meta_item_list() {
491 if items.iter().filter_map(|i| i.meta_item()).any(|it| it.check_name(flag)) {
492 return true;
493 }
494 }
495 }
496
497 false
498 }
499
500 pub fn from_ast(diagnostic: &::rustc_errors::Handler, attrs: &[ast::Attribute]) -> Attributes {
501 let mut doc_strings = vec![];
502 let mut sp = None;
503 let mut cfg = Cfg::True;
504 let mut doc_line = 0;
505
506 let other_attrs = attrs
507 .iter()
508 .filter_map(|attr| {
509 if let Some(value) = attr.doc_str() {
510 let (value, mk_fragment): (_, fn(_, _, _) -> _) = if attr.is_doc_comment() {
511 (strip_doc_comment_decoration(&value.as_str()), DocFragment::SugaredDoc)
512 } else {
513 (value.to_string(), DocFragment::RawDoc)
514 };
515
516 let line = doc_line;
517 doc_line += value.lines().count();
518 doc_strings.push(mk_fragment(line, attr.span, value));
519
520 if sp.is_none() {
521 sp = Some(attr.span);
522 }
523 None
524 } else {
525 if attr.check_name(sym::doc) {
526 if let Some(mi) = attr.meta() {
527 if let Some(cfg_mi) = Attributes::extract_cfg(&mi) {
528 // Extracted #[doc(cfg(...))]
529 match Cfg::parse(cfg_mi) {
530 Ok(new_cfg) => cfg &= new_cfg,
531 Err(e) => diagnostic.span_err(e.span, e.msg),
532 }
533 } else if let Some((filename, contents)) =
534 Attributes::extract_include(&mi)
535 {
536 let line = doc_line;
537 doc_line += contents.lines().count();
538 doc_strings.push(DocFragment::Include(
539 line, attr.span, filename, contents,
540 ));
541 }
542 }
543 }
544 Some(attr.clone())
545 }
546 })
547 .collect();
548
549 // treat #[target_feature(enable = "feat")] attributes as if they were
550 // #[doc(cfg(target_feature = "feat"))] attributes as well
551 for attr in attrs.lists(sym::target_feature) {
552 if attr.check_name(sym::enable) {
553 if let Some(feat) = attr.value_str() {
554 let meta = attr::mk_name_value_item_str(
555 Ident::with_dummy_span(sym::target_feature),
556 feat,
557 DUMMY_SP,
558 );
559 if let Ok(feat_cfg) = Cfg::parse(&meta) {
560 cfg &= feat_cfg;
561 }
562 }
563 }
564 }
565
566 let inner_docs = attrs
567 .iter()
568 .filter(|a| a.doc_str().is_some())
569 .next()
570 .map_or(true, |a| a.style == AttrStyle::Inner);
571
572 Attributes {
573 doc_strings,
574 other_attrs,
575 cfg: if cfg == Cfg::True { None } else { Some(Arc::new(cfg)) },
576 span: sp,
577 links: vec![],
578 inner_docs,
579 }
580 }
581
582 /// Finds the `doc` attribute as a NameValue and returns the corresponding
583 /// value found.
584 pub fn doc_value(&self) -> Option<&str> {
585 self.doc_strings.first().map(|s| s.as_str())
586 }
587
588 /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
589 /// with newlines.
590 pub fn collapsed_doc_value(&self) -> Option<String> {
591 if !self.doc_strings.is_empty() { Some(self.doc_strings.iter().collect()) } else { None }
592 }
593
594 /// Gets links as a vector
595 ///
596 /// Cache must be populated before call
597 pub fn links(&self, krate: &CrateNum) -> Vec<(String, String)> {
598 use crate::html::format::href;
599
600 self.links
601 .iter()
602 .filter_map(|&(ref s, did, ref fragment)| {
603 match did {
604 Some(did) => {
605 if let Some((mut href, ..)) = href(did) {
606 if let Some(ref fragment) = *fragment {
607 href.push_str("#");
608 href.push_str(fragment);
609 }
610 Some((s.clone(), href))
611 } else {
612 None
613 }
614 }
615 None => {
616 if let Some(ref fragment) = *fragment {
617 let cache = cache();
618 let url = match cache.extern_locations.get(krate) {
619 Some(&(_, ref src, ExternalLocation::Local)) => {
620 src.to_str().expect("invalid file path")
621 }
622 Some(&(_, _, ExternalLocation::Remote(ref s))) => s,
623 Some(&(_, _, ExternalLocation::Unknown)) | None => {
624 "https://doc.rust-lang.org/nightly"
625 }
626 };
627 // This is a primitive so the url is done "by hand".
628 let tail = fragment.find('#').unwrap_or_else(|| fragment.len());
629 Some((
630 s.clone(),
631 format!(
632 "{}{}std/primitive.{}.html{}",
633 url,
634 if !url.ends_with('/') { "/" } else { "" },
635 &fragment[..tail],
636 &fragment[tail..]
637 ),
638 ))
639 } else {
640 panic!("This isn't a primitive?!");
641 }
642 }
643 }
644 })
645 .collect()
646 }
647 }
648
649 impl PartialEq for Attributes {
650 fn eq(&self, rhs: &Self) -> bool {
651 self.doc_strings == rhs.doc_strings
652 && self.cfg == rhs.cfg
653 && self.span == rhs.span
654 && self.links == rhs.links
655 && self
656 .other_attrs
657 .iter()
658 .map(|attr| attr.id)
659 .eq(rhs.other_attrs.iter().map(|attr| attr.id))
660 }
661 }
662
663 impl Eq for Attributes {}
664
665 impl Hash for Attributes {
666 fn hash<H: Hasher>(&self, hasher: &mut H) {
667 self.doc_strings.hash(hasher);
668 self.cfg.hash(hasher);
669 self.span.hash(hasher);
670 self.links.hash(hasher);
671 for attr in &self.other_attrs {
672 attr.id.hash(hasher);
673 }
674 }
675 }
676
677 impl AttributesExt for Attributes {
678 fn lists(&self, name: Symbol) -> ListAttributesIter<'_> {
679 self.other_attrs.lists(name)
680 }
681 }
682
683 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
684 pub enum GenericBound {
685 TraitBound(PolyTrait, hir::TraitBoundModifier),
686 Outlives(Lifetime),
687 }
688
689 impl GenericBound {
690 pub fn maybe_sized(cx: &DocContext<'_>) -> GenericBound {
691 let did = cx.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
692 let empty = cx.tcx.intern_substs(&[]);
693 let path = external_path(cx, cx.tcx.item_name(did), Some(did), false, vec![], empty);
694 inline::record_extern_fqn(cx, did, TypeKind::Trait);
695 GenericBound::TraitBound(
696 PolyTrait {
697 trait_: ResolvedPath { path, param_names: None, did, is_generic: false },
698 generic_params: Vec::new(),
699 },
700 hir::TraitBoundModifier::Maybe,
701 )
702 }
703
704 pub fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool {
705 use rustc_hir::TraitBoundModifier as TBM;
706 if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self {
707 if trait_.def_id() == cx.tcx.lang_items().sized_trait() {
708 return true;
709 }
710 }
711 false
712 }
713
714 pub fn get_poly_trait(&self) -> Option<PolyTrait> {
715 if let GenericBound::TraitBound(ref p, _) = *self {
716 return Some(p.clone());
717 }
718 None
719 }
720
721 pub fn get_trait_type(&self) -> Option<Type> {
722 if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, _) = *self {
723 Some(trait_.clone())
724 } else {
725 None
726 }
727 }
728 }
729
730 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
731 pub struct Lifetime(pub String);
732
733 impl Lifetime {
734 pub fn get_ref<'a>(&'a self) -> &'a str {
735 let Lifetime(ref s) = *self;
736 let s: &'a str = s;
737 s
738 }
739
740 pub fn statik() -> Lifetime {
741 Lifetime("'static".to_string())
742 }
743 }
744
745 #[derive(Clone, Debug)]
746 pub enum WherePredicate {
747 BoundPredicate { ty: Type, bounds: Vec<GenericBound> },
748 RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
749 EqPredicate { lhs: Type, rhs: Type },
750 }
751
752 impl WherePredicate {
753 pub fn get_bounds(&self) -> Option<&[GenericBound]> {
754 match *self {
755 WherePredicate::BoundPredicate { ref bounds, .. } => Some(bounds),
756 WherePredicate::RegionPredicate { ref bounds, .. } => Some(bounds),
757 _ => None,
758 }
759 }
760 }
761
762 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
763 pub enum GenericParamDefKind {
764 Lifetime,
765 Type {
766 did: DefId,
767 bounds: Vec<GenericBound>,
768 default: Option<Type>,
769 synthetic: Option<hir::SyntheticTyParamKind>,
770 },
771 Const {
772 did: DefId,
773 ty: Type,
774 },
775 }
776
777 impl GenericParamDefKind {
778 pub fn is_type(&self) -> bool {
779 match *self {
780 GenericParamDefKind::Type { .. } => true,
781 _ => false,
782 }
783 }
784
785 // FIXME(eddyb) this either returns the default of a type parameter, or the
786 // type of a `const` parameter. It seems that the intention is to *visit*
787 // any embedded types, but `get_type` seems to be the wrong name for that.
788 pub fn get_type(&self) -> Option<Type> {
789 match self {
790 GenericParamDefKind::Type { default, .. } => default.clone(),
791 GenericParamDefKind::Const { ty, .. } => Some(ty.clone()),
792 GenericParamDefKind::Lifetime => None,
793 }
794 }
795 }
796
797 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
798 pub struct GenericParamDef {
799 pub name: String,
800 pub kind: GenericParamDefKind,
801 }
802
803 impl GenericParamDef {
804 pub fn is_synthetic_type_param(&self) -> bool {
805 match self.kind {
806 GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => false,
807 GenericParamDefKind::Type { ref synthetic, .. } => synthetic.is_some(),
808 }
809 }
810
811 pub fn is_type(&self) -> bool {
812 self.kind.is_type()
813 }
814
815 pub fn get_type(&self) -> Option<Type> {
816 self.kind.get_type()
817 }
818
819 pub fn get_bounds(&self) -> Option<&[GenericBound]> {
820 match self.kind {
821 GenericParamDefKind::Type { ref bounds, .. } => Some(bounds),
822 _ => None,
823 }
824 }
825 }
826
827 // maybe use a Generic enum and use Vec<Generic>?
828 #[derive(Clone, Debug, Default)]
829 pub struct Generics {
830 pub params: Vec<GenericParamDef>,
831 pub where_predicates: Vec<WherePredicate>,
832 }
833
834 #[derive(Clone, Debug)]
835 pub struct Method {
836 pub generics: Generics,
837 pub decl: FnDecl,
838 pub header: hir::FnHeader,
839 pub defaultness: Option<hir::Defaultness>,
840 pub all_types: Vec<Type>,
841 pub ret_types: Vec<Type>,
842 }
843
844 #[derive(Clone, Debug)]
845 pub struct TyMethod {
846 pub header: hir::FnHeader,
847 pub decl: FnDecl,
848 pub generics: Generics,
849 pub all_types: Vec<Type>,
850 pub ret_types: Vec<Type>,
851 }
852
853 #[derive(Clone, Debug)]
854 pub struct Function {
855 pub decl: FnDecl,
856 pub generics: Generics,
857 pub header: hir::FnHeader,
858 pub all_types: Vec<Type>,
859 pub ret_types: Vec<Type>,
860 }
861
862 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
863 pub struct FnDecl {
864 pub inputs: Arguments,
865 pub output: FunctionRetTy,
866 pub c_variadic: bool,
867 pub attrs: Attributes,
868 }
869
870 impl FnDecl {
871 pub fn self_type(&self) -> Option<SelfTy> {
872 self.inputs.values.get(0).and_then(|v| v.to_self())
873 }
874
875 /// Returns the sugared return type for an async function.
876 ///
877 /// For example, if the return type is `impl std::future::Future<Output = i32>`, this function
878 /// will return `i32`.
879 ///
880 /// # Panics
881 ///
882 /// This function will panic if the return type does not match the expected sugaring for async
883 /// functions.
884 pub fn sugared_async_return_type(&self) -> FunctionRetTy {
885 match &self.output {
886 FunctionRetTy::Return(Type::ImplTrait(bounds)) => match &bounds[0] {
887 GenericBound::TraitBound(PolyTrait { trait_, .. }, ..) => {
888 let bindings = trait_.bindings().unwrap();
889 FunctionRetTy::Return(bindings[0].ty().clone())
890 }
891 _ => panic!("unexpected desugaring of async function"),
892 },
893 _ => panic!("unexpected desugaring of async function"),
894 }
895 }
896 }
897
898 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
899 pub struct Arguments {
900 pub values: Vec<Argument>,
901 }
902
903 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
904 pub struct Argument {
905 pub type_: Type,
906 pub name: String,
907 }
908
909 #[derive(Clone, PartialEq, Debug)]
910 pub enum SelfTy {
911 SelfValue,
912 SelfBorrowed(Option<Lifetime>, Mutability),
913 SelfExplicit(Type),
914 }
915
916 impl Argument {
917 pub fn to_self(&self) -> Option<SelfTy> {
918 if self.name != "self" {
919 return None;
920 }
921 if self.type_.is_self_type() {
922 return Some(SelfValue);
923 }
924 match self.type_ {
925 BorrowedRef { ref lifetime, mutability, ref type_ } if type_.is_self_type() => {
926 Some(SelfBorrowed(lifetime.clone(), mutability))
927 }
928 _ => Some(SelfExplicit(self.type_.clone())),
929 }
930 }
931 }
932
933 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
934 pub enum FunctionRetTy {
935 Return(Type),
936 DefaultReturn,
937 }
938
939 impl GetDefId for FunctionRetTy {
940 fn def_id(&self) -> Option<DefId> {
941 match *self {
942 Return(ref ty) => ty.def_id(),
943 DefaultReturn => None,
944 }
945 }
946 }
947
948 #[derive(Clone, Debug)]
949 pub struct Trait {
950 pub auto: bool,
951 pub unsafety: hir::Unsafety,
952 pub items: Vec<Item>,
953 pub generics: Generics,
954 pub bounds: Vec<GenericBound>,
955 pub is_spotlight: bool,
956 pub is_auto: bool,
957 }
958
959 #[derive(Clone, Debug)]
960 pub struct TraitAlias {
961 pub generics: Generics,
962 pub bounds: Vec<GenericBound>,
963 }
964
965 /// A trait reference, which may have higher ranked lifetimes.
966 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
967 pub struct PolyTrait {
968 pub trait_: Type,
969 pub generic_params: Vec<GenericParamDef>,
970 }
971
972 /// A representation of a type suitable for hyperlinking purposes. Ideally, one can get the original
973 /// type out of the AST/`TyCtxt` given one of these, if more information is needed. Most
974 /// importantly, it does not preserve mutability or boxes.
975 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
976 pub enum Type {
977 /// Structs/enums/traits (most that would be an `hir::TyKind::Path`).
978 ResolvedPath {
979 path: Path,
980 param_names: Option<Vec<GenericBound>>,
981 did: DefId,
982 /// `true` if is a `T::Name` path for associated types.
983 is_generic: bool,
984 },
985 /// For parameterized types, so the consumer of the JSON don't go
986 /// looking for types which don't exist anywhere.
987 Generic(String),
988 /// Primitives are the fixed-size numeric types (plus int/usize/float), char,
989 /// arrays, slices, and tuples.
990 Primitive(PrimitiveType),
991 /// `extern "ABI" fn`
992 BareFunction(Box<BareFunctionDecl>),
993 Tuple(Vec<Type>),
994 Slice(Box<Type>),
995 Array(Box<Type>, String),
996 Never,
997 RawPointer(Mutability, Box<Type>),
998 BorrowedRef {
999 lifetime: Option<Lifetime>,
1000 mutability: Mutability,
1001 type_: Box<Type>,
1002 },
1003
1004 // `<Type as Trait>::Name`
1005 QPath {
1006 name: String,
1007 self_type: Box<Type>,
1008 trait_: Box<Type>,
1009 },
1010
1011 // `_`
1012 Infer,
1013
1014 // `impl TraitA + TraitB + ...`
1015 ImplTrait(Vec<GenericBound>),
1016 }
1017
1018 #[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)]
1019 pub enum PrimitiveType {
1020 Isize,
1021 I8,
1022 I16,
1023 I32,
1024 I64,
1025 I128,
1026 Usize,
1027 U8,
1028 U16,
1029 U32,
1030 U64,
1031 U128,
1032 F32,
1033 F64,
1034 Char,
1035 Bool,
1036 Str,
1037 Slice,
1038 Array,
1039 Tuple,
1040 Unit,
1041 RawPointer,
1042 Reference,
1043 Fn,
1044 Never,
1045 }
1046
1047 #[derive(Clone, Copy, Debug)]
1048 pub enum TypeKind {
1049 Enum,
1050 Function,
1051 Module,
1052 Const,
1053 Static,
1054 Struct,
1055 Union,
1056 Trait,
1057 Typedef,
1058 Foreign,
1059 Macro,
1060 Attr,
1061 Derive,
1062 TraitAlias,
1063 }
1064
1065 pub trait GetDefId {
1066 fn def_id(&self) -> Option<DefId>;
1067 }
1068
1069 impl<T: GetDefId> GetDefId for Option<T> {
1070 fn def_id(&self) -> Option<DefId> {
1071 self.as_ref().and_then(|d| d.def_id())
1072 }
1073 }
1074
1075 impl Type {
1076 pub fn primitive_type(&self) -> Option<PrimitiveType> {
1077 match *self {
1078 Primitive(p) | BorrowedRef { type_: box Primitive(p), .. } => Some(p),
1079 Slice(..) | BorrowedRef { type_: box Slice(..), .. } => Some(PrimitiveType::Slice),
1080 Array(..) | BorrowedRef { type_: box Array(..), .. } => Some(PrimitiveType::Array),
1081 Tuple(ref tys) => {
1082 if tys.is_empty() {
1083 Some(PrimitiveType::Unit)
1084 } else {
1085 Some(PrimitiveType::Tuple)
1086 }
1087 }
1088 RawPointer(..) => Some(PrimitiveType::RawPointer),
1089 BorrowedRef { type_: box Generic(..), .. } => Some(PrimitiveType::Reference),
1090 BareFunction(..) => Some(PrimitiveType::Fn),
1091 Never => Some(PrimitiveType::Never),
1092 _ => None,
1093 }
1094 }
1095
1096 pub fn is_generic(&self) -> bool {
1097 match *self {
1098 ResolvedPath { is_generic, .. } => is_generic,
1099 _ => false,
1100 }
1101 }
1102
1103 pub fn is_self_type(&self) -> bool {
1104 match *self {
1105 Generic(ref name) => name == "Self",
1106 _ => false,
1107 }
1108 }
1109
1110 pub fn generics(&self) -> Option<Vec<Type>> {
1111 match *self {
1112 ResolvedPath { ref path, .. } => path.segments.last().and_then(|seg| {
1113 if let GenericArgs::AngleBracketed { ref args, .. } = seg.args {
1114 Some(
1115 args.iter()
1116 .filter_map(|arg| match arg {
1117 GenericArg::Type(ty) => Some(ty.clone()),
1118 _ => None,
1119 })
1120 .collect(),
1121 )
1122 } else {
1123 None
1124 }
1125 }),
1126 _ => None,
1127 }
1128 }
1129
1130 pub fn bindings(&self) -> Option<&[TypeBinding]> {
1131 match *self {
1132 ResolvedPath { ref path, .. } => path.segments.last().and_then(|seg| {
1133 if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args {
1134 Some(&**bindings)
1135 } else {
1136 None
1137 }
1138 }),
1139 _ => None,
1140 }
1141 }
1142
1143 pub fn is_full_generic(&self) -> bool {
1144 match *self {
1145 Type::Generic(_) => true,
1146 _ => false,
1147 }
1148 }
1149
1150 pub fn projection(&self) -> Option<(&Type, DefId, &str)> {
1151 let (self_, trait_, name) = match self {
1152 QPath { ref self_type, ref trait_, ref name } => (self_type, trait_, name),
1153 _ => return None,
1154 };
1155 let trait_did = match **trait_ {
1156 ResolvedPath { did, .. } => did,
1157 _ => return None,
1158 };
1159 Some((&self_, trait_did, name))
1160 }
1161 }
1162
1163 impl GetDefId for Type {
1164 fn def_id(&self) -> Option<DefId> {
1165 match *self {
1166 ResolvedPath { did, .. } => Some(did),
1167 Primitive(p) => crate::html::render::cache().primitive_locations.get(&p).cloned(),
1168 BorrowedRef { type_: box Generic(..), .. } => {
1169 Primitive(PrimitiveType::Reference).def_id()
1170 }
1171 BorrowedRef { ref type_, .. } => type_.def_id(),
1172 Tuple(ref tys) => {
1173 if tys.is_empty() {
1174 Primitive(PrimitiveType::Unit).def_id()
1175 } else {
1176 Primitive(PrimitiveType::Tuple).def_id()
1177 }
1178 }
1179 BareFunction(..) => Primitive(PrimitiveType::Fn).def_id(),
1180 Never => Primitive(PrimitiveType::Never).def_id(),
1181 Slice(..) => Primitive(PrimitiveType::Slice).def_id(),
1182 Array(..) => Primitive(PrimitiveType::Array).def_id(),
1183 RawPointer(..) => Primitive(PrimitiveType::RawPointer).def_id(),
1184 QPath { ref self_type, .. } => self_type.def_id(),
1185 _ => None,
1186 }
1187 }
1188 }
1189
1190 impl PrimitiveType {
1191 pub fn from_str(s: &str) -> Option<PrimitiveType> {
1192 match s {
1193 "isize" => Some(PrimitiveType::Isize),
1194 "i8" => Some(PrimitiveType::I8),
1195 "i16" => Some(PrimitiveType::I16),
1196 "i32" => Some(PrimitiveType::I32),
1197 "i64" => Some(PrimitiveType::I64),
1198 "i128" => Some(PrimitiveType::I128),
1199 "usize" => Some(PrimitiveType::Usize),
1200 "u8" => Some(PrimitiveType::U8),
1201 "u16" => Some(PrimitiveType::U16),
1202 "u32" => Some(PrimitiveType::U32),
1203 "u64" => Some(PrimitiveType::U64),
1204 "u128" => Some(PrimitiveType::U128),
1205 "bool" => Some(PrimitiveType::Bool),
1206 "char" => Some(PrimitiveType::Char),
1207 "str" => Some(PrimitiveType::Str),
1208 "f32" => Some(PrimitiveType::F32),
1209 "f64" => Some(PrimitiveType::F64),
1210 "array" => Some(PrimitiveType::Array),
1211 "slice" => Some(PrimitiveType::Slice),
1212 "tuple" => Some(PrimitiveType::Tuple),
1213 "unit" => Some(PrimitiveType::Unit),
1214 "pointer" => Some(PrimitiveType::RawPointer),
1215 "reference" => Some(PrimitiveType::Reference),
1216 "fn" => Some(PrimitiveType::Fn),
1217 "never" => Some(PrimitiveType::Never),
1218 _ => None,
1219 }
1220 }
1221
1222 pub fn as_str(&self) -> &'static str {
1223 use self::PrimitiveType::*;
1224 match *self {
1225 Isize => "isize",
1226 I8 => "i8",
1227 I16 => "i16",
1228 I32 => "i32",
1229 I64 => "i64",
1230 I128 => "i128",
1231 Usize => "usize",
1232 U8 => "u8",
1233 U16 => "u16",
1234 U32 => "u32",
1235 U64 => "u64",
1236 U128 => "u128",
1237 F32 => "f32",
1238 F64 => "f64",
1239 Str => "str",
1240 Bool => "bool",
1241 Char => "char",
1242 Array => "array",
1243 Slice => "slice",
1244 Tuple => "tuple",
1245 Unit => "unit",
1246 RawPointer => "pointer",
1247 Reference => "reference",
1248 Fn => "fn",
1249 Never => "never",
1250 }
1251 }
1252
1253 pub fn to_url_str(&self) -> &'static str {
1254 self.as_str()
1255 }
1256 }
1257
1258 impl From<ast::IntTy> for PrimitiveType {
1259 fn from(int_ty: ast::IntTy) -> PrimitiveType {
1260 match int_ty {
1261 ast::IntTy::Isize => PrimitiveType::Isize,
1262 ast::IntTy::I8 => PrimitiveType::I8,
1263 ast::IntTy::I16 => PrimitiveType::I16,
1264 ast::IntTy::I32 => PrimitiveType::I32,
1265 ast::IntTy::I64 => PrimitiveType::I64,
1266 ast::IntTy::I128 => PrimitiveType::I128,
1267 }
1268 }
1269 }
1270
1271 impl From<ast::UintTy> for PrimitiveType {
1272 fn from(uint_ty: ast::UintTy) -> PrimitiveType {
1273 match uint_ty {
1274 ast::UintTy::Usize => PrimitiveType::Usize,
1275 ast::UintTy::U8 => PrimitiveType::U8,
1276 ast::UintTy::U16 => PrimitiveType::U16,
1277 ast::UintTy::U32 => PrimitiveType::U32,
1278 ast::UintTy::U64 => PrimitiveType::U64,
1279 ast::UintTy::U128 => PrimitiveType::U128,
1280 }
1281 }
1282 }
1283
1284 impl From<ast::FloatTy> for PrimitiveType {
1285 fn from(float_ty: ast::FloatTy) -> PrimitiveType {
1286 match float_ty {
1287 ast::FloatTy::F32 => PrimitiveType::F32,
1288 ast::FloatTy::F64 => PrimitiveType::F64,
1289 }
1290 }
1291 }
1292
1293 #[derive(Clone, PartialEq, Eq, Debug)]
1294 pub enum Visibility {
1295 Public,
1296 Inherited,
1297 Crate,
1298 Restricted(DefId, Path),
1299 }
1300
1301 #[derive(Clone, Debug)]
1302 pub struct Struct {
1303 pub struct_type: doctree::StructType,
1304 pub generics: Generics,
1305 pub fields: Vec<Item>,
1306 pub fields_stripped: bool,
1307 }
1308
1309 #[derive(Clone, Debug)]
1310 pub struct Union {
1311 pub struct_type: doctree::StructType,
1312 pub generics: Generics,
1313 pub fields: Vec<Item>,
1314 pub fields_stripped: bool,
1315 }
1316
1317 /// This is a more limited form of the standard Struct, different in that
1318 /// it lacks the things most items have (name, id, parameterization). Found
1319 /// only as a variant in an enum.
1320 #[derive(Clone, Debug)]
1321 pub struct VariantStruct {
1322 pub struct_type: doctree::StructType,
1323 pub fields: Vec<Item>,
1324 pub fields_stripped: bool,
1325 }
1326
1327 #[derive(Clone, Debug)]
1328 pub struct Enum {
1329 pub variants: IndexVec<VariantIdx, Item>,
1330 pub generics: Generics,
1331 pub variants_stripped: bool,
1332 }
1333
1334 #[derive(Clone, Debug)]
1335 pub struct Variant {
1336 pub kind: VariantKind,
1337 }
1338
1339 #[derive(Clone, Debug)]
1340 pub enum VariantKind {
1341 CLike,
1342 Tuple(Vec<Type>),
1343 Struct(VariantStruct),
1344 }
1345
1346 #[derive(Clone, Debug)]
1347 pub struct Span {
1348 pub filename: FileName,
1349 pub loline: usize,
1350 pub locol: usize,
1351 pub hiline: usize,
1352 pub hicol: usize,
1353 pub original: rustc_span::Span,
1354 }
1355
1356 impl Span {
1357 pub fn empty() -> Span {
1358 Span {
1359 filename: FileName::Anon(0),
1360 loline: 0,
1361 locol: 0,
1362 hiline: 0,
1363 hicol: 0,
1364 original: rustc_span::DUMMY_SP,
1365 }
1366 }
1367
1368 pub fn span(&self) -> rustc_span::Span {
1369 self.original
1370 }
1371 }
1372
1373 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1374 pub struct Path {
1375 pub global: bool,
1376 pub res: Res,
1377 pub segments: Vec<PathSegment>,
1378 }
1379
1380 impl Path {
1381 pub fn last_name(&self) -> &str {
1382 self.segments.last().expect("segments were empty").name.as_str()
1383 }
1384 }
1385
1386 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1387 pub enum GenericArg {
1388 Lifetime(Lifetime),
1389 Type(Type),
1390 Const(Constant),
1391 }
1392
1393 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1394 pub enum GenericArgs {
1395 AngleBracketed { args: Vec<GenericArg>, bindings: Vec<TypeBinding> },
1396 Parenthesized { inputs: Vec<Type>, output: Option<Type> },
1397 }
1398
1399 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1400 pub struct PathSegment {
1401 pub name: String,
1402 pub args: GenericArgs,
1403 }
1404
1405 #[derive(Clone, Debug)]
1406 pub struct Typedef {
1407 pub type_: Type,
1408 pub generics: Generics,
1409 // Type of target item.
1410 pub item_type: Option<Type>,
1411 }
1412
1413 impl GetDefId for Typedef {
1414 fn def_id(&self) -> Option<DefId> {
1415 self.type_.def_id()
1416 }
1417 }
1418
1419 #[derive(Clone, Debug)]
1420 pub struct OpaqueTy {
1421 pub bounds: Vec<GenericBound>,
1422 pub generics: Generics,
1423 }
1424
1425 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1426 pub struct BareFunctionDecl {
1427 pub unsafety: hir::Unsafety,
1428 pub generic_params: Vec<GenericParamDef>,
1429 pub decl: FnDecl,
1430 pub abi: Abi,
1431 }
1432
1433 #[derive(Clone, Debug)]
1434 pub struct Static {
1435 pub type_: Type,
1436 pub mutability: Mutability,
1437 /// It's useful to have the value of a static documented, but I have no
1438 /// desire to represent expressions (that'd basically be all of the AST,
1439 /// which is huge!). So, have a string.
1440 pub expr: String,
1441 }
1442
1443 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
1444 pub struct Constant {
1445 pub type_: Type,
1446 pub expr: String,
1447 pub value: Option<String>,
1448 pub is_literal: bool,
1449 }
1450
1451 #[derive(Clone, PartialEq, Debug)]
1452 pub enum ImplPolarity {
1453 Positive,
1454 Negative,
1455 }
1456
1457 #[derive(Clone, Debug)]
1458 pub struct Impl {
1459 pub unsafety: hir::Unsafety,
1460 pub generics: Generics,
1461 pub provided_trait_methods: FxHashSet<String>,
1462 pub trait_: Option<Type>,
1463 pub for_: Type,
1464 pub items: Vec<Item>,
1465 pub polarity: Option<ImplPolarity>,
1466 pub synthetic: bool,
1467 pub blanket_impl: Option<Type>,
1468 }
1469
1470 #[derive(Clone, Debug)]
1471 pub enum Import {
1472 // use source as str;
1473 Simple(String, ImportSource),
1474 // use source::*;
1475 Glob(ImportSource),
1476 }
1477
1478 #[derive(Clone, Debug)]
1479 pub struct ImportSource {
1480 pub path: Path,
1481 pub did: Option<DefId>,
1482 }
1483
1484 #[derive(Clone, Debug)]
1485 pub struct Macro {
1486 pub source: String,
1487 pub imported_from: Option<String>,
1488 }
1489
1490 #[derive(Clone, Debug)]
1491 pub struct ProcMacro {
1492 pub kind: MacroKind,
1493 pub helpers: Vec<String>,
1494 }
1495
1496 #[derive(Clone, Debug)]
1497 pub struct Stability {
1498 pub level: stability::StabilityLevel,
1499 pub feature: Option<String>,
1500 pub since: String,
1501 pub deprecation: Option<Deprecation>,
1502 pub unstable_reason: Option<String>,
1503 pub issue: Option<NonZeroU32>,
1504 }
1505
1506 #[derive(Clone, Debug)]
1507 pub struct Deprecation {
1508 pub since: Option<String>,
1509 pub note: Option<String>,
1510 }
1511
1512 /// An type binding on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
1513 /// `A: Send + Sync` in `Foo<A: Send + Sync>`).
1514 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1515 pub struct TypeBinding {
1516 pub name: String,
1517 pub kind: TypeBindingKind,
1518 }
1519
1520 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1521 pub enum TypeBindingKind {
1522 Equality { ty: Type },
1523 Constraint { bounds: Vec<GenericBound> },
1524 }
1525
1526 impl TypeBinding {
1527 pub fn ty(&self) -> &Type {
1528 match self.kind {
1529 TypeBindingKind::Equality { ref ty } => ty,
1530 _ => panic!("expected equality type binding for parenthesized generic args"),
1531 }
1532 }
1533 }