Skip to main content

Body

Enum Body 

Source
pub enum Body {
    Unstructured(ExprBody),
    Structured(ExprBody),
    TargetDispatch(SeqHashMap<TargetTriple, FunDeclRef>),
    Extern(String),
    Intrinsic {
        name: String,
        arg_names: Vec<Option<String>>,
    },
    Opaque,
    Missing,
    Error(Error),
}
Expand description

The body of a function.

A normal function has a body that’s either structured or unstructured. These are two equivalent representations of the same function body, which only differ in how control-flow is represented. By default bodies are structured; passing --ullbc to Charon makes bodies unstructured.

Besides these, some functions have virtual bodies or no body, see the doc for each variant.

Variants§

§

Unstructured(ExprBody)

Body represented as a control-flow graph (CFG), i.e. with numbered blocks and jumps/GOTOs between them. This is available when passing --ullbc to Charon.

This is also the same structure as rustc’s MIR, and is in fact a direct translation of it.

§

Structured(ExprBody)

Body represented with structured control flow, i.e. with nested if/match/loop blocks. This is available when --ullbc is not passed to Charon.

This structure is recovered from the unstructured body in the ullbc_to_llbc pass.

§

TargetDispatch(SeqHashMap<TargetTriple, FunDeclRef>)

A façade body that dispatches to one of several per-target function bodies. This is created during multi-target merging (using --target) to represent functions that have a different implementation across targets.

§

Extern(String)

Function declared in an extern { ... } block. The string is the foreign symbol name.

§

Intrinsic

Rust intrinsic function. This has no body and describes a “built-in” operation that must be handled by the codegen backend.

Fields

§name: String

The intrinsic name.

§arg_names: Vec<Option<String>>

The argument names, None if not available.

§

Opaque

A body that the user chose not to translate, based on opacity settings like --include/--opaque.

§

Missing

A body that was not available.

These can occur when using a sysroot that doesn’t have MIR for all the standard library functions. This is the case of the sysroot that ships with every Rust toolchain, but Charon uses a custom-built sysroot that does. So this shouldn’t happen unless you’re passing --sysroot to charon.

§

Error(Error)

We encountered an error while translating this body.

Implementations§

Source§

impl Body

Source

pub fn is_unstructured(&self) -> bool

Source

pub fn is_structured(&self) -> bool

Source

pub fn is_target_dispatch(&self) -> bool

Source

pub fn is_extern(&self) -> bool

Source

pub fn is_intrinsic(&self) -> bool

Source

pub fn is_opaque(&self) -> bool

Source

pub fn is_missing(&self) -> bool

Source

pub fn is_error(&self) -> bool

Source§

impl Body

Source§

impl Body

Source

pub fn as_unstructured_mut(&mut self) -> Option<&mut ExprBody>

Source

pub fn as_structured_mut(&mut self) -> Option<&mut ExprBody>

Source

pub fn as_target_dispatch_mut( &mut self, ) -> Option<&mut SeqHashMap<TargetTriple, FunDeclRef>>

Source

pub fn as_extern_mut(&mut self) -> Option<&mut String>

Source

pub fn as_intrinsic_mut( &mut self, ) -> Option<(&mut String, &mut Vec<Option<String>>)>

Source

pub fn as_opaque_mut(&mut self) -> Option<()>

Source

pub fn as_missing_mut(&mut self) -> Option<()>

Source

pub fn as_error_mut(&mut self) -> Option<&mut Error>

Source§

impl Body

Source§

impl Body

Source

pub fn has_contents(&self) -> bool

Whether there is an actual body with statements etc, as opposed to the body being missing for some reason.

Source

pub fn locals(&self) -> &Locals

Trait Implementations§

Source§

impl AstVisitable for Body

Source§

fn drive<V: VisitAst>(&self, v: &mut V) -> ControlFlow<V::Break>

Recursively visit this type with the provided visitor. This calls the visitor’s visit_$any method if it exists, otherwise visit_inner.
Source§

fn drive_mut<V: VisitAstMut>(&mut self, v: &mut V) -> ControlFlow<V::Break>

Recursively visit this type with the provided visitor. This calls the visitor’s visit_$any method if it exists, otherwise visit_inner.
Source§

fn drive_two<V: ZipAst>(&self, other: &Self, v: &mut V) -> ControlFlow<V::Break>

Recursively visit this type with the provided visitor. This calls the visitor’s visit_$any method if it exists, otherwise visit_inner.
Source§

fn name(&self) -> &'static str

The name of the type, used for debug logging.
Source§

fn dyn_visit<T: AstVisitable>(&self, f: impl FnMut(&T))
where Self: Sized,

Visit all occurrences of that type inside self, in pre-order traversal.
Source§

fn dyn_visit_mut<T: AstVisitable>(&mut self, f: impl FnMut(&mut T))
where Self: Sized,

Visit all occurrences of that type inside self, in pre-order traversal.
Source§

impl BodyVisitable for Body

Source§

fn drive_body<V: VisitBody>(&self, v: &mut V) -> ControlFlow<V::Break>

Recursively visit this type with the provided visitor. This calls the visitor’s visit_$any method if it exists, otherwise visit_inner.
Source§

fn drive_body_mut<V: VisitBodyMut>( &mut self, v: &mut V, ) -> ControlFlow<V::Break>

Recursively visit this type with the provided visitor. This calls the visitor’s visit_$any method if it exists, otherwise visit_inner.
Source§

fn dyn_visit_in_body<T: BodyVisitable>(&self, f: impl FnMut(&T))
where Self: Sized,

Visit all occurrences of that type inside self, in pre-order traversal.
Source§

