Struct ExprUseVisitor

Source
pub struct ExprUseVisitor<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> {
    cx: Cx,
    delegate: RefCell<D>,
    upvars: Option<&'tcx FxIndexMap<HirId, Upvar>>,
}
Expand description

A visitor that reports how each expression is being used.

See module-level docs and Delegate for details.

Fields§

§cx: Cx§delegate: RefCell<D>

We use a RefCell here so that delegates can mutate themselves, but we can still have calls to our own helper functions.

§upvars: Option<&'tcx FxIndexMap<HirId, Upvar>>

Implementations§

Source§

impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'tcx, (&'a LateContext<'tcx>, LocalDefId), D>

Source

pub fn for_clippy( cx: &'a LateContext<'tcx>, body_def_id: LocalDefId, delegate: D, ) -> Self

Source§

impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D>

Source

pub(crate) fn new(cx: Cx, delegate: D) -> Self

Creates the ExprUseVisitor, configuring it with the various options provided:

  • delegate – who receives the callbacks
  • param_env — parameter environment for trait lookups (esp. pertaining to Copy)
  • typeck_results — typeck results for the code being analyzed
Source

pub fn consume_body(&self, body: &Body<'_>) -> Result<(), Cx::Error>

Source

fn consume_or_copy( &self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId, )

Source

pub fn consume_clone_or_copy( &self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId, )

Source

fn consume_exprs(&self, exprs: &[Expr<'_>]) -> Result<(), Cx::Error>

Source

pub fn consume_expr(&self, expr: &Expr<'_>) -> Result<(), Cx::Error>

Source

pub fn consume_or_clone_expr(&self, expr: &Expr<'_>) -> Result<(), Cx::Error>

Source

fn mutate_expr(&self, expr: &Expr<'_>) -> Result<(), Cx::Error>

Source

fn borrow_expr(&self, expr: &Expr<'_>, bk: BorrowKind) -> Result<(), Cx::Error>

Source

pub fn walk_expr(&self, expr: &Expr<'_>) -> Result<(), Cx::Error>

Source

fn walk_stmt(&self, stmt: &Stmt<'_>) -> Result<(), Cx::Error>

Source

fn maybe_read_scrutinee<'t>( &self, discr: &Expr<'_>, discr_place: PlaceWithHirId<'tcx>, pats: impl Iterator<Item = &'t Pat<'t>>, ) -> Result<(), Cx::Error>

Source

fn walk_local<F>( &self, expr: &Expr<'_>, pat: &Pat<'_>, els: Option<&Block<'_>>, f: F, ) -> Result<(), Cx::Error>
where F: FnMut() -> Result<(), Cx::Error>,

Source

fn walk_block(&self, blk: &Block<'_>) -> Result<(), Cx::Error>

Indicates that the value of blk will be consumed, meaning either copied or moved depending on its type.

Source

fn walk_struct_expr<'hir>( &self, fields: &[ExprField<'_>], opt_with: &StructTailExpr<'hir>, ) -> Result<(), Cx::Error>

Source

fn walk_adjustment(&self, expr: &Expr<'_>) -> Result<(), Cx::Error>

Invoke the appropriate delegate calls for anything that gets consumed or borrowed as part of the automatic adjustment process.

Source

fn walk_autoref( &self, expr: &Expr<'_>, base_place: &PlaceWithHirId<'tcx>, autoref: &AutoBorrow, )

Walks the autoref autoref applied to the autoderef’d expr. base_place is expr represented as a place, after all relevant autoderefs have occurred.

Source

fn walk_arm( &self, discr_place: &PlaceWithHirId<'tcx>, arm: &Arm<'_>, ) -> Result<(), Cx::Error>

Source

fn walk_irrefutable_pat( &self, discr_place: &PlaceWithHirId<'tcx>, pat: &Pat<'_>, ) -> Result<(), Cx::Error>

Walks a pat that occurs in isolation (i.e., top-level of fn argument or let binding, and not a match arm or nested pat.)

Source

fn walk_pat( &self, discr_place: &PlaceWithHirId<'tcx>, pat: &Pat<'_>, has_guard: bool, ) -> Result<(), Cx::Error>

The core driver for walking a pattern

Source

fn walk_captures(&self, closure_expr: &Closure<'_>) -> Result<(), Cx::Error>

Handle the case where the current body contains a closure.

When the current body being handled is a closure, then we must make sure that

  • The parent closure only captures Places from the nested closure that are not local to it.

In the following example the closures c only captures p.x even though incr is a capture of the nested closure

struct P { x: i32 }
let mut p = P { x: 4 };
let c = || {
   let incr = 10;
   let nested = || p.x += incr;
};
  • When reporting the Place back to the Delegate, ensure that the UpvarId uses the enclosing closure as the DefId.
Source§

impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D>

The job of the methods whose name starts with cat_ is to analyze expressions and construct the corresponding Places. The cat stands for “categorize”, this is a leftover from long ago when places were called “categorizations”.

Note that a Place differs somewhat from the expression itself. For example, auto-derefs are explicit. Also, an index a[b] is decomposed into two operations: a dereference to reach the array data and then an index to jump forward to the relevant item.

Source

fn expect_and_resolve_type( &self, id: HirId, ty: Option<Ty<'tcx>>, ) -> Result<Ty<'tcx>, Cx::Error>

Source

fn node_ty(&self, hir_id: HirId) -> Result<Ty<'tcx>, Cx::Error>

Source

fn expr_ty(&self, expr: &Expr<'_>) -> Result<Ty<'tcx>, Cx::Error>

Source

fn expr_ty_adjusted(&self, expr: &Expr<'_>) -> Result<Ty<'tcx>, Cx::Error>

Source

fn pat_ty_adjusted(&self, pat: &Pat<'_>) -> Result<Ty<'tcx>, Cx::Error>

Returns the type of value that this pattern matches against. Some non-obvious cases:

  • a ref x binding matches against a value of type T and gives x the type &T; we return T.
  • a pattern with implicit derefs (thanks to default binding modes #42640) may look like Some(x) but in fact have implicit deref patterns attached (e.g., it is really &Some(x)). In that case, we return the “outermost” type (e.g., &Option<T>).
Source

fn pat_ty_unadjusted(&self, pat: &Pat<'_>) -> Result<Ty<'tcx>, Cx::Error>

Like Self::pat_ty_adjusted, but ignores implicit & patterns.

Source

fn cat_expr(&self, expr: &Expr<'_>) -> Result<PlaceWithHirId<'tcx>, Cx::Error>

Source

fn cat_expr_( &self, expr: &Expr<'_>, adjustments: &[Adjustment<'tcx>], ) -> Result<PlaceWithHirId<'tcx>, Cx::Error>

This recursion helper avoids going through too many adjustments, since only non-overloaded deref recurses.

Source

fn cat_expr_adjusted( &self, expr: &Expr<'_>, previous: PlaceWithHirId<'tcx>, adjustment: &Adjustment<'tcx>, ) -> Result<PlaceWithHirId<'tcx>, Cx::Error>

Source

fn cat_expr_adjusted_with<F>( &self, expr: &Expr<'_>, previous: F, adjustment: &Adjustment<'tcx>, ) -> Result<PlaceWithHirId<'tcx>, Cx::Error>
where F: FnOnce() -> Result<PlaceWithHirId<'tcx>, Cx::Error>,

Source

fn cat_expr_unadjusted( &self, expr: &Expr<'_>, ) -> Result<PlaceWithHirId<'tcx>, Cx::Error>

Source

fn cat_res( &self, hir_id: HirId, span: Span, expr_ty: Ty<'tcx>, res: Res, ) -> Result<PlaceWithHirId<'tcx>, Cx::Error>

Source

fn cat_upvar( &self, hir_id: HirId, var_id: HirId, ) -> Result<PlaceWithHirId<'tcx>, Cx::Error>

Categorize an upvar.

Note: the actual upvar access contains invisible derefs of closure environment and upvar reference as appropriate. Only regionck cares about these dereferences, so we let it compute them as needed.

Source

fn cat_rvalue(&self, hir_id: HirId, expr_ty: Ty<'tcx>) -> PlaceWithHirId<'tcx>

Source

fn cat_projection( &self, node: HirId, base_place: PlaceWithHirId<'tcx>, ty: Ty<'tcx>, kind: ProjectionKind, ) -> PlaceWithHirId<'tcx>

Source

fn cat_overloaded_place( &self, expr: &Expr<'_>, base: &Expr<'_>, ) -> Result<PlaceWithHirId<'tcx>, Cx::Error>

Source

fn cat_deref( &self, node: HirId, base_place: PlaceWithHirId<'tcx>, ) -> Result<PlaceWithHirId<'tcx>, Cx::Error>

Source

fn variant_index_for_adt( &self, qpath: &QPath<'_>, pat_hir_id: HirId, span: Span, ) -> Result<VariantIdx, Cx::Error>

Returns the variant index for an ADT used within a Struct or TupleStruct pattern Here pat_hir_id is the HirId of the pattern itself.

Source

fn total_fields_in_adt_variant( &self, pat_hir_id: HirId, variant_index: VariantIdx, span: Span, ) -> Result<usize, Cx::Error>

Returns the total number of fields in an ADT variant used within a pattern. Here pat_hir_id is the HirId of the pattern itself.

Source

fn total_fields_in_tuple( &self, pat_hir_id: HirId, span: Span, ) -> Result<usize, Cx::Error>

Returns the total number of fields in a tuple used within a Tuple pattern. Here pat_hir_id is the HirId of the pattern itself.

Source

fn cat_pattern<F>( &self, place_with_id: PlaceWithHirId<'tcx>, pat: &Pat<'_>, op: &mut F, ) -> Result<(), Cx::Error>
where F: FnMut(&PlaceWithHirId<'tcx>, &Pat<'_>) -> Result<(), Cx::Error>,

Here, place is the PlaceWithHirId being matched and pat is the pattern it is being matched against.

In general, the way that this works is that we walk down the pattern, constructing a PlaceWithHirId that represents the path that will be taken to reach the value being matched.

Source

fn pat_deref_place( &self, hir_id: HirId, base_place: PlaceWithHirId<'tcx>, inner: &Pat<'_>, target_ty: Ty<'tcx>, ) -> Result<PlaceWithHirId<'tcx>, Cx::Error>

Represents the place matched on by a deref pattern’s interior.

Source

fn is_multivariant_adt(&self, ty: Ty<'tcx>, span: Span) -> bool

Auto Trait Implementations§

§

impl<'tcx, Cx, D> DynSend for ExprUseVisitor<'tcx, Cx, D>
where Cx: DynSend, D: DynSend,

§

impl<'tcx, Cx, D> !DynSync for ExprUseVisitor<'tcx, Cx, D>

§

impl<'tcx, Cx, D> !Freeze for ExprUseVisitor<'tcx, Cx, D>

§

impl<'tcx, Cx, D> !RefUnwindSafe for ExprUseVisitor<'tcx, Cx, D>

§

impl<'tcx, Cx, D> Send for ExprUseVisitor<'tcx, Cx, D>
where Cx: Send, D: Send,

§

impl<'tcx, Cx, D> !Sync for ExprUseVisitor<'tcx, Cx, D>

§

impl<'tcx, Cx, D> Unpin for ExprUseVisitor<'tcx, Cx, D>
where Cx: Unpin, D: Unpin,

§

impl<'tcx, Cx, D> UnwindSafe for ExprUseVisitor<'tcx, Cx, D>
where Cx: UnwindSafe, D: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Aligned for T

Source§

const ALIGN: Alignment

Alignment of Self.
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, R> CollectAndApply<T, R> for T

Source§

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<_>>()).

Source§

type Output = R

Source§

impl<T> Filterable for T

Source§

fn filterable( self, filter_name: &'static str, ) -> RequestFilterDataProvider<T, fn(DataRequest<'_>) -> bool>

Creates a filterable data provider with the given name for debugging. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

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

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

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<P> IntoQueryParam<P> for P

Source§

impl<T> MaybeResult<T> for T

Source§

type Error = !

Source§

fn from(_: Result<T, <T as MaybeResult<T>>::Error>) -> T

Source§

fn to_result(self) -> Result<T, <T as MaybeResult<T>>::Error>

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

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

Initializes a with the given initializer. Read more
Source§

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

Dereferences the given pointer. Read more
Source§

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

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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<I, T, U> Upcast<I, U> for T
where U: UpcastFrom<I, T>,

Source§

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

Source§

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

Source§

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

Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<Tcx, T> Value<Tcx> for T
where Tcx: DepContext,

Source§

default fn from_cycle_error( tcx: Tcx, cycle_error: &CycleError, _guar: ErrorGuaranteed, ) -> T

Source§

impl<T> WithSubscriber for T

Source§

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
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

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

impl<T> ErasedDestructor for T
where T: 'static,

Layout§

Note: Unable to compute type layout, possibly due to this type having generic parameters. Layout can only be computed for concrete, fully-instantiated types.