Skip to content

Commit 8d84646

Browse files
Don't mark zero-sized arrays as indirectly mutable when borrowed
1 parent a1ad38f commit 8d84646

File tree

1 file changed

+31
-15
lines changed

1 file changed

+31
-15
lines changed

src/librustc_mir/dataflow/impls/indirect_mutation.rs

+31-15
Original file line numberDiff line numberDiff line change
@@ -97,28 +97,44 @@ struct TransferFunction<'a, 'mir, 'tcx> {
9797
param_env: ty::ParamEnv<'tcx>,
9898
}
9999

100+
impl<'tcx> TransferFunction<'_, '_, 'tcx> {
101+
/// Returns `true` if this borrow would allow mutation of the `borrowed_place`.
102+
fn borrow_allows_mutation(
103+
&self,
104+
kind: mir::BorrowKind,
105+
borrowed_place: &mir::Place<'tcx>,
106+
) -> bool {
107+
let borrowed_ty = borrowed_place.ty(self.body, self.tcx).ty;
108+
109+
// Zero-sized types cannot be mutated, since there is nothing inside to mutate.
110+
//
111+
// FIXME: For now, we only exempt arrays of length zero. We need to carefully
112+
// consider the effects before extending this to all ZSTs.
113+
if let ty::Array(_, len) = borrowed_ty.kind {
114+
if len.try_eval_usize(self.tcx, self.param_env) == Some(0) {
115+
return false;
116+
}
117+
}
118+
119+
match kind {
120+
mir::BorrowKind::Mut { .. } => true,
121+
122+
| mir::BorrowKind::Shared
123+
| mir::BorrowKind::Shallow
124+
| mir::BorrowKind::Unique
125+
=> !borrowed_ty.is_freeze(self.tcx, self.param_env, DUMMY_SP),
126+
}
127+
}
128+
}
129+
100130
impl<'tcx> Visitor<'tcx> for TransferFunction<'_, '_, 'tcx> {
101131
fn visit_rvalue(
102132
&mut self,
103133
rvalue: &mir::Rvalue<'tcx>,
104134
location: Location,
105135
) {
106136
if let mir::Rvalue::Ref(_, kind, ref borrowed_place) = *rvalue {
107-
let is_mut = match kind {
108-
mir::BorrowKind::Mut { .. } => true,
109-
110-
| mir::BorrowKind::Shared
111-
| mir::BorrowKind::Shallow
112-
| mir::BorrowKind::Unique
113-
=> {
114-
!borrowed_place
115-
.ty(self.body, self.tcx)
116-
.ty
117-
.is_freeze(self.tcx, self.param_env, DUMMY_SP)
118-
}
119-
};
120-
121-
if is_mut {
137+
if self.borrow_allows_mutation(kind, borrowed_place) {
122138
match borrowed_place.base {
123139
mir::PlaceBase::Local(borrowed_local) if !borrowed_place.is_indirect()
124140
=> self.trans.gen(borrowed_local),

0 commit comments

Comments
 (0)