]> git.lizzy.rs Git - rust.git/blob - src/rustdoc-json-types/lib.rs
Rollup merge of #101648 - Timmmm:home_dir_docs, r=joshtriplett
[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 = 23;
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. Currently, 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     Impl,
214     Static,
215     ForeignType,
216     Macro,
217     ProcAttribute,
218     ProcDerive,
219     AssocConst,
220     AssocType,
221     Primitive,
222     Keyword,
223 }
224
225 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
226 #[serde(tag = "kind", content = "inner", rename_all = "snake_case")]
227 pub enum ItemEnum {
228     Module(Module),
229     ExternCrate {
230         name: String,
231         rename: Option<String>,
232     },
233     Import(Import),
234
235     Union(Union),
236     Struct(Struct),
237     StructField(Type),
238     Enum(Enum),
239     Variant(Variant),
240
241     Function(Function),
242
243     Trait(Trait),
244     TraitAlias(TraitAlias),
245     Impl(Impl),
246
247     Typedef(Typedef),
248     OpaqueTy(OpaqueTy),
249     Constant(Constant),
250
251     Static(Static),
252
253     /// `type`s from an extern block
254     ForeignType,
255
256     /// Declarative macro_rules! macro
257     Macro(String),
258     ProcMacro(ProcMacro),
259
260     Primitive(Primitive),
261
262     AssocConst {
263         #[serde(rename = "type")]
264         type_: Type,
265         /// e.g. `const X: usize = 5;`
266         default: Option<String>,
267     },
268     AssocType {
269         generics: Generics,
270         bounds: Vec<GenericBound>,
271         /// e.g. `type X = usize;`
272         default: Option<Type>,
273     },
274 }
275
276 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
277 pub struct Module {
278     pub is_crate: bool,
279     pub items: Vec<Id>,
280     /// If `true`, this module is not part of the public API, but it contains
281     /// items that are re-exported as public API.
282     pub is_stripped: bool,
283 }
284
285 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
286 pub struct Union {
287     pub generics: Generics,
288     pub fields_stripped: bool,
289     pub fields: Vec<Id>,
290     pub impls: Vec<Id>,
291 }
292
293 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
294 pub struct Struct {
295     pub kind: StructKind,
296     pub generics: Generics,
297     pub impls: Vec<Id>,
298 }
299
300 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
301 #[serde(rename_all = "snake_case")]
302 pub enum StructKind {
303     /// A struct with no fields and no parentheses.
304     ///
305     /// ```rust
306     /// pub struct Unit;
307     /// ```
308     Unit,
309     /// A struct with unnamed fields.
310     ///
311     /// ```rust
312     /// pub struct TupleStruct(i32);
313     /// pub struct EmptyTupleStruct();
314     /// ```
315     ///
316     /// All [`Id`]'s will point to [`ItemEnum::StructField`]. Private and
317     /// `#[doc(hidden)]` fields will be given as `None`
318     Tuple(Vec<Option<Id>>),
319     /// A struct with nammed fields.
320     ///
321     /// ```rust
322     /// pub struct PlainStruct { x: i32 }
323     /// pub struct EmptyPlainStruct {}
324     /// ```
325     Plain { fields: Vec<Id>, fields_stripped: bool },
326 }
327
328 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
329 pub struct Enum {
330     pub generics: Generics,
331     pub variants_stripped: bool,
332     pub variants: Vec<Id>,
333     pub impls: Vec<Id>,
334 }
335
336 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
337 #[serde(rename_all = "snake_case")]
338 #[serde(tag = "variant_kind", content = "variant_inner")]
339 pub enum Variant {
340     /// A variant with no parentheses, and possible discriminant.
341     ///
342     /// ```rust
343     /// enum Demo {
344     ///     PlainVariant,
345     ///     PlainWithDiscriminant = 1,
346     /// }
347     /// ```
348     Plain(Option<Discriminant>),
349     /// A variant with unnamed fields.
350     ///
351     /// Unlike most of json, `#[doc(hidden)]` fields will be given as `None`
352     /// instead of being omitted, because order matters.
353     ///
354     /// ```rust
355     /// enum Demo {
356     ///     TupleVariant(i32),
357     ///     EmptyTupleVariant(),
358     /// }
359     /// ```
360     Tuple(Vec<Option<Id>>),
361     /// A variant with named fields.
362     ///
363     /// ```rust
364     /// enum Demo {
365     ///     StructVariant { x: i32 },
366     ///     EmptyStructVariant {},
367     /// }
368     /// ```
369     Struct { fields: Vec<Id>, fields_stripped: bool },
370 }
371
372 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
373 pub struct Discriminant {
374     /// The expression that produced the discriminant.
375     ///
376     /// Unlike `value`, this preserves the original formatting (eg suffixes,
377     /// hexadecimal, and underscores), making it unsuitable to be machine
378     /// interpreted.
379     ///
380     /// In some cases, when the value is to complex, this may be `"{ _ }"`.
381     /// When this occurs is unstable, and may change without notice.
382     pub expr: String,
383     /// The numerical value of the discriminant. Stored as a string due to
384     /// JSON's poor support for large integers, and the fact that it would need
385     /// to store from [`i128::MIN`] to [`u128::MAX`].
386     pub value: String,
387 }
388
389 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
390 pub struct Header {
391     #[serde(rename = "const")]
392     pub const_: bool,
393     #[serde(rename = "unsafe")]
394     pub unsafe_: bool,
395     #[serde(rename = "async")]
396     pub async_: bool,
397     pub abi: Abi,
398 }
399
400 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
401 pub enum Abi {
402     // We only have a concrete listing here for stable ABI's because their are so many
403     // See rustc_ast_passes::feature_gate::PostExpansionVisitor::check_abi for the list
404     Rust,
405     C { unwind: bool },
406     Cdecl { unwind: bool },
407     Stdcall { unwind: bool },
408     Fastcall { unwind: bool },
409     Aapcs { unwind: bool },
410     Win64 { unwind: bool },
411     SysV64 { unwind: bool },
412     System { unwind: bool },
413     Other(String),
414 }
415
416 /// Represents a function (including methods and other associated functions)
417 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
418 pub struct Function {
419     pub decl: FnDecl,
420     pub generics: Generics,
421     pub header: Header,
422     pub has_body: bool,
423 }
424
425 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
426 pub struct Generics {
427     pub params: Vec<GenericParamDef>,
428     pub where_predicates: Vec<WherePredicate>,
429 }
430
431 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
432 pub struct GenericParamDef {
433     pub name: String,
434     pub kind: GenericParamDefKind,
435 }
436
437 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
438 #[serde(rename_all = "snake_case")]
439 pub enum GenericParamDefKind {
440     Lifetime {
441         outlives: Vec<String>,
442     },
443     Type {
444         bounds: Vec<GenericBound>,
445         default: Option<Type>,
446         /// This is normally `false`, which means that this generic parameter is
447         /// declared in the Rust source text.
448         ///
449         /// If it is `true`, this generic parameter has been introduced by the
450         /// compiler behind the scenes.
451         ///
452         /// # Example
453         ///
454         /// Consider
455         ///
456         /// ```ignore (pseudo-rust)
457         /// pub fn f(_: impl Trait) {}
458         /// ```
459         ///
460         /// The compiler will transform this behind the scenes to
461         ///
462         /// ```ignore (pseudo-rust)
463         /// pub fn f<impl Trait: Trait>(_: impl Trait) {}
464         /// ```
465         ///
466         /// In this example, the generic parameter named `impl Trait` (and which
467         /// is bound by `Trait`) is synthetic, because it was not originally in
468         /// the Rust source text.
469         synthetic: bool,
470     },
471     Const {
472         #[serde(rename = "type")]
473         type_: Type,
474         default: Option<String>,
475     },
476 }
477
478 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
479 #[serde(rename_all = "snake_case")]
480 pub enum WherePredicate {
481     BoundPredicate {
482         #[serde(rename = "type")]
483         type_: Type,
484         bounds: Vec<GenericBound>,
485         /// Used for Higher-Rank Trait Bounds (HRTBs)
486         /// ```text
487         /// where for<'a> &'a T: Iterator,"
488         ///       ^^^^^^^
489         ///       |
490         ///       this part
491         /// ```
492         generic_params: Vec<GenericParamDef>,
493     },
494     RegionPredicate {
495         lifetime: String,
496         bounds: Vec<GenericBound>,
497     },
498     EqPredicate {
499         lhs: Type,
500         rhs: Term,
501     },
502 }
503
504 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
505 #[serde(rename_all = "snake_case")]
506 pub enum GenericBound {
507     TraitBound {
508         #[serde(rename = "trait")]
509         trait_: Path,
510         /// Used for Higher-Rank Trait Bounds (HRTBs)
511         /// ```text
512         /// where F: for<'a, 'b> Fn(&'a u8, &'b u8)
513         ///          ^^^^^^^^^^^
514         ///          |
515         ///          this part
516         /// ```
517         generic_params: Vec<GenericParamDef>,
518         modifier: TraitBoundModifier,
519     },
520     Outlives(String),
521 }
522
523 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
524 #[serde(rename_all = "snake_case")]
525 pub enum TraitBoundModifier {
526     None,
527     Maybe,
528     MaybeConst,
529 }
530
531 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
532 #[serde(rename_all = "snake_case")]
533 pub enum Term {
534     Type(Type),
535     Constant(Constant),
536 }
537
538 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
539 #[serde(rename_all = "snake_case")]
540 #[serde(tag = "kind", content = "inner")]
541 pub enum Type {
542     /// Structs, enums, and unions
543     ResolvedPath(Path),
544     DynTrait(DynTrait),
545     /// Parameterized types
546     Generic(String),
547     /// Built in numberic (i*, u*, f*) types, bool, and char
548     Primitive(String),
549     /// `extern "ABI" fn`
550     FunctionPointer(Box<FunctionPointer>),
551     /// `(String, u32, Box<usize>)`
552     Tuple(Vec<Type>),
553     /// `[u32]`
554     Slice(Box<Type>),
555     /// [u32; 15]
556     Array {
557         #[serde(rename = "type")]
558         type_: Box<Type>,
559         len: String,
560     },
561     /// `impl TraitA + TraitB + ...`
562     ImplTrait(Vec<GenericBound>),
563     /// `_`
564     Infer,
565     /// `*mut u32`, `*u8`, etc.
566     RawPointer {
567         mutable: bool,
568         #[serde(rename = "type")]
569         type_: Box<Type>,
570     },
571     /// `&'a mut String`, `&str`, etc.
572     BorrowedRef {
573         lifetime: Option<String>,
574         mutable: bool,
575         #[serde(rename = "type")]
576         type_: Box<Type>,
577     },
578     /// `<Type as Trait>::Name` or associated types like `T::Item` where `T: Iterator`
579     QualifiedPath {
580         name: String,
581         args: Box<GenericArgs>,
582         self_type: Box<Type>,
583         #[serde(rename = "trait")]
584         trait_: Path,
585     },
586 }
587
588 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
589 pub struct Path {
590     pub name: String,
591     pub id: Id,
592     /// Generic arguments to the type
593     /// ```test
594     /// std::borrow::Cow<'static, str>
595     ///                 ^^^^^^^^^^^^^^
596     ///                 |
597     ///                 this part
598     /// ```
599     pub args: Option<Box<GenericArgs>>,
600 }
601
602 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
603 pub struct FunctionPointer {
604     pub decl: FnDecl,
605     /// Used for Higher-Rank Trait Bounds (HRTBs)
606     /// ```text
607     /// for<'c> fn(val: &'c i32) -> i32
608     /// ^^^^^^^
609     ///       |
610     ///       this part
611     /// ```
612     pub generic_params: Vec<GenericParamDef>,
613     pub header: Header,
614 }
615
616 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
617 pub struct FnDecl {
618     /// List of argument names and their type.
619     ///
620     /// Note that not all names will be valid identifiers, as some of
621     /// them may be patterns.
622     pub inputs: Vec<(String, Type)>,
623     pub output: Option<Type>,
624     pub c_variadic: bool,
625 }
626
627 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
628 pub struct Trait {
629     pub is_auto: bool,
630     pub is_unsafe: bool,
631     pub items: Vec<Id>,
632     pub generics: Generics,
633     pub bounds: Vec<GenericBound>,
634     pub implementations: Vec<Id>,
635 }
636
637 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
638 pub struct TraitAlias {
639     pub generics: Generics,
640     pub params: Vec<GenericBound>,
641 }
642
643 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
644 pub struct Impl {
645     pub is_unsafe: bool,
646     pub generics: Generics,
647     pub provided_trait_methods: Vec<String>,
648     #[serde(rename = "trait")]
649     pub trait_: Option<Path>,
650     #[serde(rename = "for")]
651     pub for_: Type,
652     pub items: Vec<Id>,
653     pub negative: bool,
654     pub synthetic: bool,
655     pub blanket_impl: Option<Type>,
656 }
657
658 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
659 #[serde(rename_all = "snake_case")]
660 pub struct Import {
661     /// The full path being imported.
662     pub source: String,
663     /// May be different from the last segment of `source` when renaming imports:
664     /// `use source as name;`
665     pub name: String,
666     /// The ID of the item being imported. Will be `None` in case of re-exports of primitives:
667     /// ```rust
668     /// pub use i32 as my_i32;
669     /// ```
670     pub id: Option<Id>,
671     /// Whether this import uses a glob: `use source::*;`
672     pub glob: bool,
673 }
674
675 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
676 pub struct ProcMacro {
677     pub kind: MacroKind,
678     pub helpers: Vec<String>,
679 }
680
681 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
682 #[serde(rename_all = "snake_case")]
683 pub enum MacroKind {
684     /// A bang macro `foo!()`.
685     Bang,
686     /// An attribute macro `#[foo]`.
687     Attr,
688     /// A derive macro `#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]`
689     Derive,
690 }
691
692 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
693 pub struct Typedef {
694     #[serde(rename = "type")]
695     pub type_: Type,
696     pub generics: Generics,
697 }
698
699 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
700 pub struct OpaqueTy {
701     pub bounds: Vec<GenericBound>,
702     pub generics: Generics,
703 }
704
705 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
706 pub struct Static {
707     #[serde(rename = "type")]
708     pub type_: Type,
709     pub mutable: bool,
710     pub expr: String,
711 }
712
713 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
714 pub struct Primitive {
715     pub name: String,
716     pub impls: Vec<Id>,
717 }
718
719 #[cfg(test)]
720 mod tests;