Auto merge of #126963 - runtimeverification:smir_serde_derive, r=celinval

Add basic Serde serialization capabilities to Stable MIR

This PR adds basic Serde serialization capabilities to Stable MIR. It is intentionally minimal (just wrapping all stable MIR types with a Serde `derive`), so that any important design decisions can be discussed before going further. A simple test is included with this PR to validate that JSON can actually be emitted.

## Notes

When I wrapped the Stable MIR error types in `compiler/stable_mir/src/error.rs`, it caused test failures (though I'm not sure why) so I backed those out.

## Future Work

So, this PR will support serializing basic stable MIR, but it _does not_ support serializing interned values beneath `Ty`s and `AllocId`s, etc... My current thinking about how to handle this is as follows:

1.  Add new `visited_X` fields to the `Tables` struct for each interned category of interest.

2.  As serialization is occuring, serialize interned values as usual _and_ also record the interned value we referenced in `visited_X`.

    (Possibly) In addition, if an interned value recursively references other interned values, record those interned values as well.

3.  Teach the stable MIR `Context` how to access the `visited_X` values and expose them with wrappers in `stable_mir/src/lib.rs` to users (e.g. to serialize and/or further analyze them).

### Pros

This approach does not commit to any specific serialization format regarding interned values or other more complex cases, which avoids us locking into any behaviors that may not be desired long-term.

### Cons

The user will need to manually handle serializing interned values.

### Alternatives

1.  We can directly provide access to the underlying `Tables` maps for interned values; the disadvantage of this approach is that it either requires extra processing for users to filter out to only use the values that they need _or_ users may serialize extra values that they don't need. The advantage is that the implementation is even simpler. The other pros/cons are similar to the above.

2.  We can directly serialize interned values by expanding them in-place. The pro is that this may make some basic inputs easier to consume. However, the cons are that there will need to be special provisions for dealing with cyclical values on both the producer and consumer _and_ global values will possibly need to be de-duplicated on the consumer side.
This commit is contained in:
bors 2024-07-25 20:27:51 +00:00
commit 7120fdac7a
11 changed files with 242 additions and 139 deletions

View File

@ -5205,6 +5205,7 @@ name = "stable_mir"
version = "0.1.0-preview" version = "0.1.0-preview"
dependencies = [ dependencies = [
"scoped-tls", "scoped-tls",
"serde",
] ]
[[package]] [[package]]

View File

@ -5,3 +5,4 @@ edition = "2021"
[dependencies] [dependencies]
scoped-tls = "1.0" scoped-tls = "1.0"
serde = { version = "1.0.125", features = [ "derive" ] }

View File

@ -5,12 +5,13 @@ use crate::target::{MachineInfo, MachineSize as Size};
use crate::ty::{Align, IndexedVal, Ty, VariantIdx}; use crate::ty::{Align, IndexedVal, Ty, VariantIdx};
use crate::Error; use crate::Error;
use crate::Opaque; use crate::Opaque;
use serde::Serialize;
use std::fmt::{self, Debug}; use std::fmt::{self, Debug};
use std::num::NonZero; use std::num::NonZero;
use std::ops::RangeInclusive; use std::ops::RangeInclusive;
/// A function ABI definition. /// A function ABI definition.
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub struct FnAbi { pub struct FnAbi {
/// The types of each argument. /// The types of each argument.
pub args: Vec<ArgAbi>, pub args: Vec<ArgAbi>,
@ -31,7 +32,7 @@ pub struct FnAbi {
} }
/// Information about the ABI of a function's argument, or return value. /// Information about the ABI of a function's argument, or return value.
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub struct ArgAbi { pub struct ArgAbi {
pub ty: Ty, pub ty: Ty,
pub layout: Layout, pub layout: Layout,
@ -39,7 +40,7 @@ pub struct ArgAbi {
} }
/// How a function argument should be passed in to the target function. /// How a function argument should be passed in to the target function.
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum PassMode { pub enum PassMode {
/// Ignore the argument. /// Ignore the argument.
/// ///
@ -60,14 +61,14 @@ pub enum PassMode {
} }
/// The layout of a type, alongside the type itself. /// The layout of a type, alongside the type itself.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub struct TyAndLayout { pub struct TyAndLayout {
pub ty: Ty, pub ty: Ty,
pub layout: Layout, pub layout: Layout,
} }
/// The layout of a type in memory. /// The layout of a type in memory.
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub struct LayoutShape { pub struct LayoutShape {
/// The fields location withing the layout /// The fields location withing the layout
pub fields: FieldsShape, pub fields: FieldsShape,
@ -108,7 +109,7 @@ impl LayoutShape {
} }
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub struct Layout(usize); pub struct Layout(usize);
impl Layout { impl Layout {
@ -127,7 +128,7 @@ impl IndexedVal for Layout {
} }
/// Describes how the fields of a type are shaped in memory. /// Describes how the fields of a type are shaped in memory.
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum FieldsShape { pub enum FieldsShape {
/// Scalar primitives and `!`, which never have fields. /// Scalar primitives and `!`, which never have fields.
Primitive, Primitive,
@ -177,7 +178,7 @@ impl FieldsShape {
} }
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum VariantsShape { pub enum VariantsShape {
/// Single enum variants, structs/tuples, unions, and all non-ADTs. /// Single enum variants, structs/tuples, unions, and all non-ADTs.
Single { index: VariantIdx }, Single { index: VariantIdx },
@ -196,7 +197,7 @@ pub enum VariantsShape {
}, },
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum TagEncoding { pub enum TagEncoding {
/// The tag directly stores the discriminant, but possibly with a smaller layout /// The tag directly stores the discriminant, but possibly with a smaller layout
/// (so converting the tag to the discriminant can require sign extension). /// (so converting the tag to the discriminant can require sign extension).
@ -221,7 +222,7 @@ pub enum TagEncoding {
/// Describes how values of the type are passed by target ABIs, /// Describes how values of the type are passed by target ABIs,
/// in terms of categories of C types there are ABI rules for. /// in terms of categories of C types there are ABI rules for.
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum ValueAbi { pub enum ValueAbi {
Uninhabited, Uninhabited,
Scalar(Scalar), Scalar(Scalar),
@ -250,7 +251,7 @@ impl ValueAbi {
} }
/// Information about one scalar component of a Rust type. /// Information about one scalar component of a Rust type.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Serialize)]
pub enum Scalar { pub enum Scalar {
Initialized { Initialized {
/// The primitive type used to represent this value. /// The primitive type used to represent this value.
@ -280,7 +281,7 @@ impl Scalar {
} }
/// Fundamental unit of memory access and layout. /// Fundamental unit of memory access and layout.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Serialize)]
pub enum Primitive { pub enum Primitive {
/// The `bool` is the signedness of the `Integer` type. /// The `bool` is the signedness of the `Integer` type.
/// ///
@ -310,7 +311,7 @@ impl Primitive {
} }
/// Enum representing the existing integer lengths. /// Enum representing the existing integer lengths.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
pub enum IntegerLength { pub enum IntegerLength {
I8, I8,
I16, I16,
@ -320,7 +321,7 @@ pub enum IntegerLength {
} }
/// Enum representing the existing float lengths. /// Enum representing the existing float lengths.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
pub enum FloatLength { pub enum FloatLength {
F16, F16,
F32, F32,
@ -354,7 +355,7 @@ impl FloatLength {
/// An identifier that specifies the address space that some operation /// An identifier that specifies the address space that some operation
/// should operate on. Special address spaces have an effect on code generation, /// should operate on. Special address spaces have an effect on code generation,
/// depending on the target and the address spaces it implements. /// depending on the target and the address spaces it implements.
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
pub struct AddressSpace(pub u32); pub struct AddressSpace(pub u32);
impl AddressSpace { impl AddressSpace {
@ -369,7 +370,7 @@ impl AddressSpace {
/// sequence: /// sequence:
/// ///
/// 254 (-2), 255 (-1), 0, 1, 2 /// 254 (-2), 255 (-1), 0, 1, 2
#[derive(Clone, Copy, PartialEq, Eq, Hash)] #[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)]
pub struct WrappingRange { pub struct WrappingRange {
pub start: u128, pub start: u128,
pub end: u128, pub end: u128,
@ -420,7 +421,7 @@ impl Debug for WrappingRange {
} }
/// General language calling conventions. /// General language calling conventions.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum CallConvention { pub enum CallConvention {
C, C,
Rust, Rust,

View File

@ -3,9 +3,10 @@
use crate::ty::{GenericArgs, Span, Ty}; use crate::ty::{GenericArgs, Span, Ty};
use crate::{with, Crate, Symbol}; use crate::{with, Crate, Symbol};
use serde::Serialize;
/// A unique identification number for each item accessible for the current compilation unit. /// A unique identification number for each item accessible for the current compilation unit.
#[derive(Clone, Copy, PartialEq, Eq, Hash)] #[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)]
pub struct DefId(pub(crate) usize); pub struct DefId(pub(crate) usize);
/// A trait for retrieving information about a particular definition. /// A trait for retrieving information about a particular definition.

View File

@ -27,6 +27,7 @@ pub use crate::error::*;
use crate::mir::Body; use crate::mir::Body;
use crate::mir::Mutability; use crate::mir::Mutability;
use crate::ty::{ForeignModuleDef, ImplDef, IndexedVal, Span, TraitDef, Ty}; use crate::ty::{ForeignModuleDef, ImplDef, IndexedVal, Span, TraitDef, Ty};
use serde::Serialize;
pub mod abi; pub mod abi;
#[macro_use] #[macro_use]
@ -74,7 +75,7 @@ pub type TraitDecls = Vec<TraitDef>;
pub type ImplTraitDecls = Vec<ImplDef>; pub type ImplTraitDecls = Vec<ImplDef>;
/// Holds information about a crate. /// Holds information about a crate.
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug, Serialize)]
pub struct Crate { pub struct Crate {
pub id: CrateNum, pub id: CrateNum,
pub name: Symbol, pub name: Symbol,
@ -98,7 +99,7 @@ impl Crate {
} }
} }
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)]
pub enum ItemKind { pub enum ItemKind {
Fn, Fn,
Static, Static,
@ -106,7 +107,7 @@ pub enum ItemKind {
Ctor(CtorKind), Ctor(CtorKind),
} }
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)]
pub enum CtorKind { pub enum CtorKind {
Const, Const,
Fn, Fn,
@ -116,6 +117,7 @@ pub type Filename = String;
crate_def_with_ty! { crate_def_with_ty! {
/// Holds information about an item in a crate. /// Holds information about an item in a crate.
#[derive(Serialize)]
pub CrateItem; pub CrateItem;
} }
@ -188,7 +190,7 @@ pub fn all_trait_impls() -> ImplTraitDecls {
} }
/// A type that provides internal information but that can still be used for debug purpose. /// A type that provides internal information but that can still be used for debug purpose.
#[derive(Clone, PartialEq, Eq, Hash)] #[derive(Clone, PartialEq, Eq, Hash, Serialize)]
pub struct Opaque(String); pub struct Opaque(String);
impl std::fmt::Display for Opaque { impl std::fmt::Display for Opaque {

View File

@ -4,11 +4,12 @@ use crate::mir::mono::{Instance, StaticDef};
use crate::target::{Endian, MachineInfo}; use crate::target::{Endian, MachineInfo};
use crate::ty::{Allocation, Binder, ExistentialTraitRef, IndexedVal, Ty}; use crate::ty::{Allocation, Binder, ExistentialTraitRef, IndexedVal, Ty};
use crate::{with, Error}; use crate::{with, Error};
use serde::Serialize;
use std::io::Read; use std::io::Read;
/// An allocation in the SMIR global memory can be either a function pointer, /// An allocation in the SMIR global memory can be either a function pointer,
/// a static, or a "real" allocation with some data in it. /// a static, or a "real" allocation with some data in it.
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq, Serialize)]
pub enum GlobalAlloc { pub enum GlobalAlloc {
/// The alloc ID is used as a function pointer. /// The alloc ID is used as a function pointer.
Function(Instance), Function(Instance),
@ -41,7 +42,7 @@ impl GlobalAlloc {
} }
/// A unique identification number for each provenance /// A unique identification number for each provenance
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
pub struct AllocId(usize); pub struct AllocId(usize);
impl IndexedVal for AllocId { impl IndexedVal for AllocId {

View File

@ -5,10 +5,11 @@ use crate::ty::{
TyConst, TyKind, VariantIdx, TyConst, TyKind, VariantIdx,
}; };
use crate::{Error, Opaque, Span, Symbol}; use crate::{Error, Opaque, Span, Symbol};
use serde::Serialize;
use std::io; use std::io;
/// The SMIR representation of a single function. /// The SMIR representation of a single function.
#[derive(Clone, Debug)] #[derive(Clone, Debug, Serialize)]
pub struct Body { pub struct Body {
pub blocks: Vec<BasicBlock>, pub blocks: Vec<BasicBlock>,
@ -104,20 +105,20 @@ impl Body {
type LocalDecls = Vec<LocalDecl>; type LocalDecls = Vec<LocalDecl>;
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct LocalDecl { pub struct LocalDecl {
pub ty: Ty, pub ty: Ty,
pub span: Span, pub span: Span,
pub mutability: Mutability, pub mutability: Mutability,
} }
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug, Serialize)]
pub struct BasicBlock { pub struct BasicBlock {
pub statements: Vec<Statement>, pub statements: Vec<Statement>,
pub terminator: Terminator, pub terminator: Terminator,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct Terminator { pub struct Terminator {
pub kind: TerminatorKind, pub kind: TerminatorKind,
pub span: Span, pub span: Span,
@ -131,7 +132,7 @@ impl Terminator {
pub type Successors = Vec<BasicBlockIdx>; pub type Successors = Vec<BasicBlockIdx>;
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum TerminatorKind { pub enum TerminatorKind {
Goto { Goto {
target: BasicBlockIdx, target: BasicBlockIdx,
@ -221,7 +222,7 @@ impl TerminatorKind {
} }
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct InlineAsmOperand { pub struct InlineAsmOperand {
pub in_value: Option<Operand>, pub in_value: Option<Operand>,
pub out_place: Option<Place>, pub out_place: Option<Place>,
@ -230,7 +231,7 @@ pub struct InlineAsmOperand {
pub raw_rpr: String, pub raw_rpr: String,
} }
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
pub enum UnwindAction { pub enum UnwindAction {
Continue, Continue,
Unreachable, Unreachable,
@ -238,7 +239,7 @@ pub enum UnwindAction {
Cleanup(BasicBlockIdx), Cleanup(BasicBlockIdx),
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum AssertMessage { pub enum AssertMessage {
BoundsCheck { len: Operand, index: Operand }, BoundsCheck { len: Operand, index: Operand },
Overflow(BinOp, Operand, Operand), Overflow(BinOp, Operand, Operand),
@ -307,7 +308,7 @@ impl AssertMessage {
} }
} }
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
pub enum BinOp { pub enum BinOp {
Add, Add,
AddUnchecked, AddUnchecked,
@ -342,7 +343,7 @@ impl BinOp {
} }
} }
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
pub enum UnOp { pub enum UnOp {
Not, Not,
Neg, Neg,
@ -357,20 +358,20 @@ impl UnOp {
} }
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum CoroutineKind { pub enum CoroutineKind {
Desugared(CoroutineDesugaring, CoroutineSource), Desugared(CoroutineDesugaring, CoroutineSource),
Coroutine(Movability), Coroutine(Movability),
} }
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
pub enum CoroutineSource { pub enum CoroutineSource {
Block, Block,
Closure, Closure,
Fn, Fn,
} }
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
pub enum CoroutineDesugaring { pub enum CoroutineDesugaring {
Async, Async,
@ -386,7 +387,7 @@ pub(crate) type LocalDefId = Opaque;
pub(crate) type Coverage = Opaque; pub(crate) type Coverage = Opaque;
/// The FakeReadCause describes the type of pattern why a FakeRead statement exists. /// The FakeReadCause describes the type of pattern why a FakeRead statement exists.
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum FakeReadCause { pub enum FakeReadCause {
ForMatchGuard, ForMatchGuard,
ForMatchedPlace(LocalDefId), ForMatchedPlace(LocalDefId),
@ -396,7 +397,7 @@ pub enum FakeReadCause {
} }
/// Describes what kind of retag is to be performed /// Describes what kind of retag is to be performed
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)]
pub enum RetagKind { pub enum RetagKind {
FnEntry, FnEntry,
TwoPhase, TwoPhase,
@ -404,7 +405,7 @@ pub enum RetagKind {
Default, Default,
} }
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)]
pub enum Variance { pub enum Variance {
Covariant, Covariant,
Invariant, Invariant,
@ -412,26 +413,26 @@ pub enum Variance {
Bivariant, Bivariant,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct CopyNonOverlapping { pub struct CopyNonOverlapping {
pub src: Operand, pub src: Operand,
pub dst: Operand, pub dst: Operand,
pub count: Operand, pub count: Operand,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum NonDivergingIntrinsic { pub enum NonDivergingIntrinsic {
Assume(Operand), Assume(Operand),
CopyNonOverlapping(CopyNonOverlapping), CopyNonOverlapping(CopyNonOverlapping),
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct Statement { pub struct Statement {
pub kind: StatementKind, pub kind: StatementKind,
pub span: Span, pub span: Span,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum StatementKind { pub enum StatementKind {
Assign(Place, Rvalue), Assign(Place, Rvalue),
FakeRead(FakeReadCause, Place), FakeRead(FakeReadCause, Place),
@ -448,7 +449,7 @@ pub enum StatementKind {
Nop, Nop,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum Rvalue { pub enum Rvalue {
/// Creates a pointer with the indicated mutability to the place. /// Creates a pointer with the indicated mutability to the place.
/// ///
@ -622,7 +623,7 @@ impl Rvalue {
} }
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum AggregateKind { pub enum AggregateKind {
Array(Ty), Array(Ty),
Tuple, Tuple,
@ -633,14 +634,14 @@ pub enum AggregateKind {
RawPtr(Ty, Mutability), RawPtr(Ty, Mutability),
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum Operand { pub enum Operand {
Copy(Place), Copy(Place),
Move(Place), Move(Place),
Constant(ConstOperand), Constant(ConstOperand),
} }
#[derive(Clone, Eq, PartialEq)] #[derive(Clone, Eq, PartialEq, Serialize)]
pub struct Place { pub struct Place {
pub local: Local, pub local: Local,
/// projection out of a place (access a field, deref a pointer, etc) /// projection out of a place (access a field, deref a pointer, etc)
@ -653,7 +654,7 @@ impl From<Local> for Place {
} }
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct ConstOperand { pub struct ConstOperand {
pub span: Span, pub span: Span,
pub user_ty: Option<UserTypeAnnotationIndex>, pub user_ty: Option<UserTypeAnnotationIndex>,
@ -661,7 +662,7 @@ pub struct ConstOperand {
} }
/// Debug information pertaining to a user variable. /// Debug information pertaining to a user variable.
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct VarDebugInfo { pub struct VarDebugInfo {
/// The variable name. /// The variable name.
pub name: Symbol, pub name: Symbol,
@ -703,19 +704,19 @@ impl VarDebugInfo {
pub type SourceScope = u32; pub type SourceScope = u32;
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct SourceInfo { pub struct SourceInfo {
pub span: Span, pub span: Span,
pub scope: SourceScope, pub scope: SourceScope,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct VarDebugInfoFragment { pub struct VarDebugInfoFragment {
pub ty: Ty, pub ty: Ty,
pub projection: Vec<ProjectionElem>, pub projection: Vec<ProjectionElem>,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum VarDebugInfoContents { pub enum VarDebugInfoContents {
Place(Place), Place(Place),
Const(ConstOperand), Const(ConstOperand),
@ -726,7 +727,7 @@ pub enum VarDebugInfoContents {
// ProjectionElem<Local, Ty>) and user-provided type annotations (for which the projection elements // ProjectionElem<Local, Ty>) and user-provided type annotations (for which the projection elements
// are of type ProjectionElem<(), ()>). In SMIR we don't need this generality, so we just use // are of type ProjectionElem<(), ()>). In SMIR we don't need this generality, so we just use
// ProjectionElem for Places. // ProjectionElem for Places.
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum ProjectionElem { pub enum ProjectionElem {
/// Dereference projections (e.g. `*_1`) project to the address referenced by the base place. /// Dereference projections (e.g. `*_1`) project to the address referenced by the base place.
Deref, Deref,
@ -800,7 +801,7 @@ pub enum ProjectionElem {
Subtype(Ty), Subtype(Ty),
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct UserTypeProjection { pub struct UserTypeProjection {
pub base: UserTypeAnnotationIndex, pub base: UserTypeAnnotationIndex,
@ -830,7 +831,7 @@ pub type FieldIdx = usize;
type UserTypeAnnotationIndex = usize; type UserTypeAnnotationIndex = usize;
/// The possible branch sites of a [TerminatorKind::SwitchInt]. /// The possible branch sites of a [TerminatorKind::SwitchInt].
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct SwitchTargets { pub struct SwitchTargets {
/// The conditional branches where the first element represents the value that guards this /// The conditional branches where the first element represents the value that guards this
/// branch, and the second element is the branch target. /// branch, and the second element is the branch target.
@ -867,7 +868,7 @@ impl SwitchTargets {
} }
} }
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
pub enum BorrowKind { pub enum BorrowKind {
/// Data must be immutable and is aliasable. /// Data must be immutable and is aliasable.
Shared, Shared,
@ -894,14 +895,14 @@ impl BorrowKind {
} }
} }
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
pub enum MutBorrowKind { pub enum MutBorrowKind {
Default, Default,
TwoPhaseBorrow, TwoPhaseBorrow,
ClosureCapture, ClosureCapture,
} }
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
pub enum FakeBorrowKind { pub enum FakeBorrowKind {
/// A shared (deep) borrow. Data must be immutable and is aliasable. /// A shared (deep) borrow. Data must be immutable and is aliasable.
Deep, Deep,
@ -912,19 +913,19 @@ pub enum FakeBorrowKind {
Shallow, Shallow,
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum Mutability { pub enum Mutability {
Not, Not,
Mut, Mut,
} }
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
pub enum Safety { pub enum Safety {
Safe, Safe,
Unsafe, Unsafe,
} }
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
pub enum PointerCoercion { pub enum PointerCoercion {
/// Go from a fn-item type to a fn-pointer type. /// Go from a fn-item type to a fn-pointer type.
ReifyFnPointer, ReifyFnPointer,
@ -951,7 +952,7 @@ pub enum PointerCoercion {
Unsize, Unsize,
} }
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
pub enum CastKind { pub enum CastKind {
// FIXME(smir-rename): rename this to PointerExposeProvenance // FIXME(smir-rename): rename this to PointerExposeProvenance
PointerExposeAddress, PointerExposeAddress,
@ -967,7 +968,7 @@ pub enum CastKind {
Transmute, Transmute,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum NullOp { pub enum NullOp {
/// Returns the size of a value of that type. /// Returns the size of a value of that type.
SizeOf, SizeOf,

View File

@ -3,17 +3,18 @@ use crate::crate_def::CrateDef;
use crate::mir::Body; use crate::mir::Body;
use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty}; use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty};
use crate::{with, CrateItem, DefId, Error, ItemKind, Opaque, Symbol}; use crate::{with, CrateItem, DefId, Error, ItemKind, Opaque, Symbol};
use serde::Serialize;
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
use std::io; use std::io;
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum MonoItem { pub enum MonoItem {
Fn(Instance), Fn(Instance),
Static(StaticDef), Static(StaticDef),
GlobalAsm(Opaque), GlobalAsm(Opaque),
} }
#[derive(Copy, Clone, PartialEq, Eq, Hash)] #[derive(Copy, Clone, PartialEq, Eq, Hash, Serialize)]
pub struct Instance { pub struct Instance {
/// The type of instance. /// The type of instance.
pub kind: InstanceKind, pub kind: InstanceKind,
@ -22,7 +23,7 @@ pub struct Instance {
pub def: InstanceDef, pub def: InstanceDef,
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum InstanceKind { pub enum InstanceKind {
/// A user defined item. /// A user defined item.
Item, Item,
@ -240,7 +241,7 @@ impl From<StaticDef> for CrateItem {
} }
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
pub struct InstanceDef(usize); pub struct InstanceDef(usize);
impl CrateDef for InstanceDef { impl CrateDef for InstanceDef {
@ -251,6 +252,7 @@ impl CrateDef for InstanceDef {
crate_def! { crate_def! {
/// Holds information about a static variable definition. /// Holds information about a static variable definition.
#[derive(Serialize)]
pub StaticDef; pub StaticDef;
} }

View File

@ -1,9 +1,10 @@
//! Provide information about the machine that this is being compiled into. //! Provide information about the machine that this is being compiled into.
use crate::compiler_interface::with; use crate::compiler_interface::with;
use serde::Serialize;
/// The properties of the target machine being compiled into. /// The properties of the target machine being compiled into.
#[derive(Clone, PartialEq, Eq)] #[derive(Clone, PartialEq, Eq, Serialize)]
pub struct MachineInfo { pub struct MachineInfo {
pub endian: Endian, pub endian: Endian,
pub pointer_width: MachineSize, pub pointer_width: MachineSize,
@ -23,14 +24,14 @@ impl MachineInfo {
} }
} }
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq, Serialize)]
pub enum Endian { pub enum Endian {
Little, Little,
Big, Big,
} }
/// Represent the size of a component. /// Represent the size of a component.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
pub struct MachineSize { pub struct MachineSize {
num_bits: usize, num_bits: usize,
} }

View File

@ -8,10 +8,11 @@ use crate::mir::alloc::{read_target_int, read_target_uint, AllocId};
use crate::mir::mono::StaticDef; use crate::mir::mono::StaticDef;
use crate::target::MachineInfo; use crate::target::MachineInfo;
use crate::{Filename, Opaque}; use crate::{Filename, Opaque};
use serde::Serialize;
use std::fmt::{self, Debug, Display, Formatter}; use std::fmt::{self, Debug, Display, Formatter};
use std::ops::Range; use std::ops::Range;
#[derive(Copy, Clone, Eq, PartialEq, Hash)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize)]
pub struct Ty(usize); pub struct Ty(usize);
impl Debug for Ty { impl Debug for Ty {
@ -100,13 +101,13 @@ impl Ty {
} }
/// Represents a pattern in the type system /// Represents a pattern in the type system
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum Pattern { pub enum Pattern {
Range { start: Option<TyConst>, end: Option<TyConst>, include_end: bool }, Range { start: Option<TyConst>, end: Option<TyConst>, include_end: bool },
} }
/// Represents a constant in the type system /// Represents a constant in the type system
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct TyConst { pub struct TyConst {
pub(crate) kind: TyConstKind, pub(crate) kind: TyConstKind,
pub id: TyConstId, pub id: TyConstId,
@ -133,7 +134,7 @@ impl TyConst {
} }
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum TyConstKind { pub enum TyConstKind {
Param(ParamConst), Param(ParamConst),
Bound(DebruijnIndex, BoundVar), Bound(DebruijnIndex, BoundVar),
@ -144,11 +145,11 @@ pub enum TyConstKind {
ZSTValue(Ty), ZSTValue(Ty),
} }
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
pub struct TyConstId(usize); pub struct TyConstId(usize);
/// Represents a constant in MIR /// Represents a constant in MIR
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct MirConst { pub struct MirConst {
/// The constant kind. /// The constant kind.
pub(crate) kind: ConstantKind, pub(crate) kind: ConstantKind,
@ -205,17 +206,17 @@ impl MirConst {
} }
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
pub struct MirConstId(usize); pub struct MirConstId(usize);
type Ident = Opaque; type Ident = Opaque;
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct Region { pub struct Region {
pub kind: RegionKind, pub kind: RegionKind,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum RegionKind { pub enum RegionKind {
ReEarlyParam(EarlyParamRegion), ReEarlyParam(EarlyParamRegion),
ReBound(DebruijnIndex, BoundRegion), ReBound(DebruijnIndex, BoundRegion),
@ -226,7 +227,7 @@ pub enum RegionKind {
pub(crate) type DebruijnIndex = u32; pub(crate) type DebruijnIndex = u32;
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct EarlyParamRegion { pub struct EarlyParamRegion {
pub index: u32, pub index: u32,
pub name: Symbol, pub name: Symbol,
@ -234,7 +235,7 @@ pub struct EarlyParamRegion {
pub(crate) type BoundVar = u32; pub(crate) type BoundVar = u32;
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct BoundRegion { pub struct BoundRegion {
pub var: BoundVar, pub var: BoundVar,
pub kind: BoundRegionKind, pub kind: BoundRegionKind,
@ -242,13 +243,13 @@ pub struct BoundRegion {
pub(crate) type UniverseIndex = u32; pub(crate) type UniverseIndex = u32;
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct Placeholder<T> { pub struct Placeholder<T> {
pub universe: UniverseIndex, pub universe: UniverseIndex,
pub bound: T, pub bound: T,
} }
#[derive(Clone, Copy, PartialEq, Eq)] #[derive(Clone, Copy, PartialEq, Eq, Serialize)]
pub struct Span(usize); pub struct Span(usize);
impl Debug for Span { impl Debug for Span {
@ -272,7 +273,7 @@ impl Span {
} }
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug, Serialize)]
/// Information you get from `Span` in a struct form. /// Information you get from `Span` in a struct form.
/// Line and col start from 1. /// Line and col start from 1.
pub struct LineInfo { pub struct LineInfo {
@ -282,7 +283,7 @@ pub struct LineInfo {
pub end_col: usize, pub end_col: usize,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum TyKind { pub enum TyKind {
RigidTy(RigidTy), RigidTy(RigidTy),
Alias(AliasKind, AliasTy), Alias(AliasKind, AliasTy),
@ -521,7 +522,7 @@ pub struct TypeAndMut {
pub mutability: Mutability, pub mutability: Mutability,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum RigidTy { pub enum RigidTy {
Bool, Bool,
Char, Char,
@ -560,7 +561,7 @@ impl From<RigidTy> for TyKind {
} }
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
pub enum IntTy { pub enum IntTy {
Isize, Isize,
I8, I8,
@ -583,7 +584,7 @@ impl IntTy {
} }
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
pub enum UintTy { pub enum UintTy {
Usize, Usize,
U8, U8,
@ -606,7 +607,7 @@ impl UintTy {
} }
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
pub enum FloatTy { pub enum FloatTy {
F16, F16,
F32, F32,
@ -614,13 +615,14 @@ pub enum FloatTy {
F128, F128,
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
pub enum Movability { pub enum Movability {
Static, Static,
Movable, Movable,
} }
crate_def! { crate_def! {
#[derive(Serialize)]
pub ForeignModuleDef; pub ForeignModuleDef;
} }
@ -643,6 +645,7 @@ impl ForeignModule {
crate_def_with_ty! { crate_def_with_ty! {
/// Hold information about a ForeignItem in a crate. /// Hold information about a ForeignItem in a crate.
#[derive(Serialize)]
pub ForeignDef; pub ForeignDef;
} }
@ -652,7 +655,7 @@ impl ForeignDef {
} }
} }
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
pub enum ForeignItemKind { pub enum ForeignItemKind {
Fn(FnDef), Fn(FnDef),
Static(StaticDef), Static(StaticDef),
@ -661,6 +664,7 @@ pub enum ForeignItemKind {
crate_def_with_ty! { crate_def_with_ty! {
/// Hold information about a function definition in a crate. /// Hold information about a function definition in a crate.
#[derive(Serialize)]
pub FnDef; pub FnDef;
} }
@ -694,6 +698,7 @@ impl FnDef {
} }
crate_def_with_ty! { crate_def_with_ty! {
#[derive(Serialize)]
pub IntrinsicDef; pub IntrinsicDef;
} }
@ -718,26 +723,31 @@ impl From<IntrinsicDef> for FnDef {
} }
crate_def! { crate_def! {
#[derive(Serialize)]
pub ClosureDef; pub ClosureDef;
} }
crate_def! { crate_def! {
#[derive(Serialize)]
pub CoroutineDef; pub CoroutineDef;
} }
crate_def! { crate_def! {
#[derive(Serialize)]
pub ParamDef; pub ParamDef;
} }
crate_def! { crate_def! {
#[derive(Serialize)]
pub BrNamedDef; pub BrNamedDef;
} }
crate_def_with_ty! { crate_def! {
#[derive(Serialize)]
pub AdtDef; pub AdtDef;
} }
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
pub enum AdtKind { pub enum AdtKind {
Enum, Enum,
Union, Union,
@ -791,7 +801,7 @@ impl AdtDef {
} }
/// Definition of a variant, which can be either a struct / union field or an enum variant. /// Definition of a variant, which can be either a struct / union field or an enum variant.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
pub struct VariantDef { pub struct VariantDef {
/// The variant index. /// The variant index.
/// ///
@ -820,7 +830,7 @@ impl VariantDef {
} }
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct FieldDef { pub struct FieldDef {
/// The field definition. /// The field definition.
/// ///
@ -871,11 +881,13 @@ impl AdtKind {
} }
crate_def! { crate_def! {
#[derive(Serialize)]
pub AliasDef; pub AliasDef;
} }
crate_def! { crate_def! {
/// A trait's definition. /// A trait's definition.
#[derive(Serialize)]
pub TraitDef; pub TraitDef;
} }
@ -886,15 +898,18 @@ impl TraitDef {
} }
crate_def! { crate_def! {
#[derive(Serialize)]
pub GenericDef; pub GenericDef;
} }
crate_def_with_ty! { crate_def_with_ty! {
#[derive(Serialize)]
pub ConstDef; pub ConstDef;
} }
crate_def! { crate_def! {
/// A trait impl definition. /// A trait impl definition.
#[derive(Serialize)]
pub ImplDef; pub ImplDef;
} }
@ -906,15 +921,17 @@ impl ImplDef {
} }
crate_def! { crate_def! {
#[derive(Serialize)]
pub RegionDef; pub RegionDef;
} }
crate_def! { crate_def! {
#[derive(Serialize)]
pub CoroutineWitnessDef; pub CoroutineWitnessDef;
} }
/// A list of generic arguments. /// A list of generic arguments.
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct GenericArgs(pub Vec<GenericArgKind>); pub struct GenericArgs(pub Vec<GenericArgKind>);
impl std::ops::Index<ParamTy> for GenericArgs { impl std::ops::Index<ParamTy> for GenericArgs {
@ -933,7 +950,7 @@ impl std::ops::Index<ParamConst> for GenericArgs {
} }
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum GenericArgKind { pub enum GenericArgKind {
Lifetime(Region), Lifetime(Region),
Type(Ty), Type(Ty),
@ -970,13 +987,13 @@ impl GenericArgKind {
} }
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum TermKind { pub enum TermKind {
Type(Ty), Type(Ty),
Const(TyConst), Const(TyConst),
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum AliasKind { pub enum AliasKind {
Projection, Projection,
Inherent, Inherent,
@ -984,13 +1001,13 @@ pub enum AliasKind {
Weak, Weak,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct AliasTy { pub struct AliasTy {
pub def_id: AliasDef, pub def_id: AliasDef,
pub args: GenericArgs, pub args: GenericArgs,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct AliasTerm { pub struct AliasTerm {
pub def_id: AliasDef, pub def_id: AliasDef,
pub args: GenericArgs, pub args: GenericArgs,
@ -1008,7 +1025,7 @@ impl PolyFnSig {
} }
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct FnSig { pub struct FnSig {
pub inputs_and_output: Vec<Ty>, pub inputs_and_output: Vec<Ty>,
pub c_variadic: bool, pub c_variadic: bool,
@ -1026,7 +1043,7 @@ impl FnSig {
} }
} }
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug, Serialize)]
pub enum Abi { pub enum Abi {
Rust, Rust,
C { unwind: bool }, C { unwind: bool },
@ -1055,7 +1072,7 @@ pub enum Abi {
} }
/// A binder represents a possibly generic type and its bound vars. /// A binder represents a possibly generic type and its bound vars.
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct Binder<T> { pub struct Binder<T> {
pub value: T, pub value: T,
pub bound_vars: Vec<BoundVariableKind>, pub bound_vars: Vec<BoundVariableKind>,
@ -1095,38 +1112,38 @@ impl<T> Binder<T> {
} }
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct EarlyBinder<T> { pub struct EarlyBinder<T> {
pub value: T, pub value: T,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum BoundVariableKind { pub enum BoundVariableKind {
Ty(BoundTyKind), Ty(BoundTyKind),
Region(BoundRegionKind), Region(BoundRegionKind),
Const, Const,
} }
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug, Serialize)]
pub enum BoundTyKind { pub enum BoundTyKind {
Anon, Anon,
Param(ParamDef, String), Param(ParamDef, String),
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum BoundRegionKind { pub enum BoundRegionKind {
BrAnon, BrAnon,
BrNamed(BrNamedDef, String), BrNamed(BrNamedDef, String),
BrEnv, BrEnv,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum DynKind { pub enum DynKind {
Dyn, Dyn,
DynStar, DynStar,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum ExistentialPredicate { pub enum ExistentialPredicate {
Trait(ExistentialTraitRef), Trait(ExistentialTraitRef),
Projection(ExistentialProjection), Projection(ExistentialProjection),
@ -1136,7 +1153,7 @@ pub enum ExistentialPredicate {
/// An existential reference to a trait where `Self` is not included. /// An existential reference to a trait where `Self` is not included.
/// ///
/// The `generic_args` will include any other known argument. /// The `generic_args` will include any other known argument.
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct ExistentialTraitRef { pub struct ExistentialTraitRef {
pub def_id: TraitDef, pub def_id: TraitDef,
pub generic_args: GenericArgs, pub generic_args: GenericArgs,
@ -1154,20 +1171,20 @@ impl ExistentialTraitRef {
} }
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct ExistentialProjection { pub struct ExistentialProjection {
pub def_id: TraitDef, pub def_id: TraitDef,
pub generic_args: GenericArgs, pub generic_args: GenericArgs,
pub term: TermKind, pub term: TermKind,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct ParamTy { pub struct ParamTy {
pub index: u32, pub index: u32,
pub name: String, pub name: String,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct BoundTy { pub struct BoundTy {
pub var: usize, pub var: usize,
pub kind: BoundTyKind, pub kind: BoundTyKind,
@ -1178,7 +1195,7 @@ pub type Bytes = Vec<Option<u8>>;
/// Size in bytes. /// Size in bytes.
pub type Size = usize; pub type Size = usize;
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
pub struct Prov(pub AllocId); pub struct Prov(pub AllocId);
pub type Align = u64; pub type Align = u64;
@ -1186,14 +1203,14 @@ pub type Promoted = u32;
pub type InitMaskMaterialized = Vec<u64>; pub type InitMaskMaterialized = Vec<u64>;
/// Stores the provenance information of pointers stored in memory. /// Stores the provenance information of pointers stored in memory.
#[derive(Clone, Debug, Eq, PartialEq, Hash)] #[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
pub struct ProvenanceMap { pub struct ProvenanceMap {
/// Provenance in this map applies from the given offset for an entire pointer-size worth of /// Provenance in this map applies from the given offset for an entire pointer-size worth of
/// bytes. Two entries in this map are always at least a pointer size apart. /// bytes. Two entries in this map are always at least a pointer size apart.
pub ptrs: Vec<(Size, Prov)>, pub ptrs: Vec<(Size, Prov)>,
} }
#[derive(Clone, Debug, Eq, PartialEq, Hash)] #[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
pub struct Allocation { pub struct Allocation {
pub bytes: Bytes, pub bytes: Bytes,
pub provenance: ProvenanceMap, pub provenance: ProvenanceMap,
@ -1269,7 +1286,7 @@ impl Allocation {
} }
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum ConstantKind { pub enum ConstantKind {
Ty(TyConst), Ty(TyConst),
Allocated(Allocation), Allocated(Allocation),
@ -1280,27 +1297,27 @@ pub enum ConstantKind {
ZeroSized, ZeroSized,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct ParamConst { pub struct ParamConst {
pub index: u32, pub index: u32,
pub name: String, pub name: String,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct UnevaluatedConst { pub struct UnevaluatedConst {
pub def: ConstDef, pub def: ConstDef,
pub args: GenericArgs, pub args: GenericArgs,
pub promoted: Option<Promoted>, pub promoted: Option<Promoted>,
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
pub enum TraitSpecializationKind { pub enum TraitSpecializationKind {
None, None,
Marker, Marker,
AlwaysApplicable, AlwaysApplicable,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct TraitDecl { pub struct TraitDecl {
pub def_id: TraitDef, pub def_id: TraitDef,
pub safety: Safety, pub safety: Safety,
@ -1333,7 +1350,7 @@ impl TraitDecl {
pub type ImplTrait = EarlyBinder<TraitRef>; pub type ImplTrait = EarlyBinder<TraitRef>;
/// A complete reference to a trait, i.e., one where `Self` is known. /// A complete reference to a trait, i.e., one where `Self` is known.
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct TraitRef { pub struct TraitRef {
pub def_id: TraitDef, pub def_id: TraitDef,
/// The generic arguments for this definition. /// The generic arguments for this definition.
@ -1367,7 +1384,7 @@ impl TraitRef {
} }
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct Generics { pub struct Generics {
pub parent: Option<GenericDef>, pub parent: Option<GenericDef>,
pub parent_count: usize, pub parent_count: usize,
@ -1378,14 +1395,14 @@ pub struct Generics {
pub host_effect_index: Option<usize>, pub host_effect_index: Option<usize>,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum GenericParamDefKind { pub enum GenericParamDefKind {
Lifetime, Lifetime,
Type { has_default: bool, synthetic: bool }, Type { has_default: bool, synthetic: bool },
Const { has_default: bool }, Const { has_default: bool },
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct GenericParamDef { pub struct GenericParamDef {
pub name: super::Symbol, pub name: super::Symbol,
pub def_id: GenericDef, pub def_id: GenericDef,
@ -1399,7 +1416,7 @@ pub struct GenericPredicates {
pub predicates: Vec<(PredicateKind, Span)>, pub predicates: Vec<(PredicateKind, Span)>,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum PredicateKind { pub enum PredicateKind {
Clause(ClauseKind), Clause(ClauseKind),
ObjectSafe(TraitDef), ObjectSafe(TraitDef),
@ -1410,7 +1427,7 @@ pub enum PredicateKind {
AliasRelate(TermKind, TermKind, AliasRelationDirection), AliasRelate(TermKind, TermKind, AliasRelationDirection),
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum ClauseKind { pub enum ClauseKind {
Trait(TraitPredicate), Trait(TraitPredicate),
RegionOutlives(RegionOutlivesPredicate), RegionOutlives(RegionOutlivesPredicate),
@ -1421,57 +1438,57 @@ pub enum ClauseKind {
ConstEvaluatable(TyConst), ConstEvaluatable(TyConst),
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum ClosureKind { pub enum ClosureKind {
Fn, Fn,
FnMut, FnMut,
FnOnce, FnOnce,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct SubtypePredicate { pub struct SubtypePredicate {
pub a: Ty, pub a: Ty,
pub b: Ty, pub b: Ty,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct CoercePredicate { pub struct CoercePredicate {
pub a: Ty, pub a: Ty,
pub b: Ty, pub b: Ty,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum AliasRelationDirection { pub enum AliasRelationDirection {
Equate, Equate,
Subtype, Subtype,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct TraitPredicate { pub struct TraitPredicate {
pub trait_ref: TraitRef, pub trait_ref: TraitRef,
pub polarity: PredicatePolarity, pub polarity: PredicatePolarity,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct OutlivesPredicate<A, B>(pub A, pub B); pub struct OutlivesPredicate<A, B>(pub A, pub B);
pub type RegionOutlivesPredicate = OutlivesPredicate<Region, Region>; pub type RegionOutlivesPredicate = OutlivesPredicate<Region, Region>;
pub type TypeOutlivesPredicate = OutlivesPredicate<Ty, Region>; pub type TypeOutlivesPredicate = OutlivesPredicate<Ty, Region>;
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct ProjectionPredicate { pub struct ProjectionPredicate {
pub projection_term: AliasTerm, pub projection_term: AliasTerm,
pub term: TermKind, pub term: TermKind,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum ImplPolarity { pub enum ImplPolarity {
Positive, Positive,
Negative, Negative,
Reservation, Reservation,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum PredicatePolarity { pub enum PredicatePolarity {
Positive, Positive,
Negative, Negative,
@ -1514,7 +1531,7 @@ index_impl!(Span);
/// `a` is in the variant with the `VariantIdx` of `0`, /// `a` is in the variant with the `VariantIdx` of `0`,
/// `c` is in the variant with the `VariantIdx` of `1`, and /// `c` is in the variant with the `VariantIdx` of `1`, and
/// `g` is in the variant with the `VariantIdx` of `0`. /// `g` is in the variant with the `VariantIdx` of `0`.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
pub struct VariantIdx(usize); pub struct VariantIdx(usize);
index_impl!(VariantIdx); index_impl!(VariantIdx);

View File

@ -0,0 +1,75 @@
//@ run-pass
//! Test that users are able to use serialize stable MIR constructs.
//@ ignore-stage1
//@ ignore-cross-compile
//@ ignore-remote
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
//@ edition: 2021
#![feature(rustc_private)]
#![feature(assert_matches)]
#![feature(control_flow_enum)]
#[macro_use]
extern crate rustc_smir;
extern crate rustc_driver;
extern crate rustc_interface;
extern crate rustc_middle;
extern crate stable_mir;
extern crate serde;
extern crate serde_json;
use rustc_middle::ty::TyCtxt;
use rustc_smir::rustc_internal;
use stable_mir::mir::Body;
use std::io::{Write, BufWriter};
use std::ops::ControlFlow;
use serde_json::to_string;
const CRATE_NAME: &str = "input";
fn serialize_to_json(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
let path = "output.json";
let mut writer = BufWriter::new(std::fs::File::create(path)
.expect("Failed to create path"));
let local_crate = stable_mir::local_crate();
let items: Vec<Body> = stable_mir::all_local_items()
.iter()
.map(|item| { item.body() })
.collect();
let crate_data = ( local_crate.name, items );
writer.write_all(to_string(&crate_data)
.expect("serde_json failed")
.as_bytes()).expect("JSON serialization failed");
ControlFlow::Continue(())
}
/// This test will generate and analyze a dummy crate using the stable mir.
/// For that, it will first write the dummy crate into a file.
/// Then it will create a `StableMir` using custom arguments and then
/// it will run the compiler.
fn main() {
let path = "internal_input.rs";
generate_input(&path).unwrap();
let args = vec![
"rustc".to_string(),
"--crate-name".to_string(),
CRATE_NAME.to_string(),
path.to_string(),
];
run_with_tcx!(args, serialize_to_json).unwrap();
}
fn generate_input(path: &str) -> std::io::Result<()> {
let mut file = std::fs::File::create(path)?;
write!(
file,
r#"
pub fn main() {{
}}
"#
)?;
Ok(())
}