fn dyn_visit_in_body_mut<T: BodyVisitable>(&mut self, f: impl FnMut(&mut T))
where Self: Sized,

Visit all occurrences of that type inside self, in pre-order traversal.
Source§

impl Clone for Body

Source§

fn clone(&self) -> Body

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Body

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de, __State: ?Sized + DedupSerializerState> DeserializeState<'de, __State> for Body

Source§

fn deserialize_state<__D>( __state: &__State, __deserializer: __D, ) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Source§

impl<'s, V> Drive<'s, V> for Body
where V: Visitor + Visit<'s, ExprBody> + Visit<'s, ExprBody> + Visit<'s, SeqHashMap<TargetTriple, FunDeclRef>> + Visit<'s, String> + Visit<'s, Vec<Option<String>>> + Visit<'s, Error>,

Source§

fn drive_inner(&'s self, visitor: &mut V) -> ControlFlow<V::Break>

Call v.visit() on the immediate contents of self.
Source§

impl<'s, V> DriveMut<'s, V> for Body
where V: Visitor + VisitMut<'s, ExprBody> + VisitMut<'s, ExprBody> + VisitMut<'s, SeqHashMap<TargetTriple, FunDeclRef>> + VisitMut<'s, String> + VisitMut<'s, Vec<Option<String>>> + VisitMut<'s, Error>,

Source§

fn drive_inner_mut(&'s mut self, visitor: &mut V) -> ControlFlow<V::Break>

Call v.visit() on the immediate contents of self.
Source§

impl<'s, V> DriveTwo<'s, V> for Body
where V: Visitor<Break: Default> + VisitTwo<'s, ExprBody> + VisitTwo<'s, ExprBody> + VisitTwo<'s, SeqHashMap<TargetTriple, FunDeclRef>> + VisitTwo<'s, String> + VisitTwo<'s, Vec<Option<String>>> + VisitTwo<'s, Error>,

Source§

fn drive_two_inner( &'s self, other: &'s Self, visitor: &mut V, ) -> ControlFlow<V::Break>

Call v.visit() on the immediate contents of self and other, if they correspond. If the values don’t match up, this returns Break(Default::default()).
Source§

impl<C: AstFormatter> FmtWithCtx<C> for Body

Source§

fn fmt_with_ctx(&self, ctx: &C, f: &mut Formatter<'_>) -> Result

Source§

fn with_ctx<'a>(&'a self, ctx: &'a C) -> WithCtx<'a, C, Self>

Returns a struct that implements Display. This allows the following: Read more
Source§

fn to_string_with_ctx(&self, ctx: &C) -> String

Source§

impl<__State: ?Sized + DedupSerializerState> SerializeState<__State> for Body

Source§

fn serialize_state<__S>( &self, __state: &__State, __serializer: __S, ) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Auto Trait Implementations§

§

impl Freeze for Body

§

impl RefUnwindSafe for Body

§

impl Send for Body

§

impl Sync for Body

§

impl Unpin for Body

§

impl UnsafeUnpin for Body

§

impl UnwindSafe for Body

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Mappable for T
where T: Any + Send + Sync,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> TyVisitable for T
where T: AstVisitable,

Source§

fn visit_vars(&mut self, v: &mut impl VarsVisitor)

Visit the variables contained in self, as seen from the outside of self. This means that any variable bound inside self will be skipped, and all the seen De Bruijn indices will count from the outside of self.
Source§

fn substitute(self, generics: &GenericArgs) -> Self

Substitute the generic variables inside self by replacing them with the provided values. Note: if self is an item that comes from a TraitDecl, you must use substitute_with_self or substitute_inner_binder, otherwise you’ll get panics.
Source§

fn substitute_inner_binder(self, generics: &GenericArgs) -> Self

Substitute the generic variables inside self by replacing them with the provided values. This is appropriate when substituting an inner binder.
Source§

fn substitute_explicits(self, generics: &GenericArgs) -> Self

Substitute only the type, region and const generic args.
Source§

fn substitute_with_self( self, generics: &GenericArgs, self_ref: &TraitRefKind, ) -> Self

Substitute the generic variables as well as the TraitRefKind::SelfId trait ref.
Source§

fn substitute_with_tref(self, tref: &TraitRef) -> Self

Substitute the generic variables as well as the TraitRefKind::SelfId trait ref.
Source§

fn try_substitute_with_tref( self, tref: &TraitRef, ) -> Result<Self, GenericsMismatch>

Substitute the generic variables as well as the TraitRefKind::SelfId trait ref.
Source§

fn try_substitute( self, generics: &GenericArgs, ) -> Result<Self, GenericsMismatch>

Source§

fn try_substitute_with_self( self, generics: &GenericArgs, self_ref: &TraitRefKind, ) -> Result<Self, GenericsMismatch>

Source§

fn move_under_binder(self) -> Self

Move under one binder.
Source§

fn move_under_binders(self, depth: DeBruijnId) -> Self

Move under depth binders.
Source§

fn move_from_under_binder(self) -> Option<Self>

Move from under one binder.
Source§

fn move_from_under_binders(self, depth: DeBruijnId) -> Option<Self>

Move the value out of depth binders. Returns None if it contains a variable bound in one of these depth binders.
Source§

fn visit_db_id<B>( &mut self, f: impl FnMut(&mut DeBruijnId) -> ControlFlow<B>, ) -> ControlFlow<B>

Visit the de Bruijn ids contained in self, as seen from the outside of self. This means that any variable bound inside self will be skipped, and all the seen indices will count from the outside of self.
Source§

fn replace_erased_regions(self, f: impl FnMut() -> Region) -> Self

Replace all the erased regions by the output of the provided function. Binders levels are handled automatically.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more