add serde derive Serialize to stable_mir

This commit is contained in:
Stephen Skeirik 2024-06-17 17:01:38 -04:00
parent c290e9de32
commit 414ebeaeea
11 changed files with 242 additions and 139 deletions

View file

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

View file

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

View file

@ -5,12 +5,13 @@
use crate::ty::{Align, IndexedVal, Ty, VariantIdx};
use crate::Error;
use crate::Opaque;
use serde::Serialize;
use std::fmt::{self, Debug};
use std::num::NonZero;
use std::ops::RangeInclusive;
/// A function ABI definition.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub struct FnAbi {
/// The types of each argument.
pub args: Vec<ArgAbi>,
@ -31,7 +32,7 @@ pub struct FnAbi {
}
/// 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 ty: Ty,
pub layout: Layout,
@ -39,7 +40,7 @@ pub struct ArgAbi {
}
/// 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 {
/// Ignore the argument.
///
@ -60,14 +61,14 @@ pub enum PassMode {
}
/// 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 ty: Ty,
pub layout: Layout,
}
/// The layout of a type in memory.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub struct LayoutShape {
/// The fields location withing the layout
pub fields: FieldsShape,
@ -108,7 +109,7 @@ pub fn is_1zst(&self) -> bool {
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub struct Layout(usize);
impl Layout {
@ -127,7 +128,7 @@ fn to_index(&self) -> usize {
}
/// 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 {
/// Scalar primitives and `!`, which never have fields.
Primitive,
@ -177,7 +178,7 @@ pub fn count(&self) -> usize {
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum VariantsShape {
/// Single enum variants, structs/tuples, unions, and all non-ADTs.
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 {
/// The tag directly stores the discriminant, but possibly with a smaller layout
/// (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,
/// 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 {
Uninhabited,
Scalar(Scalar),
@ -250,7 +251,7 @@ pub fn is_unsized(&self) -> bool {
}
/// 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 {
Initialized {
/// The primitive type used to represent this value.
@ -280,7 +281,7 @@ pub fn has_niche(&self, target: &MachineInfo) -> bool {
}
/// 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 {
/// The `bool` is the signedness of the `Integer` type.
///
@ -310,7 +311,7 @@ pub fn size(self, target: &MachineInfo) -> Size {
}
/// 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 {
I8,
I16,
@ -320,7 +321,7 @@ pub enum IntegerLength {
}
/// 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 {
F16,
F32,
@ -354,7 +355,7 @@ pub fn bits(self) -> usize {
/// An identifier that specifies the address space that some operation
/// should operate on. Special address spaces have an effect on code generation,
/// 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);
impl AddressSpace {
@ -369,7 +370,7 @@ impl AddressSpace {
/// sequence:
///
/// 254 (-2), 255 (-1), 0, 1, 2
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)]
pub struct WrappingRange {
pub start: u128,
pub end: u128,
@ -420,7 +421,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
}
/// General language calling conventions.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum CallConvention {
C,
Rust,

View file

@ -3,9 +3,10 @@
use crate::ty::{GenericArgs, Span, Ty};
use crate::{with, Crate, Symbol};
use serde::Serialize;
/// 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);
/// A trait for retrieving information about a particular definition.

View file

@ -27,6 +27,7 @@
use crate::mir::Body;
use crate::mir::Mutability;
use crate::ty::{ForeignModuleDef, ImplDef, IndexedVal, Span, TraitDef, Ty};
use serde::Serialize;
pub mod abi;
#[macro_use]
@ -74,7 +75,7 @@ fn to_index(&self) -> usize {
pub type ImplTraitDecls = Vec<ImplDef>;
/// Holds information about a crate.
#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
pub struct Crate {
pub id: CrateNum,
pub name: Symbol,
@ -98,7 +99,7 @@ pub fn trait_impls(&self) -> ImplTraitDecls {
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)]
pub enum ItemKind {
Fn,
Static,
@ -106,7 +107,7 @@ pub enum ItemKind {
Ctor(CtorKind),
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)]
pub enum CtorKind {
Const,
Fn,
@ -116,6 +117,7 @@ pub enum CtorKind {
crate_def_with_ty! {
/// Holds information about an item in a crate.
#[derive(Serialize)]
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.
#[derive(Clone, PartialEq, Eq, Hash)]
#[derive(Clone, PartialEq, Eq, Hash, Serialize)]
pub struct Opaque(String);
impl std::fmt::Display for Opaque {

View file

@ -4,11 +4,12 @@
use crate::target::{Endian, MachineInfo};
use crate::ty::{Allocation, Binder, ExistentialTraitRef, IndexedVal, Ty};
use crate::{with, Error};
use serde::Serialize;
use std::io::Read;
/// An allocation in the SMIR global memory can be either a function pointer,
/// 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 {
/// The alloc ID is used as a function pointer.
Function(Instance),
@ -41,7 +42,7 @@ pub fn vtable_allocation(&self) -> Option<AllocId> {
}
/// 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);
impl IndexedVal for AllocId {

View file

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

View file

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

View file

@ -1,9 +1,10 @@
//! Provide information about the machine that this is being compiled into.
use crate::compiler_interface::with;
use serde::Serialize;
/// The properties of the target machine being compiled into.
#[derive(Clone, PartialEq, Eq)]
#[derive(Clone, PartialEq, Eq, Serialize)]
pub struct MachineInfo {
pub endian: Endian,
pub pointer_width: MachineSize,
@ -23,14 +24,14 @@ pub fn target_pointer_width() -> MachineSize {
}
}
#[derive(Copy, Clone, PartialEq, Eq)]
#[derive(Copy, Clone, PartialEq, Eq, Serialize)]
pub enum Endian {
Little,
Big,
}
/// 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 {
num_bits: usize,
}

View file

@ -8,10 +8,11 @@
use crate::mir::mono::StaticDef;
use crate::target::MachineInfo;
use crate::{Filename, Opaque};
use serde::Serialize;
use std::fmt::{self, Debug, Display, Formatter};
use std::ops::Range;
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize)]
pub struct Ty(usize);
impl Debug for Ty {
@ -100,13 +101,13 @@ pub fn kind(&self) -> TyKind {
}
/// Represents a pattern in the type system
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum Pattern {
Range { start: Option<TyConst>, end: Option<TyConst>, include_end: bool },
}
/// Represents a constant in the type system
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct TyConst {
pub(crate) kind: TyConstKind,
pub id: TyConstId,
@ -133,7 +134,7 @@ pub fn eval_target_usize(&self) -> Result<u64, Error> {
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum TyConstKind {
Param(ParamConst),
Bound(DebruijnIndex, BoundVar),
@ -144,11 +145,11 @@ pub enum TyConstKind {
ZSTValue(Ty),
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
pub struct TyConstId(usize);
/// Represents a constant in MIR
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct MirConst {
/// The constant kind.
pub(crate) kind: ConstantKind,
@ -205,17 +206,17 @@ pub fn try_from_uint(value: u128, uint_ty: UintTy) -> Result<MirConst, Error> {
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
pub struct MirConstId(usize);
type Ident = Opaque;
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct Region {
pub kind: RegionKind,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum RegionKind {
ReEarlyParam(EarlyParamRegion),
ReBound(DebruijnIndex, BoundRegion),
@ -226,7 +227,7 @@ pub enum RegionKind {
pub(crate) type DebruijnIndex = u32;
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct EarlyParamRegion {
pub index: u32,
pub name: Symbol,
@ -234,7 +235,7 @@ pub struct EarlyParamRegion {
pub(crate) type BoundVar = u32;
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct BoundRegion {
pub var: BoundVar,
pub kind: BoundRegionKind,
@ -242,13 +243,13 @@ pub struct BoundRegion {
pub(crate) type UniverseIndex = u32;
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct Placeholder<T> {
pub universe: UniverseIndex,
pub bound: T,
}
#[derive(Clone, Copy, PartialEq, Eq)]
#[derive(Clone, Copy, PartialEq, Eq, Serialize)]
pub struct Span(usize);
impl Debug for Span {
@ -272,7 +273,7 @@ pub fn get_lines(&self) -> LineInfo {
}
}
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, Serialize)]
/// Information you get from `Span` in a struct form.
/// Line and col start from 1.
pub struct LineInfo {
@ -282,7 +283,7 @@ pub struct LineInfo {
pub end_col: usize,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum TyKind {
RigidTy(RigidTy),
Alias(AliasKind, AliasTy),
@ -521,7 +522,7 @@ pub struct TypeAndMut {
pub mutability: Mutability,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum RigidTy {
Bool,
Char,
@ -560,7 +561,7 @@ fn from(value: RigidTy) -> Self {
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
pub enum IntTy {
Isize,
I8,
@ -583,7 +584,7 @@ pub fn num_bytes(self) -> usize {
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
pub enum UintTy {
Usize,
U8,
@ -606,19 +607,20 @@ pub fn num_bytes(self) -> usize {
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
pub enum FloatTy {
F32,
F64,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
pub enum Movability {
Static,
Movable,
}
crate_def! {
#[derive(Serialize)]
pub ForeignModuleDef;
}
@ -641,6 +643,7 @@ pub fn items(&self) -> Vec<ForeignDef> {
crate_def_with_ty! {
/// Hold information about a ForeignItem in a crate.
#[derive(Serialize)]
pub ForeignDef;
}
@ -650,7 +653,7 @@ pub fn kind(&self) -> ForeignItemKind {
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
pub enum ForeignItemKind {
Fn(FnDef),
Static(StaticDef),
@ -659,6 +662,7 @@ pub enum ForeignItemKind {
crate_def_with_ty! {
/// Hold information about a function definition in a crate.
#[derive(Serialize)]
pub FnDef;
}
@ -692,6 +696,7 @@ pub fn fn_sig(&self) -> PolyFnSig {
}
crate_def_with_ty! {
#[derive(Serialize)]
pub IntrinsicDef;
}
@ -716,26 +721,31 @@ fn from(def: IntrinsicDef) -> Self {
}
crate_def! {
#[derive(Serialize)]
pub ClosureDef;
}
crate_def! {
#[derive(Serialize)]
pub CoroutineDef;
}
crate_def! {
#[derive(Serialize)]
pub ParamDef;
}
crate_def! {
#[derive(Serialize)]
pub BrNamedDef;
}
crate_def_with_ty! {
crate_def! {
#[derive(Serialize)]
pub AdtDef;
}
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
pub enum AdtKind {
Enum,
Union,
@ -789,7 +799,7 @@ pub fn variant(&self, idx: VariantIdx) -> Option<VariantDef> {
}
/// 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 {
/// The variant index.
///
@ -818,7 +828,7 @@ pub fn fields(&self) -> Vec<FieldDef> {
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct FieldDef {
/// The field definition.
///
@ -869,11 +879,13 @@ pub fn is_union(&self) -> bool {
}
crate_def! {
#[derive(Serialize)]
pub AliasDef;
}
crate_def! {
/// A trait's definition.
#[derive(Serialize)]
pub TraitDef;
}
@ -884,15 +896,18 @@ pub fn declaration(trait_def: &TraitDef) -> TraitDecl {
}
crate_def! {
#[derive(Serialize)]
pub GenericDef;
}
crate_def_with_ty! {
#[derive(Serialize)]
pub ConstDef;
}
crate_def! {
/// A trait impl definition.
#[derive(Serialize)]
pub ImplDef;
}
@ -904,15 +919,17 @@ pub fn trait_impl(&self) -> ImplTrait {
}
crate_def! {
#[derive(Serialize)]
pub RegionDef;
}
crate_def! {
#[derive(Serialize)]
pub CoroutineWitnessDef;
}
/// A list of generic arguments.
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct GenericArgs(pub Vec<GenericArgKind>);
impl std::ops::Index<ParamTy> for GenericArgs {
@ -931,7 +948,7 @@ fn index(&self, index: ParamConst) -> &Self::Output {
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum GenericArgKind {
Lifetime(Region),
Type(Ty),
@ -968,13 +985,13 @@ pub fn ty(&self) -> Option<&Ty> {
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum TermKind {
Type(Ty),
Const(TyConst),
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum AliasKind {
Projection,
Inherent,
@ -982,13 +999,13 @@ pub enum AliasKind {
Weak,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct AliasTy {
pub def_id: AliasDef,
pub args: GenericArgs,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct AliasTerm {
pub def_id: AliasDef,
pub args: GenericArgs,
@ -1006,7 +1023,7 @@ pub fn fn_ptr_abi(self) -> Result<FnAbi, Error> {
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct FnSig {
pub inputs_and_output: Vec<Ty>,
pub c_variadic: bool,
@ -1024,7 +1041,7 @@ pub fn inputs(&self) -> &[Ty] {
}
}
#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
pub enum Abi {
Rust,
C { unwind: bool },
@ -1054,7 +1071,7 @@ pub enum Abi {
}
/// 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 value: T,
pub bound_vars: Vec<BoundVariableKind>,
@ -1094,38 +1111,38 @@ pub fn map_bound<F, U>(self, f: F) -> Binder<U>
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct EarlyBinder<T> {
pub value: T,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum BoundVariableKind {
Ty(BoundTyKind),
Region(BoundRegionKind),
Const,
}
#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
pub enum BoundTyKind {
Anon,
Param(ParamDef, String),
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum BoundRegionKind {
BrAnon,
BrNamed(BrNamedDef, String),
BrEnv,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum DynKind {
Dyn,
DynStar,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum ExistentialPredicate {
Trait(ExistentialTraitRef),
Projection(ExistentialProjection),
@ -1135,7 +1152,7 @@ pub enum ExistentialPredicate {
/// An existential reference to a trait where `Self` is not included.
///
/// The `generic_args` will include any other known argument.
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct ExistentialTraitRef {
pub def_id: TraitDef,
pub generic_args: GenericArgs,
@ -1153,20 +1170,20 @@ pub fn with_self_ty(&self, self_ty: Ty) -> TraitRef {
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct ExistentialProjection {
pub def_id: TraitDef,
pub generic_args: GenericArgs,
pub term: TermKind,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct ParamTy {
pub index: u32,
pub name: String,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct BoundTy {
pub var: usize,
pub kind: BoundTyKind,
@ -1177,7 +1194,7 @@ pub struct BoundTy {
/// Size in bytes.
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 type Align = u64;
@ -1185,14 +1202,14 @@ pub struct BoundTy {
pub type InitMaskMaterialized = Vec<u64>;
/// 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 {
/// 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.
pub ptrs: Vec<(Size, Prov)>,
}
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
pub struct Allocation {
pub bytes: Bytes,
pub provenance: ProvenanceMap,
@ -1268,7 +1285,7 @@ pub fn is_null(&self) -> Result<bool, Error> {
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum ConstantKind {
Ty(TyConst),
Allocated(Allocation),
@ -1279,27 +1296,27 @@ pub enum ConstantKind {
ZeroSized,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct ParamConst {
pub index: u32,
pub name: String,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct UnevaluatedConst {
pub def: ConstDef,
pub args: GenericArgs,
pub promoted: Option<Promoted>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
pub enum TraitSpecializationKind {
None,
Marker,
AlwaysApplicable,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct TraitDecl {
pub def_id: TraitDef,
pub safety: Safety,
@ -1332,7 +1349,7 @@ pub fn explicit_predicates_of(&self) -> GenericPredicates {
pub type ImplTrait = EarlyBinder<TraitRef>;
/// 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 def_id: TraitDef,
/// The generic arguments for this definition.
@ -1366,7 +1383,7 @@ pub fn self_ty(&self) -> Ty {
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct Generics {
pub parent: Option<GenericDef>,
pub parent_count: usize,
@ -1377,14 +1394,14 @@ pub struct Generics {
pub host_effect_index: Option<usize>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum GenericParamDefKind {
Lifetime,
Type { has_default: bool, synthetic: bool },
Const { has_default: bool },
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct GenericParamDef {
pub name: super::Symbol,
pub def_id: GenericDef,
@ -1398,7 +1415,7 @@ pub struct GenericPredicates {
pub predicates: Vec<(PredicateKind, Span)>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum PredicateKind {
Clause(ClauseKind),
ObjectSafe(TraitDef),
@ -1409,7 +1426,7 @@ pub enum PredicateKind {
AliasRelate(TermKind, TermKind, AliasRelationDirection),
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum ClauseKind {
Trait(TraitPredicate),
RegionOutlives(RegionOutlivesPredicate),
@ -1420,57 +1437,57 @@ pub enum ClauseKind {
ConstEvaluatable(TyConst),
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum ClosureKind {
Fn,
FnMut,
FnOnce,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct SubtypePredicate {
pub a: Ty,
pub b: Ty,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct CoercePredicate {
pub a: Ty,
pub b: Ty,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum AliasRelationDirection {
Equate,
Subtype,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct TraitPredicate {
pub trait_ref: TraitRef,
pub polarity: PredicatePolarity,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct OutlivesPredicate<A, B>(pub A, pub B);
pub type RegionOutlivesPredicate = OutlivesPredicate<Region, Region>;
pub type TypeOutlivesPredicate = OutlivesPredicate<Ty, Region>;
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct ProjectionPredicate {
pub projection_term: AliasTerm,
pub term: TermKind,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum ImplPolarity {
Positive,
Negative,
Reservation,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum PredicatePolarity {
Positive,
Negative,
@ -1513,7 +1530,7 @@ fn to_index(&self) -> usize {
/// `a` is in the variant with the `VariantIdx` of `0`,
/// `c` is in the variant with the `VariantIdx` of `1`, and
/// `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);
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(())
}