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