Skip to content

Commit e1983d2

Browse files
committed
Auto merge of rust-lang#16669 - ShoyuVanilla:merge-borrow-kind-unique, r=Veykril
Merge `BorrowKind::Unique` into `BorrowKind::Mut` Resolves rust-lang#15170
2 parents 6903a5c + a336bdc commit e1983d2

File tree

7 files changed

+68
-83
lines changed

7 files changed

+68
-83
lines changed

crates/hir-ty/src/infer/closure.rs

+19-15
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use stdx::never;
2323
use crate::{
2424
db::{HirDatabase, InternedClosure},
2525
from_placeholder_idx, make_binders,
26-
mir::{BorrowKind, MirSpan, ProjectionElem},
26+
mir::{BorrowKind, MirSpan, MutBorrowKind, ProjectionElem},
2727
static_lifetime, to_chalk_trait_id,
2828
traits::FnTrait,
2929
utils::{self, generics, Generics},
@@ -142,9 +142,13 @@ impl HirPlace {
142142
mut current_capture: CaptureKind,
143143
len: usize,
144144
) -> CaptureKind {
145-
if let CaptureKind::ByRef(BorrowKind::Mut { .. }) = current_capture {
145+
if let CaptureKind::ByRef(BorrowKind::Mut {
146+
kind: MutBorrowKind::Default | MutBorrowKind::TwoPhasedBorrow,
147+
}) = current_capture
148+
{
146149
if self.projections[len..].iter().any(|it| *it == ProjectionElem::Deref) {
147-
current_capture = CaptureKind::ByRef(BorrowKind::Unique);
150+
current_capture =
151+
CaptureKind::ByRef(BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture });
148152
}
149153
}
150154
current_capture
@@ -377,7 +381,7 @@ impl InferenceContext<'_> {
377381
if let Some(place) = self.place_of_expr(expr) {
378382
self.add_capture(
379383
place,
380-
CaptureKind::ByRef(BorrowKind::Mut { allow_two_phase_borrow: false }),
384+
CaptureKind::ByRef(BorrowKind::Mut { kind: MutBorrowKind::Default }),
381385
expr.into(),
382386
);
383387
}
@@ -426,9 +430,7 @@ impl InferenceContext<'_> {
426430

427431
fn ref_capture_with_adjusts(&mut self, m: Mutability, tgt_expr: ExprId, rest: &[Adjustment]) {
428432
let capture_kind = match m {
429-
Mutability::Mut => {
430-
CaptureKind::ByRef(BorrowKind::Mut { allow_two_phase_borrow: false })
431-
}
433+
Mutability::Mut => CaptureKind::ByRef(BorrowKind::Mut { kind: MutBorrowKind::Default }),
432434
Mutability::Not => CaptureKind::ByRef(BorrowKind::Shared),
433435
};
434436
if let Some(place) = self.place_of_expr_without_adjust(tgt_expr) {
@@ -648,7 +650,7 @@ impl InferenceContext<'_> {
648650
self.walk_pat_inner(
649651
pat,
650652
&mut update_result,
651-
BorrowKind::Mut { allow_two_phase_borrow: false },
653+
BorrowKind::Mut { kind: MutBorrowKind::Default },
652654
);
653655
}
654656

@@ -699,7 +701,7 @@ impl InferenceContext<'_> {
699701
},
700702
}
701703
if self.result.pat_adjustments.get(&p).map_or(false, |it| !it.is_empty()) {
702-
for_mut = BorrowKind::Unique;
704+
for_mut = BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture };
703705
}
704706
self.body.walk_pats_shallow(p, |p| self.walk_pat_inner(p, update_result, for_mut));
705707
}
@@ -880,7 +882,7 @@ impl InferenceContext<'_> {
880882
}
881883
BindingMode::Ref(Mutability::Not) => BorrowKind::Shared,
882884
BindingMode::Ref(Mutability::Mut) => {
883-
BorrowKind::Mut { allow_two_phase_borrow: false }
885+
BorrowKind::Mut { kind: MutBorrowKind::Default }
884886
}
885887
};
886888
self.add_capture(place, CaptureKind::ByRef(capture_kind), pat.into());
@@ -930,9 +932,7 @@ impl InferenceContext<'_> {
930932
r = cmp::min(
931933
r,
932934
match &it.kind {
933-
CaptureKind::ByRef(BorrowKind::Unique | BorrowKind::Mut { .. }) => {
934-
FnTrait::FnMut
935-
}
935+
CaptureKind::ByRef(BorrowKind::Mut { .. }) => FnTrait::FnMut,
936936
CaptureKind::ByRef(BorrowKind::Shallow | BorrowKind::Shared) => FnTrait::Fn,
937937
CaptureKind::ByValue => FnTrait::FnOnce,
938938
},
@@ -949,8 +949,12 @@ impl InferenceContext<'_> {
949949
};
950950
self.consume_expr(*body);
951951
for item in &self.current_captures {
952-
if matches!(item.kind, CaptureKind::ByRef(BorrowKind::Mut { .. }))
953-
&& !item.place.projections.contains(&ProjectionElem::Deref)
952+
if matches!(
953+
item.kind,
954+
CaptureKind::ByRef(BorrowKind::Mut {
955+
kind: MutBorrowKind::Default | MutBorrowKind::TwoPhasedBorrow
956+
})
957+
) && !item.place.projections.contains(&ProjectionElem::Deref)
954958
{
955959
// FIXME: remove the `mutated_bindings_in_closure` completely and add proper fake reads in
956960
// MIR. I didn't do that due duplicate diagnostics.

crates/hir-ty/src/mir.rs

+14-47
Original file line numberDiff line numberDiff line change
@@ -659,66 +659,33 @@ pub enum BorrowKind {
659659
/// We can also report errors with this kind of borrow differently.
660660
Shallow,
661661

662-
/// Data must be immutable but not aliasable. This kind of borrow
663-
/// cannot currently be expressed by the user and is used only in
664-
/// implicit closure bindings. It is needed when the closure is
665-
/// borrowing or mutating a mutable referent, e.g.:
666-
/// ```
667-
/// let mut z = 3;
668-
/// let x: &mut isize = &mut z;
669-
/// let y = || *x += 5;
670-
/// ```
671-
/// If we were to try to translate this closure into a more explicit
672-
/// form, we'd encounter an error with the code as written:
673-
/// ```compile_fail,E0594
674-
/// struct Env<'a> { x: &'a &'a mut isize }
675-
/// let mut z = 3;
676-
/// let x: &mut isize = &mut z;
677-
/// let y = (&mut Env { x: &x }, fn_ptr); // Closure is pair of env and fn
678-
/// fn fn_ptr(env: &mut Env) { **env.x += 5; }
679-
/// ```
680-
/// This is then illegal because you cannot mutate an `&mut` found
681-
/// in an aliasable location. To solve, you'd have to translate with
682-
/// an `&mut` borrow:
683-
/// ```compile_fail,E0596
684-
/// struct Env<'a> { x: &'a mut &'a mut isize }
685-
/// let mut z = 3;
686-
/// let x: &mut isize = &mut z;
687-
/// let y = (&mut Env { x: &mut x }, fn_ptr); // changed from &x to &mut x
688-
/// fn fn_ptr(env: &mut Env) { **env.x += 5; }
689-
/// ```
690-
/// Now the assignment to `**env.x` is legal, but creating a
691-
/// mutable pointer to `x` is not because `x` is not mutable. We
692-
/// could fix this by declaring `x` as `let mut x`. This is ok in
693-
/// user code, if awkward, but extra weird for closures, since the
694-
/// borrow is hidden.
695-
///
696-
/// So we introduce a "unique imm" borrow -- the referent is
697-
/// immutable, but not aliasable. This solves the problem. For
698-
/// simplicity, we don't give users the way to express this
699-
/// borrow, it's just used when translating closures.
700-
Unique,
701-
702662
/// Data is mutable and not aliasable.
703-
Mut {
704-
/// `true` if this borrow arose from method-call auto-ref
705-
/// (i.e., `adjustment::Adjust::Borrow`).
706-
allow_two_phase_borrow: bool,
707-
},
663+
Mut { kind: MutBorrowKind },
664+
}
665+
666+
#[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord)]
667+
pub enum MutBorrowKind {
668+
Default,
669+
/// This borrow arose from method-call auto-ref
670+
/// (i.e., adjustment::Adjust::Borrow).
671+
TwoPhasedBorrow,
672+
/// Data must be immutable but not aliasable. This kind of borrow cannot currently
673+
/// be expressed by the user and is used only in implicit closure bindings.
674+
ClosureCapture,
708675
}
709676

710677
impl BorrowKind {
711678
fn from_hir(m: hir_def::type_ref::Mutability) -> Self {
712679
match m {
713680
hir_def::type_ref::Mutability::Shared => BorrowKind::Shared,
714-
hir_def::type_ref::Mutability::Mut => BorrowKind::Mut { allow_two_phase_borrow: false },
681+
hir_def::type_ref::Mutability::Mut => BorrowKind::Mut { kind: MutBorrowKind::Default },
715682
}
716683
}
717684

718685
fn from_chalk(m: Mutability) -> Self {
719686
match m {
720687
Mutability::Not => BorrowKind::Shared,
721-
Mutability::Mut => BorrowKind::Mut { allow_two_phase_borrow: false },
688+
Mutability::Mut => BorrowKind::Mut { kind: MutBorrowKind::Default },
722689
}
723690
}
724691
}

crates/hir-ty/src/mir/borrowck.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ use crate::{
1919
};
2020

2121
use super::{
22-
BasicBlockId, BorrowKind, LocalId, MirBody, MirLowerError, MirSpan, Place, ProjectionElem,
23-
Rvalue, StatementKind, TerminatorKind,
22+
BasicBlockId, BorrowKind, LocalId, MirBody, MirLowerError, MirSpan, MutBorrowKind, Place,
23+
ProjectionElem, Rvalue, StatementKind, TerminatorKind,
2424
};
2525

2626
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -540,7 +540,13 @@ fn mutability_of_locals(
540540
}
541541
Rvalue::ShallowInitBox(_, _) | Rvalue::ShallowInitBoxWithAlloc(_) => (),
542542
}
543-
if let Rvalue::Ref(BorrowKind::Mut { .. }, p) = value {
543+
if let Rvalue::Ref(
544+
BorrowKind::Mut {
545+
kind: MutBorrowKind::Default | MutBorrowKind::TwoPhasedBorrow,
546+
},
547+
p,
548+
) = value
549+
{
544550
if place_case(db, body, p) != ProjectionCase::Indirect {
545551
push_mut_span(p.local, statement.span, &mut result);
546552
}

crates/hir-ty/src/mir/lower/as_place.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! MIR lowering for places
22
3+
use crate::mir::MutBorrowKind;
4+
35
use super::*;
46
use hir_def::FunctionId;
57
use hir_expand::name;
@@ -328,7 +330,7 @@ impl MirLowerCtx<'_> {
328330
Mutability::Mut,
329331
LangItem::DerefMut,
330332
name![deref_mut],
331-
BorrowKind::Mut { allow_two_phase_borrow: false },
333+
BorrowKind::Mut { kind: MutBorrowKind::Default },
332334
)
333335
};
334336
let ty_ref = TyKind::Ref(chalk_mut, static_lifetime(), source_ty.clone()).intern(Interner);

crates/hir-ty/src/mir/lower/pattern_matching.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
use hir_def::{hir::LiteralOrConst, resolver::HasResolver, AssocItemId};
44

55
use crate::{
6-
mir::lower::{
7-
BasicBlockId, BinOp, BindingId, BorrowKind, Either, Expr, FieldId, Idx, Interner,
8-
MemoryMap, MirLowerCtx, MirLowerError, MirSpan, Mutability, Operand, Pat, PatId, Place,
9-
PlaceElem, ProjectionElem, RecordFieldPat, ResolveValueResult, Result, Rvalue,
10-
Substitution, SwitchTargets, TerminatorKind, TupleFieldId, TupleId, TyBuilder, TyKind,
11-
ValueNs, VariantData, VariantId,
6+
mir::{
7+
lower::{
8+
BasicBlockId, BinOp, BindingId, BorrowKind, Either, Expr, FieldId, Idx, Interner,
9+
MemoryMap, MirLowerCtx, MirLowerError, MirSpan, Mutability, Operand, Pat, PatId, Place,
10+
PlaceElem, ProjectionElem, RecordFieldPat, ResolveValueResult, Result, Rvalue,
11+
Substitution, SwitchTargets, TerminatorKind, TupleFieldId, TupleId, TyBuilder, TyKind,
12+
ValueNs, VariantData, VariantId,
13+
},
14+
MutBorrowKind,
1215
},
1316
BindingMode,
1417
};
@@ -450,7 +453,7 @@ impl MirLowerCtx<'_> {
450453
BindingMode::Move => Operand::Copy(cond_place).into(),
451454
BindingMode::Ref(Mutability::Not) => Rvalue::Ref(BorrowKind::Shared, cond_place),
452455
BindingMode::Ref(Mutability::Mut) => {
453-
Rvalue::Ref(BorrowKind::Mut { allow_two_phase_borrow: false }, cond_place)
456+
Rvalue::Ref(BorrowKind::Mut { kind: MutBorrowKind::Default }, cond_place)
454457
}
455458
},
456459
span,

crates/hir-ty/src/mir/pretty.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ use crate::{
1818
};
1919

2020
use super::{
21-
AggregateKind, BasicBlockId, BorrowKind, LocalId, MirBody, Operand, Place, Rvalue, UnOp,
21+
AggregateKind, BasicBlockId, BorrowKind, LocalId, MirBody, MutBorrowKind, Operand, Place,
22+
Rvalue, UnOp,
2223
};
2324

2425
macro_rules! w {
@@ -366,8 +367,10 @@ impl<'a> MirPrettyCtx<'a> {
366367
match r {
367368
BorrowKind::Shared => w!(self, "&"),
368369
BorrowKind::Shallow => w!(self, "&shallow "),
369-
BorrowKind::Unique => w!(self, "&uniq "),
370-
BorrowKind::Mut { .. } => w!(self, "&mut "),
370+
BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture } => w!(self, "&uniq "),
371+
BorrowKind::Mut {
372+
kind: MutBorrowKind::Default | MutBorrowKind::TwoPhasedBorrow,
373+
} => w!(self, "&mut "),
371374
}
372375
self.place(p);
373376
}

crates/hir/src/lib.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ use hir_ty::{
6868
known_const_to_ast,
6969
layout::{Layout as TyLayout, RustcEnumVariantIdx, RustcFieldIdx, TagEncoding},
7070
method_resolution::{self, TyFingerprint},
71-
mir::interpret_mir,
71+
mir::{interpret_mir, MutBorrowKind},
7272
primitive::UintTy,
7373
traits::FnTrait,
7474
AliasTy, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId, GenericArg,
@@ -3754,12 +3754,12 @@ impl ClosureCapture {
37543754
hir_ty::CaptureKind::ByRef(
37553755
hir_ty::mir::BorrowKind::Shallow | hir_ty::mir::BorrowKind::Shared,
37563756
) => CaptureKind::SharedRef,
3757-
hir_ty::CaptureKind::ByRef(hir_ty::mir::BorrowKind::Unique) => {
3758-
CaptureKind::UniqueSharedRef
3759-
}
3760-
hir_ty::CaptureKind::ByRef(hir_ty::mir::BorrowKind::Mut { .. }) => {
3761-
CaptureKind::MutableRef
3762-
}
3757+
hir_ty::CaptureKind::ByRef(hir_ty::mir::BorrowKind::Mut {
3758+
kind: MutBorrowKind::ClosureCapture,
3759+
}) => CaptureKind::UniqueSharedRef,
3760+
hir_ty::CaptureKind::ByRef(hir_ty::mir::BorrowKind::Mut {
3761+
kind: MutBorrowKind::Default | MutBorrowKind::TwoPhasedBorrow,
3762+
}) => CaptureKind::MutableRef,
37633763
hir_ty::CaptureKind::ByValue => CaptureKind::Move,
37643764
}
37653765
}

0 commit comments

Comments
 (0)