]> git.lizzy.rs Git - rust.git/blob - src/librustdoc/clean/types.rs
754f1c2eeeb21c0b6609457fd227ee895d597524
[rust.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::lazy::SyncOnceCell as OnceCell;
7 use std::rc::Rc;
8 use std::sync::Arc;
9 use std::{slice, vec};
10
11 use arrayvec::ArrayVec;
12 use rustc_ast::attr;
13 use rustc_ast::util::comments::beautify_doc_string;
14 use rustc_ast::{self as ast, AttrStyle};
15 use rustc_attr::{ConstStability, Deprecation, Stability, StabilityLevel};
16 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
17 use rustc_feature::UnstableFeatures;
18 use rustc_hir as hir;
19 use rustc_hir::def::{CtorKind, Res};
20 use rustc_hir::def_id::{CrateNum, DefId, DefIndex};
21 use rustc_hir::lang_items::LangItem;
22 use rustc_hir::Mutability;
23 use rustc_index::vec::IndexVec;
24 use rustc_middle::ty::{self, TyCtxt};
25 use rustc_session::Session;
26 use rustc_span::hygiene::MacroKind;
27 use rustc_span::source_map::DUMMY_SP;
28 use rustc_span::symbol::{kw, sym, Ident, Symbol, SymbolStr};
29 use rustc_span::{self, FileName, Loc};
30 use rustc_target::abi::VariantIdx;
31 use rustc_target::spec::abi::Abi;
32
33 use crate::clean::cfg::Cfg;
34 use crate::clean::external_path;
35 use crate::clean::inline;
36 use crate::clean::types::Type::{QPath, ResolvedPath};
37 use crate::clean::Clean;
38 use crate::core::DocContext;
39 use crate::formats::cache::Cache;
40 use crate::formats::item_type::ItemType;
41 use crate::html::render::cache::ExternalLocation;
42
43 use self::FnRetTy::*;
44 use self::ItemKind::*;
45 use self::SelfTy::*;
46 use self::Type::*;
47
48 thread_local!(crate static MAX_DEF_IDX: RefCell<FxHashMap<CrateNum, DefIndex>> = Default::default());
49
50 #[derive(Clone, Debug)]
51 crate struct Crate {
52     crate name: Symbol,
53     crate version: Option<String>,
54     crate src: FileName,
55     crate module: Option<Item>,
56     crate externs: Vec<(CrateNum, ExternalCrate)>,
57     crate primitives: Vec<(DefId, PrimitiveType)>,
58     // These are later on moved into `CACHEKEY`, leaving the map empty.
59     // Only here so that they can be filtered through the rustdoc passes.
60     crate external_traits: Rc<RefCell<FxHashMap<DefId, Trait>>>,
61     crate masked_crates: FxHashSet<CrateNum>,
62     crate collapsed: bool,
63 }
64
65 #[derive(Clone, Debug)]
66 crate struct ExternalCrate {
67     crate name: Symbol,
68     crate src: FileName,
69     crate attrs: Attributes,
70     crate primitives: Vec<(DefId, PrimitiveType)>,
71     crate keywords: Vec<(DefId, Symbol)>,
72 }
73
74 /// Anything with a source location and set of attributes and, optionally, a
75 /// name. That is, anything that can be documented. This doesn't correspond
76 /// directly to the AST's concept of an item; it's a strict superset.
77 #[derive(Clone)]
78 crate struct Item {
79     /// Stringified span
80     crate source: Span,
81     /// Not everything has a name. E.g., impls
82     crate name: Option<Symbol>,
83     crate attrs: Box<Attributes>,
84     crate visibility: Visibility,
85     crate kind: Box<ItemKind>,
86     crate def_id: DefId,
87 }
88
89 // `Item` is used a lot. Make sure it doesn't unintentionally get bigger.
90 #[cfg(target_arch = "x86_64")]
91 rustc_data_structures::static_assert_size!(Item, 48);
92
93 impl fmt::Debug for Item {
94     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
95         let def_id: &dyn fmt::Debug = if self.is_fake() { &"**FAKE**" } else { &self.def_id };
96
97         fmt.debug_struct("Item")
98             .field("source", &self.source)
99             .field("name", &self.name)
100             .field("attrs", &self.attrs)
101             .field("kind", &self.kind)
102             .field("visibility", &self.visibility)
103             .field("def_id", def_id)
104             .finish()
105     }
106 }
107
108 impl Item {
109     crate fn stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option<&'tcx Stability> {
110         if self.is_fake() { None } else { tcx.lookup_stability(self.def_id) }
111     }
112
113     crate fn const_stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ConstStability> {
114         if self.is_fake() { None } else { tcx.lookup_const_stability(self.def_id) }
115     }
116
117     crate fn deprecation(&self, tcx: TyCtxt<'_>) -> Option<Deprecation> {
118         if self.is_fake() { None } else { tcx.lookup_deprecation(self.def_id) }
119     }
120
121     /// Finds the `doc` attribute as a NameValue and returns the corresponding
122     /// value found.
123     crate fn doc_value(&self) -> Option<String> {
124         self.attrs.doc_value()
125     }
126
127     /// Convenience wrapper around [`Self::from_def_id_and_parts`] which converts
128     /// `hir_id` to a [`DefId`]
129     pub fn from_hir_id_and_parts(
130         hir_id: hir::HirId,
131         name: Option<Symbol>,
132         kind: ItemKind,
133         cx: &DocContext<'_>,
134     ) -> Item {
135         Item::from_def_id_and_parts(cx.tcx.hir().local_def_id(hir_id).to_def_id(), name, kind, cx)
136     }
137
138     pub fn from_def_id_and_parts(
139         def_id: DefId,
140         name: Option<Symbol>,
141         kind: ItemKind,
142         cx: &DocContext<'_>,
143     ) -> Item {
144         debug!("name={:?}, def_id={:?}", name, def_id);
145
146         // `span_if_local()` lies about functions and only gives the span of the function signature
147         let source = def_id.as_local().map_or_else(
148             || cx.tcx.def_span(def_id),
149             |local| {
150                 let hir = cx.tcx.hir();
151                 hir.span_with_body(hir.local_def_id_to_hir_id(local))
152             },
153         );
154
155         Item {
156             def_id,
157             kind: box kind,
158             name,
159             source: source.clean(cx),
160             attrs: box cx.tcx.get_attrs(def_id).clean(cx),
161             visibility: cx.tcx.visibility(def_id).clean(cx),
162         }
163     }
164
165     /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
166     /// with newlines.
167     crate fn collapsed_doc_value(&self) -> Option<String> {
168         self.attrs.collapsed_doc_value()
169     }
170
171     crate fn links(&self, cache: &Cache) -> Vec<RenderedLink> {
172         self.attrs.links(&self.def_id.krate, cache)
173     }
174
175     crate fn is_crate(&self) -> bool {
176         matches!(
177             *self.kind,
178             StrippedItem(box ModuleItem(Module { is_crate: true, .. }))
179                 | ModuleItem(Module { is_crate: true, .. })
180         )
181     }
182     crate fn is_mod(&self) -> bool {
183         self.type_() == ItemType::Module
184     }
185     crate fn is_trait(&self) -> bool {
186         self.type_() == ItemType::Trait
187     }
188     crate fn is_struct(&self) -> bool {
189         self.type_() == ItemType::Struct
190     }
191     crate fn is_enum(&self) -> bool {
192         self.type_() == ItemType::Enum
193     }
194     crate fn is_variant(&self) -> bool {
195         self.type_() == ItemType::Variant
196     }
197     crate fn is_associated_type(&self) -> bool {
198         self.type_() == ItemType::AssocType
199     }
200     crate fn is_associated_const(&self) -> bool {
201         self.type_() == ItemType::AssocConst
202     }
203     crate fn is_method(&self) -> bool {
204         self.type_() == ItemType::Method
205     }
206     crate fn is_ty_method(&self) -> bool {
207         self.type_() == ItemType::TyMethod
208     }
209     crate fn is_typedef(&self) -> bool {
210         self.type_() == ItemType::Typedef
211     }
212     crate fn is_primitive(&self) -> bool {
213         self.type_() == ItemType::Primitive
214     }
215     crate fn is_union(&self) -> bool {
216         self.type_() == ItemType::Union
217     }
218     crate fn is_import(&self) -> bool {
219         self.type_() == ItemType::Import
220     }
221     crate fn is_extern_crate(&self) -> bool {
222         self.type_() == ItemType::ExternCrate
223     }
224     crate fn is_keyword(&self) -> bool {
225         self.type_() == ItemType::Keyword
226     }
227     crate fn is_stripped(&self) -> bool {
228         match *self.kind {
229             StrippedItem(..) => true,
230             ImportItem(ref i) => !i.should_be_displayed,
231             _ => false,
232         }
233     }
234     crate fn has_stripped_fields(&self) -> Option<bool> {
235         match *self.kind {
236             StructItem(ref _struct) => Some(_struct.fields_stripped),
237             UnionItem(ref union) => Some(union.fields_stripped),
238             VariantItem(Variant::Struct(ref vstruct)) => Some(vstruct.fields_stripped),
239             _ => None,
240         }
241     }
242
243     crate fn stability_class(&self, tcx: TyCtxt<'_>) -> Option<String> {
244         self.stability(tcx).as_ref().and_then(|ref s| {
245             let mut classes = Vec::with_capacity(2);
246
247             if s.level.is_unstable() {
248                 classes.push("unstable");
249             }
250
251             // FIXME: what about non-staged API items that are deprecated?
252             if self.deprecation(tcx).is_some() {
253                 classes.push("deprecated");
254             }
255
256             if !classes.is_empty() { Some(classes.join(" ")) } else { None }
257         })
258     }
259
260     crate fn stable_since(&self, tcx: TyCtxt<'_>) -> Option<SymbolStr> {
261         match self.stability(tcx)?.level {
262             StabilityLevel::Stable { since, .. } => Some(since.as_str()),
263             StabilityLevel::Unstable { .. } => None,
264         }
265     }
266
267     crate fn const_stable_since(&self, tcx: TyCtxt<'_>) -> Option<SymbolStr> {
268         match self.const_stability(tcx)?.level {
269             StabilityLevel::Stable { since, .. } => Some(since.as_str()),
270             StabilityLevel::Unstable { .. } => None,
271         }
272     }
273
274     crate fn is_non_exhaustive(&self) -> bool {
275         self.attrs.other_attrs.iter().any(|a| a.has_name(sym::non_exhaustive))
276     }
277
278     /// Returns a documentation-level item type from the item.
279     crate fn type_(&self) -> ItemType {
280         ItemType::from(self)
281     }
282
283     crate fn is_default(&self) -> bool {
284         match *self.kind {
285             ItemKind::MethodItem(_, Some(defaultness)) => {
286                 defaultness.has_value() && !defaultness.is_final()
287             }
288             _ => false,
289         }
290     }
291
292     /// See the documentation for [`next_def_id()`].
293     ///
294     /// [`next_def_id()`]: DocContext::next_def_id()
295     crate fn is_fake(&self) -> bool {
296         MAX_DEF_IDX.with(|m| {
297             m.borrow().get(&self.def_id.krate).map(|&idx| idx <= self.def_id.index).unwrap_or(false)
298         })
299     }
300 }
301
302 #[derive(Clone, Debug)]
303 crate enum ItemKind {
304     ExternCrateItem(Symbol, Option<Symbol>),
305     ImportItem(Import),
306     StructItem(Struct),
307     UnionItem(Union),
308     EnumItem(Enum),
309     FunctionItem(Function),
310     ModuleItem(Module),
311     TypedefItem(Typedef, bool /* is associated type */),
312     OpaqueTyItem(OpaqueTy),
313     StaticItem(Static),
314     ConstantItem(Constant),
315     TraitItem(Trait),
316     TraitAliasItem(TraitAlias),
317     ImplItem(Impl),
318     /// A method signature only. Used for required methods in traits (ie,
319     /// non-default-methods).
320     TyMethodItem(Function),
321     /// A method with a body.
322     MethodItem(Function, Option<hir::Defaultness>),
323     StructFieldItem(Type),
324     VariantItem(Variant),
325     /// `fn`s from an extern block
326     ForeignFunctionItem(Function),
327     /// `static`s from an extern block
328     ForeignStaticItem(Static),
329     /// `type`s from an extern block
330     ForeignTypeItem,
331     MacroItem(Macro),
332     ProcMacroItem(ProcMacro),
333     PrimitiveItem(PrimitiveType),
334     AssocConstItem(Type, Option<String>),
335     /// An associated item in a trait or trait impl.
336     ///
337     /// The bounds may be non-empty if there is a `where` clause.
338     /// The `Option<Type>` is the default concrete type (e.g. `trait Trait { type Target = usize; }`)
339     AssocTypeItem(Vec<GenericBound>, Option<Type>),
340     /// An item that has been stripped by a rustdoc pass
341     StrippedItem(Box<ItemKind>),
342     KeywordItem(Symbol),
343 }
344
345 impl ItemKind {
346     /// Some items contain others such as structs (for their fields) and Enums
347     /// (for their variants). This method returns those contained items.
348     crate fn inner_items(&self) -> impl Iterator<Item = &Item> {
349         match self {
350             StructItem(s) => s.fields.iter(),
351             UnionItem(u) => u.fields.iter(),
352             VariantItem(Variant::Struct(v)) => v.fields.iter(),
353             EnumItem(e) => e.variants.iter(),
354             TraitItem(t) => t.items.iter(),
355             ImplItem(i) => i.items.iter(),
356             ModuleItem(m) => m.items.iter(),
357             ExternCrateItem(_, _)
358             | ImportItem(_)
359             | FunctionItem(_)
360             | TypedefItem(_, _)
361             | OpaqueTyItem(_)
362             | StaticItem(_)
363             | ConstantItem(_)
364             | TraitAliasItem(_)
365             | TyMethodItem(_)
366             | MethodItem(_, _)
367             | StructFieldItem(_)
368             | VariantItem(_)
369             | ForeignFunctionItem(_)
370             | ForeignStaticItem(_)
371             | ForeignTypeItem
372             | MacroItem(_)
373             | ProcMacroItem(_)
374             | PrimitiveItem(_)
375             | AssocConstItem(_, _)
376             | AssocTypeItem(_, _)
377             | StrippedItem(_)
378             | KeywordItem(_) => [].iter(),
379         }
380     }
381
382     crate fn is_type_alias(&self) -> bool {
383         matches!(self, ItemKind::TypedefItem(..) | ItemKind::AssocTypeItem(..))
384     }
385 }
386
387 #[derive(Clone, Debug)]
388 crate struct Module {
389     crate items: Vec<Item>,
390     crate is_crate: bool,
391 }
392
393 crate struct ListAttributesIter<'a> {
394     attrs: slice::Iter<'a, ast::Attribute>,
395     current_list: vec::IntoIter<ast::NestedMetaItem>,
396     name: Symbol,
397 }
398
399 impl<'a> Iterator for ListAttributesIter<'a> {
400     type Item = ast::NestedMetaItem;
401
402     fn next(&mut self) -> Option<Self::Item> {
403         if let Some(nested) = self.current_list.next() {
404             return Some(nested);
405         }
406
407         for attr in &mut self.attrs {
408             if let Some(list) = attr.meta_item_list() {
409                 if attr.has_name(self.name) {
410                     self.current_list = list.into_iter();
411                     if let Some(nested) = self.current_list.next() {
412                         return Some(nested);
413                     }
414                 }
415             }
416         }
417
418         None
419     }
420
421     fn size_hint(&self) -> (usize, Option<usize>) {
422         let lower = self.current_list.len();
423         (lower, None)
424     }
425 }
426
427 crate trait AttributesExt {
428     /// Finds an attribute as List and returns the list of attributes nested inside.
429     fn lists(&self, name: Symbol) -> ListAttributesIter<'_>;
430 }
431
432 impl AttributesExt for [ast::Attribute] {
433     fn lists(&self, name: Symbol) -> ListAttributesIter<'_> {
434         ListAttributesIter { attrs: self.iter(), current_list: Vec::new().into_iter(), name }
435     }
436 }
437
438 crate trait NestedAttributesExt {
439     /// Returns `true` if the attribute list contains a specific `Word`
440     fn has_word(self, word: Symbol) -> bool;
441     fn get_word_attr(self, word: Symbol) -> (Option<ast::NestedMetaItem>, bool);
442 }
443
444 impl<I: Iterator<Item = ast::NestedMetaItem> + IntoIterator<Item = ast::NestedMetaItem>>
445     NestedAttributesExt for I
446 {
447     fn has_word(self, word: Symbol) -> bool {
448         self.into_iter().any(|attr| attr.is_word() && attr.has_name(word))
449     }
450
451     fn get_word_attr(mut self, word: Symbol) -> (Option<ast::NestedMetaItem>, bool) {
452         match self.find(|attr| attr.is_word() && attr.has_name(word)) {
453             Some(a) => (Some(a), true),
454             None => (None, false),
455         }
456     }
457 }
458
459 /// A portion of documentation, extracted from a `#[doc]` attribute.
460 ///
461 /// Each variant contains the line number within the complete doc-comment where the fragment
462 /// starts, as well as the Span where the corresponding doc comment or attribute is located.
463 ///
464 /// Included files are kept separate from inline doc comments so that proper line-number
465 /// information can be given when a doctest fails. Sugared doc comments and "raw" doc comments are
466 /// kept separate because of issue #42760.
467 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
468 crate struct DocFragment {
469     crate line: usize,
470     crate span: rustc_span::Span,
471     /// The module this doc-comment came from.
472     ///
473     /// This allows distinguishing between the original documentation and a pub re-export.
474     /// If it is `None`, the item was not re-exported.
475     crate parent_module: Option<DefId>,
476     crate doc: Symbol,
477     crate kind: DocFragmentKind,
478     crate need_backline: bool,
479     crate indent: usize,
480 }
481
482 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
483 crate enum DocFragmentKind {
484     /// A doc fragment created from a `///` or `//!` doc comment.
485     SugaredDoc,
486     /// A doc fragment created from a "raw" `#[doc=""]` attribute.
487     RawDoc,
488     /// A doc fragment created from a `#[doc(include="filename")]` attribute. Contains both the
489     /// given filename and the file contents.
490     Include { filename: Symbol },
491 }
492
493 // The goal of this function is to apply the `DocFragment` transformations that are required when
494 // transforming into the final markdown. So the transformations in here are:
495 //
496 // * Applying the computed indent to each lines in each doc fragment (a `DocFragment` can contain
497 //   multiple lines in case of `#[doc = ""]`).
498 // * Adding backlines between `DocFragment`s and adding an extra one if required (stored in the
499 //   `need_backline` field).
500 fn add_doc_fragment(out: &mut String, frag: &DocFragment) {
501     let s = frag.doc.as_str();
502     let mut iter = s.lines().peekable();
503     while let Some(line) = iter.next() {
504         if line.chars().any(|c| !c.is_whitespace()) {
505             assert!(line.len() >= frag.indent);
506             out.push_str(&line[frag.indent..]);
507         } else {
508             out.push_str(line);
509         }
510         if iter.peek().is_some() {
511             out.push('\n');
512         }
513     }
514     if frag.need_backline {
515         out.push('\n');
516     }
517 }
518
519 impl<'a> FromIterator<&'a DocFragment> for String {
520     fn from_iter<T>(iter: T) -> Self
521     where
522         T: IntoIterator<Item = &'a DocFragment>,
523     {
524         let mut prev_kind: Option<DocFragmentKind> = None;
525         iter.into_iter().fold(String::new(), |mut acc, frag| {
526             if !acc.is_empty()
527                 && prev_kind
528                     .take()
529                     .map(|p| matches!(p, DocFragmentKind::Include { .. }) && p != frag.kind)
530                     .unwrap_or(false)
531             {
532                 acc.push('\n');
533             }
534             add_doc_fragment(&mut acc, &frag);
535             prev_kind = Some(frag.kind);
536             acc
537         })
538     }
539 }
540
541 #[derive(Clone, Debug, Default)]
542 crate struct Attributes {
543     crate doc_strings: Vec<DocFragment>,
544     crate other_attrs: Vec<ast::Attribute>,
545     crate cfg: Option<Arc<Cfg>>,
546     crate span: Option<rustc_span::Span>,
547     /// map from Rust paths to resolved defs and potential URL fragments
548     crate links: Vec<ItemLink>,
549     crate inner_docs: bool,
550 }
551
552 #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
553 /// A link that has not yet been rendered.
554 ///
555 /// This link will be turned into a rendered link by [`Attributes::links`]
556 crate struct ItemLink {
557     /// The original link written in the markdown
558     pub(crate) link: String,
559     /// The link text displayed in the HTML.
560     ///
561     /// This may not be the same as `link` if there was a disambiguator
562     /// in an intra-doc link (e.g. \[`fn@f`\])
563     pub(crate) link_text: String,
564     pub(crate) did: Option<DefId>,
565     /// The url fragment to append to the link
566     pub(crate) fragment: Option<String>,
567 }
568
569 pub struct RenderedLink {
570     /// The text the link was original written as.
571     ///
572     /// This could potentially include disambiguators and backticks.
573     pub(crate) original_text: String,
574     /// The text to display in the HTML
575     pub(crate) new_text: String,
576     /// The URL to put in the `href`
577     pub(crate) href: String,
578 }
579
580 impl Attributes {
581     /// Extracts the content from an attribute `#[doc(cfg(content))]`.
582     crate fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> {
583         use rustc_ast::NestedMetaItem::MetaItem;
584
585         if let ast::MetaItemKind::List(ref nmis) = mi.kind {
586             if nmis.len() == 1 {
587                 if let MetaItem(ref cfg_mi) = nmis[0] {
588                     if cfg_mi.has_name(sym::cfg) {
589                         if let ast::MetaItemKind::List(ref cfg_nmis) = cfg_mi.kind {
590                             if cfg_nmis.len() == 1 {
591                                 if let MetaItem(ref content_mi) = cfg_nmis[0] {
592                                     return Some(content_mi);
593                                 }
594                             }
595                         }
596                     }
597                 }
598             }
599         }
600
601         None
602     }
603
604     /// Reads a `MetaItem` from within an attribute, looks for whether it is a
605     /// `#[doc(include="file")]`, and returns the filename and contents of the file as loaded from
606     /// its expansion.
607     crate fn extract_include(mi: &ast::MetaItem) -> Option<(Symbol, Symbol)> {
608         mi.meta_item_list().and_then(|list| {
609             for meta in list {
610                 if meta.has_name(sym::include) {
611                     // the actual compiled `#[doc(include="filename")]` gets expanded to
612                     // `#[doc(include(file="filename", contents="file contents")]` so we need to
613                     // look for that instead
614                     return meta.meta_item_list().and_then(|list| {
615                         let mut filename: Option<Symbol> = None;
616                         let mut contents: Option<Symbol> = None;
617
618                         for it in list {
619                             if it.has_name(sym::file) {
620                                 if let Some(name) = it.value_str() {
621                                     filename = Some(name);
622                                 }
623                             } else if it.has_name(sym::contents) {
624                                 if let Some(docs) = it.value_str() {
625                                     contents = Some(docs);
626                                 }
627                             }
628                         }
629
630                         if let (Some(filename), Some(contents)) = (filename, contents) {
631                             Some((filename, contents))
632                         } else {
633                             None
634                         }
635                     });
636                 }
637             }
638
639             None
640         })
641     }
642
643     crate fn has_doc_flag(&self, flag: Symbol) -> bool {
644         for attr in &self.other_attrs {
645             if !attr.has_name(sym::doc) {
646                 continue;
647             }
648
649             if let Some(items) = attr.meta_item_list() {
650                 if items.iter().filter_map(|i| i.meta_item()).any(|it| it.has_name(flag)) {
651                     return true;
652                 }
653             }
654         }
655
656         false
657     }
658
659     crate fn from_ast(
660         diagnostic: &::rustc_errors::Handler,
661         attrs: &[ast::Attribute],
662         additional_attrs: Option<(&[ast::Attribute], DefId)>,
663     ) -> Attributes {
664         let mut doc_strings: Vec<DocFragment> = vec![];
665         let mut sp = None;
666         let mut cfg = Cfg::True;
667         let mut doc_line = 0;
668
669         fn update_need_backline(doc_strings: &mut Vec<DocFragment>, frag: &DocFragment) {
670             if let Some(prev) = doc_strings.last_mut() {
671                 if matches!(prev.kind, DocFragmentKind::Include { .. })
672                     || prev.kind != frag.kind
673                     || prev.parent_module != frag.parent_module
674                 {
675                     // add a newline for extra padding between segments
676                     prev.need_backline = prev.kind == DocFragmentKind::SugaredDoc
677                         || prev.kind == DocFragmentKind::RawDoc
678                 } else {
679                     prev.need_backline = true;
680                 }
681             }
682         }
683
684         let clean_attr = |(attr, parent_module): (&ast::Attribute, _)| {
685             if let Some(value) = attr.doc_str() {
686                 trace!("got doc_str={:?}", value);
687                 let value = beautify_doc_string(value);
688                 let kind = if attr.is_doc_comment() {
689                     DocFragmentKind::SugaredDoc
690                 } else {
691                     DocFragmentKind::RawDoc
692                 };
693
694                 let line = doc_line;
695                 doc_line += value.as_str().lines().count();
696                 let frag = DocFragment {
697                     line,
698                     span: attr.span,
699                     doc: value,
700                     kind,
701                     parent_module,
702                     need_backline: false,
703                     indent: 0,
704                 };
705
706                 update_need_backline(&mut doc_strings, &frag);
707
708                 doc_strings.push(frag);
709
710                 if sp.is_none() {
711                     sp = Some(attr.span);
712                 }
713                 None
714             } else {
715                 if attr.has_name(sym::doc) {
716                     if let Some(mi) = attr.meta() {
717                         if let Some(cfg_mi) = Attributes::extract_cfg(&mi) {
718                             // Extracted #[doc(cfg(...))]
719                             match Cfg::parse(cfg_mi) {
720                                 Ok(new_cfg) => cfg &= new_cfg,
721                                 Err(e) => diagnostic.span_err(e.span, e.msg),
722                             }
723                         } else if let Some((filename, contents)) = Attributes::extract_include(&mi)
724                         {
725                             let line = doc_line;
726                             doc_line += contents.as_str().lines().count();
727                             let frag = DocFragment {
728                                 line,
729                                 span: attr.span,
730                                 doc: contents,
731                                 kind: DocFragmentKind::Include { filename },
732                                 parent_module,
733                                 need_backline: false,
734                                 indent: 0,
735                             };
736                             update_need_backline(&mut doc_strings, &frag);
737                             doc_strings.push(frag);
738                         }
739                     }
740                 }
741                 Some(attr.clone())
742             }
743         };
744
745         // Additional documentation should be shown before the original documentation
746         let other_attrs = additional_attrs
747             .into_iter()
748             .map(|(attrs, id)| attrs.iter().map(move |attr| (attr, Some(id))))
749             .flatten()
750             .chain(attrs.iter().map(|attr| (attr, None)))
751             .filter_map(clean_attr)
752             .collect();
753
754         // treat #[target_feature(enable = "feat")] attributes as if they were
755         // #[doc(cfg(target_feature = "feat"))] attributes as well
756         for attr in attrs.lists(sym::target_feature) {
757             if attr.has_name(sym::enable) {
758                 if let Some(feat) = attr.value_str() {
759                     let meta = attr::mk_name_value_item_str(
760                         Ident::with_dummy_span(sym::target_feature),
761                         feat,
762                         DUMMY_SP,
763                     );
764                     if let Ok(feat_cfg) = Cfg::parse(&meta) {
765                         cfg &= feat_cfg;
766                     }
767                 }
768             }
769         }
770
771         let inner_docs = attrs
772             .iter()
773             .find(|a| a.doc_str().is_some())
774             .map_or(true, |a| a.style == AttrStyle::Inner);
775
776         Attributes {
777             doc_strings,
778             other_attrs,
779             cfg: if cfg == Cfg::True { None } else { Some(Arc::new(cfg)) },
780             span: sp,
781             links: vec![],
782             inner_docs,
783         }
784     }
785
786     /// Finds the `doc` attribute as a NameValue and returns the corresponding
787     /// value found.
788     crate fn doc_value(&self) -> Option<String> {
789         let mut iter = self.doc_strings.iter();
790
791         let ori = iter.next()?;
792         let mut out = String::new();
793         add_doc_fragment(&mut out, &ori);
794         while let Some(new_frag) = iter.next() {
795             if matches!(ori.kind, DocFragmentKind::Include { .. })
796                 || new_frag.kind != ori.kind
797                 || new_frag.parent_module != ori.parent_module
798             {
799                 break;
800             }
801             add_doc_fragment(&mut out, &new_frag);
802         }
803         if out.is_empty() { None } else { Some(out) }
804     }
805
806     /// Return the doc-comments on this item, grouped by the module they came from.
807     ///
808     /// The module can be different if this is a re-export with added documentation.
809     crate fn collapsed_doc_value_by_module_level(&self) -> FxHashMap<Option<DefId>, String> {
810         let mut ret = FxHashMap::default();
811
812         for new_frag in self.doc_strings.iter() {
813             let out = ret.entry(new_frag.parent_module).or_default();
814             add_doc_fragment(out, &new_frag);
815         }
816         ret
817     }
818
819     /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
820     /// with newlines.
821     crate fn collapsed_doc_value(&self) -> Option<String> {
822         if self.doc_strings.is_empty() { None } else { Some(self.doc_strings.iter().collect()) }
823     }
824
825     /// Gets links as a vector
826     ///
827     /// Cache must be populated before call
828     crate fn links(&self, krate: &CrateNum, cache: &Cache) -> Vec<RenderedLink> {
829         use crate::html::format::href;
830         use crate::html::render::CURRENT_DEPTH;
831
832         self.links
833             .iter()
834             .filter_map(|ItemLink { link: s, link_text, did, fragment }| {
835                 match *did {
836                     Some(did) => {
837                         if let Some((mut href, ..)) = href(did, cache) {
838                             if let Some(ref fragment) = *fragment {
839                                 href.push('#');
840                                 href.push_str(fragment);
841                             }
842                             Some(RenderedLink {
843                                 original_text: s.clone(),
844                                 new_text: link_text.clone(),
845                                 href,
846                             })
847                         } else {
848                             None
849                         }
850                     }
851                     None => {
852                         if let Some(ref fragment) = *fragment {
853                             let url = match cache.extern_locations.get(krate) {
854                                 Some(&(_, _, ExternalLocation::Local)) => {
855                                     let depth = CURRENT_DEPTH.with(|l| l.get());
856                                     "../".repeat(depth)
857                                 }
858                                 Some(&(_, _, ExternalLocation::Remote(ref s))) => s.to_string(),
859                                 Some(&(_, _, ExternalLocation::Unknown)) | None => String::from(
860                                     // NOTE: intentionally doesn't pass crate name to avoid having
861                                     // different primitive links between crates
862                                     if UnstableFeatures::from_environment(None).is_nightly_build() {
863                                         "https://doc.rust-lang.org/nightly"
864                                     } else {
865                                         "https://doc.rust-lang.org"
866                                     },
867                                 ),
868                             };
869                             // This is a primitive so the url is done "by hand".
870                             let tail = fragment.find('#').unwrap_or_else(|| fragment.len());
871                             Some(RenderedLink {
872                                 original_text: s.clone(),
873                                 new_text: link_text.clone(),
874                                 href: format!(
875                                     "{}{}std/primitive.{}.html{}",
876                                     url,
877                                     if !url.ends_with('/') { "/" } else { "" },
878                                     &fragment[..tail],
879                                     &fragment[tail..]
880                                 ),
881                             })
882                         } else {
883                             panic!("This isn't a primitive?!");
884                         }
885                     }
886                 }
887             })
888             .collect()
889     }
890
891     crate fn get_doc_aliases(&self) -> FxHashSet<String> {
892         self.other_attrs
893             .lists(sym::doc)
894             .filter(|a| a.has_name(sym::alias))
895             .filter_map(|a| a.value_str().map(|s| s.to_string()))
896             .filter(|v| !v.is_empty())
897             .collect::<FxHashSet<_>>()
898     }
899 }
900
901 impl PartialEq for Attributes {
902     fn eq(&self, rhs: &Self) -> bool {
903         self.doc_strings == rhs.doc_strings
904             && self.cfg == rhs.cfg
905             && self.span == rhs.span
906             && self.links == rhs.links
907             && self
908                 .other_attrs
909                 .iter()
910                 .map(|attr| attr.id)
911                 .eq(rhs.other_attrs.iter().map(|attr| attr.id))
912     }
913 }
914
915 impl Eq for Attributes {}
916
917 impl Hash for Attributes {
918     fn hash<H: Hasher>(&self, hasher: &mut H) {
919         self.doc_strings.hash(hasher);
920         self.cfg.hash(hasher);
921         self.span.hash(hasher);
922         self.links.hash(hasher);
923         for attr in &self.other_attrs {
924             attr.id.hash(hasher);
925         }
926     }
927 }
928
929 impl AttributesExt for Attributes {
930     fn lists(&self, name: Symbol) -> ListAttributesIter<'_> {
931         self.other_attrs.lists(name)
932     }
933 }
934
935 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
936 crate enum GenericBound {
937     TraitBound(PolyTrait, hir::TraitBoundModifier),
938     Outlives(Lifetime),
939 }
940
941 impl GenericBound {
942     crate fn maybe_sized(cx: &DocContext<'_>) -> GenericBound {
943         let did = cx.tcx.require_lang_item(LangItem::Sized, None);
944         let empty = cx.tcx.intern_substs(&[]);
945         let path = external_path(cx, cx.tcx.item_name(did), Some(did), false, vec![], empty);
946         inline::record_extern_fqn(cx, did, TypeKind::Trait);
947         GenericBound::TraitBound(
948             PolyTrait {
949                 trait_: ResolvedPath { path, param_names: None, did, is_generic: false },
950                 generic_params: Vec::new(),
951             },
952             hir::TraitBoundModifier::Maybe,
953         )
954     }
955
956     crate fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool {
957         use rustc_hir::TraitBoundModifier as TBM;
958         if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self {
959             if trait_.def_id() == cx.tcx.lang_items().sized_trait() {
960                 return true;
961             }
962         }
963         false
964     }
965
966     crate fn get_poly_trait(&self) -> Option<PolyTrait> {
967         if let GenericBound::TraitBound(ref p, _) = *self {
968             return Some(p.clone());
969         }
970         None
971     }
972
973     crate fn get_trait_type(&self) -> Option<Type> {
974         if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, _) = *self {
975             Some(trait_.clone())
976         } else {
977             None
978         }
979     }
980 }
981
982 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
983 crate struct Lifetime(pub Symbol);
984
985 impl Lifetime {
986     crate fn get_ref(&self) -> SymbolStr {
987         self.0.as_str()
988     }
989
990     crate fn statik() -> Lifetime {
991         Lifetime(kw::StaticLifetime)
992     }
993
994     crate fn elided() -> Lifetime {
995         Lifetime(kw::UnderscoreLifetime)
996     }
997 }
998
999 #[derive(Clone, Debug)]
1000 crate enum WherePredicate {
1001     BoundPredicate { ty: Type, bounds: Vec<GenericBound> },
1002     RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
1003     EqPredicate { lhs: Type, rhs: Type },
1004 }
1005
1006 impl WherePredicate {
1007     crate fn get_bounds(&self) -> Option<&[GenericBound]> {
1008         match *self {
1009             WherePredicate::BoundPredicate { ref bounds, .. } => Some(bounds),
1010             WherePredicate::RegionPredicate { ref bounds, .. } => Some(bounds),
1011             _ => None,
1012         }
1013     }
1014 }
1015
1016 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1017 crate enum GenericParamDefKind {
1018     Lifetime,
1019     Type {
1020         did: DefId,
1021         bounds: Vec<GenericBound>,
1022         default: Option<Type>,
1023         synthetic: Option<hir::SyntheticTyParamKind>,
1024     },
1025     Const {
1026         did: DefId,
1027         ty: Type,
1028     },
1029 }
1030
1031 impl GenericParamDefKind {
1032     crate fn is_type(&self) -> bool {
1033         matches!(self, GenericParamDefKind::Type { .. })
1034     }
1035
1036     // FIXME(eddyb) this either returns the default of a type parameter, or the
1037     // type of a `const` parameter. It seems that the intention is to *visit*
1038     // any embedded types, but `get_type` seems to be the wrong name for that.
1039     crate fn get_type(&self) -> Option<Type> {
1040         match self {
1041             GenericParamDefKind::Type { default, .. } => default.clone(),
1042             GenericParamDefKind::Const { ty, .. } => Some(ty.clone()),
1043             GenericParamDefKind::Lifetime => None,
1044         }
1045     }
1046 }
1047
1048 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1049 crate struct GenericParamDef {
1050     crate name: Symbol,
1051     crate kind: GenericParamDefKind,
1052 }
1053
1054 impl GenericParamDef {
1055     crate fn is_synthetic_type_param(&self) -> bool {
1056         match self.kind {
1057             GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => false,
1058             GenericParamDefKind::Type { ref synthetic, .. } => synthetic.is_some(),
1059         }
1060     }
1061
1062     crate fn is_type(&self) -> bool {
1063         self.kind.is_type()
1064     }
1065
1066     crate fn get_type(&self) -> Option<Type> {
1067         self.kind.get_type()
1068     }
1069
1070     crate fn get_bounds(&self) -> Option<&[GenericBound]> {
1071         match self.kind {
1072             GenericParamDefKind::Type { ref bounds, .. } => Some(bounds),
1073             _ => None,
1074         }
1075     }
1076 }
1077
1078 // maybe use a Generic enum and use Vec<Generic>?
1079 #[derive(Clone, Debug, Default)]
1080 crate struct Generics {
1081     crate params: Vec<GenericParamDef>,
1082     crate where_predicates: Vec<WherePredicate>,
1083 }
1084
1085 #[derive(Clone, Debug)]
1086 crate struct Function {
1087     crate decl: FnDecl,
1088     crate generics: Generics,
1089     crate header: hir::FnHeader,
1090 }
1091
1092 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1093 crate struct FnDecl {
1094     crate inputs: Arguments,
1095     crate output: FnRetTy,
1096     crate c_variadic: bool,
1097     crate attrs: Attributes,
1098 }
1099
1100 impl FnDecl {
1101     crate fn self_type(&self) -> Option<SelfTy> {
1102         self.inputs.values.get(0).and_then(|v| v.to_self())
1103     }
1104
1105     /// Returns the sugared return type for an async function.
1106     ///
1107     /// For example, if the return type is `impl std::future::Future<Output = i32>`, this function
1108     /// will return `i32`.
1109     ///
1110     /// # Panics
1111     ///
1112     /// This function will panic if the return type does not match the expected sugaring for async
1113     /// functions.
1114     crate fn sugared_async_return_type(&self) -> FnRetTy {
1115         match &self.output {
1116             FnRetTy::Return(Type::ImplTrait(bounds)) => match &bounds[0] {
1117                 GenericBound::TraitBound(PolyTrait { trait_, .. }, ..) => {
1118                     let bindings = trait_.bindings().unwrap();
1119                     FnRetTy::Return(bindings[0].ty().clone())
1120                 }
1121                 _ => panic!("unexpected desugaring of async function"),
1122             },
1123             _ => panic!("unexpected desugaring of async function"),
1124         }
1125     }
1126 }
1127
1128 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1129 crate struct Arguments {
1130     crate values: Vec<Argument>,
1131 }
1132
1133 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1134 crate struct Argument {
1135     crate type_: Type,
1136     crate name: Symbol,
1137 }
1138
1139 #[derive(Clone, PartialEq, Debug)]
1140 crate enum SelfTy {
1141     SelfValue,
1142     SelfBorrowed(Option<Lifetime>, Mutability),
1143     SelfExplicit(Type),
1144 }
1145
1146 impl Argument {
1147     crate fn to_self(&self) -> Option<SelfTy> {
1148         if self.name != kw::SelfLower {
1149             return None;
1150         }
1151         if self.type_.is_self_type() {
1152             return Some(SelfValue);
1153         }
1154         match self.type_ {
1155             BorrowedRef { ref lifetime, mutability, ref type_ } if type_.is_self_type() => {
1156                 Some(SelfBorrowed(lifetime.clone(), mutability))
1157             }
1158             _ => Some(SelfExplicit(self.type_.clone())),
1159         }
1160     }
1161 }
1162
1163 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1164 crate enum FnRetTy {
1165     Return(Type),
1166     DefaultReturn,
1167 }
1168
1169 impl GetDefId for FnRetTy {
1170     fn def_id(&self) -> Option<DefId> {
1171         match *self {
1172             Return(ref ty) => ty.def_id(),
1173             DefaultReturn => None,
1174         }
1175     }
1176
1177     fn def_id_full(&self, cache: &Cache) -> Option<DefId> {
1178         match *self {
1179             Return(ref ty) => ty.def_id_full(cache),
1180             DefaultReturn => None,
1181         }
1182     }
1183 }
1184
1185 #[derive(Clone, Debug)]
1186 crate struct Trait {
1187     crate unsafety: hir::Unsafety,
1188     crate items: Vec<Item>,
1189     crate generics: Generics,
1190     crate bounds: Vec<GenericBound>,
1191     crate is_spotlight: bool,
1192     crate is_auto: bool,
1193 }
1194
1195 #[derive(Clone, Debug)]
1196 crate struct TraitAlias {
1197     crate generics: Generics,
1198     crate bounds: Vec<GenericBound>,
1199 }
1200
1201 /// A trait reference, which may have higher ranked lifetimes.
1202 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1203 crate struct PolyTrait {
1204     crate trait_: Type,
1205     crate generic_params: Vec<GenericParamDef>,
1206 }
1207
1208 /// A representation of a type suitable for hyperlinking purposes. Ideally, one can get the original
1209 /// type out of the AST/`TyCtxt` given one of these, if more information is needed. Most
1210 /// importantly, it does not preserve mutability or boxes.
1211 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1212 crate enum Type {
1213     /// Structs/enums/traits (most that would be an `hir::TyKind::Path`).
1214     ResolvedPath {
1215         path: Path,
1216         param_names: Option<Vec<GenericBound>>,
1217         did: DefId,
1218         /// `true` if is a `T::Name` path for associated types.
1219         is_generic: bool,
1220     },
1221     /// For parameterized types, so the consumer of the JSON don't go
1222     /// looking for types which don't exist anywhere.
1223     Generic(Symbol),
1224     /// Primitives are the fixed-size numeric types (plus int/usize/float), char,
1225     /// arrays, slices, and tuples.
1226     Primitive(PrimitiveType),
1227     /// `extern "ABI" fn`
1228     BareFunction(Box<BareFunctionDecl>),
1229     Tuple(Vec<Type>),
1230     Slice(Box<Type>),
1231     /// The `String` field is about the size or the constant representing the array's length.
1232     Array(Box<Type>, String),
1233     Never,
1234     RawPointer(Mutability, Box<Type>),
1235     BorrowedRef {
1236         lifetime: Option<Lifetime>,
1237         mutability: Mutability,
1238         type_: Box<Type>,
1239     },
1240
1241     // `<Type as Trait>::Name`
1242     QPath {
1243         name: Symbol,
1244         self_type: Box<Type>,
1245         trait_: Box<Type>,
1246     },
1247
1248     // `_`
1249     Infer,
1250
1251     // `impl TraitA + TraitB + ...`
1252     ImplTrait(Vec<GenericBound>),
1253 }
1254
1255 #[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)]
1256 /// N.B. this has to be different from `hir::PrimTy` because it also includes types that aren't
1257 /// paths, like `Unit`.
1258 crate enum PrimitiveType {
1259     Isize,
1260     I8,
1261     I16,
1262     I32,
1263     I64,
1264     I128,
1265     Usize,
1266     U8,
1267     U16,
1268     U32,
1269     U64,
1270     U128,
1271     F32,
1272     F64,
1273     Char,
1274     Bool,
1275     Str,
1276     Slice,
1277     Array,
1278     Tuple,
1279     Unit,
1280     RawPointer,
1281     Reference,
1282     Fn,
1283     Never,
1284 }
1285
1286 #[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)]
1287 crate enum TypeKind {
1288     Enum,
1289     Function,
1290     Module,
1291     Const,
1292     Static,
1293     Struct,
1294     Union,
1295     Trait,
1296     Typedef,
1297     Foreign,
1298     Macro,
1299     Attr,
1300     Derive,
1301     TraitAlias,
1302     Primitive,
1303 }
1304
1305 impl From<hir::def::DefKind> for TypeKind {
1306     fn from(other: hir::def::DefKind) -> Self {
1307         match other {
1308             hir::def::DefKind::Enum => Self::Enum,
1309             hir::def::DefKind::Fn => Self::Function,
1310             hir::def::DefKind::Mod => Self::Module,
1311             hir::def::DefKind::Const => Self::Const,
1312             hir::def::DefKind::Static => Self::Static,
1313             hir::def::DefKind::Struct => Self::Struct,
1314             hir::def::DefKind::Union => Self::Union,
1315             hir::def::DefKind::Trait => Self::Trait,
1316             hir::def::DefKind::TyAlias => Self::Typedef,
1317             hir::def::DefKind::TraitAlias => Self::TraitAlias,
1318             hir::def::DefKind::Macro(_) => Self::Macro,
1319             hir::def::DefKind::ForeignTy
1320             | hir::def::DefKind::Variant
1321             | hir::def::DefKind::AssocTy
1322             | hir::def::DefKind::TyParam
1323             | hir::def::DefKind::ConstParam
1324             | hir::def::DefKind::Ctor(..)
1325             | hir::def::DefKind::AssocFn
1326             | hir::def::DefKind::AssocConst
1327             | hir::def::DefKind::ExternCrate
1328             | hir::def::DefKind::Use
1329             | hir::def::DefKind::ForeignMod
1330             | hir::def::DefKind::AnonConst
1331             | hir::def::DefKind::OpaqueTy
1332             | hir::def::DefKind::Field
1333             | hir::def::DefKind::LifetimeParam
1334             | hir::def::DefKind::GlobalAsm
1335             | hir::def::DefKind::Impl
1336             | hir::def::DefKind::Closure
1337             | hir::def::DefKind::Generator => Self::Foreign,
1338         }
1339     }
1340 }
1341
1342 crate trait GetDefId {
1343     /// Use this method to get the [`DefId`] of a [`clean`] AST node.
1344     /// This will return [`None`] when called on a primitive [`clean::Type`].
1345     /// Use [`Self::def_id_full`] if you want to include primitives.
1346     ///
1347     /// [`clean`]: crate::clean
1348     /// [`clean::Type`]: crate::clean::Type
1349     // FIXME: get rid of this function and always use `def_id_full`
1350     fn def_id(&self) -> Option<DefId>;
1351
1352     /// Use this method to get the [DefId] of a [clean] AST node, including [PrimitiveType]s.
1353     ///
1354     /// See [`Self::def_id`] for more.
1355     ///
1356     /// [clean]: crate::clean
1357     fn def_id_full(&self, cache: &Cache) -> Option<DefId>;
1358 }
1359
1360 impl<T: GetDefId> GetDefId for Option<T> {
1361     fn def_id(&self) -> Option<DefId> {
1362         self.as_ref().and_then(|d| d.def_id())
1363     }
1364
1365     fn def_id_full(&self, cache: &Cache) -> Option<DefId> {
1366         self.as_ref().and_then(|d| d.def_id_full(cache))
1367     }
1368 }
1369
1370 impl Type {
1371     crate fn primitive_type(&self) -> Option<PrimitiveType> {
1372         match *self {
1373             Primitive(p) | BorrowedRef { type_: box Primitive(p), .. } => Some(p),
1374             Slice(..) | BorrowedRef { type_: box Slice(..), .. } => Some(PrimitiveType::Slice),
1375             Array(..) | BorrowedRef { type_: box Array(..), .. } => Some(PrimitiveType::Array),
1376             Tuple(ref tys) => {
1377                 if tys.is_empty() {
1378                     Some(PrimitiveType::Unit)
1379                 } else {
1380                     Some(PrimitiveType::Tuple)
1381                 }
1382             }
1383             RawPointer(..) => Some(PrimitiveType::RawPointer),
1384             BorrowedRef { type_: box Generic(..), .. } => Some(PrimitiveType::Reference),
1385             BareFunction(..) => Some(PrimitiveType::Fn),
1386             Never => Some(PrimitiveType::Never),
1387             _ => None,
1388         }
1389     }
1390
1391     crate fn is_generic(&self) -> bool {
1392         match *self {
1393             ResolvedPath { is_generic, .. } => is_generic,
1394             _ => false,
1395         }
1396     }
1397
1398     crate fn is_self_type(&self) -> bool {
1399         match *self {
1400             Generic(name) => name == kw::SelfUpper,
1401             _ => false,
1402         }
1403     }
1404
1405     crate fn generics(&self) -> Option<Vec<&Type>> {
1406         match *self {
1407             ResolvedPath { ref path, .. } => path.segments.last().and_then(|seg| {
1408                 if let GenericArgs::AngleBracketed { ref args, .. } = seg.args {
1409                     Some(
1410                         args.iter()
1411                             .filter_map(|arg| match arg {
1412                                 GenericArg::Type(ty) => Some(ty),
1413                                 _ => None,
1414                             })
1415                             .collect(),
1416                     )
1417                 } else {
1418                     None
1419                 }
1420             }),
1421             _ => None,
1422         }
1423     }
1424
1425     crate fn bindings(&self) -> Option<&[TypeBinding]> {
1426         match *self {
1427             ResolvedPath { ref path, .. } => path.segments.last().and_then(|seg| {
1428                 if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args {
1429                     Some(&**bindings)
1430                 } else {
1431                     None
1432                 }
1433             }),
1434             _ => None,
1435         }
1436     }
1437
1438     crate fn is_full_generic(&self) -> bool {
1439         matches!(self, Type::Generic(_))
1440     }
1441
1442     crate fn is_primitive(&self) -> bool {
1443         match self {
1444             Self::Primitive(_) => true,
1445             Self::BorrowedRef { ref type_, .. } | Self::RawPointer(_, ref type_) => {
1446                 type_.is_primitive()
1447             }
1448             _ => false,
1449         }
1450     }
1451
1452     crate fn projection(&self) -> Option<(&Type, DefId, Symbol)> {
1453         let (self_, trait_, name) = match self {
1454             QPath { self_type, trait_, name } => (self_type, trait_, name),
1455             _ => return None,
1456         };
1457         let trait_did = match **trait_ {
1458             ResolvedPath { did, .. } => did,
1459             _ => return None,
1460         };
1461         Some((&self_, trait_did, *name))
1462     }
1463 }
1464
1465 impl Type {
1466     fn inner_def_id(&self, cache: Option<&Cache>) -> Option<DefId> {
1467         let t: PrimitiveType = match *self {
1468             ResolvedPath { did, .. } => return Some(did),
1469             Primitive(p) => return cache.and_then(|c| c.primitive_locations.get(&p).cloned()),
1470             BorrowedRef { type_: box Generic(..), .. } => PrimitiveType::Reference,
1471             BorrowedRef { ref type_, .. } => return type_.inner_def_id(cache),
1472             Tuple(ref tys) => {
1473                 if tys.is_empty() {
1474                     PrimitiveType::Unit
1475                 } else {
1476                     PrimitiveType::Tuple
1477                 }
1478             }
1479             BareFunction(..) => PrimitiveType::Fn,
1480             Never => PrimitiveType::Never,
1481             Slice(..) => PrimitiveType::Slice,
1482             Array(..) => PrimitiveType::Array,
1483             RawPointer(..) => PrimitiveType::RawPointer,
1484             QPath { ref self_type, .. } => return self_type.inner_def_id(cache),
1485             Generic(_) | Infer | ImplTrait(_) => return None,
1486         };
1487         cache.and_then(|c| Primitive(t).def_id_full(c))
1488     }
1489 }
1490
1491 impl GetDefId for Type {
1492     fn def_id(&self) -> Option<DefId> {
1493         self.inner_def_id(None)
1494     }
1495
1496     fn def_id_full(&self, cache: &Cache) -> Option<DefId> {
1497         self.inner_def_id(Some(cache))
1498     }
1499 }
1500
1501 impl PrimitiveType {
1502     crate fn from_hir(prim: hir::PrimTy) -> PrimitiveType {
1503         use ast::{FloatTy, IntTy, UintTy};
1504         match prim {
1505             hir::PrimTy::Int(IntTy::Isize) => PrimitiveType::Isize,
1506             hir::PrimTy::Int(IntTy::I8) => PrimitiveType::I8,
1507             hir::PrimTy::Int(IntTy::I16) => PrimitiveType::I16,
1508             hir::PrimTy::Int(IntTy::I32) => PrimitiveType::I32,
1509             hir::PrimTy::Int(IntTy::I64) => PrimitiveType::I64,
1510             hir::PrimTy::Int(IntTy::I128) => PrimitiveType::I128,
1511             hir::PrimTy::Uint(UintTy::Usize) => PrimitiveType::Usize,
1512             hir::PrimTy::Uint(UintTy::U8) => PrimitiveType::U8,
1513             hir::PrimTy::Uint(UintTy::U16) => PrimitiveType::U16,
1514             hir::PrimTy::Uint(UintTy::U32) => PrimitiveType::U32,
1515             hir::PrimTy::Uint(UintTy::U64) => PrimitiveType::U64,
1516             hir::PrimTy::Uint(UintTy::U128) => PrimitiveType::U128,
1517             hir::PrimTy::Float(FloatTy::F32) => PrimitiveType::F32,
1518             hir::PrimTy::Float(FloatTy::F64) => PrimitiveType::F64,
1519             hir::PrimTy::Str => PrimitiveType::Str,
1520             hir::PrimTy::Bool => PrimitiveType::Bool,
1521             hir::PrimTy::Char => PrimitiveType::Char,
1522         }
1523     }
1524
1525     crate fn from_symbol(s: Symbol) -> Option<PrimitiveType> {
1526         match s {
1527             sym::isize => Some(PrimitiveType::Isize),
1528             sym::i8 => Some(PrimitiveType::I8),
1529             sym::i16 => Some(PrimitiveType::I16),
1530             sym::i32 => Some(PrimitiveType::I32),
1531             sym::i64 => Some(PrimitiveType::I64),
1532             sym::i128 => Some(PrimitiveType::I128),
1533             sym::usize => Some(PrimitiveType::Usize),
1534             sym::u8 => Some(PrimitiveType::U8),
1535             sym::u16 => Some(PrimitiveType::U16),
1536             sym::u32 => Some(PrimitiveType::U32),
1537             sym::u64 => Some(PrimitiveType::U64),
1538             sym::u128 => Some(PrimitiveType::U128),
1539             sym::bool => Some(PrimitiveType::Bool),
1540             sym::char => Some(PrimitiveType::Char),
1541             sym::str => Some(PrimitiveType::Str),
1542             sym::f32 => Some(PrimitiveType::F32),
1543             sym::f64 => Some(PrimitiveType::F64),
1544             sym::array => Some(PrimitiveType::Array),
1545             sym::slice => Some(PrimitiveType::Slice),
1546             sym::tuple => Some(PrimitiveType::Tuple),
1547             sym::unit => Some(PrimitiveType::Unit),
1548             sym::pointer => Some(PrimitiveType::RawPointer),
1549             sym::reference => Some(PrimitiveType::Reference),
1550             kw::Fn => Some(PrimitiveType::Fn),
1551             sym::never => Some(PrimitiveType::Never),
1552             _ => None,
1553         }
1554     }
1555
1556     crate fn as_str(&self) -> &'static str {
1557         use self::PrimitiveType::*;
1558         match *self {
1559             Isize => "isize",
1560             I8 => "i8",
1561             I16 => "i16",
1562             I32 => "i32",
1563             I64 => "i64",
1564             I128 => "i128",
1565             Usize => "usize",
1566             U8 => "u8",
1567             U16 => "u16",
1568             U32 => "u32",
1569             U64 => "u64",
1570             U128 => "u128",
1571             F32 => "f32",
1572             F64 => "f64",
1573             Str => "str",
1574             Bool => "bool",
1575             Char => "char",
1576             Array => "array",
1577             Slice => "slice",
1578             Tuple => "tuple",
1579             Unit => "unit",
1580             RawPointer => "pointer",
1581             Reference => "reference",
1582             Fn => "fn",
1583             Never => "never",
1584         }
1585     }
1586
1587     crate fn impls(&self, tcx: TyCtxt<'_>) -> &'static ArrayVec<[DefId; 4]> {
1588         Self::all_impls(tcx).get(self).expect("missing impl for primitive type")
1589     }
1590
1591     crate fn all_impls(tcx: TyCtxt<'_>) -> &'static FxHashMap<PrimitiveType, ArrayVec<[DefId; 4]>> {
1592         static CELL: OnceCell<FxHashMap<PrimitiveType, ArrayVec<[DefId; 4]>>> = OnceCell::new();
1593
1594         CELL.get_or_init(move || {
1595             use self::PrimitiveType::*;
1596
1597             /// A macro to create a FxHashMap.
1598             ///
1599             /// Example:
1600             ///
1601             /// ```
1602             /// let letters = map!{"a" => "b", "c" => "d"};
1603             /// ```
1604             ///
1605             /// Trailing commas are allowed.
1606             /// Commas between elements are required (even if the expression is a block).
1607             macro_rules! map {
1608                 ($( $key: expr => $val: expr ),* $(,)*) => {{
1609                     let mut map = ::rustc_data_structures::fx::FxHashMap::default();
1610                     $( map.insert($key, $val); )*
1611                     map
1612                 }}
1613             }
1614
1615             let single = |a: Option<DefId>| a.into_iter().collect();
1616             let both = |a: Option<DefId>, b: Option<DefId>| -> ArrayVec<_> {
1617                 a.into_iter().chain(b).collect()
1618             };
1619
1620             let lang_items = tcx.lang_items();
1621             map! {
1622                 Isize => single(lang_items.isize_impl()),
1623                 I8 => single(lang_items.i8_impl()),
1624                 I16 => single(lang_items.i16_impl()),
1625                 I32 => single(lang_items.i32_impl()),
1626                 I64 => single(lang_items.i64_impl()),
1627                 I128 => single(lang_items.i128_impl()),
1628                 Usize => single(lang_items.usize_impl()),
1629                 U8 => single(lang_items.u8_impl()),
1630                 U16 => single(lang_items.u16_impl()),
1631                 U32 => single(lang_items.u32_impl()),
1632                 U64 => single(lang_items.u64_impl()),
1633                 U128 => single(lang_items.u128_impl()),
1634                 F32 => both(lang_items.f32_impl(), lang_items.f32_runtime_impl()),
1635                 F64 => both(lang_items.f64_impl(), lang_items.f64_runtime_impl()),
1636                 Char => single(lang_items.char_impl()),
1637                 Bool => single(lang_items.bool_impl()),
1638                 Str => both(lang_items.str_impl(), lang_items.str_alloc_impl()),
1639                 Slice => {
1640                     lang_items
1641                         .slice_impl()
1642                         .into_iter()
1643                         .chain(lang_items.slice_u8_impl())
1644                         .chain(lang_items.slice_alloc_impl())
1645                         .chain(lang_items.slice_u8_alloc_impl())
1646                         .collect()
1647                 },
1648                 Array => single(lang_items.array_impl()),
1649                 Tuple => ArrayVec::new(),
1650                 Unit => ArrayVec::new(),
1651                 RawPointer => {
1652                     lang_items
1653                         .const_ptr_impl()
1654                         .into_iter()
1655                         .chain(lang_items.mut_ptr_impl())
1656                         .chain(lang_items.const_slice_ptr_impl())
1657                         .chain(lang_items.mut_slice_ptr_impl())
1658                         .collect()
1659                 },
1660                 Reference => ArrayVec::new(),
1661                 Fn => ArrayVec::new(),
1662                 Never => ArrayVec::new(),
1663             }
1664         })
1665     }
1666
1667     crate fn to_url_str(&self) -> &'static str {
1668         self.as_str()
1669     }
1670
1671     crate fn as_sym(&self) -> Symbol {
1672         use PrimitiveType::*;
1673         match self {
1674             Isize => sym::isize,
1675             I8 => sym::i8,
1676             I16 => sym::i16,
1677             I32 => sym::i32,
1678             I64 => sym::i64,
1679             I128 => sym::i128,
1680             Usize => sym::usize,
1681             U8 => sym::u8,
1682             U16 => sym::u16,
1683             U32 => sym::u32,
1684             U64 => sym::u64,
1685             U128 => sym::u128,
1686             F32 => sym::f32,
1687             F64 => sym::f64,
1688             Str => sym::str,
1689             Bool => sym::bool,
1690             Char => sym::char,
1691             Array => sym::array,
1692             Slice => sym::slice,
1693             Tuple => sym::tuple,
1694             Unit => sym::unit,
1695             RawPointer => sym::pointer,
1696             Reference => sym::reference,
1697             Fn => kw::Fn,
1698             Never => sym::never,
1699         }
1700     }
1701 }
1702
1703 impl From<ast::IntTy> for PrimitiveType {
1704     fn from(int_ty: ast::IntTy) -> PrimitiveType {
1705         match int_ty {
1706             ast::IntTy::Isize => PrimitiveType::Isize,
1707             ast::IntTy::I8 => PrimitiveType::I8,
1708             ast::IntTy::I16 => PrimitiveType::I16,
1709             ast::IntTy::I32 => PrimitiveType::I32,
1710             ast::IntTy::I64 => PrimitiveType::I64,
1711             ast::IntTy::I128 => PrimitiveType::I128,
1712         }
1713     }
1714 }
1715
1716 impl From<ast::UintTy> for PrimitiveType {
1717     fn from(uint_ty: ast::UintTy) -> PrimitiveType {
1718         match uint_ty {
1719             ast::UintTy::Usize => PrimitiveType::Usize,
1720             ast::UintTy::U8 => PrimitiveType::U8,
1721             ast::UintTy::U16 => PrimitiveType::U16,
1722             ast::UintTy::U32 => PrimitiveType::U32,
1723             ast::UintTy::U64 => PrimitiveType::U64,
1724             ast::UintTy::U128 => PrimitiveType::U128,
1725         }
1726     }
1727 }
1728
1729 impl From<ast::FloatTy> for PrimitiveType {
1730     fn from(float_ty: ast::FloatTy) -> PrimitiveType {
1731         match float_ty {
1732             ast::FloatTy::F32 => PrimitiveType::F32,
1733             ast::FloatTy::F64 => PrimitiveType::F64,
1734         }
1735     }
1736 }
1737
1738 impl From<ty::IntTy> for PrimitiveType {
1739     fn from(int_ty: ty::IntTy) -> PrimitiveType {
1740         match int_ty {
1741             ty::IntTy::Isize => PrimitiveType::Isize,
1742             ty::IntTy::I8 => PrimitiveType::I8,
1743             ty::IntTy::I16 => PrimitiveType::I16,
1744             ty::IntTy::I32 => PrimitiveType::I32,
1745             ty::IntTy::I64 => PrimitiveType::I64,
1746             ty::IntTy::I128 => PrimitiveType::I128,
1747         }
1748     }
1749 }
1750
1751 impl From<ty::UintTy> for PrimitiveType {
1752     fn from(uint_ty: ty::UintTy) -> PrimitiveType {
1753         match uint_ty {
1754             ty::UintTy::Usize => PrimitiveType::Usize,
1755             ty::UintTy::U8 => PrimitiveType::U8,
1756             ty::UintTy::U16 => PrimitiveType::U16,
1757             ty::UintTy::U32 => PrimitiveType::U32,
1758             ty::UintTy::U64 => PrimitiveType::U64,
1759             ty::UintTy::U128 => PrimitiveType::U128,
1760         }
1761     }
1762 }
1763
1764 impl From<ty::FloatTy> for PrimitiveType {
1765     fn from(float_ty: ty::FloatTy) -> PrimitiveType {
1766         match float_ty {
1767             ty::FloatTy::F32 => PrimitiveType::F32,
1768             ty::FloatTy::F64 => PrimitiveType::F64,
1769         }
1770     }
1771 }
1772
1773 impl From<hir::PrimTy> for PrimitiveType {
1774     fn from(prim_ty: hir::PrimTy) -> PrimitiveType {
1775         match prim_ty {
1776             hir::PrimTy::Int(int_ty) => int_ty.into(),
1777             hir::PrimTy::Uint(uint_ty) => uint_ty.into(),
1778             hir::PrimTy::Float(float_ty) => float_ty.into(),
1779             hir::PrimTy::Str => PrimitiveType::Str,
1780             hir::PrimTy::Bool => PrimitiveType::Bool,
1781             hir::PrimTy::Char => PrimitiveType::Char,
1782         }
1783     }
1784 }
1785
1786 #[derive(Copy, Clone, Debug)]
1787 crate enum Visibility {
1788     Public,
1789     Inherited,
1790     Restricted(DefId),
1791 }
1792
1793 impl Visibility {
1794     crate fn is_public(&self) -> bool {
1795         matches!(self, Visibility::Public)
1796     }
1797 }
1798
1799 #[derive(Clone, Debug)]
1800 crate struct Struct {
1801     crate struct_type: CtorKind,
1802     crate generics: Generics,
1803     crate fields: Vec<Item>,
1804     crate fields_stripped: bool,
1805 }
1806
1807 #[derive(Clone, Debug)]
1808 crate struct Union {
1809     crate generics: Generics,
1810     crate fields: Vec<Item>,
1811     crate fields_stripped: bool,
1812 }
1813
1814 /// This is a more limited form of the standard Struct, different in that
1815 /// it lacks the things most items have (name, id, parameterization). Found
1816 /// only as a variant in an enum.
1817 #[derive(Clone, Debug)]
1818 crate struct VariantStruct {
1819     crate struct_type: CtorKind,
1820     crate fields: Vec<Item>,
1821     crate fields_stripped: bool,
1822 }
1823
1824 #[derive(Clone, Debug)]
1825 crate struct Enum {
1826     crate variants: IndexVec<VariantIdx, Item>,
1827     crate generics: Generics,
1828     crate variants_stripped: bool,
1829 }
1830
1831 #[derive(Clone, Debug)]
1832 crate enum Variant {
1833     CLike,
1834     Tuple(Vec<Type>),
1835     Struct(VariantStruct),
1836 }
1837
1838 /// Small wrapper around `rustc_span::Span` that adds helper methods and enforces calling `source_callsite`.
1839 #[derive(Clone, Debug)]
1840 crate struct Span(rustc_span::Span);
1841
1842 impl Span {
1843     crate fn from_rustc_span(sp: rustc_span::Span) -> Self {
1844         // Get the macro invocation instead of the definition,
1845         // in case the span is result of a macro expansion.
1846         // (See rust-lang/rust#39726)
1847         Self(sp.source_callsite())
1848     }
1849
1850     crate fn dummy() -> Self {
1851         Self(rustc_span::DUMMY_SP)
1852     }
1853
1854     crate fn span(&self) -> rustc_span::Span {
1855         self.0
1856     }
1857
1858     crate fn filename(&self, sess: &Session) -> FileName {
1859         sess.source_map().span_to_filename(self.0)
1860     }
1861
1862     crate fn lo(&self, sess: &Session) -> Loc {
1863         sess.source_map().lookup_char_pos(self.0.lo())
1864     }
1865
1866     crate fn hi(&self, sess: &Session) -> Loc {
1867         sess.source_map().lookup_char_pos(self.0.hi())
1868     }
1869
1870     crate fn cnum(&self, sess: &Session) -> CrateNum {
1871         // FIXME: is there a time when the lo and hi crate would be different?
1872         self.lo(sess).file.cnum
1873     }
1874 }
1875
1876 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1877 crate struct Path {
1878     crate global: bool,
1879     crate res: Res,
1880     crate segments: Vec<PathSegment>,
1881 }
1882
1883 impl Path {
1884     crate fn last(&self) -> Symbol {
1885         self.segments.last().expect("segments were empty").name
1886     }
1887
1888     crate fn last_name(&self) -> SymbolStr {
1889         self.segments.last().expect("segments were empty").name.as_str()
1890     }
1891
1892     crate fn whole_name(&self) -> String {
1893         String::from(if self.global { "::" } else { "" })
1894             + &self.segments.iter().map(|s| s.name.to_string()).collect::<Vec<_>>().join("::")
1895     }
1896 }
1897
1898 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1899 crate enum GenericArg {
1900     Lifetime(Lifetime),
1901     Type(Type),
1902     Const(Constant),
1903 }
1904
1905 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1906 crate enum GenericArgs {
1907     AngleBracketed { args: Vec<GenericArg>, bindings: Vec<TypeBinding> },
1908     Parenthesized { inputs: Vec<Type>, output: Option<Type> },
1909 }
1910
1911 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1912 crate struct PathSegment {
1913     crate name: Symbol,
1914     crate args: GenericArgs,
1915 }
1916
1917 #[derive(Clone, Debug)]
1918 crate struct Typedef {
1919     crate type_: Type,
1920     crate generics: Generics,
1921     /// `type_` can come from either the HIR or from metadata. If it comes from HIR, it may be a type
1922     /// alias instead of the final type. This will always have the final type, regardless of whether
1923     /// `type_` came from HIR or from metadata.
1924     ///
1925     /// If `item_type.is_none()`, `type_` is guarenteed to come from metadata (and therefore hold the
1926     /// final type).
1927     crate item_type: Option<Type>,
1928 }
1929
1930 impl GetDefId for Typedef {
1931     fn def_id(&self) -> Option<DefId> {
1932         self.type_.def_id()
1933     }
1934
1935     fn def_id_full(&self, cache: &Cache) -> Option<DefId> {
1936         self.type_.def_id_full(cache)
1937     }
1938 }
1939
1940 #[derive(Clone, Debug)]
1941 crate struct OpaqueTy {
1942     crate bounds: Vec<GenericBound>,
1943     crate generics: Generics,
1944 }
1945
1946 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1947 crate struct BareFunctionDecl {
1948     crate unsafety: hir::Unsafety,
1949     crate generic_params: Vec<GenericParamDef>,
1950     crate decl: FnDecl,
1951     crate abi: Abi,
1952 }
1953
1954 #[derive(Clone, Debug)]
1955 crate struct Static {
1956     crate type_: Type,
1957     crate mutability: Mutability,
1958     /// It's useful to have the value of a static documented, but I have no
1959     /// desire to represent expressions (that'd basically be all of the AST,
1960     /// which is huge!). So, have a string.
1961     crate expr: String,
1962 }
1963
1964 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
1965 crate struct Constant {
1966     crate type_: Type,
1967     crate expr: String,
1968     crate value: Option<String>,
1969     crate is_literal: bool,
1970 }
1971
1972 #[derive(Clone, Debug)]
1973 crate struct Impl {
1974     crate unsafety: hir::Unsafety,
1975     crate generics: Generics,
1976     crate provided_trait_methods: FxHashSet<Symbol>,
1977     crate trait_: Option<Type>,
1978     crate for_: Type,
1979     crate items: Vec<Item>,
1980     crate negative_polarity: bool,
1981     crate synthetic: bool,
1982     crate blanket_impl: Option<Type>,
1983 }
1984
1985 #[derive(Clone, Debug)]
1986 crate struct Import {
1987     crate kind: ImportKind,
1988     crate source: ImportSource,
1989     crate should_be_displayed: bool,
1990 }
1991
1992 impl Import {
1993     crate fn new_simple(name: Symbol, source: ImportSource, should_be_displayed: bool) -> Self {
1994         Self { kind: ImportKind::Simple(name), source, should_be_displayed }
1995     }
1996
1997     crate fn new_glob(source: ImportSource, should_be_displayed: bool) -> Self {
1998         Self { kind: ImportKind::Glob, source, should_be_displayed }
1999     }
2000 }
2001
2002 #[derive(Clone, Debug)]
2003 crate enum ImportKind {
2004     // use source as str;
2005     Simple(Symbol),
2006     // use source::*;
2007     Glob,
2008 }
2009
2010 #[derive(Clone, Debug)]
2011 crate struct ImportSource {
2012     crate path: Path,
2013     crate did: Option<DefId>,
2014 }
2015
2016 #[derive(Clone, Debug)]
2017 crate struct Macro {
2018     crate source: String,
2019     crate imported_from: Option<Symbol>,
2020 }
2021
2022 #[derive(Clone, Debug)]
2023 crate struct ProcMacro {
2024     crate kind: MacroKind,
2025     crate helpers: Vec<Symbol>,
2026 }
2027
2028 /// An type binding on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
2029 /// `A: Send + Sync` in `Foo<A: Send + Sync>`).
2030 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
2031 crate struct TypeBinding {
2032     crate name: Symbol,
2033     crate kind: TypeBindingKind,
2034 }
2035
2036 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
2037 crate enum TypeBindingKind {
2038     Equality { ty: Type },
2039     Constraint { bounds: Vec<GenericBound> },
2040 }
2041
2042 impl TypeBinding {
2043     crate fn ty(&self) -> &Type {
2044         match self.kind {
2045             TypeBindingKind::Equality { ref ty } => ty,
2046             _ => panic!("expected equality type binding for parenthesized generic args"),
2047         }
2048     }
2049 }