diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index dceeac48d6a..eaa6ce82906 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -29,6 +29,10 @@ pub trait Delegate<'tcx> { // The value found at `place` is moved, depending // on `mode`. Where `diag_expr_id` is the id used for diagnostics for `place`. // + // Use of a `Copy` type in a ByValue context is considered a use + // by `ImmBorrow` and `borrow` is called instead. + // + // // The parameter `diag_expr_id` indicates the HIR id that ought to be used for // diagnostics. Around pattern matching such as `let pat = expr`, the diagnostic // id will be the id of the expression `expr` but the place itself will have @@ -134,16 +138,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } fn delegate_consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { - debug!("delegate_consume(place_with_id={:?})", place_with_id); - - let mode = copy_or_move(&self.mc, place_with_id); - - match mode { - ConsumeMode::Move => self.delegate.consume(place_with_id, diag_expr_id), - ConsumeMode::Copy => { - self.delegate.borrow(place_with_id, diag_expr_id, ty::BorrowKind::ImmBorrow) - } - } + delegate_consume(&self.mc, self.delegate, place_with_id, diag_expr_id) } fn consume_exprs(&mut self, exprs: &[hir::Expr<'_>]) { @@ -653,15 +648,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } ty::BindByValue(..) => { debug!("walk_pat binding consuming pat"); - let mode = copy_or_move(mc, &place); - match mode { - ConsumeMode::Move => delegate.consume(place, discr_place.hir_id), - ConsumeMode::Copy => delegate.borrow( - place, - discr_place.hir_id, - ty::BorrowKind::ImmBorrow, - ), - } + delegate_consume(mc, *delegate, place, discr_place.hir_id); } } } @@ -808,3 +795,23 @@ fn copy_or_move<'a, 'tcx>( ConsumeMode::Copy } } + +// - If a place is used in a `ByValue` context then move it if it's not a `Copy` type. +// - If the place that is a `Copy` type consider it a `ImmBorrow`. +fn delegate_consume<'a, 'tcx>( + mc: &mc::MemCategorizationContext<'a, 'tcx>, + delegate: &mut (dyn Delegate<'tcx> + 'a), + place_with_id: &PlaceWithHirId<'tcx>, + diag_expr_id: hir::HirId, +) { + debug!("delegate_consume(place_with_id={:?})", place_with_id); + + let mode = copy_or_move(&mc, place_with_id); + + match mode { + ConsumeMode::Move => delegate.consume(place_with_id, diag_expr_id), + ConsumeMode::Copy => { + delegate.borrow(place_with_id, diag_expr_id, ty::BorrowKind::ImmBorrow) + } + } +}