Skip to main content

Evaluator

Struct Evaluator 

Source
pub struct Evaluator<'a, 'db> {
Show 27 fields db: &'db dyn HirDatabase, param_env: ParamEnvAndCrate<'db>, target_data_layout: &'db TargetDataLayout, stack: Vec<u8>, heap: Vec<u8>, code_stack: Vec<StackFrame<'a, 'db>>, static_locations: FxHashMap<StaticId, Address>, vtable_map: VTableMap<'db>, thread_local_storage: TlsData, random_state: Rand64, stdout: Vec<u8>, stderr: Vec<u8>, layout_cache: RefCell<FxHashMap<Ty<'db>, Arc<Layout>>>, projected_ty_cache: RefCell<FxHashMap<(PlaceTy<'db>, ProjectionElem<LocalId>), PlaceTy<'db>>>, not_special_fn_cache: RefCell<FxHashSet<FunctionId>>, mir_or_dyn_index_cache: RefCell<FxHashMap<(FunctionId, GenericArgs<'db>), MirOrDynIndex<'db>>>, unused_locals_store: RefCell<FxHashMap<InferBodyId<'db>, Vec<Locals<'a, 'db>>>>, cached_ptr_size: usize, cached_fn_trait_func: Option<FunctionId>, cached_fn_mut_trait_func: Option<FunctionId>, cached_fn_once_trait_func: Option<FunctionId>, crate_id: Crate, assert_placeholder_ty_is_unused: bool, execution_limit: usize, stack_depth_limit: usize, memory_limit: usize, infcx: InferCtxt<'db>,
}

Fields§

§db: &'db dyn HirDatabase§param_env: ParamEnvAndCrate<'db>§target_data_layout: &'db TargetDataLayout§stack: Vec<u8>§heap: Vec<u8>§code_stack: Vec<StackFrame<'a, 'db>>§static_locations: FxHashMap<StaticId, Address>

Stores the global location of the statics. We const evaluate every static first time we need it and see it’s missing, then we add it to this to reuse.

§vtable_map: VTableMap<'db>

We don’t really have function pointers, i.e. pointers to some assembly instructions that we can run. Instead, we store the type as an interned id in place of function and vtable pointers, and we recover back the type at the time of use.

§thread_local_storage: TlsData§random_state: Rand64§stdout: Vec<u8>§stderr: Vec<u8>§layout_cache: RefCell<FxHashMap<Ty<'db>, Arc<Layout>>>§projected_ty_cache: RefCell<FxHashMap<(PlaceTy<'db>, ProjectionElem<LocalId>), PlaceTy<'db>>>§not_special_fn_cache: RefCell<FxHashSet<FunctionId>>§mir_or_dyn_index_cache: RefCell<FxHashMap<(FunctionId, GenericArgs<'db>), MirOrDynIndex<'db>>>§unused_locals_store: RefCell<FxHashMap<InferBodyId<'db>, Vec<Locals<'a, 'db>>>>

Constantly dropping and creating Locals is very costly. We store old locals that we normally want to drop here, to reuse their allocations later.

§cached_ptr_size: usize§cached_fn_trait_func: Option<FunctionId>§cached_fn_mut_trait_func: Option<FunctionId>§cached_fn_once_trait_func: Option<FunctionId>§crate_id: Crate§assert_placeholder_ty_is_unused: bool§execution_limit: usize

A general limit on execution, to prevent non terminating programs from breaking r-a main process

§stack_depth_limit: usize

An additional limit on stack depth, to prevent stack overflow

§memory_limit: usize

Maximum count of bytes that heap and stack can grow

§infcx: InferCtxt<'db>

Implementations§

Source§

impl<'a, 'db> Evaluator<'a, 'db>

Source

fn detect_simd_ty( &self, ty: Ty<'db>, ) -> Result<(usize, Ty<'db>), MirEvalError<'db>>

Source

