1 use std::cell::RefCell;
2 use std::default::Default;
4 use std::hash::{Hash, Hasher};
5 use std::iter::FromIterator;
6 use std::lazy::SyncOnceCell as OnceCell;
12 use rustc_ast::util::comments::beautify_doc_string;
13 use rustc_ast::{self as ast, AttrStyle};
14 use rustc_ast::{FloatTy, IntTy, UintTy};
15 use rustc_attr::{ConstStability, Deprecation, Stability, StabilityLevel};
16 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
17 use rustc_feature::UnstableFeatures;
19 use rustc_hir::def::Res;
20 use rustc_hir::def_id::{CrateNum, DefId};
21 use rustc_hir::lang_items::LangItem;
22 use rustc_hir::Mutability;
23 use rustc_index::vec::IndexVec;
24 use rustc_middle::ty::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 use smallvec::{smallvec, SmallVec};
34 use crate::clean::cfg::Cfg;
35 use crate::clean::external_path;
36 use crate::clean::inline;
37 use crate::clean::types::Type::{QPath, ResolvedPath};
38 use crate::clean::Clean;
39 use crate::core::DocContext;
41 use crate::formats::cache::cache;
42 use crate::formats::item_type::ItemType;
43 use crate::html::render::cache::ExternalLocation;
46 use self::ItemKind::*;
50 thread_local!(crate static MAX_DEF_ID: RefCell<FxHashMap<CrateNum, DefId>> = Default::default());
52 #[derive(Clone, Debug)]
55 crate version: Option<String>,
57 crate module: Option<Item>,
58 crate externs: Vec<(CrateNum, ExternalCrate)>,
59 crate primitives: Vec<(DefId, PrimitiveType)>,
60 // These are later on moved into `CACHEKEY`, leaving the map empty.
61 // Only here so that they can be filtered through the rustdoc passes.
62 crate external_traits: Rc<RefCell<FxHashMap<DefId, Trait>>>,
63 crate masked_crates: FxHashSet<CrateNum>,
64 crate collapsed: bool,
67 #[derive(Clone, Debug)]
68 crate struct ExternalCrate {
71 crate attrs: Attributes,
72 crate primitives: Vec<(DefId, PrimitiveType)>,
73 crate keywords: Vec<(DefId, Symbol)>,
76 /// Anything with a source location and set of attributes and, optionally, a
77 /// name. That is, anything that can be documented. This doesn't correspond
78 /// directly to the AST's concept of an item; it's a strict superset.
83 /// Not everything has a name. E.g., impls
84 crate name: Option<Symbol>,
85 crate attrs: Attributes,
86 crate visibility: Visibility,
89 crate stability: Option<Stability>,
90 crate deprecation: Option<Deprecation>,
91 crate const_stability: Option<ConstStability>,
94 impl fmt::Debug for Item {
95 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
96 let def_id: &dyn fmt::Debug = if self.is_fake() { &"**FAKE**" } else { &self.def_id };
98 fmt.debug_struct("Item")
99 .field("source", &self.source)
100 .field("name", &self.name)
101 .field("attrs", &self.attrs)
102 .field("kind", &self.kind)
103 .field("visibility", &self.visibility)
104 .field("def_id", def_id)
105 .field("stability", &self.stability)
106 .field("deprecation", &self.deprecation)
112 /// Finds the `doc` attribute as a NameValue and returns the corresponding
114 crate fn doc_value(&self) -> Option<&str> {
115 self.attrs.doc_value()
118 /// Convenience wrapper around [`Self::from_def_id_and_parts`] which converts
119 /// `hir_id` to a [`DefId`]
120 pub fn from_hir_id_and_parts(
122 name: Option<Symbol>,
126 Item::from_def_id_and_parts(cx.tcx.hir().local_def_id(hir_id).to_def_id(), name, kind, cx)
129 pub fn from_def_id_and_parts(
131 name: Option<Symbol>,
135 debug!("name={:?}, def_id={:?}", name, def_id);
137 // `span_if_local()` lies about functions and only gives the span of the function signature
138 let source = def_id.as_local().map_or_else(
139 || cx.tcx.def_span(def_id),
141 let hir = cx.tcx.hir();
142 hir.span_with_body(hir.local_def_id_to_hir_id(local))
150 source: source.clean(cx),
151 attrs: cx.tcx.get_attrs(def_id).clean(cx),
152 visibility: cx.tcx.visibility(def_id).clean(cx),
153 stability: cx.tcx.lookup_stability(def_id).cloned(),
154 deprecation: cx.tcx.lookup_deprecation(def_id),
155 const_stability: cx.tcx.lookup_const_stability(def_id).cloned(),
159 /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
161 crate fn collapsed_doc_value(&self) -> Option<String> {
162 self.attrs.collapsed_doc_value()
165 crate fn links(&self) -> Vec<RenderedLink> {
166 self.attrs.links(&self.def_id.krate)
169 crate fn is_crate(&self) -> bool {
171 StrippedItem(box ModuleItem(Module { is_crate: true, .. }))
172 | ModuleItem(Module { is_crate: true, .. }) => true,
176 crate fn is_mod(&self) -> bool {
177 self.type_() == ItemType::Module
179 crate fn is_trait(&self) -> bool {
180 self.type_() == ItemType::Trait
182 crate fn is_struct(&self) -> bool {
183 self.type_() == ItemType::Struct
185 crate fn is_enum(&self) -> bool {
186 self.type_() == ItemType::Enum
188 crate fn is_variant(&self) -> bool {
189 self.type_() == ItemType::Variant
191 crate fn is_associated_type(&self) -> bool {
192 self.type_() == ItemType::AssocType
194 crate fn is_associated_const(&self) -> bool {
195 self.type_() == ItemType::AssocConst
197 crate fn is_method(&self) -> bool {
198 self.type_() == ItemType::Method
200 crate fn is_ty_method(&self) -> bool {
201 self.type_() == ItemType::TyMethod
203 crate fn is_typedef(&self) -> bool {
204 self.type_() == ItemType::Typedef
206 crate fn is_primitive(&self) -> bool {
207 self.type_() == ItemType::Primitive
209 crate fn is_union(&self) -> bool {
210 self.type_() == ItemType::Union
212 crate fn is_import(&self) -> bool {
213 self.type_() == ItemType::Import
215 crate fn is_extern_crate(&self) -> bool {
216 self.type_() == ItemType::ExternCrate
218 crate fn is_keyword(&self) -> bool {
219 self.type_() == ItemType::Keyword
221 crate fn is_stripped(&self) -> bool {
223 StrippedItem(..) => true,
224 ImportItem(ref i) => !i.should_be_displayed,
228 crate fn has_stripped_fields(&self) -> Option<bool> {
230 StructItem(ref _struct) => Some(_struct.fields_stripped),
231 UnionItem(ref union) => Some(union.fields_stripped),
232 VariantItem(Variant { kind: VariantKind::Struct(ref vstruct) }) => {
233 Some(vstruct.fields_stripped)
239 crate fn stability_class(&self) -> Option<String> {
240 self.stability.as_ref().and_then(|ref s| {
241 let mut classes = Vec::with_capacity(2);
243 if s.level.is_unstable() {
244 classes.push("unstable");
247 // FIXME: what about non-staged API items that are deprecated?
248 if self.deprecation.is_some() {
249 classes.push("deprecated");
252 if !classes.is_empty() { Some(classes.join(" ")) } else { None }
256 crate fn stable_since(&self) -> Option<SymbolStr> {
257 match self.stability?.level {
258 StabilityLevel::Stable { since, .. } => Some(since.as_str()),
259 StabilityLevel::Unstable { .. } => None,
263 crate fn const_stable_since(&self) -> Option<SymbolStr> {
264 match self.const_stability?.level {
265 StabilityLevel::Stable { since, .. } => Some(since.as_str()),
266 StabilityLevel::Unstable { .. } => None,
270 crate fn is_non_exhaustive(&self) -> bool {
271 self.attrs.other_attrs.iter().any(|a| a.has_name(sym::non_exhaustive))
274 /// Returns a documentation-level item type from the item.
275 crate fn type_(&self) -> ItemType {
279 crate fn is_default(&self) -> bool {
281 ItemKind::MethodItem(_, Some(defaultness)) => {
282 defaultness.has_value() && !defaultness.is_final()
288 /// See comments on next_def_id
289 crate fn is_fake(&self) -> bool {
290 MAX_DEF_ID.with(|m| {
291 m.borrow().get(&self.def_id.krate).map(|id| self.def_id >= *id).unwrap_or(false)
296 #[derive(Clone, Debug)]
297 crate enum ItemKind {
298 ExternCrateItem(Symbol, Option<Symbol>),
303 FunctionItem(Function),
305 TypedefItem(Typedef, bool /* is associated type */),
306 OpaqueTyItem(OpaqueTy),
308 ConstantItem(Constant),
310 TraitAliasItem(TraitAlias),
312 /// A method signature only. Used for required methods in traits (ie,
313 /// non-default-methods).
314 TyMethodItem(Function),
315 /// A method with a body.
316 MethodItem(Function, Option<hir::Defaultness>),
317 StructFieldItem(Type),
318 VariantItem(Variant),
319 /// `fn`s from an extern block
320 ForeignFunctionItem(Function),
321 /// `static`s from an extern block
322 ForeignStaticItem(Static),
323 /// `type`s from an extern block
326 ProcMacroItem(ProcMacro),
327 PrimitiveItem(PrimitiveType),
328 AssocConstItem(Type, Option<String>),
329 AssocTypeItem(Vec<GenericBound>, Option<Type>),
330 /// An item that has been stripped by a rustdoc pass
331 StrippedItem(Box<ItemKind>),
336 /// Some items contain others such as structs (for their fields) and Enums
337 /// (for their variants). This method returns those contained items.
338 crate fn inner_items(&self) -> impl Iterator<Item = &Item> {
340 StructItem(s) => s.fields.iter(),
341 UnionItem(u) => u.fields.iter(),
342 VariantItem(Variant { kind: VariantKind::Struct(v) }) => v.fields.iter(),
343 EnumItem(e) => e.variants.iter(),
344 TraitItem(t) => t.items.iter(),
345 ImplItem(i) => i.items.iter(),
346 ModuleItem(m) => m.items.iter(),
347 ExternCrateItem(_, _)
359 | ForeignFunctionItem(_)
360 | ForeignStaticItem(_)
365 | AssocConstItem(_, _)
366 | AssocTypeItem(_, _)
368 | KeywordItem(_) => [].iter(),
372 crate fn is_type_alias(&self) -> bool {
374 ItemKind::TypedefItem(_, _) | ItemKind::AssocTypeItem(_, _) => true,
380 #[derive(Clone, Debug)]
381 crate struct Module {
382 crate items: Vec<Item>,
383 crate is_crate: bool,
386 crate struct ListAttributesIter<'a> {
387 attrs: slice::Iter<'a, ast::Attribute>,
388 current_list: vec::IntoIter<ast::NestedMetaItem>,
392 impl<'a> Iterator for ListAttributesIter<'a> {
393 type Item = ast::NestedMetaItem;
395 fn next(&mut self) -> Option<Self::Item> {
396 if let Some(nested) = self.current_list.next() {
400 for attr in &mut self.attrs {
401 if let Some(list) = attr.meta_item_list() {
402 if attr.has_name(self.name) {
403 self.current_list = list.into_iter();
404 if let Some(nested) = self.current_list.next() {
414 fn size_hint(&self) -> (usize, Option<usize>) {
415 let lower = self.current_list.len();
420 crate trait AttributesExt {
421 /// Finds an attribute as List and returns the list of attributes nested inside.
422 fn lists(&self, name: Symbol) -> ListAttributesIter<'_>;
425 impl AttributesExt for [ast::Attribute] {
426 fn lists(&self, name: Symbol) -> ListAttributesIter<'_> {
427 ListAttributesIter { attrs: self.iter(), current_list: Vec::new().into_iter(), name }
431 crate trait NestedAttributesExt {
432 /// Returns `true` if the attribute list contains a specific `Word`
433 fn has_word(self, word: Symbol) -> bool;
436 impl<I: IntoIterator<Item = ast::NestedMetaItem>> NestedAttributesExt for I {
437 fn has_word(self, word: Symbol) -> bool {
438 self.into_iter().any(|attr| attr.is_word() && attr.has_name(word))
442 /// A portion of documentation, extracted from a `#[doc]` attribute.
444 /// Each variant contains the line number within the complete doc-comment where the fragment
445 /// starts, as well as the Span where the corresponding doc comment or attribute is located.
447 /// Included files are kept separate from inline doc comments so that proper line-number
448 /// information can be given when a doctest fails. Sugared doc comments and "raw" doc comments are
449 /// kept separate because of issue #42760.
450 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
451 crate struct DocFragment {
453 crate span: rustc_span::Span,
454 /// The module this doc-comment came from.
456 /// This allows distinguishing between the original documentation and a pub re-export.
457 /// If it is `None`, the item was not re-exported.
458 crate parent_module: Option<DefId>,
460 crate kind: DocFragmentKind,
463 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
464 crate enum DocFragmentKind {
465 /// A doc fragment created from a `///` or `//!` doc comment.
467 /// A doc fragment created from a "raw" `#[doc=""]` attribute.
469 /// A doc fragment created from a `#[doc(include="filename")]` attribute. Contains both the
470 /// given filename and the file contents.
471 Include { filename: String },
474 impl<'a> FromIterator<&'a DocFragment> for String {
475 fn from_iter<T>(iter: T) -> Self
477 T: IntoIterator<Item = &'a DocFragment>,
479 iter.into_iter().fold(String::new(), |mut acc, frag| {
483 acc.push_str(&frag.doc);
489 #[derive(Clone, Debug, Default)]
490 crate struct Attributes {
491 crate doc_strings: Vec<DocFragment>,
492 crate other_attrs: Vec<ast::Attribute>,
493 crate cfg: Option<Arc<Cfg>>,
494 crate span: Option<rustc_span::Span>,
495 /// map from Rust paths to resolved defs and potential URL fragments
496 crate links: Vec<ItemLink>,
497 crate inner_docs: bool,
500 #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
501 /// A link that has not yet been rendered.
503 /// This link will be turned into a rendered link by [`Attributes::links`]
504 crate struct ItemLink {
505 /// The original link written in the markdown
506 pub(crate) link: String,
507 /// The link text displayed in the HTML.
509 /// This may not be the same as `link` if there was a disambiguator
510 /// in an intra-doc link (e.g. \[`fn@f`\])
511 pub(crate) link_text: String,
512 pub(crate) did: Option<DefId>,
513 /// The url fragment to append to the link
514 pub(crate) fragment: Option<String>,
517 pub struct RenderedLink {
518 /// The text the link was original written as.
520 /// This could potentially include disambiguators and backticks.
521 pub(crate) original_text: String,
522 /// The text to display in the HTML
523 pub(crate) new_text: String,
524 /// The URL to put in the `href`
525 pub(crate) href: String,
529 /// Extracts the content from an attribute `#[doc(cfg(content))]`.
530 crate fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> {
531 use rustc_ast::NestedMetaItem::MetaItem;
533 if let ast::MetaItemKind::List(ref nmis) = mi.kind {
535 if let MetaItem(ref cfg_mi) = nmis[0] {
536 if cfg_mi.has_name(sym::cfg) {
537 if let ast::MetaItemKind::List(ref cfg_nmis) = cfg_mi.kind {
538 if cfg_nmis.len() == 1 {
539 if let MetaItem(ref content_mi) = cfg_nmis[0] {
540 return Some(content_mi);
552 /// Reads a `MetaItem` from within an attribute, looks for whether it is a
553 /// `#[doc(include="file")]`, and returns the filename and contents of the file as loaded from
555 crate fn extract_include(mi: &ast::MetaItem) -> Option<(String, String)> {
556 mi.meta_item_list().and_then(|list| {
558 if meta.has_name(sym::include) {
559 // the actual compiled `#[doc(include="filename")]` gets expanded to
560 // `#[doc(include(file="filename", contents="file contents")]` so we need to
561 // look for that instead
562 return meta.meta_item_list().and_then(|list| {
563 let mut filename: Option<String> = None;
564 let mut contents: Option<String> = None;
567 if it.has_name(sym::file) {
568 if let Some(name) = it.value_str() {
569 filename = Some(name.to_string());
571 } else if it.has_name(sym::contents) {
572 if let Some(docs) = it.value_str() {
573 contents = Some(docs.to_string());
578 if let (Some(filename), Some(contents)) = (filename, contents) {
579 Some((filename, contents))
591 crate fn has_doc_flag(&self, flag: Symbol) -> bool {
592 for attr in &self.other_attrs {
593 if !attr.has_name(sym::doc) {
597 if let Some(items) = attr.meta_item_list() {
598 if items.iter().filter_map(|i| i.meta_item()).any(|it| it.has_name(flag)) {
608 diagnostic: &::rustc_errors::Handler,
609 attrs: &[ast::Attribute],
610 additional_attrs: Option<(&[ast::Attribute], DefId)>,
612 let mut doc_strings = vec![];
614 let mut cfg = Cfg::True;
615 let mut doc_line = 0;
617 let clean_attr = |(attr, parent_module): (&ast::Attribute, _)| {
618 if let Some(value) = attr.doc_str() {
619 trace!("got doc_str={:?}", value);
620 let value = beautify_doc_string(value);
621 let kind = if attr.is_doc_comment() {
622 DocFragmentKind::SugaredDoc
624 DocFragmentKind::RawDoc
628 doc_line += value.lines().count();
629 doc_strings.push(DocFragment {
638 sp = Some(attr.span);
642 if attr.has_name(sym::doc) {
643 if let Some(mi) = attr.meta() {
644 if let Some(cfg_mi) = Attributes::extract_cfg(&mi) {
645 // Extracted #[doc(cfg(...))]
646 match Cfg::parse(cfg_mi) {
647 Ok(new_cfg) => cfg &= new_cfg,
648 Err(e) => diagnostic.span_err(e.span, e.msg),
650 } else if let Some((filename, contents)) = Attributes::extract_include(&mi)
653 doc_line += contents.lines().count();
654 doc_strings.push(DocFragment {
658 kind: DocFragmentKind::Include { filename },
659 parent_module: parent_module,
668 // Additional documentation should be shown before the original documentation
669 let other_attrs = additional_attrs
671 .map(|(attrs, id)| attrs.iter().map(move |attr| (attr, Some(id))))
673 .chain(attrs.iter().map(|attr| (attr, None)))
674 .filter_map(clean_attr)
677 // treat #[target_feature(enable = "feat")] attributes as if they were
678 // #[doc(cfg(target_feature = "feat"))] attributes as well
679 for attr in attrs.lists(sym::target_feature) {
680 if attr.has_name(sym::enable) {
681 if let Some(feat) = attr.value_str() {
682 let meta = attr::mk_name_value_item_str(
683 Ident::with_dummy_span(sym::target_feature),
687 if let Ok(feat_cfg) = Cfg::parse(&meta) {
694 let inner_docs = attrs
696 .find(|a| a.doc_str().is_some())
697 .map_or(true, |a| a.style == AttrStyle::Inner);
702 cfg: if cfg == Cfg::True { None } else { Some(Arc::new(cfg)) },
709 /// Finds the `doc` attribute as a NameValue and returns the corresponding
711 crate fn doc_value(&self) -> Option<&str> {
712 self.doc_strings.first().map(|s| s.doc.as_str())
715 /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
717 crate fn collapsed_doc_value(&self) -> Option<String> {
718 if !self.doc_strings.is_empty() { Some(self.doc_strings.iter().collect()) } else { None }
721 /// Gets links as a vector
723 /// Cache must be populated before call
724 crate fn links(&self, krate: &CrateNum) -> Vec<RenderedLink> {
725 use crate::html::format::href;
726 use crate::html::render::CURRENT_DEPTH;
730 .filter_map(|ItemLink { link: s, link_text, did, fragment }| {
733 if let Some((mut href, ..)) = href(did) {
734 if let Some(ref fragment) = *fragment {
736 href.push_str(fragment);
739 original_text: s.clone(),
740 new_text: link_text.clone(),
748 if let Some(ref fragment) = *fragment {
750 let url = match cache.extern_locations.get(krate) {
751 Some(&(_, _, ExternalLocation::Local)) => {
752 let depth = CURRENT_DEPTH.with(|l| l.get());
755 Some(&(_, _, ExternalLocation::Remote(ref s))) => s.to_string(),
756 Some(&(_, _, ExternalLocation::Unknown)) | None => String::from(
757 // NOTE: intentionally doesn't pass crate name to avoid having
758 // different primitive links between crates
759 if UnstableFeatures::from_environment(None).is_nightly_build() {
760 "https://doc.rust-lang.org/nightly"
762 "https://doc.rust-lang.org"
766 // This is a primitive so the url is done "by hand".
767 let tail = fragment.find('#').unwrap_or_else(|| fragment.len());
769 original_text: s.clone(),
770 new_text: link_text.clone(),
772 "{}{}std/primitive.{}.html{}",
774 if !url.ends_with('/') { "/" } else { "" },
780 panic!("This isn't a primitive?!");
788 crate fn get_doc_aliases(&self) -> FxHashSet<String> {
791 .filter(|a| a.has_name(sym::alias))
792 .filter_map(|a| a.value_str().map(|s| s.to_string()))
793 .filter(|v| !v.is_empty())
794 .collect::<FxHashSet<_>>()
798 impl PartialEq for Attributes {
799 fn eq(&self, rhs: &Self) -> bool {
800 self.doc_strings == rhs.doc_strings
801 && self.cfg == rhs.cfg
802 && self.span == rhs.span
803 && self.links == rhs.links
808 .eq(rhs.other_attrs.iter().map(|attr| attr.id))
812 impl Eq for Attributes {}
814 impl Hash for Attributes {
815 fn hash<H: Hasher>(&self, hasher: &mut H) {
816 self.doc_strings.hash(hasher);
817 self.cfg.hash(hasher);
818 self.span.hash(hasher);
819 self.links.hash(hasher);
820 for attr in &self.other_attrs {
821 attr.id.hash(hasher);
826 impl AttributesExt for Attributes {
827 fn lists(&self, name: Symbol) -> ListAttributesIter<'_> {
828 self.other_attrs.lists(name)
832 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
833 crate enum GenericBound {
834 TraitBound(PolyTrait, hir::TraitBoundModifier),
839 crate fn maybe_sized(cx: &DocContext<'_>) -> GenericBound {
840 let did = cx.tcx.require_lang_item(LangItem::Sized, None);
841 let empty = cx.tcx.intern_substs(&[]);
842 let path = external_path(cx, cx.tcx.item_name(did), Some(did), false, vec![], empty);
843 inline::record_extern_fqn(cx, did, TypeKind::Trait);
844 GenericBound::TraitBound(
846 trait_: ResolvedPath { path, param_names: None, did, is_generic: false },
847 generic_params: Vec::new(),
849 hir::TraitBoundModifier::Maybe,
853 crate fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool {
854 use rustc_hir::TraitBoundModifier as TBM;
855 if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self {
856 if trait_.def_id() == cx.tcx.lang_items().sized_trait() {
863 crate fn get_poly_trait(&self) -> Option<PolyTrait> {
864 if let GenericBound::TraitBound(ref p, _) = *self {
865 return Some(p.clone());
870 crate fn get_trait_type(&self) -> Option<Type> {
871 if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, _) = *self {
879 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
880 crate struct Lifetime(pub Symbol);
883 crate fn get_ref(&self) -> SymbolStr {
887 crate fn statik() -> Lifetime {
888 Lifetime(kw::StaticLifetime)
891 crate fn elided() -> Lifetime {
892 Lifetime(kw::UnderscoreLifetime)
896 #[derive(Clone, Debug)]
897 crate enum WherePredicate {
898 BoundPredicate { ty: Type, bounds: Vec<GenericBound> },
899 RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
900 EqPredicate { lhs: Type, rhs: Type },
903 impl WherePredicate {
904 crate fn get_bounds(&self) -> Option<&[GenericBound]> {
906 WherePredicate::BoundPredicate { ref bounds, .. } => Some(bounds),
907 WherePredicate::RegionPredicate { ref bounds, .. } => Some(bounds),
913 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
914 crate enum GenericParamDefKind {
918 bounds: Vec<GenericBound>,
919 default: Option<Type>,
920 synthetic: Option<hir::SyntheticTyParamKind>,
928 impl GenericParamDefKind {
929 crate fn is_type(&self) -> bool {
931 GenericParamDefKind::Type { .. } => true,
936 // FIXME(eddyb) this either returns the default of a type parameter, or the
937 // type of a `const` parameter. It seems that the intention is to *visit*
938 // any embedded types, but `get_type` seems to be the wrong name for that.
939 crate fn get_type(&self) -> Option<Type> {
941 GenericParamDefKind::Type { default, .. } => default.clone(),
942 GenericParamDefKind::Const { ty, .. } => Some(ty.clone()),
943 GenericParamDefKind::Lifetime => None,
948 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
949 crate struct GenericParamDef {
951 crate kind: GenericParamDefKind,
954 impl GenericParamDef {
955 crate fn is_synthetic_type_param(&self) -> bool {
957 GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => false,
958 GenericParamDefKind::Type { ref synthetic, .. } => synthetic.is_some(),
962 crate fn is_type(&self) -> bool {
966 crate fn get_type(&self) -> Option<Type> {
970 crate fn get_bounds(&self) -> Option<&[GenericBound]> {
972 GenericParamDefKind::Type { ref bounds, .. } => Some(bounds),
978 // maybe use a Generic enum and use Vec<Generic>?
979 #[derive(Clone, Debug, Default)]
980 crate struct Generics {
981 crate params: Vec<GenericParamDef>,
982 crate where_predicates: Vec<WherePredicate>,
985 #[derive(Clone, Debug)]
986 crate struct Function {
988 crate generics: Generics,
989 crate header: hir::FnHeader,
990 crate all_types: Vec<(Type, TypeKind)>,
991 crate ret_types: Vec<(Type, TypeKind)>,
994 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
995 crate struct FnDecl {
996 crate inputs: Arguments,
997 crate output: FnRetTy,
998 crate c_variadic: bool,
999 crate attrs: Attributes,
1003 crate fn self_type(&self) -> Option<SelfTy> {
1004 self.inputs.values.get(0).and_then(|v| v.to_self())
1007 /// Returns the sugared return type for an async function.
1009 /// For example, if the return type is `impl std::future::Future<Output = i32>`, this function
1010 /// will return `i32`.
1014 /// This function will panic if the return type does not match the expected sugaring for async
1016 crate fn sugared_async_return_type(&self) -> FnRetTy {
1017 match &self.output {
1018 FnRetTy::Return(Type::ImplTrait(bounds)) => match &bounds[0] {
1019 GenericBound::TraitBound(PolyTrait { trait_, .. }, ..) => {
1020 let bindings = trait_.bindings().unwrap();
1021 FnRetTy::Return(bindings[0].ty().clone())
1023 _ => panic!("unexpected desugaring of async function"),
1025 _ => panic!("unexpected desugaring of async function"),
1030 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1031 crate struct Arguments {
1032 crate values: Vec<Argument>,
1035 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1036 crate struct Argument {
1041 #[derive(Clone, PartialEq, Debug)]
1044 SelfBorrowed(Option<Lifetime>, Mutability),
1049 crate fn to_self(&self) -> Option<SelfTy> {
1050 if self.name != kw::SelfLower {
1053 if self.type_.is_self_type() {
1054 return Some(SelfValue);
1057 BorrowedRef { ref lifetime, mutability, ref type_ } if type_.is_self_type() => {
1058 Some(SelfBorrowed(lifetime.clone(), mutability))
1060 _ => Some(SelfExplicit(self.type_.clone())),
1065 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1066 crate enum FnRetTy {
1071 impl GetDefId for FnRetTy {
1072 fn def_id(&self) -> Option<DefId> {
1074 Return(ref ty) => ty.def_id(),
1075 DefaultReturn => None,
1080 #[derive(Clone, Debug)]
1081 crate struct Trait {
1082 crate unsafety: hir::Unsafety,
1083 crate items: Vec<Item>,
1084 crate generics: Generics,
1085 crate bounds: Vec<GenericBound>,
1086 crate is_spotlight: bool,
1087 crate is_auto: bool,
1090 #[derive(Clone, Debug)]
1091 crate struct TraitAlias {
1092 crate generics: Generics,
1093 crate bounds: Vec<GenericBound>,
1096 /// A trait reference, which may have higher ranked lifetimes.
1097 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1098 crate struct PolyTrait {
1100 crate generic_params: Vec<GenericParamDef>,
1103 /// A representation of a type suitable for hyperlinking purposes. Ideally, one can get the original
1104 /// type out of the AST/`TyCtxt` given one of these, if more information is needed. Most
1105 /// importantly, it does not preserve mutability or boxes.
1106 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1108 /// Structs/enums/traits (most that would be an `hir::TyKind::Path`).
1111 param_names: Option<Vec<GenericBound>>,
1113 /// `true` if is a `T::Name` path for associated types.
1116 /// For parameterized types, so the consumer of the JSON don't go
1117 /// looking for types which don't exist anywhere.
1119 /// Primitives are the fixed-size numeric types (plus int/usize/float), char,
1120 /// arrays, slices, and tuples.
1121 Primitive(PrimitiveType),
1122 /// `extern "ABI" fn`
1123 BareFunction(Box<BareFunctionDecl>),
1126 Array(Box<Type>, String),
1128 RawPointer(Mutability, Box<Type>),
1130 lifetime: Option<Lifetime>,
1131 mutability: Mutability,
1135 // `<Type as Trait>::Name`
1138 self_type: Box<Type>,
1145 // `impl TraitA + TraitB + ...`
1146 ImplTrait(Vec<GenericBound>),
1149 #[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)]
1150 /// N.B. this has to be different from `hir::PrimTy` because it also includes types that aren't
1151 /// paths, like `Unit`.
1152 crate enum PrimitiveType {
1180 #[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)]
1181 crate enum TypeKind {
1198 crate trait GetDefId {
1199 fn def_id(&self) -> Option<DefId>;
1202 impl<T: GetDefId> GetDefId for Option<T> {
1203 fn def_id(&self) -> Option<DefId> {
1204 self.as_ref().and_then(|d| d.def_id())
1209 crate fn primitive_type(&self) -> Option<PrimitiveType> {
1211 Primitive(p) | BorrowedRef { type_: box Primitive(p), .. } => Some(p),
1212 Slice(..) | BorrowedRef { type_: box Slice(..), .. } => Some(PrimitiveType::Slice),
1213 Array(..) | BorrowedRef { type_: box Array(..), .. } => Some(PrimitiveType::Array),
1216 Some(PrimitiveType::Unit)
1218 Some(PrimitiveType::Tuple)
1221 RawPointer(..) => Some(PrimitiveType::RawPointer),
1222 BorrowedRef { type_: box Generic(..), .. } => Some(PrimitiveType::Reference),
1223 BareFunction(..) => Some(PrimitiveType::Fn),
1224 Never => Some(PrimitiveType::Never),
1229 crate fn is_generic(&self) -> bool {
1231 ResolvedPath { is_generic, .. } => is_generic,
1236 crate fn is_self_type(&self) -> bool {
1238 Generic(name) => name == kw::SelfUpper,
1243 crate fn generics(&self) -> Option<Vec<Type>> {
1245 ResolvedPath { ref path, .. } => path.segments.last().and_then(|seg| {
1246 if let GenericArgs::AngleBracketed { ref args, .. } = seg.args {
1249 .filter_map(|arg| match arg {
1250 GenericArg::Type(ty) => Some(ty.clone()),
1263 crate fn bindings(&self) -> Option<&[TypeBinding]> {
1265 ResolvedPath { ref path, .. } => path.segments.last().and_then(|seg| {
1266 if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args {
1276 crate fn is_full_generic(&self) -> bool {
1278 Type::Generic(_) => true,
1283 crate fn projection(&self) -> Option<(&Type, DefId, Symbol)> {
1284 let (self_, trait_, name) = match self {
1285 QPath { ref self_type, ref trait_, name } => (self_type, trait_, name),
1288 let trait_did = match **trait_ {
1289 ResolvedPath { did, .. } => did,
1292 Some((&self_, trait_did, *name))
1296 impl GetDefId for Type {
1297 fn def_id(&self) -> Option<DefId> {
1299 ResolvedPath { did, .. } => Some(did),
1300 Primitive(p) => cache().primitive_locations.get(&p).cloned(),
1301 BorrowedRef { type_: box Generic(..), .. } => {
1302 Primitive(PrimitiveType::Reference).def_id()
1304 BorrowedRef { ref type_, .. } => type_.def_id(),
1307 Primitive(PrimitiveType::Unit).def_id()
1309 Primitive(PrimitiveType::Tuple).def_id()
1312 BareFunction(..) => Primitive(PrimitiveType::Fn).def_id(),
1313 Never => Primitive(PrimitiveType::Never).def_id(),
1314 Slice(..) => Primitive(PrimitiveType::Slice).def_id(),
1315 Array(..) => Primitive(PrimitiveType::Array).def_id(),
1316 RawPointer(..) => Primitive(PrimitiveType::RawPointer).def_id(),
1317 QPath { ref self_type, .. } => self_type.def_id(),
1323 impl PrimitiveType {
1324 crate fn from_hir(prim: hir::PrimTy) -> PrimitiveType {
1326 hir::PrimTy::Int(IntTy::Isize) => PrimitiveType::Isize,
1327 hir::PrimTy::Int(IntTy::I8) => PrimitiveType::I8,
1328 hir::PrimTy::Int(IntTy::I16) => PrimitiveType::I16,
1329 hir::PrimTy::Int(IntTy::I32) => PrimitiveType::I32,
1330 hir::PrimTy::Int(IntTy::I64) => PrimitiveType::I64,
1331 hir::PrimTy::Int(IntTy::I128) => PrimitiveType::I128,
1332 hir::PrimTy::Uint(UintTy::Usize) => PrimitiveType::Usize,
1333 hir::PrimTy::Uint(UintTy::U8) => PrimitiveType::U8,
1334 hir::PrimTy::Uint(UintTy::U16) => PrimitiveType::U16,
1335 hir::PrimTy::Uint(UintTy::U32) => PrimitiveType::U32,
1336 hir::PrimTy::Uint(UintTy::U64) => PrimitiveType::U64,
1337 hir::PrimTy::Uint(UintTy::U128) => PrimitiveType::U128,
1338 hir::PrimTy::Float(FloatTy::F32) => PrimitiveType::F32,
1339 hir::PrimTy::Float(FloatTy::F64) => PrimitiveType::F64,
1340 hir::PrimTy::Str => PrimitiveType::Str,
1341 hir::PrimTy::Bool => PrimitiveType::Bool,
1342 hir::PrimTy::Char => PrimitiveType::Char,
1346 crate fn from_symbol(s: Symbol) -> Option<PrimitiveType> {
1348 sym::isize => Some(PrimitiveType::Isize),
1349 sym::i8 => Some(PrimitiveType::I8),
1350 sym::i16 => Some(PrimitiveType::I16),
1351 sym::i32 => Some(PrimitiveType::I32),
1352 sym::i64 => Some(PrimitiveType::I64),
1353 sym::i128 => Some(PrimitiveType::I128),
1354 sym::usize => Some(PrimitiveType::Usize),
1355 sym::u8 => Some(PrimitiveType::U8),
1356 sym::u16 => Some(PrimitiveType::U16),
1357 sym::u32 => Some(PrimitiveType::U32),
1358 sym::u64 => Some(PrimitiveType::U64),
1359 sym::u128 => Some(PrimitiveType::U128),
1360 sym::bool => Some(PrimitiveType::Bool),
1361 sym::char => Some(PrimitiveType::Char),
1362 sym::str => Some(PrimitiveType::Str),
1363 sym::f32 => Some(PrimitiveType::F32),
1364 sym::f64 => Some(PrimitiveType::F64),
1365 sym::array => Some(PrimitiveType::Array),
1366 sym::slice => Some(PrimitiveType::Slice),
1367 sym::tuple => Some(PrimitiveType::Tuple),
1368 sym::unit => Some(PrimitiveType::Unit),
1369 sym::pointer => Some(PrimitiveType::RawPointer),
1370 sym::reference => Some(PrimitiveType::Reference),
1371 kw::Fn => Some(PrimitiveType::Fn),
1372 sym::never => Some(PrimitiveType::Never),
1377 crate fn as_str(&self) -> &'static str {
1378 use self::PrimitiveType::*;
1401 RawPointer => "pointer",
1402 Reference => "reference",
1408 crate fn impls(&self, tcx: TyCtxt<'_>) -> &'static SmallVec<[DefId; 4]> {
1409 Self::all_impls(tcx).get(self).expect("missing impl for primitive type")
1412 crate fn all_impls(tcx: TyCtxt<'_>) -> &'static FxHashMap<PrimitiveType, SmallVec<[DefId; 4]>> {
1413 static CELL: OnceCell<FxHashMap<PrimitiveType, SmallVec<[DefId; 4]>>> = OnceCell::new();
1415 CELL.get_or_init(move || {
1416 use self::PrimitiveType::*;
1418 /// A macro to create a FxHashMap.
1423 /// let letters = map!{"a" => "b", "c" => "d"};
1426 /// Trailing commas are allowed.
1427 /// Commas between elements are required (even if the expression is a block).
1429 ($( $key: expr => $val: expr ),* $(,)*) => {{
1430 let mut map = ::rustc_data_structures::fx::FxHashMap::default();
1431 $( map.insert($key, $val); )*
1436 let single = |a: Option<DefId>| a.into_iter().collect();
1437 let both = |a: Option<DefId>, b: Option<DefId>| -> SmallVec<_> {
1438 a.into_iter().chain(b).collect()
1441 let lang_items = tcx.lang_items();
1443 Isize => single(lang_items.isize_impl()),
1444 I8 => single(lang_items.i8_impl()),
1445 I16 => single(lang_items.i16_impl()),
1446 I32 => single(lang_items.i32_impl()),
1447 I64 => single(lang_items.i64_impl()),
1448 I128 => single(lang_items.i128_impl()),
1449 Usize => single(lang_items.usize_impl()),
1450 U8 => single(lang_items.u8_impl()),
1451 U16 => single(lang_items.u16_impl()),
1452 U32 => single(lang_items.u32_impl()),
1453 U64 => single(lang_items.u64_impl()),
1454 U128 => single(lang_items.u128_impl()),
1455 F32 => both(lang_items.f32_impl(), lang_items.f32_runtime_impl()),
1456 F64 => both(lang_items.f64_impl(), lang_items.f64_runtime_impl()),
1457 Char => single(lang_items.char_impl()),
1458 Bool => single(lang_items.bool_impl()),
1459 Str => both(lang_items.str_impl(), lang_items.str_alloc_impl()),
1464 .chain(lang_items.slice_u8_impl())
1465 .chain(lang_items.slice_alloc_impl())
1466 .chain(lang_items.slice_u8_alloc_impl())
1469 Array => single(lang_items.array_impl()),
1470 Tuple => smallvec![],
1471 Unit => smallvec![],
1476 .chain(lang_items.mut_ptr_impl())
1477 .chain(lang_items.const_slice_ptr_impl())
1478 .chain(lang_items.mut_slice_ptr_impl())
1481 Reference => smallvec![],
1483 Never => smallvec![],
1488 crate fn to_url_str(&self) -> &'static str {
1492 crate fn as_sym(&self) -> Symbol {
1493 use PrimitiveType::*;
1495 Isize => sym::isize,
1501 Usize => sym::usize,
1512 Array => sym::array,
1513 Slice => sym::slice,
1514 Tuple => sym::tuple,
1516 RawPointer => sym::pointer,
1517 Reference => sym::reference,
1519 Never => sym::never,
1524 impl From<ast::IntTy> for PrimitiveType {
1525 fn from(int_ty: ast::IntTy) -> PrimitiveType {
1527 ast::IntTy::Isize => PrimitiveType::Isize,
1528 ast::IntTy::I8 => PrimitiveType::I8,
1529 ast::IntTy::I16 => PrimitiveType::I16,
1530 ast::IntTy::I32 => PrimitiveType::I32,
1531 ast::IntTy::I64 => PrimitiveType::I64,
1532 ast::IntTy::I128 => PrimitiveType::I128,
1537 impl From<ast::UintTy> for PrimitiveType {
1538 fn from(uint_ty: ast::UintTy) -> PrimitiveType {
1540 ast::UintTy::Usize => PrimitiveType::Usize,
1541 ast::UintTy::U8 => PrimitiveType::U8,
1542 ast::UintTy::U16 => PrimitiveType::U16,
1543 ast::UintTy::U32 => PrimitiveType::U32,
1544 ast::UintTy::U64 => PrimitiveType::U64,
1545 ast::UintTy::U128 => PrimitiveType::U128,
1550 impl From<ast::FloatTy> for PrimitiveType {
1551 fn from(float_ty: ast::FloatTy) -> PrimitiveType {
1553 ast::FloatTy::F32 => PrimitiveType::F32,
1554 ast::FloatTy::F64 => PrimitiveType::F64,
1559 impl From<hir::PrimTy> for PrimitiveType {
1560 fn from(prim_ty: hir::PrimTy) -> PrimitiveType {
1562 hir::PrimTy::Int(int_ty) => int_ty.into(),
1563 hir::PrimTy::Uint(uint_ty) => uint_ty.into(),
1564 hir::PrimTy::Float(float_ty) => float_ty.into(),
1565 hir::PrimTy::Str => PrimitiveType::Str,
1566 hir::PrimTy::Bool => PrimitiveType::Bool,
1567 hir::PrimTy::Char => PrimitiveType::Char,
1572 #[derive(Clone, Debug)]
1573 crate enum Visibility {
1576 Restricted(DefId, rustc_hir::definitions::DefPath),
1580 crate fn is_public(&self) -> bool {
1581 matches!(self, Visibility::Public)
1585 #[derive(Clone, Debug)]
1586 crate struct Struct {
1587 crate struct_type: doctree::StructType,
1588 crate generics: Generics,
1589 crate fields: Vec<Item>,
1590 crate fields_stripped: bool,
1593 #[derive(Clone, Debug)]
1594 crate struct Union {
1595 crate struct_type: doctree::StructType,
1596 crate generics: Generics,
1597 crate fields: Vec<Item>,
1598 crate fields_stripped: bool,
1601 /// This is a more limited form of the standard Struct, different in that
1602 /// it lacks the things most items have (name, id, parameterization). Found
1603 /// only as a variant in an enum.
1604 #[derive(Clone, Debug)]
1605 crate struct VariantStruct {
1606 crate struct_type: doctree::StructType,
1607 crate fields: Vec<Item>,
1608 crate fields_stripped: bool,
1611 #[derive(Clone, Debug)]
1613 crate variants: IndexVec<VariantIdx, Item>,
1614 crate generics: Generics,
1615 crate variants_stripped: bool,
1618 #[derive(Clone, Debug)]
1619 crate struct Variant {
1620 crate kind: VariantKind,
1623 #[derive(Clone, Debug)]
1624 crate enum VariantKind {
1627 Struct(VariantStruct),
1630 /// Small wrapper around `rustc_span::Span` that adds helper methods and enforces calling `source_callsite`.
1631 #[derive(Clone, Debug)]
1632 crate struct Span(rustc_span::Span);
1635 crate fn from_rustc_span(sp: rustc_span::Span) -> Self {
1636 // Get the macro invocation instead of the definition,
1637 // in case the span is result of a macro expansion.
1638 // (See rust-lang/rust#39726)
1639 Self(sp.source_callsite())
1642 crate fn dummy() -> Self {
1643 Self(rustc_span::DUMMY_SP)
1646 crate fn span(&self) -> rustc_span::Span {
1650 crate fn filename(&self, sess: &Session) -> FileName {
1651 sess.source_map().span_to_filename(self.0)
1654 crate fn lo(&self, sess: &Session) -> Loc {
1655 sess.source_map().lookup_char_pos(self.0.lo())
1658 crate fn hi(&self, sess: &Session) -> Loc {
1659 sess.source_map().lookup_char_pos(self.0.hi())
1662 crate fn cnum(&self, sess: &Session) -> CrateNum {
1663 // FIXME: is there a time when the lo and hi crate would be different?
1664 self.lo(sess).file.cnum
1668 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1672 crate segments: Vec<PathSegment>,
1676 crate fn last(&self) -> Symbol {
1677 self.segments.last().expect("segments were empty").name
1680 crate fn last_name(&self) -> SymbolStr {
1681 self.segments.last().expect("segments were empty").name.as_str()
1684 crate fn whole_name(&self) -> String {
1685 String::from(if self.global { "::" } else { "" })
1686 + &self.segments.iter().map(|s| s.name.to_string()).collect::<Vec<_>>().join("::")
1690 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1691 crate enum GenericArg {
1697 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1698 crate enum GenericArgs {
1699 AngleBracketed { args: Vec<GenericArg>, bindings: Vec<TypeBinding> },
1700 Parenthesized { inputs: Vec<Type>, output: Option<Type> },
1703 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1704 crate struct PathSegment {
1706 crate args: GenericArgs,
1709 #[derive(Clone, Debug)]
1710 crate struct Typedef {
1712 crate generics: Generics,
1713 // Type of target item.
1714 crate item_type: Option<Type>,
1717 impl GetDefId for Typedef {
1718 fn def_id(&self) -> Option<DefId> {
1723 #[derive(Clone, Debug)]
1724 crate struct OpaqueTy {
1725 crate bounds: Vec<GenericBound>,
1726 crate generics: Generics,
1729 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1730 crate struct BareFunctionDecl {
1731 crate unsafety: hir::Unsafety,
1732 crate generic_params: Vec<GenericParamDef>,
1737 #[derive(Clone, Debug)]
1738 crate struct Static {
1740 crate mutability: Mutability,
1741 /// It's useful to have the value of a static documented, but I have no
1742 /// desire to represent expressions (that'd basically be all of the AST,
1743 /// which is huge!). So, have a string.
1747 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
1748 crate struct Constant {
1751 crate value: Option<String>,
1752 crate is_literal: bool,
1755 #[derive(Clone, PartialEq, Debug)]
1756 crate enum ImplPolarity {
1761 #[derive(Clone, Debug)]
1763 crate unsafety: hir::Unsafety,
1764 crate generics: Generics,
1765 crate provided_trait_methods: FxHashSet<Symbol>,
1766 crate trait_: Option<Type>,
1768 crate items: Vec<Item>,
1769 crate polarity: Option<ImplPolarity>,
1770 crate synthetic: bool,
1771 crate blanket_impl: Option<Type>,
1774 #[derive(Clone, Debug)]
1775 crate struct Import {
1776 crate kind: ImportKind,
1777 crate source: ImportSource,
1778 crate should_be_displayed: bool,
1782 crate fn new_simple(name: Symbol, source: ImportSource, should_be_displayed: bool) -> Self {
1783 Self { kind: ImportKind::Simple(name), source, should_be_displayed }
1786 crate fn new_glob(source: ImportSource, should_be_displayed: bool) -> Self {
1787 Self { kind: ImportKind::Glob, source, should_be_displayed }
1791 #[derive(Clone, Debug)]
1792 crate enum ImportKind {
1793 // use source as str;
1799 #[derive(Clone, Debug)]
1800 crate struct ImportSource {
1802 crate did: Option<DefId>,
1805 #[derive(Clone, Debug)]
1806 crate struct Macro {
1807 crate source: String,
1808 crate imported_from: Option<Symbol>,
1811 #[derive(Clone, Debug)]
1812 crate struct ProcMacro {
1813 crate kind: MacroKind,
1814 crate helpers: Vec<Symbol>,
1817 /// An type binding on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
1818 /// `A: Send + Sync` in `Foo<A: Send + Sync>`).
1819 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1820 crate struct TypeBinding {
1822 crate kind: TypeBindingKind,
1825 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
1826 crate enum TypeBindingKind {
1827 Equality { ty: Type },
1828 Constraint { bounds: Vec<GenericBound> },
1832 crate fn ty(&self) -> &Type {
1834 TypeBindingKind::Equality { ref ty } => ty,
1835 _ => panic!("expected equality type binding for parenthesized generic args"),