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