pub(super) fn exec_simd_intrinsic( &mut self, name: &str, args: &[IntervalAndTy<'db>], _generic_args: GenericArgs<'db>, destination: Interval, _locals: &Locals<'a, 'db>, _span: MirSpan, ) -> Result<(), MirEvalError<'db>>

Source§

impl<'a, 'db> Evaluator<'a, 'db>

Source

pub(super) fn detect_and_exec_special_function( &mut self, def: FunctionId, args: &[IntervalAndTy<'db>], generic_args: GenericArgs<'db>, locals: &Locals<'a, 'db>, destination: Interval, span: MirSpan, ) -> Result<bool, MirEvalError<'db>>

Source

pub(super) fn detect_and_redirect_special_function( &mut self, def: FunctionId, ) -> Result<Option<FunctionId>, MirEvalError<'db>>

Source

fn exec_clone( &mut self, def: FunctionId, args: &[IntervalAndTy<'db>], self_ty: Ty<'db>, locals: &Locals<'a, 'db>, destination: Interval, span: MirSpan, ) -> Result<(), MirEvalError<'db>>

Clone has special impls for tuples and function pointers

Source

fn exec_clone_for_fields( &mut self, ty_iter: impl Iterator<Item = Ty<'db>>, layout: Arc<Layout>, addr: Address, def: FunctionId, locals: &Locals<'a, 'db>, destination: Interval, span: MirSpan, ) -> Result<(), MirEvalError<'db>>

Source

fn exec_alloc_fn( &mut self, alloc_fn: AttrFlags, args: &[IntervalAndTy<'db>], destination: Interval, ) -> Result<(), MirEvalError<'db>>

Source

fn detect_lang_function(&self, def: FunctionId) -> Option<EvalLangItem>

Source

fn exec_lang_item( &mut self, it: EvalLangItem, generic_args: GenericArgs<'db>, args: &[IntervalAndTy<'db>], locals: &Locals<'a, 'db>, span: MirSpan, ) -> Result<Vec<u8>, MirEvalError<'db>>

Source

fn exec_syscall( &mut self, id: i64, args: &[IntervalAndTy<'db>], destination: Interval, _locals: &Locals<'a, 'db>, _span: MirSpan, ) -> Result<(), MirEvalError<'db>>

Source

fn exec_extern_c( &mut self, as_str: &str, args: &[IntervalAndTy<'db>], _generic_args: GenericArgs<'db>, destination: Interval, locals: &Locals<'a, 'db>, span: MirSpan, ) -> Result<(), MirEvalError<'db>>

Source

fn exec_intrinsic( &mut self, name: &str, args: &[IntervalAndTy<'db>], generic_args: GenericArgs<'db>, destination: Interval, locals: &Locals<'a, 'db>, span: MirSpan, needs_override: bool, ) -> Result<bool, MirEvalError<'db>>

Source

fn size_align_of_unsized( &mut self, ty: Ty<'db>, metadata: Interval, locals: &Locals<'a, 'db>, ) -> Result<(usize, usize), MirEvalError<'db>>

Source

fn exec_atomic_intrinsic( &mut self, name: &str, args: &[IntervalAndTy<'db>], generic_args: GenericArgs<'db>, destination: Interval, locals: &Locals<'a, 'db>, _span: MirSpan, ) -> Result<(), MirEvalError<'db>>

Source§

impl<'a, 'db> Evaluator<'a, 'db>

Source

pub fn new( db: &'db dyn HirDatabase, owner: InferBodyId<'db>, assert_placeholder_ty_is_unused: bool, trait_env: Option<ParamEnvAndCrate<'db>>, ) -> Result<Evaluator<'a, 'db>, MirEvalError<'db>>

Source

fn interner(&self) -> DbInterner<'db>

Source

fn lang_items(&self) -> &'db LangItems

Source

fn place_addr( &self, p: &Place, locals: &Locals<'a, 'db>, ) -> Result<Address, MirEvalError<'db>>

Source

fn place_interval( &self, p: &Place, locals: &Locals<'a, 'db>, ) -> Result<Interval, MirEvalError<'db>>

Source

fn ptr_size(&self) -> usize

Source

fn caller_location_fields( &self, owner: InferBodyId<'db>, span: MirSpan, ) -> (String, u32, u32)

Source

fn resolve_mir_span( &self, owner: InferBodyId<'db>, span: MirSpan, ) -> Option<(FileId, TextRange)>

Source

fn projected_ty( &self, ty: PlaceTy<'db>, proj: ProjectionElem<LocalId>, ) -> PlaceTy<'db>

Source

fn place_addr_and_ty_and_metadata<'b>( &'b self, p: &Place, locals: &'b Locals<'a, 'db>, ) -> Result<(Address, Ty<'db>, Option<IntervalOrOwned>), MirEvalError<'db>>

Source

fn layout(&self, ty: Ty<'db>) -> Result<Arc<Layout>, MirEvalError<'db>>

Source

fn layout_adt( &self, adt: AdtId, subst: GenericArgs<'db>, ) -> Result<Arc<Layout>, MirEvalError<'db>>

Source

fn place_ty<'b>( &'b self, p: &Place, locals: &'b Locals<'a, 'db>, ) -> Result<Ty<'db>, MirEvalError<'db>>

Source

fn operand_ty( &self, o: &Operand, locals: &Locals<'a, 'db>, ) -> Result<Ty<'db>, MirEvalError<'db>>

Source

fn operand_ty_and_eval( &mut self, o: &Operand, locals: &mut Locals<'a, 'db>, ) -> Result<IntervalAndTy<'db>, MirEvalError<'db>>

Source

fn interpret_mir( &mut self, body: &'db MirBody<'db>, args: impl Iterator<Item = IntervalOrOwned>, ) -> Result<Interval, MirEvalError<'db>>

Source

fn fill_locals_for_body( &mut self, body: &'db MirBody<'db>, locals: &mut Locals<'a, 'db>, args: impl Iterator<Item = IntervalOrOwned>, ) -> Result<(), MirEvalError<'db>>

Source

fn create_locals_for_body( &mut self, body: &'db MirBody<'db>, destination: Option<Interval>, ) -> Result<(Locals<'a, 'db>, usize), MirEvalError<'db>>

Source

fn eval_rvalue( &mut self, r: &Rvalue, locals: &mut Locals<'a, 'db>, ) -> Result<IntervalOrOwned, MirEvalError<'db>>

Source

fn compute_discriminant( &self, ty: Ty<'db>, bytes: &[u8], ) -> Result<i128, MirEvalError<'db>>

Source

fn coerce_unsized_look_through_fields<T>( &self, ty: Ty<'db>, goal: impl Fn(TyKind<'db>) -> Option<T>, ) -> Result<T, MirEvalError<'db>>

Source

fn coerce_unsized( &mut self, addr: Interval, current_ty: Ty<'db>, target_ty: Ty<'db>, ) -> Result<IntervalOrOwned, MirEvalError<'db>>

Source

fn unsizing_ptr_from_addr( &mut self, target_ty: Ty<'db>, current_ty: Ty<'db>, addr: Interval, ) -> Result<IntervalOrOwned, MirEvalError<'db>>

Adds metadata to the address and create the fat pointer result of the unsizing operation.

Source

fn layout_of_variant( &mut self, it: VariantId, subst: GenericArgs<'db>, locals: &Locals<'a, 'db>, ) -> Result<(usize, Arc<Layout>, Option<(usize, usize, i128)>), MirEvalError<'db>>

Source

fn construct_with_layout( &mut self, size: usize, variant_layout: &Layout, tag: Option<(usize, usize, i128)>, values: impl Iterator<Item = IntervalOrOwned>, ) -> Result<Vec<u8>, MirEvalError<'db>>

Source

fn eval_operand( &mut self, it: &Operand, locals: &mut Locals<'a, 'db>, ) -> Result<Interval, MirEvalError<'db>>

Source

fn allocate_valtree_in_heap( &mut self, ty: Ty<'db>, valtree: ValTree<'db>, ) -> Result<Interval, MirEvalError<'db>>

Source

fn allocate_const_in_heap( &mut self, locals: &Locals<'a, 'db>, konst: Const<'db>, ) -> Result<Interval, MirEvalError<'db>>

Source

fn allocate_allocation_in_heap( &mut self, locals: &Locals<'a, 'db>, allocation: Allocation<'db>, ) -> Result<Interval, MirEvalError<'db>>

Source

fn eval_place( &mut self, p: &Place, locals: &Locals<'a, 'db>, ) -> Result<Interval, MirEvalError<'db>>

Source

fn read_memory( &self, addr: Address, size: usize, ) -> Result<&[u8], MirEvalError<'db>>

Source

fn write_memory_using_ref( &mut self, addr: Address, size: usize, ) -> Result<&mut [u8], MirEvalError<'db>>

Source

fn write_memory( &mut self, addr: Address, r: &[u8], ) -> Result<(), MirEvalError<'db>>

Source

fn copy_from_interval_or_owned( &mut self, addr: Address, r: IntervalOrOwned, ) -> Result<(), MirEvalError<'db>>

Source

fn copy_from_interval( &mut self, addr: Address, r: Interval, ) -> Result<(), MirEvalError<'db>>

Source

fn size_align_of( &self, ty: Ty<'db>, locals: &Locals<'a, 'db>, ) -> Result<Option<(usize, usize)>, MirEvalError<'db>>

Source

fn size_of_sized( &self, ty: Ty<'db>, locals: &Locals<'a, 'db>, what: &'static str, ) -> Result<usize, MirEvalError<'db>>

A version of self.size_of which returns error if the type is unsized. what argument should be something that complete this: error: type {ty} was unsized. {what} should be sized

Source

fn size_align_of_sized( &self, ty: Ty<'db>, locals: &Locals<'a, 'db>, what: &'static str, ) -> Result<(usize, usize), MirEvalError<'db>>

A version of self.size_align_of which returns error if the type is unsized. what argument should be something that complete this: error: type {ty} was unsized. {what} should be sized

Source

fn heap_allocate( &mut self, size: usize, align: usize, ) -> Result<Address, MirEvalError<'db>>

Source

fn detect_fn_trait(&self, def: FunctionId) -> Option<FnTrait>

Source

fn create_memory_map( &self, bytes: &[u8], ty: Ty<'db>, locals: &Locals<'a, 'db>, ) -> Result<ComplexMemoryMap<'db>, MirEvalError<'db>>

Source

fn patch_addresses( &mut self, patch_map: &FxHashMap<usize, usize>, ty_of_bytes: impl Fn(&[u8]) -> Result<Ty<'db>, MirEvalError<'db>> + Copy, addr: Address, ty: Ty<'db>, locals: &Locals<'a, 'db>, ) -> Result<(), MirEvalError<'db>>

Source

fn exec_fn_pointer( &mut self, bytes: Interval, destination: Interval, args: &[IntervalAndTy<'db>], locals: &Locals<'a, 'db>, target_bb: Option<BasicBlockId>, span: MirSpan, ) -> Result<Option<StackFrame<'a, 'db>>, MirEvalError<'db>>

Source

fn exec_closure( &mut self, closure: InternedClosureId<'db>, closure_data: Interval, generic_args: GenericArgs<'db>, destination: Interval, args: &[IntervalAndTy<'db>], locals: &Locals<'a, 'db>, span: MirSpan, ) -> Result<Option<StackFrame<'a, 'db>>, MirEvalError<'db>>

Source

fn exec_fn_def( &mut self, def: CallableDefId, generic_args: GenericArgs<'db>, destination: Interval, args: &[IntervalAndTy<'db>], locals: &Locals<'a, 'db>, target_bb: Option<BasicBlockId>, span: MirSpan, ) -> Result<Option<StackFrame<'a, 'db>>, MirEvalError<'db>>

Source

fn get_mir_or_dyn_index( &self, def: FunctionId, generic_args: GenericArgs<'db>, locals: &Locals<'a, 'db>, span: MirSpan, ) -> Result<MirOrDynIndex<'db>, MirEvalError<'db>>

Source

fn exec_fn_with_args( &mut self, def: FunctionId, args: &[IntervalAndTy<'db>], generic_args: GenericArgs<'db>, locals: &Locals<'a, 'db>, destination: Interval, target_bb: Option<BasicBlockId>, span: MirSpan, ) -> Result<Option<StackFrame<'a, 'db>>, MirEvalError<'db>>

Source

fn exec_looked_up_function( &mut self, mir_body: &'db MirBody<'db>, locals: &Locals<'a, 'db>, def: FunctionId, arg_bytes: impl Iterator<Item = IntervalOrOwned>, span: MirSpan, destination: Interval, target_bb: Option<BasicBlockId>, ) -> Result<Option<StackFrame<'a, 'db>>, MirEvalError<'db>>

Source

fn exec_fn_trait( &mut self, def: FunctionId, args: &[IntervalAndTy<'db>], generic_args: GenericArgs<'db>, locals: &Locals<'a, 'db>, destination: Interval, target_bb: Option<BasicBlockId>, span: MirSpan, ) -> Result<Option<StackFrame<'a, 'db>>, MirEvalError<'db>>

Source

fn eval_static( &mut self, st: StaticId, locals: &Locals<'a, 'db>, ) -> Result<Address, MirEvalError<'db>>

Source

fn const_eval_discriminant( &self, variant: EnumVariantId, ) -> Result<i128, MirEvalError<'db>>

Source

fn drop_place( &mut self, place: &Place, locals: &mut Locals<'a, 'db>, span: MirSpan, ) -> Result<(), MirEvalError<'db>>

Source

fn run_drop_glue_deep( &mut self, ty: Ty<'db>, locals: &Locals<'a, 'db>, addr: Address, metadata: &[u8], span: MirSpan, ) -> Result<(), MirEvalError<'db>>

Source

fn write_to_stdout( &mut self, interval: Interval, ) -> Result<(), MirEvalError<'db>>

Source

fn write_to_stderr( &mut self, interval: Interval, ) -> Result<(), MirEvalError<'db>>

Auto Trait Implementations§

§

impl<'a, 'db> !Freeze for Evaluator<'a, 'db>

§

impl<'a, 'db> !RefUnwindSafe for Evaluator<'a, 'db>

§

impl<'a, 'db> !Send for Evaluator<'a, 'db>

§

impl<'a, 'db> !Sync for Evaluator<'a, 'db>

§

impl<'a, 'db> Unpin for Evaluator<'a, 'db>

§

impl<'a, 'db> UnsafeUnpin for Evaluator<'a, 'db>

§

impl<'a, 'db> !UnwindSafe for Evaluator<'a, 'db>

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
§

impl<T, R> CollectAndApply<T, R> for T

§

fn collect_and_apply<I, F>(iter: I, f: F) -> R
where I: Iterator<Item = T>, F: FnOnce(&[T]) -> R,

Equivalent to f(&iter.collect::<Vec<_>>()).

§

type Output = R

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.

§

impl<T> IntoBox<dyn Any> for T
where T: Any,

§

fn into_box(self) -> Box<dyn Any>

Convert self into the appropriate boxed form.
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
§

impl<T> Lookup<T> for T

§

fn into_owned(self) -> T

§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. 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.
§

impl<I, T, U> Upcast<I, U> for T
where U: UpcastFrom<I, T>,

§

fn upcast(self, interner: I) -> U

§

impl<I, T> UpcastFrom<I, T> for T

§

fn upcast_from(from: T, _tcx: I) -> T

§

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