]> git.lizzy.rs Git - rust.git/blob - src/librustdoc/clean/types.rs
Improve html::render::cache::get_real_types code
[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<'a> From<&'a hir::def::DefKind> for TypeKind {
1306     fn from(other: &hir::def::DefKind) -> Self {
1307         Self::from(*other)
1308     }
1309 }
1310
1311 impl From<hir::def::DefKind> for TypeKind {
1312     fn from(other: hir::def::DefKind) -> Self {
1313         match other {
1314             hir::def::DefKind::Enum => Self::Enum,
1315             hir::def::DefKind::Fn => Self::Function,
1316             hir::def::DefKind::Mod => Self::Module,
1317             hir::def::DefKind::Const => Self::Const,
1318             hir::def::DefKind::Static => Self::Static,
1319             hir::def::DefKind::Struct => Self::Struct,
1320             hir::def::DefKind::Union => Self::Union,
1321             hir::def::DefKind::Trait => Self::Trait,
1322             hir::def::DefKind::TyAlias => Self::Typedef,
1323             hir::def::DefKind::ForeignTy => Self::Foreign,
1324             hir::def::DefKind::TraitAlias => Self::TraitAlias,
1325             hir::def::DefKind::Macro(_) => Self::Macro,
1326             hir::def::DefKind::Variant
1327             | hir::def::DefKind::AssocTy
1328             | hir::def::DefKind::TyParam
1329             | hir::def::DefKind::ConstParam
1330             | hir::def::DefKind::Ctor(..)
1331             | hir::def::DefKind::AssocFn
1332             | hir::def::DefKind::AssocConst
1333             | hir::def::DefKind::ExternCrate
1334             | hir::def::DefKind::Use
1335             | hir::def::DefKind::ForeignMod
1336             | hir::def::DefKind::AnonConst
1337             | hir::def::DefKind::OpaqueTy
1338             | hir::def::DefKind::Field
1339             | hir::def::DefKind::LifetimeParam
1340             | hir::def::DefKind::GlobalAsm
1341             | hir::def::DefKind::Impl
1342             | hir::def::DefKind::Closure
1343             | hir::def::DefKind::Generator => Self::Foreign,
1344         }
1345     }
1346 }
1347
1348 crate trait GetDefId {
1349     /// Use this method to get the [`DefId`] of a [`clean`] AST node.
1350     /// This will return [`None`] when called on a primitive [`clean::Type`].
1351     /// Use [`Self::def_id_full`] if you want to include primitives.
1352     ///
1353     /// [`clean`]: crate::clean
1354     /// [`clean::Type`]: crate::clean::Type
1355     // FIXME: get rid of this function and always use `def_id_full`
1356     fn def_id(&self) -> Option<DefId>;
1357
1358     /// Use this method to get the [DefId] of a [clean] AST node, including [PrimitiveType]s.
1359     ///
1360     /// See [`Self::def_id`] for more.
1361     ///
1362     /// [clean]: crate::clean
1363     fn def_id_full(&self, cache: &Cache) -> Option<DefId>;
1364 }
1365
1366 impl<T: GetDefId> GetDefId for Option<T> {
1367     fn def_id(&self) -> Option<DefId> {
1368         self.as_ref().and_then(|d| d.def_id())
1369     }
1370
1371     fn def_id_full(&self, cache: &Cache) -> Option<DefId> {
1372         self.as_ref().and_then(|d| d.def_id_full(cache))
1373     }
1374 }
1375
1376 impl Type {
1377     crate fn primitive_type(&self) -> Option<PrimitiveType> {
1378         match *self {
1379             Primitive(p) | BorrowedRef { type_: box Primitive(p), .. } => Some(p),
1380             Slice(..) | BorrowedRef { type_: box Slice(..), .. } => Some(PrimitiveType::Slice),
1381             Array(..) | BorrowedRef { type_: box Array(..), .. } => Some(PrimitiveType::Array),
1382             Tuple(ref tys) => {
1383                 if tys.is_empty() {
1384                     Some(PrimitiveType::Unit)
1385                 } else {
1386                     Some(PrimitiveType::Tuple)
1387                 }
1388             }
1389             RawPointer(..) => Some(PrimitiveType::RawPointer),
1390             BorrowedRef { type_: box Generic(..), .. } => Some(PrimitiveType::Reference),
1391             BareFunction(..) => Some(PrimitiveType::Fn),
1392             Never => Some(PrimitiveType::Never),
1393             _ => None,
1394         }
1395     }
1396
1397     crate fn is_generic(&self) -> bool {
1398         match *self {
1399             ResolvedPath { is_generic, .. } => is_generic,
1400             _ => false,
1401         }
1402     }
1403
1404     crate fn is_self_type(&self) -> bool {
1405         match *self {
1406             Generic(name) => name == kw::SelfUpper,
1407             _ => false,
1408         }
1409     }
1410
1411     crate fn generics(&self) -> Option<Vec<&Type>> {
1412         match *self {
1413             ResolvedPath { ref path, .. } => path.segments.last().and_then(|seg| {
1414                 if let GenericArgs::AngleBracketed { ref args, .. } = seg.args {
1415                     Some(
1416                         args.iter()
1417                             .filter_map(|arg| match arg {
1418                                 GenericArg::Type(ty) => Some(ty),
1419                                 _ => None,
1420                             })
1421                             .collect(),
1422                     )
1423                 } else {
1424                     None
1425                 }
1426             }),
1427             _ => None,
1428         }
1429     }
1430
1431     crate fn bindings(&self) -> Option<&[TypeBinding]> {
1432         match *self {
1433             ResolvedPath { ref path, .. } => path.segments.last().and_then(|seg| {
1434                 if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args {
1435                     Some(&**bindings)
1436                 } else {
1437                     None
1438                 }
1439             }),
1440             _ => None,
1441         }
1442     }
1443
1444     crate fn is_full_generic(&self) -> bool {
1445         matches!(self, Type::Generic(_))
1446     }
1447
1448     crate fn is_primitive(&self) -> bool {
1449         match self {
1450             Self::Primitive(_) => true,
1451             Self::BorrowedRef { ref type_, .. } | Self::RawPointer(_, ref type_) => {
1452                 type_.is_primitive()
1453             }
1454             _ => false,
1455         }
1456     }
1457
1458     crate fn projection(&self) -> Option<(&Type, DefId, Symbol)> {
1459         let (self_, trait_, name) = match self {
1460             QPath { self_type, trait_, name } => (self_type, trait_, name),
1461             _ => return None,
1462         };
1463         let trait_did = match **trait_ {
1464             ResolvedPath { did, .. } => did,
1465             _ => return None,
1466         };
1467         Some((&self_, trait_did, *name))
1468     }
1469 }
1470
1471 impl Type {
1472     fn inner_def_id(&self, cache: Option<&Cache>) -> Option<DefId> {
1473         let t: PrimitiveType = match *self {
1474             ResolvedPath { did, .. } => return Some(did),
1475             Primitive(p) => return cache.and_then(|c| c.primitive_locations.get(&p).cloned()),
1476             BorrowedRef { type_: box Generic(..), .. } => PrimitiveType::Reference,
1477             BorrowedRef { ref type_, .. } => return type_.inner_def_id(cache),
1478             Tuple(ref tys) => {
1479                 if tys.is_empty() {
1480                     PrimitiveType::Unit
1481                 } else {
1482                     PrimitiveType::Tuple
1483                 }
1484             }
1485             BareFunction(..) => PrimitiveType::Fn,
1486             Never => PrimitiveType::Never,
1487             Slice(..) => PrimitiveType::Slice,
1488             Array(..) => PrimitiveType::Array,
1489             RawPointer(..) => PrimitiveType::RawPointer,
1490             QPath { ref self_type, .. } => return self_type.inner_def_id(cache),
1491             Generic(_) | Infer | ImplTrait(_) => return None,
1492         };
1493         cache.and_then(|c| Primitive(t).def_id_full(c))
1494     }
1495 }
1496
1497 impl GetDefId for Type {
1498     fn def_id(&self) -> Option<DefId> {
1499         self.inner_def_id(None)
1500     }
1501
1502     fn def_id_full(&self, cache: &Cache) -> Option<DefId> {
1503         self.inner_def_id(Some(cache))
1504     }
1505 }
1506
1507 impl PrimitiveType {
1508     crate fn from_hir(prim: hir::PrimTy) -> PrimitiveType {
1509         use ast::{FloatTy, IntTy, UintTy};
1510         match prim {
1511             hir::PrimTy::Int(IntTy::Isize) => PrimitiveType::Isize,
1512             hir::PrimTy::Int(IntTy::I8) => PrimitiveType::I8,
1513             hir::PrimTy::Int(IntTy::I16) => PrimitiveType::I16,
1514             hir::PrimTy::Int(IntTy::I32) => PrimitiveType::I32,
1515             hir::PrimTy::Int(IntTy::I64) => PrimitiveType::I64,
1516             hir::PrimTy::Int(IntTy::I128) => PrimitiveType::I128,
1517             hir::PrimTy::Uint(UintTy::Usize) => PrimitiveType::Usize,
1518             hir::PrimTy::Uint(UintTy::U8) => PrimitiveType::U8,
1519             hir::PrimTy::Uint(UintTy::U16) => PrimitiveType::U16,
1520             hir::PrimTy::Uint(UintTy::U32) => PrimitiveType::U32,
1521             hir::PrimTy::Uint(UintTy::U64) => PrimitiveType::U64,
1522             hir::PrimTy::Uint(UintTy::U128) => PrimitiveType::U128,
1523             hir::PrimTy::Float(FloatTy::F32) => PrimitiveType::F32,
1524             hir::PrimTy::Float(FloatTy::F64) => PrimitiveType::F64,
1525             hir::PrimTy::Str => PrimitiveType::Str,
1526             hir::PrimTy::Bool => PrimitiveType::Bool,
1527             hir::PrimTy::Char => PrimitiveType::Char,
1528         }
1529     }
1530
1531     crate fn from_symbol(s: Symbol) -> Option<PrimitiveType> {
1532         match s {
1533             sym::isize => Some(PrimitiveType::Isize),
1534             sym::i8 => Some(PrimitiveType::I8),
1535             sym::i16 => Some(PrimitiveType::I16),
1536             sym::i32 => Some(PrimitiveType::I32),
1537             sym::i64 => Some(PrimitiveType::I64),
1538             sym::i128 => Some(PrimitiveType::I128),
1539             sym::usize => Some(PrimitiveType::Usize),
1540             sym::u8 => Some(PrimitiveType::U8),
1541             sym::u16 => Some(PrimitiveType::U16),
1542             sym::u32 => Some(PrimitiveType::U32),
1543             sym::u64 => Some(PrimitiveType::U64),
1544             sym::u128 => Some(PrimitiveType::U128),
1545             sym::bool => Some(PrimitiveType::Bool),
1546             sym::char => Some(PrimitiveType::Char),
1547             sym::str => Some(PrimitiveType::Str),
1548             sym::f32 => Some(PrimitiveType::F32),
1549             sym::f64 => Some(PrimitiveType::F64),
1550             sym::array => Some(PrimitiveType::Array),
1551             sym::slice => Some(PrimitiveType::Slice),
1552             sym::tuple => Some(PrimitiveType::Tuple),
1553             sym::unit => Some(PrimitiveType::Unit),
1554             sym::pointer => Some(PrimitiveType::RawPointer),
1555             sym::reference => Some(PrimitiveType::Reference),
1556             kw::Fn => Some(PrimitiveType::Fn),
1557             sym::never => Some(PrimitiveType::Never),
1558             _ => None,
1559         }
1560     }
1561
1562     crate fn as_str(&self) -> &'static str {
1563         use self::PrimitiveType::*;
1564         match *self {
1565             Isize => "isize",
1566             I8 => "i8",
1567             I16 => "i16",
1568             I32 => "i32",
1569             I64 => "i64",
1570             I128 => "i128",
1571             Usize => "usize",
1572             U8 => "u8",
1573             U16 => "u16",
1574             U32 => "u32",
1575             U64 => "u64",
1576             U128 => "u128",
1577             F32 => "f32",
1578             F64 => "f64",
1579             Str => "str",
1580             Bool => "bool",
1581             Char => "char",
1582             Array => "array",
1583             Slice => "slice",
1584             Tuple => "tuple",
1585             Unit => "unit",
1586             RawPointer => "pointer",
1587             Reference => "reference",
1588             Fn => "fn",
1589             Never => "never",
1590         }
1591     }
1592
1593     crate fn impls(&self, tcx: TyCtxt<'_>) -> &'static ArrayVec<[DefId; 4]> {
1594         Self::all_impls(tcx).get(self).expect("missing impl for primitive type")
1595     }
1596
1597     crate fn all_impls(tcx: TyCtxt<'_>) -> &'static FxHashMap<PrimitiveType, ArrayVec<[DefId; 4]>> {
1598         static CELL: OnceCell<FxHashMap<PrimitiveType, ArrayVec<[DefId; 4]>>> = OnceCell::new();
1599
1600         CELL.get_or_init(move || {
1601             use self::PrimitiveType::*;
1602
1603             /// A macro to create a FxHashMap.
1604             ///
1605             /// Example:
1606             ///
1607             /// ```
1608             /// let letters = map!{"a" => "b", "c" => "d"};
1609             /// ```
1610             ///
1611             /// Trailing commas are allowed.
1612             /// Commas between elements are required (even if the expression is a block).
1613             macro_rules! map {
1614                 ($( $key: expr => $val: expr ),* $(,)*) => {{
1615                     let mut map = ::rustc_data_structures::fx::FxHashMap::default();
1616                     $( map.insert($key, $val); )*
1617                     map
1618                 }}
1619             }
1620
1621             let single = |a: Option<DefId>| a.into_iter().collect();
1622             let both = |a: Option<DefId>, b: Option<DefId>| -> ArrayVec<_> {
1623                 a.into_iter().chain(b).collect()
1624             };
1625
1626             let lang_items = tcx.lang_items();
1627             map! {
1628                 Isize => single(lang_items.isize_impl()),
1629                 I8 => single(lang_items.i8_impl()),
1630                 I16 => single(lang_items.i16_impl()),
1631                 I32 => single(lang_items.i32_impl()),
1632                 I64 => single(lang_items.i64_impl()),
1633                 I128 => single(lang_items.i128_impl()),
1634                 Usize => single(lang_items.usize_impl()),
1635                 U8 => single(lang_items.u8_impl()),
1636                 U16 => single(lang_items.u16_impl()),
1637                 U32 => single(lang_items.u32_impl()),
1638                 U64 => single(lang_items.u64_impl()),
1639                 U128 => single(lang_items.u128_impl()),
1640                 F32 => both(lang_items.f32_impl(), lang_items.f32_runtime_impl()),
1641                 F64 => both(lang_items.f64_impl(), lang_items.f64_runtime_impl()),
1642                 Char => single(lang_items.char_impl()),
1643                 Bool => single(lang_items.bool_impl()),
1644                 Str => both(lang_items.str_impl(), lang_items.str_alloc_impl()),
1645                 Slice => {
1646                     lang_items
1647                         .slice_impl()
1648                         .into_iter()
1649                         .chain(lang_items.slice_u8_impl())
1650                         .chain(lang_items.slice_alloc_impl())
1651                         .chain(lang_items.slice_u8_alloc_impl())
1652                         .collect()
1653                 },
1654                 Array => single(lang_items.array_impl()),
1655                 Tuple => ArrayVec::new(),
1656                 Unit => ArrayVec::new(),
1657                 RawPointer => {
1658                     lang_items
1659                         .const_ptr_impl()
1660                         .into_iter()
1661                         .chain(lang_items.mut_ptr_impl())
1662                         .chain(lang_items.const_slice_ptr_impl())
1663                         .chain(lang_items.mut_slice_ptr_impl())
1664                         .collect()
1665                 },
1666                 Reference => ArrayVec::new(),
1667                 Fn => ArrayVec::new(),
1668                 Never => ArrayVec::new(),
1669             }
1670         })
1671     }
1672
1673     crate fn to_url_str(&self) -> &'static str {
1674         self.as_str()
1675     }
1676
1677     crate fn as_sym(&self) -> Symbol {
1678         use PrimitiveType::*;
1679         match self {
1680             Isize => sym::isize,
1681             I8 => sym::i8,
1682             I16 => sym::i16,
1683             I32 => sym::i32,
1684             I64 => sym::i64,
1685             I128 => sym::i128,
1686             Usize => sym::usize,
1687             U8 => sym::u8,
1688             U16 => sym::u16,
1689             U32 => sym::u32,
1690             U64 => sym::u64,
1691             U128 => sym::u128,
1692             F32 => sym::f32,
1693             F64 => sym::f64,
1694             Str => sym::str,
1695             Bool => sym::bool,
1696             Char => sym::char,
1697             Array => sym::array,
1698             Slice => sym::slice,
1699             Tuple => sym::tuple,
1700             Unit => sym::unit,
1701             RawPointer => sym::pointer,
1702             Reference => sym::reference,
1703             Fn => kw::Fn,
1704             Never => sym::never,
1705         }
1706     }
1707 }
1708
1709 impl From<ast::IntTy> for PrimitiveType {
1710     fn from(int_ty: ast::IntTy) -> PrimitiveType {
1711         match int_ty {
1712             ast::IntTy::Isize => PrimitiveType::Isize,
1713             ast::IntTy::I8 => PrimitiveType::I8,
1714             ast::IntTy::I16 => PrimitiveType::I16,
1715             ast::IntTy::I32 => PrimitiveType::I32,
1716             ast::IntTy::I64 => PrimitiveType::I64,
1717             ast::IntTy::I128 => PrimitiveType::I128,
1718         }
1719     }
1720 }
1721
1722 impl From<ast::UintTy> for PrimitiveType {
1723     fn from(uint_ty: ast::UintTy) -> PrimitiveType {
1724         match uint_ty {
1725             ast::UintTy::Usize => PrimitiveType::Usize,
1726             ast::UintTy::U8 => PrimitiveType::U8,
1727             ast::UintTy::U16 => PrimitiveType::U16,
1728             ast::UintTy::U32 => PrimitiveType::U32,
1729             ast::UintTy::U64 => PrimitiveType::U64,
1730             ast::UintTy::U128 => PrimitiveType::U128,
1731         }
1732     }
1733 }
1734
1735 impl From<ast::FloatTy> for PrimitiveType {
1736     fn from(float_ty: ast::FloatTy) -> PrimitiveType {
1737         match float_ty {
1738             ast::FloatTy::F32 => PrimitiveType::F32,
1739             ast::FloatTy::F64 => PrimitiveType::F64,
1740         }
1741     }
1742 }
1743
1744 impl From<ty::IntTy> for PrimitiveType {
1745     fn from(int_ty: ty::IntTy) -> PrimitiveType {
1746         match int_ty {
1747             ty::IntTy::Isize => PrimitiveType::Isize,
1748             ty::IntTy::I8 => PrimitiveType::I8,
1749             ty::IntTy::I16 => PrimitiveType::I16,
1750             ty::IntTy::I32 => PrimitiveType::I32,
1751             ty::IntTy::I64 => PrimitiveType::I64,
1752             ty::IntTy::I128 => PrimitiveType::I128,
1753         }
1754     }
1755 }
1756
1757 impl From<ty::UintTy> for PrimitiveType {
1758     fn from(uint_ty: ty::UintTy) -> PrimitiveType {
1759         match uint_ty {
1760             ty::UintTy::Usize => PrimitiveType::Usize,
1761             ty::UintTy::U8 => PrimitiveType::U8,
1762             ty::UintTy::U16 => PrimitiveType::U16,
1763             ty::UintTy::U32 => PrimitiveType::U32,
1764             ty::UintTy::U64 => PrimitiveType::U64,
1765             ty::UintTy::U128 => PrimitiveType::U128,
1766         }
1767     }
1768 }
1769
1770 impl From<ty::FloatTy> for PrimitiveType {
1771     fn from(float_ty: ty::FloatTy) -> PrimitiveType {
1772         match float_ty {
1773             ty::FloatTy::F32 => PrimitiveType::F32,
1774             ty::FloatTy::F64 => PrimitiveType::F64,
1775         }
1776     }
1777 }
1778
1779 impl From<hir::PrimTy> for PrimitiveType {
1780     fn from(prim_ty: hir::PrimTy) -> PrimitiveType {
1781         match prim_ty {
1782             hir::PrimTy::Int(int_ty) => int_ty.into(),
1783             hir::PrimTy::Uint(uint_ty) => uint_ty.into(),
1784             hir::PrimTy::Float(float_ty) => float_ty.into(),
1785             hir::PrimTy::Str => PrimitiveType::Str,
1786             hir::PrimTy::Bool => PrimitiveType::Bool,
1787             hir::PrimTy::Char => PrimitiveType::Char,
1788         }
1789     }
1790 }
1791
1792 #[derive(Copy, Clone, Debug)]
1793 crate enum Visibility {
1794     Public,
1795     Inherited,
1796     Restricted(DefId),
1797 }
1798
1799 impl Visibility {
1800     crate fn is_public(&self) -> bool {
1801         matches!(self, Visibility::Public)
1802     }
1803 }
1804
1805 #[derive(Clone, Debug)]
1806 crate struct Struct {
1807     crate struct_type: CtorKind,
1808     crate generics: Generics,
1809     crate fields: Vec<Item>,
1810     crate fields_stripped: bool,
1811 }
1812
1813 #[derive(Clone, Debug)]
1814 crate struct Union {
1815     crate generics: Generics,
1816     crate fields: Vec<Item>,
1817     crate fields_stripped: bool,
1818 }
1819
1820 /// This is a more limited form of the standard Struct, different in that
1821 /// it lacks the things most items have (name, id, parameterization). Found
1822 /// only as a variant in an enum.
1823 #[derive(Clone, Debug)]
1824 crate struct VariantStruct {
1825     crate struct_type: CtorKind,
1826     crate fields: Vec<Item>,
1827     crate fields_stripped: bool,
1828 }
1829
1830 #[derive(Clone, Debug)]
1831 crate struct Enum {
1832     crate variants: IndexVec<VariantIdx, Item>,
1833     crate generics: Generics,
1834     crate variants_stripped: bool,
1835 }
1836
1837 #[derive(Clone, Debug)]
1838 crate enum Variant {
1839     CLike,
1840     Tuple(Vec<Type>),
1841     Struct(VariantStruct),
1842 }
1843
1844 /// Small wrapper around `rustc_span::Span` that adds helper methods and enforces calling `source_callsite`.
1845 #[derive(Clone, Debug)]
1846 crate struct Span(rustc_span::Span);
1847
1848 impl Span {
1849     crate fn from_rustc_span(sp: rustc_span::Span) -> Self {
1850         // Get the macro invocation instead of the definition,
1851         // in case the span is result of a macro expansion.
1852         // (See rust-lang/rust#39726)
1853         Self(sp.source_callsite())
1854     }
1855
1856     crate fn dummy() -> Self {
1857         Self(rustc_span::DUMMY_SP)
1858     }
1859
1860     crate fn span(&self) -> rustc_span::Span {
1861         self.0
1862     }
1863
1864     crate fn filename(&self, sess: &Session) -> FileName {
1865         sess.source_map().span_to_filename(self.0)
1866     }
1867
1868     crate fn lo(&self, sess: &Session) -> Loc {
1869         sess.source_map().lookup_char_pos(self.0.lo())
1870     }
1871
1872     crate fn hi(&self, sess: &Session) -> Loc {
1873         sess.source_map().lookup_char_pos(self.0.hi())
1874     }
1875
1876     crate fn cnum(&self, sess: &Session) -> CrateNum {
1877         // FIXME: is there a time when the lo and hi crate would be different?
1878         self.lo(sess).file.cnum
1879     }
1880 }
1881
1882 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1883 crate struct Path {
1884     crate global: bool,
1885     crate res: Res,
1886     crate segments: Vec<PathSegment>,
1887 }
1888
1889 impl Path {
1890     crate fn last(&self) -> Symbol {
1891         self.segments.last().expect("segments were empty").name
1892     }
1893
1894     crate fn last_name(&self) -> SymbolStr {
1895         self.segments.last().expect("segments were empty").name.as_str()
1896     }
1897
1898     crate fn whole_name(&self) -> String {
1899         String::from(if self.global { "::" } else { "" })
1900             + &self.segments.iter().map(|s| s.name.to_string()).collect::<Vec<_>>().join("::")
1901     }
1902 }
1903
1904 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1905 crate enum GenericArg {
1906     Lifetime(Lifetime),
1907     Type(Type),
1908     Const(Constant),
1909 }
1910
1911 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1912 crate enum GenericArgs {
1913     AngleBracketed { args: Vec<GenericArg>, bindings: Vec<TypeBinding> },
1914     Parenthesized { inputs: Vec<Type>, output: Option<Type> },
1915 }
1916
1917 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1918 crate struct PathSegment {
1919     crate name: Symbol,
1920     crate args: GenericArgs,
1921 }
1922
1923 #[derive(Clone, Debug)]
1924 crate struct Typedef {
1925     crate type_: Type,
1926     crate generics: Generics,
1927     /// `type_` can come from either the HIR or from metadata. If it comes from HIR, it may be a type
1928     /// alias instead of the final type. This will always have the final type, regardless of whether
1929     /// `type_` came from HIR or from metadata.
1930     ///
1931     /// If `item_type.is_none()`, `type_` is guarenteed to come from metadata (and therefore hold the
1932     /// final type).
1933     crate item_type: Option<Type>,
1934 }
1935
1936 impl GetDefId for Typedef {
1937     fn def_id(&self) -> Option<DefId> {
1938         self.type_.def_id()
1939     }
1940
1941     fn def_id_full(&self, cache: &Cache) -> Option<DefId> {
1942         self.type_.def_id_full(cache)
1943     }
1944 }
1945
1946 #[derive(Clone, Debug)]
1947 crate struct OpaqueTy {
1948     crate bounds: Vec<GenericBound>,
1949     crate generics: Generics,
1950 }
1951
1952 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1953 crate struct BareFunctionDecl {
1954     crate unsafety: hir::Unsafety,
1955     crate generic_params: Vec<GenericParamDef>,
1956     crate decl: FnDecl,
1957     crate abi: Abi,
1958 }
1959
1960 #[derive(Clone, Debug)]
1961 crate struct Static {
1962     crate type_: Type,
1963     crate mutability: Mutability,
1964     /// It's useful to have the value of a static documented, but I have no
1965     /// desire to represent expressions (that'd basically be all of the AST,
1966     /// which is huge!). So, have a string.
1967     crate expr: String,
1968 }
1969
1970 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
1971 crate struct Constant {
1972     crate type_: Type,
1973     crate expr: String,
1974     crate value: Option<String>,
1975     crate is_literal: bool,
1976 }
1977
1978 #[derive(Clone, Debug)]
1979 crate struct Impl {
1980     crate unsafety: hir::Unsafety,
1981     crate generics: Generics,
1982     crate provided_trait_methods: FxHashSet<Symbol>,
1983     crate trait_: Option<Type>,
1984     crate for_: Type,
1985     crate items: Vec<Item>,
1986     crate negative_polarity: bool,
1987     crate synthetic: bool,
1988     crate blanket_impl: Option<Type>,
1989 }
1990
1991 #[derive(Clone, Debug)]
1992 crate struct Import {
1993     crate kind: ImportKind,
1994     crate source: ImportSource,
1995     crate should_be_displayed: bool,
1996 }
1997
1998 impl Import {
1999     crate fn new_simple(name: Symbol, source: ImportSource, should_be_displayed: bool) -> Self {
2000         Self { kind: ImportKind::Simple(name), source, should_be_displayed }
2001     }
2002
2003     crate fn new_glob(source: ImportSource, should_be_displayed: bool) -> Self {
2004         Self { kind: ImportKind::Glob, source, should_be_displayed }
2005     }
2006 }
2007
2008 #[derive(Clone, Debug)]
2009 crate enum ImportKind {
2010     // use source as str;
2011     Simple(Symbol),
2012     // use source::*;
2013     Glob,
2014 }
2015
2016 #[derive(Clone, Debug)]
2017 crate struct ImportSource {
2018     crate path: Path,
2019     crate did: Option<DefId>,
2020 }
2021
2022 #[derive(Clone, Debug)]
2023 crate struct Macro {
2024     crate source: String,
2025     crate imported_from: Option<Symbol>,
2026 }
2027
2028 #[derive(Clone, Debug)]
2029 crate struct ProcMacro {
2030     crate kind: MacroKind,
2031     crate helpers: Vec<Symbol>,
2032 }
2033
2034 /// An type binding on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
2035 /// `A: Send + Sync` in `Foo<A: Send + Sync>`).
2036 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
2037 crate struct TypeBinding {
2038     crate name: Symbol,
2039     crate kind: TypeBindingKind,
2040 }
2041
2042 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
2043 crate enum TypeBindingKind {
2044     Equality { ty: Type },
2045     Constraint { bounds: Vec<GenericBound> },
2046 }
2047
2048 impl TypeBinding {
2049     crate fn ty(&self) -> &Type {
2050         match self.kind {
2051             TypeBindingKind::Equality { ref ty } => ty,
2052             _ => panic!("expected equality type binding for parenthesized generic args"),
2053         }
2054     }
2055 }