diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 42aa3bcee49..befc0732d0e 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -258,15 +258,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; }; - let mutbl = match mutbl { - hir::Mutability::Not => AutoBorrowMutability::Not, - hir::Mutability::Mut => AutoBorrowMutability::Mut { - // For initial two-phase borrow - // deployment, conservatively omit - // overloaded function call ops. - allow_two_phase_borrow: AllowTwoPhase::No, - }, - }; + // For initial two-phase borrow + // deployment, conservatively omit + // overloaded function call ops. + let mutbl = AutoBorrowMutability::new(*mutbl, AllowTwoPhase::No); + autoref = Some(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(*region, mutbl)), target: method.sig.inputs()[0], diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index f1213983e61..7098583908b 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -478,12 +478,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let ty::Ref(r_borrow, _, _) = ty.kind() else { span_bug!(span, "expected a ref type, got {:?}", ty); }; - let mutbl = match mutbl_b { - hir::Mutability::Not => AutoBorrowMutability::Not, - hir::Mutability::Mut => { - AutoBorrowMutability::Mut { allow_two_phase_borrow: self.allow_two_phase } - } - }; + let mutbl = AutoBorrowMutability::new(mutbl_b, self.allow_two_phase); adjustments.push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(*r_borrow, mutbl)), target: ty, @@ -552,15 +547,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let coercion = Coercion(self.cause.span); let r_borrow = self.next_region_var(coercion); - let mutbl = match mutbl_b { - hir::Mutability::Not => AutoBorrowMutability::Not, - hir::Mutability::Mut => AutoBorrowMutability::Mut { - // We don't allow two-phase borrows here, at least for initial - // implementation. If it happens that this coercion is a function argument, - // the reborrow in coerce_borrowed_ptr will pick it up. - allow_two_phase_borrow: AllowTwoPhase::No, - }, - }; + + // We don't allow two-phase borrows here, at least for initial + // implementation. If it happens that this coercion is a function argument, + // the reborrow in coerce_borrowed_ptr will pick it up. + let mutbl = AutoBorrowMutability::new(mutbl_b, AllowTwoPhase::No); + Some(( Adjustment { kind: Adjust::Deref(None), target: ty_a }, Adjustment { diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index d996d6ec610..b8928305b7c 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -170,14 +170,11 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { let base_ty = target; target = self.tcx.mk_ref(region, ty::TypeAndMut { mutbl, ty: target }); - let mutbl = match mutbl { - hir::Mutability::Not => AutoBorrowMutability::Not, - hir::Mutability::Mut => AutoBorrowMutability::Mut { - // Method call receivers are the primary use case - // for two-phase borrows. - allow_two_phase_borrow: AllowTwoPhase::Yes, - }, - }; + + // Method call receivers are the primary use case + // for two-phase borrows. + let mutbl = AutoBorrowMutability::new(mutbl, AllowTwoPhase::Yes); + adjustments.push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)), target, diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index adc7a21f265..b12d84af4ad 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -263,14 +263,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let by_ref_binop = !op.node.is_by_value(); if is_assign == IsAssign::Yes || by_ref_binop { if let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].kind() { - let mutbl = match mutbl { - hir::Mutability::Not => AutoBorrowMutability::Not, - hir::Mutability::Mut => AutoBorrowMutability::Mut { - // Allow two-phase borrows for binops in initial deployment - // since they desugar to methods - allow_two_phase_borrow: AllowTwoPhase::Yes, - }, - }; + let mutbl = AutoBorrowMutability::new(*mutbl, AllowTwoPhase::Yes); let autoref = Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(*region, mutbl)), target: method.sig.inputs()[0], @@ -280,14 +273,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if by_ref_binop { if let ty::Ref(region, _, mutbl) = method.sig.inputs()[1].kind() { - let mutbl = match mutbl { - hir::Mutability::Not => AutoBorrowMutability::Not, - hir::Mutability::Mut => AutoBorrowMutability::Mut { - // Allow two-phase borrows for binops in initial deployment - // since they desugar to methods - allow_two_phase_borrow: AllowTwoPhase::Yes, - }, - }; + // Allow two-phase borrows for binops in initial deployment + // since they desugar to methods + let mutbl = AutoBorrowMutability::new(*mutbl, AllowTwoPhase::Yes); + let autoref = Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(*region, mutbl)), target: method.sig.inputs()[1], diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index b8e6f0258d0..7036c4a7b27 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -159,6 +159,18 @@ pub enum AutoBorrowMutability { Not, } +impl AutoBorrowMutability { + /// Creates an `AutoBorrowMutability` from a mutability and allowance of two phase borrows. + /// + /// Note that when `mutbl.is_not()`, `allow_two_phase_borrow` is ignored + pub fn new(mutbl: hir::Mutability, allow_two_phase_borrow: AllowTwoPhase) -> Self { + match mutbl { + hir::Mutability::Not => Self::Not, + hir::Mutability::Mut => Self::Mut { allow_two_phase_borrow }, + } + } +} + impl From for hir::Mutability { fn from(m: AutoBorrowMutability) -> Self { match m {