Make captures in ByUse context be always ty::UpvarCapture::ByUse
This commit is contained in:
parent
65d65e5e7e
commit
1702c00056
2 changed files with 33 additions and 17 deletions
|
|
@ -324,6 +324,18 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
|
|||
}
|
||||
}
|
||||
|
||||
pub fn consume_clone_or_copy(&self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
|
||||
debug!("delegate_consume_or_clone(place_with_id={:?})", place_with_id);
|
||||
|
||||
if self.cx.type_is_copy_modulo_regions(place_with_id.place.ty()) {
|
||||
self.delegate.borrow_mut().copy(place_with_id, diag_expr_id);
|
||||
} else if self.cx.type_is_use_cloned_modulo_regions(place_with_id.place.ty()) {
|
||||
self.delegate.borrow_mut().use_cloned(place_with_id, diag_expr_id);
|
||||
} else {
|
||||
self.delegate.borrow_mut().consume(place_with_id, diag_expr_id);
|
||||
}
|
||||
}
|
||||
|
||||
fn consume_exprs(&self, exprs: &[hir::Expr<'_>]) -> Result<(), Cx::Error> {
|
||||
for expr in exprs {
|
||||
self.consume_expr(expr)?;
|
||||
|
|
@ -346,15 +358,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
|
|||
debug!("consume_or_clone_expr(expr={:?})", expr);
|
||||
|
||||
let place_with_id = self.cat_expr(expr)?;
|
||||
|
||||
if self.cx.type_is_copy_modulo_regions(place_with_id.place.ty()) {
|
||||
self.delegate.borrow_mut().copy(&place_with_id, place_with_id.hir_id);
|
||||
} else if self.cx.type_is_use_cloned_modulo_regions(place_with_id.place.ty()) {
|
||||
self.delegate.borrow_mut().use_cloned(&place_with_id, place_with_id.hir_id);
|
||||
} else {
|
||||
self.delegate.borrow_mut().consume(&place_with_id, place_with_id.hir_id);
|
||||
}
|
||||
|
||||
self.consume_clone_or_copy(&place_with_id, place_with_id.hir_id);
|
||||
self.walk_expr(expr)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -1132,9 +1136,12 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
|
|||
);
|
||||
|
||||
match capture_info.capture_kind {
|
||||
ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => {
|
||||
ty::UpvarCapture::ByValue => {
|
||||
self.consume_or_copy(&place_with_id, place_with_id.hir_id);
|
||||
}
|
||||
ty::UpvarCapture::ByUse => {
|
||||
self.consume_clone_or_copy(&place_with_id, place_with_id.hir_id);
|
||||
}
|
||||
ty::UpvarCapture::ByRef(upvar_borrow) => {
|
||||
self.delegate.borrow_mut().borrow(
|
||||
&place_with_id,
|
||||
|
|
|
|||
|
|
@ -1709,11 +1709,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// Otherwise you'd get an error in 2021 immediately because you'd be trying to take
|
||||
// ownership of the (borrowed) String or else you'd take ownership of b, as in 2018 and
|
||||
// before, which is also an error.
|
||||
hir::CaptureBy::Value { .. } | hir::CaptureBy::Use { .. }
|
||||
if !place.deref_tys().any(Ty::is_ref) =>
|
||||
{
|
||||
hir::CaptureBy::Value { .. } if !place.deref_tys().any(Ty::is_ref) => {
|
||||
ty::UpvarCapture::ByValue
|
||||
}
|
||||
hir::CaptureBy::Use { .. } if !place.deref_tys().any(Ty::is_ref) => {
|
||||
ty::UpvarCapture::ByUse
|
||||
}
|
||||
hir::CaptureBy::Value { .. } | hir::CaptureBy::Use { .. } | hir::CaptureBy::Ref => {
|
||||
ty::UpvarCapture::ByRef(BorrowKind::Immutable)
|
||||
}
|
||||
|
|
@ -2404,10 +2405,18 @@ fn determine_capture_info(
|
|||
// We select the CaptureKind which ranks higher based the following priority order:
|
||||
// (ByUse | ByValue) > MutBorrow > UniqueImmBorrow > ImmBorrow
|
||||
match (capture_info_a.capture_kind, capture_info_b.capture_kind) {
|
||||
(ty::UpvarCapture::ByUse, _) => capture_info_a,
|
||||
(_, ty::UpvarCapture::ByUse) => capture_info_b,
|
||||
(ty::UpvarCapture::ByValue, _) => capture_info_a,
|
||||
(_, ty::UpvarCapture::ByValue) => capture_info_b,
|
||||
(ty::UpvarCapture::ByUse, ty::UpvarCapture::ByValue)
|
||||
| (ty::UpvarCapture::ByValue, ty::UpvarCapture::ByUse) => {
|
||||
bug!("Same capture can't be ByUse and ByValue at the same time")
|
||||
}
|
||||
(ty::UpvarCapture::ByValue, ty::UpvarCapture::ByValue)
|
||||
| (ty::UpvarCapture::ByUse, ty::UpvarCapture::ByUse)
|
||||
| (ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse, ty::UpvarCapture::ByRef(_)) => {
|
||||
capture_info_a
|
||||
}
|
||||
(ty::UpvarCapture::ByRef(_), ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse) => {
|
||||
capture_info_b
|
||||
}
|
||||
(ty::UpvarCapture::ByRef(ref_a), ty::UpvarCapture::ByRef(ref_b)) => {
|
||||
match (ref_a, ref_b) {
|
||||
// Take LHS:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue