|
1 | 1 | //! A different sort of visitor for walking fn bodies. Unlike the
|
2 | 2 | //! normal visitor, which just walks the entire body in one shot, the
|
3 | 3 | //! `ExprUseVisitor` determines how expressions are being used.
|
| 4 | +//! |
| 5 | +//! In the compiler, this is only used for upvar inference, but there |
| 6 | +//! are many uses within clippy. |
4 | 7 |
|
5 | 8 | use std::cell::{Ref, RefCell};
|
6 | 9 | use std::ops::Deref;
|
@@ -35,11 +38,8 @@ pub trait Delegate<'tcx> {
|
35 | 38 | /// The value found at `place` is moved, depending
|
36 | 39 | /// on `mode`. Where `diag_expr_id` is the id used for diagnostics for `place`.
|
37 | 40 | ///
|
38 |
| - /// Use of a `Copy` type in a ByValue context is considered a use |
39 |
| - /// by `ImmBorrow` and `borrow` is called instead. This is because |
40 |
| - /// a shared borrow is the "minimum access" that would be needed |
41 |
| - /// to perform a copy. |
42 |
| - /// |
| 41 | + /// If the value is `Copy`, [`copy`][Self::copy] is called instead, which |
| 42 | + /// by default falls back to [`borrow`][Self::borrow]. |
43 | 43 | ///
|
44 | 44 | /// The parameter `diag_expr_id` indicates the HIR id that ought to be used for
|
45 | 45 | /// diagnostics. Around pattern matching such as `let pat = expr`, the diagnostic
|
@@ -73,6 +73,10 @@ pub trait Delegate<'tcx> {
|
73 | 73 |
|
74 | 74 | /// The value found at `place` is being copied.
|
75 | 75 | /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details).
|
| 76 | + /// |
| 77 | + /// If an implementation is not provided, use of a `Copy` type in a ByValue context is instead |
| 78 | + /// considered a use by `ImmBorrow` and `borrow` is called instead. This is because a shared |
| 79 | + /// borrow is the "minimum access" that would be needed to perform a copy. |
76 | 80 | fn copy(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
|
77 | 81 | // In most cases, copying data from `x` is equivalent to doing `*&x`, so by default
|
78 | 82 | // we treat a copy of `x` as a borrow of `x`.
|
@@ -141,6 +145,8 @@ impl<'tcx, D: Delegate<'tcx>> Delegate<'tcx> for &mut D {
|
141 | 145 | }
|
142 | 146 | }
|
143 | 147 |
|
| 148 | +/// This trait makes `ExprUseVisitor` usable with both [`FnCtxt`] |
| 149 | +/// and [`LateContext`], depending on where in the compiler it is used. |
144 | 150 | pub trait TypeInformationCtxt<'tcx> {
|
145 | 151 | type TypeckResults<'a>: Deref<Target = ty::TypeckResults<'tcx>>
|
146 | 152 | where
|
@@ -268,9 +274,9 @@ impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) {
|
268 | 274 | }
|
269 | 275 | }
|
270 | 276 |
|
271 |
| -/// The ExprUseVisitor type |
| 277 | +/// A visitor that reports how each expression is being used. |
272 | 278 | ///
|
273 |
| -/// This is the code that actually walks the tree. |
| 279 | +/// See [module-level docs][self] and [`Delegate`] for details. |
274 | 280 | pub struct ExprUseVisitor<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> {
|
275 | 281 | cx: Cx,
|
276 | 282 | /// We use a `RefCell` here so that delegates can mutate themselves, but we can
|
@@ -1285,7 +1291,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
|
1285 | 1291 | self.pat_ty_unadjusted(pat)
|
1286 | 1292 | }
|
1287 | 1293 |
|
1288 |
| - /// Like `TypeckResults::pat_ty`, but ignores implicit `&` patterns. |
| 1294 | + /// Like [`Self::pat_ty_adjusted`], but ignores implicit `&` patterns. |
1289 | 1295 | fn pat_ty_unadjusted(&self, pat: &hir::Pat<'_>) -> Result<Ty<'tcx>, Cx::Error> {
|
1290 | 1296 | let base_ty = self.node_ty(pat.hir_id)?;
|
1291 | 1297 | trace!(?base_ty);
|
|
0 commit comments