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: usizeA general limit on execution, to prevent non terminating programs from breaking r-a main process
stack_depth_limit: usizeAn additional limit on stack depth, to prevent stack overflow
memory_limit: usizeMaximum count of bytes that heap and stack can grow
infcx: InferCtxt<'db>Implementations§
Source§impl<'a, 'db> Evaluator<'a, 'db>
impl<'a, 'db> Evaluator<'a, 'db>
fn detect_simd_ty( &self, ty: Ty<'db>, ) -> Result<(usize, Ty<'db>), MirEvalError<'db>>
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>
impl<'a, 'db> Evaluator<'a, 'db>
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>>
pub(super) fn detect_and_redirect_special_function( &mut self, def: FunctionId, ) -> Result<Option<FunctionId>, MirEvalError<'db>>
Sourcefn exec_clone(
&mut self,
def: FunctionId,
args: &[IntervalAndTy<'db>],
self_ty: Ty<'db>,
locals: &Locals<'a, 'db>,
destination: Interval,
span: MirSpan,
) -> Result<(), MirEvalError<'db>>
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
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>>
fn exec_alloc_fn( &mut self, alloc_fn: AttrFlags, args: &[IntervalAndTy<'db>], destination: Interval, ) -> Result<(), MirEvalError<'db>>
fn detect_lang_function(&self, def: FunctionId) -> Option<EvalLangItem>
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>>
fn exec_syscall( &mut self, id: i64, args: &[IntervalAndTy<'db>], destination: Interval, _locals: &Locals<'a, 'db>, _span: MirSpan, ) -> Result<(), MirEvalError<'db>>
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>>
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>>
fn size_align_of_unsized( &mut self, ty: Ty<'db>, metadata: Interval, locals: &Locals<'a, 'db>, ) -> Result<(usize, usize), MirEvalError<'db>>
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>
impl<'a, 'db> Evaluator<'a, 'db>
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>>
fn interner(&self) -> DbInterner<'db>
fn lang_items(&self) -> &'db LangItems
fn place_addr( &self, p: &Place, locals: &Locals<'a, 'db>, ) -> Result<Address, MirEvalError<'db>>
fn place_interval( &self, p: &Place, locals: &Locals<'a, 'db>, ) -> Result<Interval, MirEvalError<'db>>
fn ptr_size(&self) -> usize
fn caller_location_fields( &self, owner: InferBodyId<'db>, span: MirSpan, ) -> (String, u32, u32)
fn resolve_mir_span( &self, owner: InferBodyId<'db>, span: MirSpan, ) -> Option<(FileId, TextRange)>
fn projected_ty( &self, ty: PlaceTy<'db>, proj: ProjectionElem<LocalId>, ) -> PlaceTy<'db>
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>>
fn layout(&self, ty: Ty<'db>) -> Result<Arc<Layout>, MirEvalError<'db>>
fn layout_adt( &self, adt: AdtId, subst: GenericArgs<'db>, ) -> Result<Arc<Layout>, MirEvalError<'db>>
fn place_ty<'b>( &'b self, p: &Place, locals: &'b Locals<'a, 'db>, ) -> Result<Ty<'db>, MirEvalError<'db>>
fn operand_ty( &self, o: &Operand, locals: &Locals<'a, 'db>, ) -> Result<Ty<'db>, MirEvalError<'db>>
fn operand_ty_and_eval( &mut self, o: &Operand, locals: &mut Locals<'a, 'db>, ) -> Result<IntervalAndTy<'db>, MirEvalError<'db>>
fn interpret_mir( &mut self, body: &'db MirBody<'db>, args: impl Iterator<Item = IntervalOrOwned>, ) -> Result<Interval, MirEvalError<'db>>
fn fill_locals_for_body( &mut self, body: &'db MirBody<'db>, locals: &mut Locals<'a, 'db>, args: impl Iterator<Item = IntervalOrOwned>, ) -> Result<(), MirEvalError<'db>>
fn create_locals_for_body( &mut self, body: &'db MirBody<'db>, destination: Option<Interval>, ) -> Result<(Locals<'a, 'db>, usize), MirEvalError<'db>>
fn eval_rvalue( &mut self, r: &Rvalue, locals: &mut Locals<'a, 'db>, ) -> Result<IntervalOrOwned, MirEvalError<'db>>
fn compute_discriminant( &self, ty: Ty<'db>, bytes: &[u8], ) -> Result<i128, MirEvalError<'db>>
fn coerce_unsized_look_through_fields<T>( &self, ty: Ty<'db>, goal: impl Fn(TyKind<'db>) -> Option<T>, ) -> Result<T, MirEvalError<'db>>
fn coerce_unsized( &mut self, addr: Interval, current_ty: Ty<'db>, target_ty: Ty<'db>, ) -> Result<IntervalOrOwned, MirEvalError<'db>>
Sourcefn unsizing_ptr_from_addr(
&mut self,
target_ty: Ty<'db>,
current_ty: Ty<'db>,
addr: Interval,
) -> Result<IntervalOrOwned, MirEvalError<'db>>
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.
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>>
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>>
fn eval_operand( &mut self, it: &Operand, locals: &mut Locals<'a, 'db>, ) -> Result<Interval, MirEvalError<'db>>
fn allocate_valtree_in_heap( &mut self, ty: Ty<'db>, valtree: ValTree<'db>, ) -> Result<Interval, MirEvalError<'db>>
fn allocate_const_in_heap( &mut self, locals: &Locals<'a, 'db>, konst: Const<'db>, ) -> Result<Interval, MirEvalError<'db>>
fn allocate_allocation_in_heap( &mut self, locals: &Locals<'a, 'db>, allocation: Allocation<'db>, ) -> Result<Interval, MirEvalError<'db>>
fn eval_place( &mut self, p: &Place, locals: &Locals<'a, 'db>, ) -> Result<Interval, MirEvalError<'db>>
fn read_memory( &self, addr: Address, size: usize, ) -> Result<&[u8], MirEvalError<'db>>
fn write_memory_using_ref( &mut self, addr: Address, size: usize, ) -> Result<&mut [u8], MirEvalError<'db>>
fn write_memory( &mut self, addr: Address, r: &[u8], ) -> Result<(), MirEvalError<'db>>
fn copy_from_interval_or_owned( &mut self, addr: Address, r: IntervalOrOwned, ) -> Result<(), MirEvalError<'db>>
fn copy_from_interval( &mut self, addr: Address, r: Interval, ) -> Result<(), MirEvalError<'db>>
fn size_align_of( &self, ty: Ty<'db>, locals: &Locals<'a, 'db>, ) -> Result<Option<(usize, usize)>, MirEvalError<'db>>
Sourcefn size_of_sized(
&self,
ty: Ty<'db>,
locals: &Locals<'a, 'db>,
what: &'static str,
) -> Result<usize, MirEvalError<'db>>
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
Sourcefn size_align_of_sized(
&self,
ty: Ty<'db>,
locals: &Locals<'a, 'db>,
what: &'static str,
) -> Result<(usize, usize), MirEvalError<'db>>
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
fn heap_allocate( &mut self, size: usize, align: usize, ) -> Result<Address, MirEvalError<'db>>
fn detect_fn_trait(&self, def: FunctionId) -> Option<FnTrait>
fn create_memory_map( &self, bytes: &[u8], ty: Ty<'db>, locals: &Locals<'a, 'db>, ) -> Result<ComplexMemoryMap<'db>, MirEvalError<'db>>
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>>
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>>
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>>
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>>
fn get_mir_or_dyn_index( &self, def: FunctionId, generic_args: GenericArgs<'db>, locals: &Locals<'a, 'db>, span: MirSpan, ) -> Result<MirOrDynIndex<'db>, MirEvalError<'db>>
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>>
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>>
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>>
fn eval_static( &mut self, st: StaticId, locals: &Locals<'a, 'db>, ) -> Result<Address, MirEvalError<'db>>
fn const_eval_discriminant( &self, variant: EnumVariantId, ) -> Result<i128, MirEvalError<'db>>
fn drop_place( &mut self, place: &Place, locals: &mut Locals<'a, 'db>, span: MirSpan, ) -> Result<(), MirEvalError<'db>>
fn run_drop_glue_deep( &mut self, ty: Ty<'db>, locals: &Locals<'a, 'db>, addr: Address, metadata: &[u8], span: MirSpan, ) -> Result<(), MirEvalError<'db>>
fn write_to_stdout( &mut self, interval: Interval, ) -> Result<(), MirEvalError<'db>>
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T, R> CollectAndApply<T, R> for T
impl<T, R> CollectAndApply<T, R> for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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