From 8fb4c41f35fee3b224ea87148cb2ae31a9ed4675 Mon Sep 17 00:00:00 2001 From: Ziru Niu Date: Wed, 31 May 2023 06:25:27 +0800 Subject: [PATCH] merge `BorrowKind::Unique` into `BorrowKind::Mut` --- compiler/rustc_borrowck/src/borrow_set.rs | 2 +- .../src/diagnostics/conflict_errors.rs | 40 ++++++++++++------- .../rustc_borrowck/src/diagnostics/mod.rs | 6 +-- .../src/diagnostics/mutability_errors.rs | 4 +- compiler/rustc_borrowck/src/invalidation.rs | 13 +++--- compiler/rustc_borrowck/src/lib.rs | 38 +++++++----------- .../rustc_borrowck/src/places_conflict.rs | 6 ++- .../src/transform/check_consts/check.rs | 3 +- .../src/transform/check_consts/resolver.rs | 2 +- .../src/transform/promote_consts.rs | 4 +- compiler/rustc_middle/src/mir/mod.rs | 12 +++--- compiler/rustc_middle/src/mir/syntax.rs | 24 +++++------ compiler/rustc_middle/src/mir/tcx.rs | 5 --- compiler/rustc_middle/src/mir/visit.rs | 3 -- .../src/build/expr/as_rvalue.rs | 6 +-- .../rustc_mir_build/src/check_unsafety.rs | 20 ++++++---- compiler/rustc_mir_build/src/thir/cx/expr.rs | 16 +++++--- .../rustc_mir_build/src/thir/pattern/mod.rs | 2 +- .../rustc_mir_dataflow/src/elaborate_drops.rs | 2 +- compiler/rustc_mir_transform/src/inline.rs | 2 +- compiler/rustc_mir_transform/src/shim.rs | 4 +- 21 files changed, 109 insertions(+), 105 deletions(-) diff --git a/compiler/rustc_borrowck/src/borrow_set.rs b/compiler/rustc_borrowck/src/borrow_set.rs index 6be20b0974d..cf17b16b63a 100644 --- a/compiler/rustc_borrowck/src/borrow_set.rs +++ b/compiler/rustc_borrowck/src/borrow_set.rs @@ -72,7 +72,7 @@ fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result { let kind = match self.kind { mir::BorrowKind::Shared => "", mir::BorrowKind::Shallow => "shallow ", - mir::BorrowKind::Unique => "uniq ", + mir::BorrowKind::Mut { kind: mir::MutBorrowKind::ClosureCapture } => "uniq ", mir::BorrowKind::Mut { .. } => "mut ", }; write!(w, "&{:?} {}{:?}", self.region, kind, self.borrowed_place) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index fd5c21cfdf6..ca7b092a8a7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -15,8 +15,9 @@ use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ self, AggregateKind, BindingForm, BorrowKind, CallSource, ClearCrossCrate, ConstraintCategory, - FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef, - ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm, + FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, MutBorrowKind, Operand, Place, + PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, + VarBindingForm, }; use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty}; use rustc_middle::util::CallKind; @@ -926,7 +927,10 @@ pub(crate) fn report_conflicting_borrow( // FIXME: supply non-"" `opt_via` when appropriate let first_borrow_desc; let mut err = match (gen_borrow_kind, issued_borrow.kind) { - (BorrowKind::Shared, BorrowKind::Mut { .. }) => { + ( + BorrowKind::Shared, + BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }, + ) => { first_borrow_desc = "mutable "; self.cannot_reborrow_already_borrowed( span, @@ -940,7 +944,10 @@ pub(crate) fn report_conflicting_borrow( None, ) } - (BorrowKind::Mut { .. }, BorrowKind::Shared) => { + ( + BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }, + BorrowKind::Shared, + ) => { first_borrow_desc = "immutable "; let mut err = self.cannot_reborrow_already_borrowed( span, @@ -962,7 +969,10 @@ pub(crate) fn report_conflicting_borrow( err } - (BorrowKind::Mut { .. }, BorrowKind::Mut { .. }) => { + ( + BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }, + BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }, + ) => { first_borrow_desc = "first "; let mut err = self.cannot_mutably_borrow_multiply( span, @@ -985,12 +995,15 @@ pub(crate) fn report_conflicting_borrow( err } - (BorrowKind::Unique, BorrowKind::Unique) => { + ( + BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture }, + BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture }, + ) => { first_borrow_desc = "first "; self.cannot_uniquely_borrow_by_two_closures(span, &desc_place, issued_span, None) } - (BorrowKind::Mut { .. } | BorrowKind::Unique, BorrowKind::Shallow) => { + (BorrowKind::Mut { .. }, BorrowKind::Shallow) => { if let Some(immutable_section_description) = self.classify_immutable_section(issued_borrow.assigned_place) { @@ -1004,7 +1017,7 @@ pub(crate) fn report_conflicting_borrow( borrow_spans.var_subdiag( None, &mut err, - Some(BorrowKind::Unique), + Some(BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture }), |kind, var_span| { use crate::session_diagnostics::CaptureVarCause::*; match kind { @@ -1038,7 +1051,7 @@ pub(crate) fn report_conflicting_borrow( } } - (BorrowKind::Unique, _) => { + (BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture }, _) => { first_borrow_desc = "first "; self.cannot_uniquely_borrow_by_one_closure( span, @@ -1052,7 +1065,7 @@ pub(crate) fn report_conflicting_borrow( ) } - (BorrowKind::Shared, BorrowKind::Unique) => { + (BorrowKind::Shared, BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture }) => { first_borrow_desc = "first "; self.cannot_reborrow_already_uniquely_borrowed( span, @@ -1067,7 +1080,7 @@ pub(crate) fn report_conflicting_borrow( ) } - (BorrowKind::Mut { .. }, BorrowKind::Unique) => { + (BorrowKind::Mut { .. }, BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture }) => { first_borrow_desc = "first "; self.cannot_reborrow_already_uniquely_borrowed( span, @@ -1085,10 +1098,7 @@ pub(crate) fn report_conflicting_borrow( (BorrowKind::Shared, BorrowKind::Shared | BorrowKind::Shallow) | ( BorrowKind::Shallow, - BorrowKind::Mut { .. } - | BorrowKind::Unique - | BorrowKind::Shared - | BorrowKind::Shallow, + BorrowKind::Mut { .. } | BorrowKind::Shared | BorrowKind::Shallow, ) => unreachable!(), }; diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 1d3cc851888..931ee8767d9 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -629,9 +629,9 @@ pub(super) fn var_subdiag( Some(kd) => match kd { rustc_middle::mir::BorrowKind::Shared | rustc_middle::mir::BorrowKind::Shallow - | rustc_middle::mir::BorrowKind::Unique => { - CaptureVarKind::Immut { kind_span: capture_kind_span } - } + | rustc_middle::mir::BorrowKind::Mut { + kind: rustc_middle::mir::MutBorrowKind::ClosureCapture, + } => CaptureVarKind::Immut { kind_span: capture_kind_span }, rustc_middle::mir::BorrowKind::Mut { .. } => { CaptureVarKind::Mut { kind_span: capture_kind_span } diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 34d466db2b4..1ba490e9a01 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -234,7 +234,7 @@ pub(crate) fn report_mutability_error( borrow_spans.var_subdiag( None, &mut err, - Some(mir::BorrowKind::Mut { allow_two_phase_borrow: false }), + Some(mir::BorrowKind::Mut { kind: mir::MutBorrowKind::Default }), |_kind, var_span| { let place = self.describe_any_place(access_place.as_ref()); crate::session_diagnostics::CaptureVarCause::MutableBorrowUsePlaceClosure { @@ -300,7 +300,7 @@ pub(crate) fn report_mutability_error( _, mir::Rvalue::Ref( _, - mir::BorrowKind::Mut { allow_two_phase_borrow: false }, + mir::BorrowKind::Mut { kind: mir::MutBorrowKind::Default }, _, ), )), diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs index e4fbe6ea4f4..0152d89eb83 100644 --- a/compiler/rustc_borrowck/src/invalidation.rs +++ b/compiler/rustc_borrowck/src/invalidation.rs @@ -255,7 +255,7 @@ fn consume_rvalue(&mut self, location: Location, rvalue: &Rvalue<'tcx>) { (Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk))) } BorrowKind::Shared => (Deep, Read(ReadKind::Borrow(bk))), - BorrowKind::Unique | BorrowKind::Mut { .. } => { + BorrowKind::Mut { .. } => { let wk = WriteKind::MutableBorrow(bk); if allow_two_phase_borrow(bk) { (Deep, Reservation(wk)) @@ -273,7 +273,7 @@ fn consume_rvalue(&mut self, location: Location, rvalue: &Rvalue<'tcx>) { Mutability::Mut => ( Deep, Write(WriteKind::MutableBorrow(BorrowKind::Mut { - allow_two_phase_borrow: false, + kind: mir::MutBorrowKind::Default, })), ), Mutability::Not => (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))), @@ -376,14 +376,11 @@ fn check_access_for_conflict( } (Read(_), BorrowKind::Shallow | BorrowKind::Shared) - | ( - Read(ReadKind::Borrow(BorrowKind::Shallow)), - BorrowKind::Unique | BorrowKind::Mut { .. }, - ) => { + | (Read(ReadKind::Borrow(BorrowKind::Shallow)), BorrowKind::Mut { .. }) => { // Reads don't invalidate shared or shallow borrows } - (Read(_), BorrowKind::Unique | BorrowKind::Mut { .. }) => { + (Read(_), BorrowKind::Mut { .. }) => { // Reading from mere reservations of mutable-borrows is OK. if !is_active(&this.dominators, borrow, location) { // If the borrow isn't active yet, reads don't invalidate it @@ -425,7 +422,7 @@ fn check_activations(&mut self, location: Location) { // only mutable borrows should be 2-phase assert!(match borrow.kind { BorrowKind::Shared | BorrowKind::Shallow => false, - BorrowKind::Unique | BorrowKind::Mut { .. } => true, + BorrowKind::Mut { .. } => true, }); self.access_place( diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 4fcdda311bf..d27dc542ad5 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -29,8 +29,8 @@ InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt, }; use rustc_middle::mir::{ - traversal, Body, ClearCrossCrate, Local, Location, Mutability, NonDivergingIntrinsic, Operand, - Place, PlaceElem, PlaceRef, VarDebugInfoContents, + traversal, Body, ClearCrossCrate, Local, Location, MutBorrowKind, Mutability, + NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef, VarDebugInfoContents, }; use rustc_middle::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind}; @@ -1071,10 +1071,9 @@ fn check_access_for_conflict( } (Read(_), BorrowKind::Shared | BorrowKind::Shallow) - | ( - Read(ReadKind::Borrow(BorrowKind::Shallow)), - BorrowKind::Unique | BorrowKind::Mut { .. }, - ) => Control::Continue, + | (Read(ReadKind::Borrow(BorrowKind::Shallow)), BorrowKind::Mut { .. }) => { + Control::Continue + } (Reservation(_), BorrowKind::Shallow | BorrowKind::Shared) => { // This used to be a future compatibility warning (to be @@ -1087,7 +1086,7 @@ fn check_access_for_conflict( Control::Continue } - (Read(kind), BorrowKind::Unique | BorrowKind::Mut { .. }) => { + (Read(kind), BorrowKind::Mut { .. }) => { // Reading from mere reservations of mutable-borrows is OK. if !is_active(this.dominators(), borrow, location) { assert!(allow_two_phase_borrow(borrow.kind)); @@ -1194,7 +1193,7 @@ fn consume_rvalue( (Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk))) } BorrowKind::Shared => (Deep, Read(ReadKind::Borrow(bk))), - BorrowKind::Unique | BorrowKind::Mut { .. } => { + BorrowKind::Mut { .. } => { let wk = WriteKind::MutableBorrow(bk); if allow_two_phase_borrow(bk) { (Deep, Reservation(wk)) @@ -1231,7 +1230,7 @@ fn consume_rvalue( Mutability::Mut => ( Deep, Write(WriteKind::MutableBorrow(BorrowKind::Mut { - allow_two_phase_borrow: false, + kind: MutBorrowKind::Default, })), ), Mutability::Not => (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))), @@ -1565,7 +1564,7 @@ fn check_activations(&mut self, location: Location, span: Span, flow_state: &Flo // only mutable borrows should be 2-phase assert!(match borrow.kind { BorrowKind::Shared | BorrowKind::Shallow => false, - BorrowKind::Unique | BorrowKind::Mut { .. } => true, + BorrowKind::Mut { .. } => true, }); self.access_place( @@ -1959,14 +1958,12 @@ fn check_access_permissions( let the_place_err; match kind { - Reservation(WriteKind::MutableBorrow( - borrow_kind @ (BorrowKind::Unique | BorrowKind::Mut { .. }), - )) - | Write(WriteKind::MutableBorrow( - borrow_kind @ (BorrowKind::Unique | BorrowKind::Mut { .. }), - )) => { + Reservation(WriteKind::MutableBorrow(borrow_kind @ BorrowKind::Mut { .. })) + | Write(WriteKind::MutableBorrow(borrow_kind @ BorrowKind::Mut { .. })) => { let is_local_mutation_allowed = match borrow_kind { - BorrowKind::Unique => LocalMutationIsAllowed::Yes, + BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture } => { + LocalMutationIsAllowed::Yes + } BorrowKind::Mut { .. } => is_local_mutation_allowed, BorrowKind::Shared | BorrowKind::Shallow => unreachable!(), }; @@ -2031,12 +2028,7 @@ fn check_access_permissions( return false; } Read( - ReadKind::Borrow( - BorrowKind::Unique - | BorrowKind::Mut { .. } - | BorrowKind::Shared - | BorrowKind::Shallow, - ) + ReadKind::Borrow(BorrowKind::Mut { .. } | BorrowKind::Shared | BorrowKind::Shallow) | ReadKind::Copy, ) => { // Access authorized diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs index 25c485b814f..c83d045a94e 100644 --- a/compiler/rustc_borrowck/src/places_conflict.rs +++ b/compiler/rustc_borrowck/src/places_conflict.rs @@ -4,7 +4,9 @@ use crate::Overlap; use crate::{AccessDepth, Deep, Shallow}; use rustc_hir as hir; -use rustc_middle::mir::{Body, BorrowKind, Local, Place, PlaceElem, PlaceRef, ProjectionElem}; +use rustc_middle::mir::{ + Body, BorrowKind, Local, MutBorrowKind, Place, PlaceElem, PlaceRef, ProjectionElem, +}; use rustc_middle::ty::{self, TyCtxt}; use std::cmp::max; use std::iter; @@ -35,7 +37,7 @@ pub fn places_conflict<'tcx>( tcx, body, borrow_place, - BorrowKind::Mut { allow_two_phase_borrow: true }, + BorrowKind::Mut { kind: MutBorrowKind::TwoPhaseBorrow }, access_place.as_ref(), AccessDepth::Deep, bias, diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 2aaf1340eb4..ee85d12a273 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -412,7 +412,6 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { BorrowKind::Shallow => { PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) } - BorrowKind::Unique => PlaceContext::MutatingUse(MutatingUseContext::Borrow), BorrowKind::Mut { .. } => { PlaceContext::MutatingUse(MutatingUseContext::Borrow) } @@ -457,7 +456,7 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { } } - Rvalue::Ref(_, kind @ (BorrowKind::Mut { .. } | BorrowKind::Unique), place) => { + Rvalue::Ref(_, kind @ BorrowKind::Mut { .. }, place) => { let ty = place.ty(self.body, self.tcx).ty; let is_allowed = match ty.kind() { // Inside a `static mut`, `&mut [...]` is allowed. diff --git a/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs b/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs index 65fe164f8ec..3a869f7f547 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs @@ -103,7 +103,7 @@ fn address_of_allows_mutation(&self, _mt: mir::Mutability, _place: mir::Place<'t fn ref_allows_mutation(&self, kind: mir::BorrowKind, place: mir::Place<'tcx>) -> bool { match kind { mir::BorrowKind::Mut { .. } => true, - mir::BorrowKind::Shared | mir::BorrowKind::Shallow | mir::BorrowKind::Unique => { + mir::BorrowKind::Shared | mir::BorrowKind::Shallow => { self.shared_borrow_allows_mutation(place) } } diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index f02464c7f99..c1abc4b5e99 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -454,7 +454,9 @@ fn validate_ref(&mut self, kind: BorrowKind, place: &Place<'tcx>) -> Result<(), match kind { // Reject these borrow types just to be safe. // FIXME(RalfJung): could we allow them? Should we? No point in it until we have a usecase. - BorrowKind::Shallow | BorrowKind::Unique => return Err(Unpromotable), + BorrowKind::Shallow | BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture } => { + return Err(Unpromotable); + } BorrowKind::Shared => { let has_mut_interior = self.qualif_local::(place.local); diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 6aa20dbed92..7b61c375707 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2035,22 +2035,24 @@ pub fn is_safe_to_remove(&self) -> bool { impl BorrowKind { pub fn mutability(&self) -> Mutability { match *self { - BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => Mutability::Not, + BorrowKind::Shared | BorrowKind::Shallow => Mutability::Not, BorrowKind::Mut { .. } => Mutability::Mut, } } pub fn allows_two_phase_borrow(&self) -> bool { match *self { - BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => false, - BorrowKind::Mut { allow_two_phase_borrow } => allow_two_phase_borrow, + BorrowKind::Shared | BorrowKind::Shallow => false, + BorrowKind::Mut { kind } => kind == MutBorrowKind::TwoPhaseBorrow, } } // FIXME: won't be used after diagnostic migration pub fn describe_mutability(&self) -> &str { match *self { - BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => "immutable", + BorrowKind::Shared + | BorrowKind::Shallow + | BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture } => "immutable", BorrowKind::Mut { .. } => "mutable", } } @@ -2090,7 +2092,7 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { let kind_str = match borrow_kind { BorrowKind::Shared => "", BorrowKind::Shallow => "shallow ", - BorrowKind::Mut { .. } | BorrowKind::Unique => "mut ", + BorrowKind::Mut { .. } => "mut ", }; // When printing regions, add trailing space if necessary. diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 10f368fc41c..458672676e2 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -182,6 +182,16 @@ pub enum BorrowKind { /// We can also report errors with this kind of borrow differently. Shallow, + /// Data is mutable and not aliasable. + Mut { kind: MutBorrowKind }, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, TyEncodable, TyDecodable)] +#[derive(Hash, HashStable)] +pub enum MutBorrowKind { + Default, + /// this borrow arose from method-call auto-ref. (i.e., `adjustment::Adjust::Borrow`) + TwoPhaseBorrow, /// Data must be immutable but not aliasable. This kind of borrow /// cannot currently be expressed by the user and is used only in /// implicit closure bindings. It is needed when the closure is @@ -220,19 +230,7 @@ pub enum BorrowKind { /// immutable, but not aliasable. This solves the problem. For /// simplicity, we don't give users the way to express this /// borrow, it's just used when translating closures. - /// - // FIXME(#112072): This is wrong. Unique borrows are mutable borrows except - // that they do not require their pointee to be marked as a mutable. - // They should still be treated as mutable borrows in every other way, - // e.g. for variance or overlap checking. - Unique, - - /// Data is mutable and not aliasable. - Mut { - /// `true` if this borrow arose from method-call auto-ref - /// (i.e., `adjustment::Adjust::Borrow`). - allow_two_phase_borrow: bool, - }, + ClosureCapture, } /////////////////////////////////////////////////////////////////////////// diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 4a16abdd4e3..65dff193c80 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -269,11 +269,6 @@ pub fn to_mutbl_lossy(self) -> hir::Mutability { BorrowKind::Mut { .. } => hir::Mutability::Mut, BorrowKind::Shared => hir::Mutability::Not, - // We have no type corresponding to a unique imm borrow, so - // use `&mut`. It gives all the capabilities of a `&uniq` - // and hence is a safe "over approximation". - BorrowKind::Unique => hir::Mutability::Mut, - // We have no type corresponding to a shallow borrow, so use // `&` as an approximation. BorrowKind::Shallow => hir::Mutability::Not, diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index ce55b770cbc..b030d1e6c3e 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -650,9 +650,6 @@ fn super_rvalue(&mut self, BorrowKind::Shallow => PlaceContext::NonMutatingUse( NonMutatingUseContext::ShallowBorrow ), - BorrowKind::Unique => PlaceContext::MutatingUse( - MutatingUseContext::Borrow - ), BorrowKind::Mut { .. } => PlaceContext::MutatingUse(MutatingUseContext::Borrow), }; diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index fd08b32807c..ec00f9a96be 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -442,7 +442,7 @@ pub(crate) fn as_rvalue( match upvar.kind { ExprKind::Borrow { borrow_kind: - BorrowKind::Mut { allow_two_phase_borrow: false }, + BorrowKind::Mut { kind: MutBorrowKind::Default }, arg, } => unpack!( block = this.limit_capture_mutability( @@ -795,8 +795,8 @@ fn limit_capture_mutability( }; let borrow_kind = match mutability { - Mutability::Not => BorrowKind::Unique, - Mutability::Mut => BorrowKind::Mut { allow_two_phase_borrow: false }, + Mutability::Not => BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture }, + Mutability::Mut => BorrowKind::Mut { kind: MutBorrowKind::Default }, }; let arg_place = arg_place_builder.to_place(this); diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 0506f2bf238..f7ef8485582 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -3,7 +3,7 @@ use rustc_middle::thir::visit::{self, Visitor}; use rustc_hir as hir; -use rustc_middle::mir::BorrowKind; +use rustc_middle::mir::{BorrowKind, MutBorrowKind}; use rustc_middle::thir::*; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt}; @@ -254,7 +254,9 @@ fn visit_pat(&mut self, pat: &Pat<'tcx>) { ); }; match borrow_kind { - BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique => { + BorrowKind::Shallow + | BorrowKind::Shared + | BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture } => { if !ty.is_freeze(self.tcx, self.param_env) { self.requires_unsafe(pat.span, BorrowOfLayoutConstrainedField); } @@ -440,15 +442,19 @@ fn visit_expr(&mut self, expr: &Expr<'tcx>) { visit::walk_expr(&mut visitor, expr); if visitor.found { match borrow_kind { - BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique + BorrowKind::Shallow + | BorrowKind::Shared + | BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture } if !self.thir[arg].ty.is_freeze(self.tcx, self.param_env) => { self.requires_unsafe(expr.span, BorrowOfLayoutConstrainedField) } - BorrowKind::Mut { .. } => { - self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField) - } - BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique => {} + BorrowKind::Mut { + kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow, + } => self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField), + BorrowKind::Shallow + | BorrowKind::Shared + | BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture } => {} } } } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index b20495d602e..7f0c2e9ca3f 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -1095,8 +1095,12 @@ fn capture_upvar( ty::UpvarCapture::ByRef(upvar_borrow) => { let borrow_kind = match upvar_borrow { ty::BorrowKind::ImmBorrow => BorrowKind::Shared, - ty::BorrowKind::UniqueImmBorrow => BorrowKind::Unique, - ty::BorrowKind::MutBorrow => BorrowKind::Mut { allow_two_phase_borrow: false }, + ty::BorrowKind::UniqueImmBorrow => { + BorrowKind::Mut { kind: mir::MutBorrowKind::ClosureCapture } + } + ty::BorrowKind::MutBorrow => { + BorrowKind::Mut { kind: mir::MutBorrowKind::Default } + } }; Expr { temp_lifetime, @@ -1132,9 +1136,9 @@ fn to_borrow_kind(&self) -> BorrowKind { use rustc_middle::ty::adjustment::AllowTwoPhase; match *self { AutoBorrowMutability::Mut { allow_two_phase_borrow } => BorrowKind::Mut { - allow_two_phase_borrow: match allow_two_phase_borrow { - AllowTwoPhase::Yes => true, - AllowTwoPhase::No => false, + kind: match allow_two_phase_borrow { + AllowTwoPhase::Yes => mir::MutBorrowKind::TwoPhaseBorrow, + AllowTwoPhase::No => mir::MutBorrowKind::Default, }, }, AutoBorrowMutability::Not => BorrowKind::Shared, @@ -1145,7 +1149,7 @@ fn to_borrow_kind(&self) -> BorrowKind { impl ToBorrowKind for hir::Mutability { fn to_borrow_kind(&self) -> BorrowKind { match *self { - hir::Mutability::Mut => BorrowKind::Mut { allow_two_phase_borrow: false }, + hir::Mutability::Mut => BorrowKind::Mut { kind: mir::MutBorrowKind::Default }, hir::Mutability::Not => BorrowKind::Shared, } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 8eeb055ed82..c30c4b65939 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -287,7 +287,7 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box (mutbl, BindingMode::ByValue), ty::BindByReference(hir::Mutability::Mut) => ( Mutability::Not, - BindingMode::ByRef(BorrowKind::Mut { allow_two_phase_borrow: false }), + BindingMode::ByRef(BorrowKind::Mut { kind: mir::MutBorrowKind::Default }), ), ty::BindByReference(hir::Mutability::Not) => { (Mutability::Not, BindingMode::ByRef(BorrowKind::Shared)) diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 27232b70d96..c0102b15a16 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -638,7 +638,7 @@ fn destructor_call_block(&mut self, (succ, unwind): (BasicBlock, Unwind)) -> Bas Place::from(ref_place), Rvalue::Ref( tcx.lifetimes.re_erased, - BorrowKind::Mut { allow_two_phase_borrow: false }, + BorrowKind::Mut { kind: MutBorrowKind::Default }, self.place, ), )], diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index b28fed7159f..703824f5bda 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -522,7 +522,7 @@ fn dest_needs_borrow(place: Place<'_>) -> bool { trace!("creating temp for return destination"); let dest = Rvalue::Ref( self.tcx.lifetimes.re_erased, - BorrowKind::Mut { allow_two_phase_borrow: false }, + BorrowKind::Mut { kind: MutBorrowKind::Default }, destination, ); let dest_ty = dest.ty(caller_body, self.tcx); diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 9d6ef9db4ea..2ae5ec4d9e6 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -188,7 +188,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) // has been put into the body. let reborrow = Rvalue::Ref( tcx.lifetimes.re_erased, - BorrowKind::Mut { allow_two_phase_borrow: false }, + BorrowKind::Mut { kind: MutBorrowKind::Default }, tcx.mk_place_deref(dropee_ptr), ); let ref_ty = reborrow.ty(body.local_decls(), tcx); @@ -712,7 +712,7 @@ fn build_call_shim<'tcx>( ) .immutable(), ); - let borrow_kind = BorrowKind::Mut { allow_two_phase_borrow: false }; + let borrow_kind = BorrowKind::Mut { kind: MutBorrowKind::Default }; statements.push(Statement { source_info, kind: StatementKind::Assign(Box::new((