]> git.lizzy.rs Git - rust.git/blob - src/rustdoc-json-types/lib.rs
4bc91fc4030e228dcd86b20a544e2b5db4ed3807
[rust.git] / src / rustdoc-json-types / lib.rs
1 //! Rustdoc's JSON output interface
2 //!
3 //! These types are the public API exposed through the `--output-format json` flag. The [`Crate`]
4 //! struct is the root of the JSON blob and all other items are contained within.
5
6 use std::collections::HashMap;
7 use std::path::PathBuf;
8
9 use serde::{Deserialize, Serialize};
10
11 /// rustdoc format-version.
12 pub const FORMAT_VERSION: u32 = 22;
13
14 /// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
15 /// about the language items in the local crate, as well as info about external items to allow
16 /// tools to find or link to them.
17 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
18 pub struct Crate {
19     /// The id of the root [`Module`] item of the local crate.
20     pub root: Id,
21     /// The version string given to `--crate-version`, if any.
22     pub crate_version: Option<String>,
23     /// Whether or not the output includes private items.
24     pub includes_private: bool,
25     /// A collection of all items in the local crate as well as some external traits and their
26     /// items that are referenced locally.
27     pub index: HashMap<Id, Item>,
28     /// Maps IDs to fully qualified paths and other info helpful for generating links.
29     pub paths: HashMap<Id, ItemSummary>,
30     /// Maps `crate_id` of items to a crate name and html_root_url if it exists.
31     pub external_crates: HashMap<u32, ExternalCrate>,
32     /// A single version number to be used in the future when making backwards incompatible changes
33     /// to the JSON output.
34     pub format_version: u32,
35 }
36
37 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
38 pub struct ExternalCrate {
39     pub name: String,
40     pub html_root_url: Option<String>,
41 }
42
43 /// For external (not defined in the local crate) items, you don't get the same level of
44 /// information. This struct should contain enough to generate a link/reference to the item in
45 /// question, or can be used by a tool that takes the json output of multiple crates to find
46 /// the actual item definition with all the relevant info.
47 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
48 pub struct ItemSummary {
49     /// Can be used to look up the name and html_root_url of the crate this item came from in the
50     /// `external_crates` map.
51     pub crate_id: u32,
52     /// The list of path components for the fully qualified path of this item (e.g.
53     /// `["std", "io", "lazy", "Lazy"]` for `std::io::lazy::Lazy`).
54     ///
55     /// Note that items can appear in multiple paths, and the one chosen is implementation
56     /// defined. Currenty, this is the full path to where the item was defined. Eg
57     /// [`String`] is currently `["alloc", "string", "String"]` and [`HashMap`] is
58     /// `["std", "collections", "hash", "map", "HashMap"]`, but this is subject to change.
59     pub path: Vec<String>,
60     /// Whether this item is a struct, trait, macro, etc.
61     pub kind: ItemKind,
62 }
63
64 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
65 pub struct Item {
66     /// The unique identifier of this item. Can be used to find this item in various mappings.
67     pub id: Id,
68     /// This can be used as a key to the `external_crates` map of [`Crate`] to see which crate
69     /// this item came from.
70     pub crate_id: u32,
71     /// Some items such as impls don't have names.
72     pub name: Option<String>,
73     /// The source location of this item (absent if it came from a macro expansion or inline
74     /// assembly).
75     pub span: Option<Span>,
76     /// By default all documented items are public, but you can tell rustdoc to output private items
77     /// so this field is needed to differentiate.
78     pub visibility: Visibility,
79     /// The full markdown docstring of this item. Absent if there is no documentation at all,
80     /// Some("") if there is some documentation but it is empty (EG `#[doc = ""]`).
81     pub docs: Option<String>,
82     /// This mapping resolves [intra-doc links](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md) from the docstring to their IDs
83     pub links: HashMap<String, Id>,
84     /// Stringified versions of the attributes on this item (e.g. `"#[inline]"`)
85     pub attrs: Vec<String>,
86     pub deprecation: Option<Deprecation>,
87     #[serde(flatten)]
88     pub inner: ItemEnum,
89 }
90
91 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
92 pub struct Span {
93     /// The path to the source file for this span relative to the path `rustdoc` was invoked with.
94     pub filename: PathBuf,
95     /// Zero indexed Line and Column of the first character of the `Span`
96     pub begin: (usize, usize),
97     /// Zero indexed Line and Column of the last character of the `Span`
98     pub end: (usize, usize),
99 }
100
101 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
102 pub struct Deprecation {
103     pub since: Option<String>,
104     pub note: Option<String>,
105 }
106
107 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
108 #[serde(rename_all = "snake_case")]
109 pub enum Visibility {
110     Public,
111     /// For the most part items are private by default. The exceptions are associated items of
112     /// public traits and variants of public enums.
113     Default,
114     Crate,
115     /// For `pub(in path)` visibility. `parent` is the module it's restricted to and `path` is how
116     /// that module was referenced (like `"super::super"` or `"crate::foo::bar"`).
117     Restricted {
118         parent: Id,
119         path: String,
120     },
121 }
122
123 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
124 pub struct DynTrait {
125     /// All the traits implemented. One of them is the vtable, and the rest must be auto traits.
126     pub traits: Vec<PolyTrait>,
127     /// The lifetime of the whole dyn object
128     /// ```text
129     /// dyn Debug + 'static
130     ///             ^^^^^^^
131     ///             |
132     ///             this part
133     /// ```
134     pub lifetime: Option<String>,
135 }
136
137 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
138 /// A trait and potential HRTBs
139 pub struct PolyTrait {
140     #[serde(rename = "trait")]
141     pub trait_: Path,
142     /// Used for Higher-Rank Trait Bounds (HRTBs)
143     /// ```text
144     /// dyn for<'a> Fn() -> &'a i32"
145     ///     ^^^^^^^
146     ///       |
147     ///       this part
148     /// ```
149     pub generic_params: Vec<GenericParamDef>,
150 }
151
152 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
153 #[serde(rename_all = "snake_case")]
154 pub enum GenericArgs {
155     /// <'a, 32, B: Copy, C = u32>
156     AngleBracketed { args: Vec<GenericArg>, bindings: Vec<TypeBinding> },
157     /// Fn(A, B) -> C
158     Parenthesized { inputs: Vec<Type>, output: Option<Type> },
159 }
160
161 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
162 #[serde(rename_all = "snake_case")]
163 pub enum GenericArg {
164     Lifetime(String),
165     Type(Type),
166     Const(Constant),
167     Infer,
168 }
169
170 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
171 pub struct Constant {
172     #[serde(rename = "type")]
173     pub type_: Type,
174     pub expr: String,
175     pub value: Option<String>,
176     pub is_literal: bool,
177 }
178
179 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
180 pub struct TypeBinding {
181     pub name: String,
182     pub args: GenericArgs,
183     pub binding: TypeBindingKind,
184 }
185
186 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
187 #[serde(rename_all = "snake_case")]
188 pub enum TypeBindingKind {
189     Equality(Term),
190     Constraint(Vec<GenericBound>),
191 }
192
193 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
194 pub struct Id(pub String);
195
196 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
197 #[serde(rename_all = "snake_case")]
198 pub enum ItemKind {
199     Module,
200     ExternCrate,
201     Import,
202     Struct,
203     StructField,
204     Union,
205     Enum,
206     Variant,
207     Function,
208     Typedef,
209     OpaqueTy,
210     Constant,
211     Trait,
212     TraitAlias,
213     Method,
214     Impl,
215     Static,
216     ForeignType,
217     Macro,
218     ProcAttribute,
219     ProcDerive,
220     AssocConst,
221     AssocType,
222     Primitive,
223     Keyword,
224 }
225
226 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
227 #[serde(tag = "kind", content = "inner", rename_all = "snake_case")]
228 pub enum ItemEnum {
229     Module(Module),
230     ExternCrate {
231         name: String,
232         rename: Option<String>,
233     },
234     Import(Import),
235
236     Union(Union),
237     Struct(Struct),
238     StructField(Type),
239     Enum(Enum),
240     Variant(Variant),
241
242     Function(Function),
243
244     Trait(Trait),
245     TraitAlias(TraitAlias),
246     Method(Method),
247     Impl(Impl),
248
249     Typedef(Typedef),
250     OpaqueTy(OpaqueTy),
251     Constant(Constant),
252
253     Static(Static),
254
255     /// `type`s from an extern block
256     ForeignType,
257
258     /// Declarative macro_rules! macro
259     Macro(String),
260     ProcMacro(ProcMacro),
261
262     Primitive(Primitive),
263
264     AssocConst {
265         #[serde(rename = "type")]
266         type_: Type,
267         /// e.g. `const X: usize = 5;`
268         default: Option<String>,
269     },
270     AssocType {
271         generics: Generics,
272         bounds: Vec<GenericBound>,
273         /// e.g. `type X = usize;`
274         default: Option<Type>,
275     },
276 }
277
278 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
279 pub struct Module {
280     pub is_crate: bool,
281     pub items: Vec<Id>,
282     /// If `true`, this module is not part of the public API, but it contains
283     /// items that are re-exported as public API.
284     pub is_stripped: bool,
285 }
286
287 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
288 pub struct Union {
289     pub generics: Generics,
290     pub fields_stripped: bool,
291     pub fields: Vec<Id>,
292     pub impls: Vec<Id>,
293 }
294
295 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
296 pub struct Struct {
297     pub kind: StructKind,
298     pub generics: Generics,
299     pub impls: Vec<Id>,
300 }
301
302 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
303 #[serde(rename_all = "snake_case")]
304 pub enum StructKind {
305     /// A struct with no fields and no parentheses.
306     ///
307     /// ```rust
308     /// pub struct Unit;
309     /// ```
310     Unit,
311     /// A struct with unnamed fields.
312     ///
313     /// ```rust
314     /// pub struct TupleStruct(i32);
315     /// pub struct EmptyTupleStruct();
316     /// ```
317     ///
318     /// All [`Id`]'s will point to [`ItemEnum::StructField`]. Private and
319     /// `#[doc(hidden)]` fields will be given as `None`
320     Tuple(Vec<Option<Id>>),
321     /// A struct with nammed fields.
322     ///
323     /// ```rust
324     /// pub struct PlainStruct { x: i32 }
325     /// pub struct EmptyPlainStruct {}
326     /// ```
327     Plain { fields: Vec<Id>, fields_stripped: bool },
328 }
329
330 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
331 pub struct Enum {
332     pub generics: Generics,
333     pub variants_stripped: bool,
334     pub variants: Vec<Id>,
335     pub impls: Vec<Id>,
336 }
337
338 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
339 #[serde(rename_all = "snake_case")]
340 #[serde(tag = "variant_kind", content = "variant_inner")]
341 pub enum Variant {
342     /// A variant with no parentheses, and possible discriminant.
343     ///
344     /// ```rust
345     /// enum Demo {
346     ///     PlainVariant,
347     ///     PlainWithDiscriminant = 1,
348     /// }
349     /// ```
350     Plain(Option<Discriminant>),
351     /// A variant with unnamed fields.
352     ///
353     /// Unlike most of json, `#[doc(hidden)]` fields will be given as `None`
354     /// instead of being ommited, because order matters.
355     ///
356     /// ```rust
357     /// enum Demo {
358     ///     TupleVariant(i32),
359     ///     EmptyTupleVariant(),
360     /// }
361     /// ```
362     Tuple(Vec<Option<Id>>),
363     /// A variant with named fields.
364     ///
365     /// ```rust
366     /// enum Demo {
367     ///     StructVariant { x: i32 },
368     ///     EmptyStructVariant {},
369     /// }
370     /// ```
371     Struct { fields: Vec<Id>, fields_stripped: bool },
372 }
373
374 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
375 pub struct Discriminant {
376     /// The expression that produced the discriminant.
377     ///
378     /// Unlike `value`, this preserves the original formatting (eg suffixes,
379     /// hexadecimal, and underscores), making it unsuitable to be machine
380     /// interpreted.
381     ///
382     /// In some cases, when the value is to complex, this may be `"{ _ }"`.
383     /// When this occurs is unstable, and may change without notice.
384     pub expr: String,
385     /// The numerical value of the discriminant. Stored as a string due to
386     /// JSON's poor support for large integers, and the fact that it would need
387     /// to store from [`i128::MIN`] to [`u128::MAX`].
388     pub value: String,
389 }
390
391 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
392 pub struct Header {
393     #[serde(rename = "const")]
394     pub const_: bool,
395     #[serde(rename = "unsafe")]
396     pub unsafe_: bool,
397     #[serde(rename = "async")]
398     pub async_: bool,
399     pub abi: Abi,
400 }
401
402 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
403 pub enum Abi {
404     // We only have a concrete listing here for stable ABI's because their are so many
405     // See rustc_ast_passes::feature_gate::PostExpansionVisitor::check_abi for the list
406     Rust,
407     C { unwind: bool },
408     Cdecl { unwind: bool },
409     Stdcall { unwind: bool },
410     Fastcall { unwind: bool },
411     Aapcs { unwind: bool },
412     Win64 { unwind: bool },
413     SysV64 { unwind: bool },
414     System { unwind: bool },
415     Other(String),
416 }
417
418 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
419 pub struct Function {
420     pub decl: FnDecl,
421     pub generics: Generics,
422     pub header: Header,
423 }
424
425 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
426 pub struct Method {
427     pub decl: FnDecl,
428     pub generics: Generics,
429     pub header: Header,
430     pub has_body: bool,
431 }
432
433 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
434 pub struct Generics {
435     pub params: Vec<GenericParamDef>,
436     pub where_predicates: Vec<WherePredicate>,
437 }
438
439 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
440 pub struct GenericParamDef {
441     pub name: String,
442     pub kind: GenericParamDefKind,
443 }
444
445 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
446 #[serde(rename_all = "snake_case")]
447 pub enum GenericParamDefKind {
448     Lifetime {
449         outlives: Vec<String>,
450     },
451     Type {
452         bounds: Vec<GenericBound>,
453         default: Option<Type>,
454         /// This is normally `false`, which means that this generic parameter is
455         /// declared in the Rust source text.
456         ///
457         /// If it is `true`, this generic parameter has been introduced by the
458         /// compiler behind the scenes.
459         ///
460         /// # Example
461         ///
462         /// Consider
463         ///
464         /// ```ignore (pseudo-rust)
465         /// pub fn f(_: impl Trait) {}
466         /// ```
467         ///
468         /// The compiler will transform this behind the scenes to
469         ///
470         /// ```ignore (pseudo-rust)
471         /// pub fn f<impl Trait: Trait>(_: impl Trait) {}
472         /// ```
473         ///
474         /// In this example, the generic parameter named `impl Trait` (and which
475         /// is bound by `Trait`) is synthetic, because it was not originally in
476         /// the Rust source text.
477         synthetic: bool,
478     },
479     Const {
480         #[serde(rename = "type")]
481         type_: Type,
482         default: Option<String>,
483     },
484 }
485
486 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
487 #[serde(rename_all = "snake_case")]
488 pub enum WherePredicate {
489     BoundPredicate {
490         #[serde(rename = "type")]
491         type_: Type,
492         bounds: Vec<GenericBound>,
493         /// Used for Higher-Rank Trait Bounds (HRTBs)
494         /// ```text
495         /// where for<'a> &'a T: Iterator,"
496         ///       ^^^^^^^
497         ///       |
498         ///       this part
499         /// ```
500         generic_params: Vec<GenericParamDef>,
501     },
502     RegionPredicate {
503         lifetime: String,
504         bounds: Vec<GenericBound>,
505     },
506     EqPredicate {
507         lhs: Type,
508         rhs: Term,
509     },
510 }
511
512 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
513 #[serde(rename_all = "snake_case")]
514 pub enum GenericBound {
515     TraitBound {
516         #[serde(rename = "trait")]
517         trait_: Path,
518         /// Used for Higher-Rank Trait Bounds (HRTBs)
519         /// ```text
520         /// where F: for<'a, 'b> Fn(&'a u8, &'b u8)
521         ///          ^^^^^^^^^^^
522         ///          |
523         ///          this part
524         /// ```
525         generic_params: Vec<GenericParamDef>,
526         modifier: TraitBoundModifier,
527     },
528     Outlives(String),
529 }
530
531 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
532 #[serde(rename_all = "snake_case")]
533 pub enum TraitBoundModifier {
534     None,
535     Maybe,
536     MaybeConst,
537 }
538
539 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
540 #[serde(rename_all = "snake_case")]
541 pub enum Term {
542     Type(Type),
543     Constant(Constant),
544 }
545
546 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
547 #[serde(rename_all = "snake_case")]
548 #[serde(tag = "kind", content = "inner")]
549 pub enum Type {
550     /// Structs, enums, and unions
551     ResolvedPath(Path),
552     DynTrait(DynTrait),
553     /// Parameterized types
554     Generic(String),
555     /// Built in numberic (i*, u*, f*) types, bool, and char
556     Primitive(String),
557     /// `extern "ABI" fn`
558     FunctionPointer(Box<FunctionPointer>),
559     /// `(String, u32, Box<usize>)`
560     Tuple(Vec<Type>),
561     /// `[u32]`
562     Slice(Box<Type>),
563     /// [u32; 15]
564     Array {
565         #[serde(rename = "type")]
566         type_: Box<Type>,
567         len: String,
568     },
569     /// `impl TraitA + TraitB + ...`
570     ImplTrait(Vec<GenericBound>),
571     /// `_`
572     Infer,
573     /// `*mut u32`, `*u8`, etc.
574     RawPointer {
575         mutable: bool,
576         #[serde(rename = "type")]
577         type_: Box<Type>,
578     },
579     /// `&'a mut String`, `&str`, etc.
580     BorrowedRef {
581         lifetime: Option<String>,
582         mutable: bool,
583         #[serde(rename = "type")]
584         type_: Box<Type>,
585     },
586     /// `<Type as Trait>::Name` or associated types like `T::Item` where `T: Iterator`
587     QualifiedPath {
588         name: String,
589         args: Box<GenericArgs>,
590         self_type: Box<Type>,
591         #[serde(rename = "trait")]
592         trait_: Path,
593     },
594 }
595
596 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
597 pub struct Path {
598     pub name: String,
599     pub id: Id,
600     /// Generic arguments to the type
601     /// ```test
602     /// std::borrow::Cow<'static, str>
603     ///                 ^^^^^^^^^^^^^^
604     ///                 |
605     ///                 this part
606     /// ```
607     pub args: Option<Box<GenericArgs>>,
608 }
609
610 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
611 pub struct FunctionPointer {
612     pub decl: FnDecl,
613     /// Used for Higher-Rank Trait Bounds (HRTBs)
614     /// ```text
615     /// for<'c> fn(val: &'c i32) -> i32
616     /// ^^^^^^^
617     ///       |
618     ///       this part
619     /// ```
620     pub generic_params: Vec<GenericParamDef>,
621     pub header: Header,
622 }
623
624 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
625 pub struct FnDecl {
626     pub inputs: Vec<(String, Type)>,
627     pub output: Option<Type>,
628     pub c_variadic: bool,
629 }
630
631 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
632 pub struct Trait {
633     pub is_auto: bool,
634     pub is_unsafe: bool,
635     pub items: Vec<Id>,
636     pub generics: Generics,
637     pub bounds: Vec<GenericBound>,
638     pub implementations: Vec<Id>,
639 }
640
641 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
642 pub struct TraitAlias {
643     pub generics: Generics,
644     pub params: Vec<GenericBound>,
645 }
646
647 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
648 pub struct Impl {
649     pub is_unsafe: bool,
650     pub generics: Generics,
651     pub provided_trait_methods: Vec<String>,
652     #[serde(rename = "trait")]
653     pub trait_: Option<Path>,
654     #[serde(rename = "for")]
655     pub for_: Type,
656     pub items: Vec<Id>,
657     pub negative: bool,
658     pub synthetic: bool,
659     pub blanket_impl: Option<Type>,
660 }
661
662 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
663 #[serde(rename_all = "snake_case")]
664 pub struct Import {
665     /// The full path being imported.
666     pub source: String,
667     /// May be different from the last segment of `source` when renaming imports:
668     /// `use source as name;`
669     pub name: String,
670     /// The ID of the item being imported. Will be `None` in case of re-exports of primitives:
671     /// ```rust
672     /// pub use i32 as my_i32;
673     /// ```
674     pub id: Option<Id>,
675     /// Whether this import uses a glob: `use source::*;`
676     pub glob: bool,
677 }
678
679 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
680 pub struct ProcMacro {
681     pub kind: MacroKind,
682     pub helpers: Vec<String>,
683 }
684
685 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
686 #[serde(rename_all = "snake_case")]
687 pub enum MacroKind {
688     /// A bang macro `foo!()`.
689     Bang,
690     /// An attribute macro `#[foo]`.
691     Attr,
692     /// A derive macro `#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]`
693     Derive,
694 }
695
696 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
697 pub struct Typedef {
698     #[serde(rename = "type")]
699     pub type_: Type,
700     pub generics: Generics,
701 }
702
703 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
704 pub struct OpaqueTy {
705     pub bounds: Vec<GenericBound>,
706     pub generics: Generics,
707 }
708
709 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
710 pub struct Static {
711     #[serde(rename = "type")]
712     pub type_: Type,
713     pub mutable: bool,
714     pub expr: String,
715 }
716
717 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
718 pub struct Primitive {
719     pub name: String,
720     pub impls: Vec<Id>,
721 }
722
723 #[cfg(test)]
724 mod tests;