Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a8e871e

Browse files
committedJan 20, 2025·
Represent the raw pointer for a array length check as a new kind of fake borrow
1 parent 2f2593f commit a8e871e

File tree

26 files changed

+186
-83
lines changed

26 files changed

+186
-83
lines changed
 

‎compiler/rustc_borrowck/src/lib.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,15 +1284,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
12841284
);
12851285
}
12861286

1287-
&Rvalue::RawPtr(mutability, place) => {
1288-
let access_kind = match mutability {
1289-
Mutability::Mut => (
1287+
&Rvalue::RawPtr(kind, place) => {
1288+
let access_kind = match kind {
1289+
RawPtrKind::Mut => (
12901290
Deep,
12911291
Write(WriteKind::MutableBorrow(BorrowKind::Mut {
12921292
kind: MutBorrowKind::Default,
12931293
})),
12941294
),
1295-
Mutability::Not => (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))),
1295+
RawPtrKind::Not => (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))),
1296+
RawPtrKind::FakeForPtrMetadata => {
1297+
(Shallow(Some(ArtificialField::ArrayLength)), Read(ReadKind::Copy))
1298+
}
12961299
};
12971300

12981301
self.access_place(

‎compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,7 @@ use std::ops::ControlFlow;
33
use rustc_data_structures::graph::dominators::Dominators;
44
use rustc_middle::bug;
55
use rustc_middle::mir::visit::Visitor;
6-
use rustc_middle::mir::{
7-
self, BasicBlock, Body, BorrowKind, FakeBorrowKind, InlineAsmOperand, Location, Mutability,
8-
NonDivergingIntrinsic, Operand, Place, Rvalue, Statement, StatementKind, Terminator,
9-
TerminatorKind,
10-
};
6+
use rustc_middle::mir::*;
117
use rustc_middle::ty::TyCtxt;
128
use tracing::debug;
139

@@ -60,7 +56,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'a, 'tcx> {
6056
StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(op)) => {
6157
self.consume_operand(location, op);
6258
}
63-
StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping {
59+
StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping {
6460
src,
6561
dst,
6662
count,
@@ -273,15 +269,18 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
273269
self.access_place(location, place, access_kind, LocalMutationIsAllowed::No);
274270
}
275271

276-
&Rvalue::RawPtr(mutability, place) => {
277-
let access_kind = match mutability {
278-
Mutability::Mut => (
272+
&Rvalue::RawPtr(kind, place) => {
273+
let access_kind = match kind {
274+
RawPtrKind::Mut => (
279275
Deep,
280276
Write(WriteKind::MutableBorrow(BorrowKind::Mut {
281-
kind: mir::MutBorrowKind::Default,
277+
kind: MutBorrowKind::Default,
282278
})),
283279
),
284-
Mutability::Not => (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))),
280+
RawPtrKind::Not => (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))),
281+
RawPtrKind::FakeForPtrMetadata => {
282+
(Shallow(Some(ArtificialField::ArrayLength)), Read(ReadKind::Copy))
283+
}
285284
};
286285

287286
self.access_place(location, place, access_kind, LocalMutationIsAllowed::No);

‎compiler/rustc_codegen_ssa/src/mir/rvalue.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -601,9 +601,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
601601
mir::Rvalue::CopyForDeref(place) => {
602602
self.codegen_operand(bx, &mir::Operand::Copy(place))
603603
}
604-
mir::Rvalue::RawPtr(mutability, place) => {
605-
let mk_ptr =
606-
move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| Ty::new_ptr(tcx, ty, mutability);
604+
mir::Rvalue::RawPtr(kind, place) => {
605+
let mk_ptr = move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| {
606+
Ty::new_ptr(tcx, ty, kind.to_mutbl_lossy())
607+
};
607608
self.codegen_place_to_pointer(bx, place, mk_ptr)
608609
}
609610

‎compiler/rustc_const_eval/src/check_consts/check.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
518518
}
519519

520520
Rvalue::Ref(_, BorrowKind::Mut { .. }, place)
521-
| Rvalue::RawPtr(Mutability::Mut, place) => {
521+
| Rvalue::RawPtr(RawPtrKind::Mut, place) => {
522522
// Inside mutable statics, we allow arbitrary mutable references.
523523
// We've allowed `static mut FOO = &mut [elements];` for a long time (the exact
524524
// reasons why are lost to history), and there is no reason to restrict that to
@@ -536,7 +536,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
536536
}
537537

538538
Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Fake(_), place)
539-
| Rvalue::RawPtr(Mutability::Not, place) => {
539+
| Rvalue::RawPtr(RawPtrKind::Not, place) => {
540540
let borrowed_place_has_mut_interior = qualifs::in_place::<HasMutInterior, _>(
541541
self.ccx,
542542
&mut |local| self.qualifs.has_mut_interior(self.ccx, local, location),
@@ -548,6 +548,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
548548
}
549549
}
550550

551+
Rvalue::RawPtr(RawPtrKind::FakeForPtrMetadata, _) => {
552+
// Do nothing.
553+
}
554+
551555
Rvalue::Cast(
552556
CastKind::PointerCoercion(
553557
PointerCoercion::MutToConstPointer

‎compiler/rustc_const_eval/src/interpret/step.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use rustc_middle::ty::layout::FnAbiOf;
99
use rustc_middle::ty::{self, Instance, Ty};
1010
use rustc_middle::{bug, mir, span_bug};
1111
use rustc_span::source_map::Spanned;
12-
use rustc_span::{DesugaringKind, Span};
1312
use rustc_target::callconv::FnAbi;
1413
use tracing::{info, instrument, trace};
1514

@@ -81,9 +80,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
8180
use rustc_middle::mir::StatementKind::*;
8281

8382
match &stmt.kind {
84-
Assign(box (place, rvalue)) => {
85-
self.eval_rvalue_into_place(rvalue, *place, stmt.source_info.span)?
86-
}
83+
Assign(box (place, rvalue)) => self.eval_rvalue_into_place(rvalue, *place)?,
8784

8885
SetDiscriminant { place, variant_index } => {
8986
let dest = self.eval_place(**place)?;
@@ -162,7 +159,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
162159
&mut self,
163160
rvalue: &mir::Rvalue<'tcx>,
164161
place: mir::Place<'tcx>,
165-
span: Span,
166162
) -> InterpResult<'tcx> {
167163
let dest = self.eval_place(place)?;
168164
// FIXME: ensure some kind of non-aliasing between LHS and RHS?
@@ -241,7 +237,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
241237
self.write_immediate(*val, &dest)?;
242238
}
243239

244-
RawPtr(_, place) => {
240+
RawPtr(kind, place) => {
245241
// Figure out whether this is an addr_of of an already raw place.
246242
let place_base_raw = if place.is_indirect_first_projection() {
247243
let ty = self.frame().body.local_decls[place.local].ty;
@@ -254,13 +250,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
254250
let src = self.eval_place(place)?;
255251
let place = self.force_allocation(&src)?;
256252
let mut val = ImmTy::from_immediate(place.to_ref(self), dest.layout);
257-
if !place_base_raw
258-
&& span.desugaring_kind() != Some(DesugaringKind::IndexBoundsCheckReborrow)
259-
{
253+
if !place_base_raw && !kind.is_fake() {
260254
// If this was not already raw, it needs retagging.
261-
// As a special hack, we exclude the desugared `PtrMetadata(&raw const *_n)`
262-
// from indexing. (Really we should not do any retag on `&raw` but that does not
263-
// currently work with Stacked Borrows.)
264255
val = M::retag_ptr_value(self, mir::RetagKind::Raw, &val)?;
265256
}
266257
self.write_immediate(*val, &dest)?;

‎compiler/rustc_middle/src/mir/syntax.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,51 @@ pub enum BorrowKind {
180180
Mut { kind: MutBorrowKind },
181181
}
182182

183+
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, TyEncodable, TyDecodable)]
184+
#[derive(Hash, HashStable)]
185+
pub enum RawPtrKind {
186+
Mut,
187+
Not,
188+
FakeForPtrMetadata,
189+
}
190+
191+
impl From<Mutability> for RawPtrKind {
192+
fn from(other: Mutability) -> Self {
193+
match other {
194+
Mutability::Mut => RawPtrKind::Mut,
195+
Mutability::Not => RawPtrKind::Not,
196+
}
197+
}
198+
}
199+
200+
impl RawPtrKind {
201+
pub fn is_fake(self) -> bool {
202+
match self {
203+
RawPtrKind::Mut | RawPtrKind::Not => false,
204+
RawPtrKind::FakeForPtrMetadata => true,
205+
}
206+
}
207+
208+
pub fn to_mutbl_lossy(self) -> Mutability {
209+
match self {
210+
RawPtrKind::Mut => Mutability::Mut,
211+
RawPtrKind::Not => Mutability::Not,
212+
213+
// We have no type corresponding to a shallow borrow, so use
214+
// `&` as an approximation.
215+
RawPtrKind::FakeForPtrMetadata => Mutability::Not,
216+
}
217+
}
218+
219+
pub fn ptr_str(self) -> &'static str {
220+
match self {
221+
RawPtrKind::Mut => "mut",
222+
RawPtrKind::Not => "const",
223+
RawPtrKind::FakeForPtrMetadata => "const (fake)",
224+
}
225+
}
226+
}
227+
183228
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, TyEncodable, TyDecodable)]
184229
#[derive(Hash, HashStable)]
185230
pub enum MutBorrowKind {
@@ -1349,7 +1394,7 @@ pub enum Rvalue<'tcx> {
13491394
///
13501395
/// Like with references, the semantics of this operation are heavily dependent on the aliasing
13511396
/// model.
1352-
RawPtr(Mutability, Place<'tcx>),
1397+
RawPtr(RawPtrKind, Place<'tcx>),
13531398

13541399
/// Yields the length of the place, as a `usize`.
13551400
///

‎compiler/rustc_middle/src/mir/tcx.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,9 @@ impl<'tcx> Rvalue<'tcx> {
206206
let place_ty = place.ty(local_decls, tcx).ty;
207207
Ty::new_ref(tcx, reg, place_ty, bk.to_mutbl_lossy())
208208
}
209-
Rvalue::RawPtr(mutability, ref place) => {
209+
Rvalue::RawPtr(kind, ref place) => {
210210
let place_ty = place.ty(local_decls, tcx).ty;
211-
Ty::new_ptr(tcx, place_ty, mutability)
211+
Ty::new_ptr(tcx, place_ty, kind.to_mutbl_lossy())
212212
}
213213
Rvalue::Len(..) => tcx.types.usize,
214214
Rvalue::Cast(.., ty) => ty,

‎compiler/rustc_middle/src/mir/type_foldable.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ TrivialTypeTraversalImpls! {
1515
SourceScopeLocalData,
1616
UserTypeAnnotationIndex,
1717
BorrowKind,
18+
RawPtrKind,
1819
CastKind,
1920
BasicBlock,
2021
SwitchTargets,

‎compiler/rustc_middle/src/mir/visit.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -685,12 +685,15 @@ macro_rules! make_mir_visitor {
685685

686686
Rvalue::RawPtr(m, path) => {
687687
let ctx = match m {
688-
Mutability::Mut => PlaceContext::MutatingUse(
688+
RawPtrKind::Mut => PlaceContext::MutatingUse(
689689
MutatingUseContext::RawBorrow
690690
),
691-
Mutability::Not => PlaceContext::NonMutatingUse(
691+
RawPtrKind::Not => PlaceContext::NonMutatingUse(
692692
NonMutatingUseContext::RawBorrow
693693
),
694+
RawPtrKind::FakeForPtrMetadata => PlaceContext::NonMutatingUse(
695+
NonMutatingUseContext::Inspect
696+
),
694697
};
695698
self.visit_place(path, ctx, location);
696699
}

‎compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> {
253253
Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?)
254254
),
255255
ExprKind::RawBorrow { mutability, arg } => Ok(
256-
Rvalue::RawPtr(*mutability, self.parse_place(*arg)?)
256+
Rvalue::RawPtr((*mutability).into(), self.parse_place(*arg)?)
257257
),
258258
ExprKind::Binary { op, lhs, rhs } => Ok(
259259
Rvalue::BinaryOp(*op, Box::new((self.parse_operand(*lhs)?, self.parse_operand(*rhs)?)))

‎compiler/rustc_mir_build/src/builder/expr/as_place.rs

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_middle::mir::*;
1111
use rustc_middle::thir::*;
1212
use rustc_middle::ty::{self, AdtDef, CanonicalUserTypeAnnotation, Ty, Variance};
1313
use rustc_middle::{bug, span_bug};
14-
use rustc_span::{DesugaringKind, Span};
14+
use rustc_span::Span;
1515
use tracing::{debug, instrument, trace};
1616

1717
use crate::builder::ForGuard::{OutsideGuard, RefWithinGuard};
@@ -643,8 +643,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
643643
source_info: SourceInfo,
644644
) -> Operand<'tcx> {
645645
let place_ty = place.ty(&self.local_decls, self.tcx).ty;
646-
let usize_ty = self.tcx.types.usize;
647-
648646
match place_ty.kind() {
649647
ty::Array(_elem_ty, len_const) => {
650648
// We know how long an array is, so just use that as a constant
@@ -653,7 +651,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
653651
// though. FIXME: Do we really *need* to count this as a use?
654652
// Could partial array tracking work off something else instead?
655653
self.cfg.push_fake_read(block, source_info, FakeReadCause::ForIndex, place);
656-
let const_ = Const::from_ty_const(*len_const, usize_ty, self.tcx);
654+
let const_ = Const::from_ty_const(*len_const, self.tcx.types.usize, self.tcx);
657655
Operand::Constant(Box::new(ConstOperand { span, user_ty: None, const_ }))
658656
}
659657
ty::Slice(_elem_ty) => {
@@ -668,27 +666,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
668666
// the MIR we're building here needs to pass NLL later.
669667
Operand::Copy(Place::from(place.local))
670668
} else {
671-
let len_span = self.tcx.with_stable_hashing_context(|hcx| {
672-
let span = source_info.span;
673-
span.mark_with_reason(
674-
None,
675-
DesugaringKind::IndexBoundsCheckReborrow,
676-
span.edition(),
677-
hcx,
678-
)
679-
});
680669
let ptr_ty = Ty::new_imm_ptr(self.tcx, place_ty);
681670
let slice_ptr = self.temp(ptr_ty, span);
682671
self.cfg.push_assign(
683672
block,
684-
SourceInfo { span: len_span, ..source_info },
673+
source_info,
685674
slice_ptr,
686-
Rvalue::RawPtr(Mutability::Not, place),
675+
Rvalue::RawPtr(RawPtrKind::FakeForPtrMetadata, place),
687676
);
688677
Operand::Move(slice_ptr)
689678
};
690679

691-
let len = self.temp(usize_ty, span);
680+
let len = self.temp(self.tcx.types.usize, span);
692681
self.cfg.push_assign(
693682
block,
694683
source_info,

‎compiler/rustc_mir_build/src/builder/expr/into.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
303303
hir::Mutability::Not => this.as_read_only_place(block, arg),
304304
hir::Mutability::Mut => this.as_place(block, arg),
305305
};
306-
let address_of = Rvalue::RawPtr(mutability, unpack!(block = place));
306+
let address_of = Rvalue::RawPtr(mutability.into(), unpack!(block = place));
307307
this.cfg.push_assign(block, source_info, destination, address_of);
308308
block.unit()
309309
}

‎compiler/rustc_mir_dataflow/src/elaborate_drops.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,7 @@ where
700700
statements: vec![
701701
self.assign(
702702
ptr,
703-
Rvalue::RawPtr(Mutability::Mut, tcx.mk_place_index(self.place, cur)),
703+
Rvalue::RawPtr(RawPtrKind::Mut, tcx.mk_place_index(self.place, cur)),
704704
),
705705
self.assign(
706706
cur.into(),
@@ -816,7 +816,7 @@ where
816816

817817
let mut delegate_block = BasicBlockData {
818818
statements: vec![
819-
self.assign(Place::from(array_ptr), Rvalue::RawPtr(Mutability::Mut, self.place)),
819+
self.assign(Place::from(array_ptr), Rvalue::RawPtr(RawPtrKind::Mut, self.place)),
820820
self.assign(
821821
Place::from(slice_ptr),
822822
Rvalue::Cast(

‎compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ enum AggregateTy<'tcx> {
188188
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
189189
enum AddressKind {
190190
Ref(BorrowKind),
191-
Address(Mutability),
191+
Address(RawPtrKind),
192192
}
193193

194194
#[derive(Debug, PartialEq, Eq, Hash)]
@@ -500,7 +500,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
500500
mplace.layout.ty,
501501
bk.to_mutbl_lossy(),
502502
),
503-
AddressKind::Address(mutbl) => Ty::new_ptr(self.tcx, mplace.layout.ty, mutbl),
503+
AddressKind::Address(mutbl) => {
504+
Ty::new_ptr(self.tcx, mplace.layout.ty, mutbl.to_mutbl_lossy())
505+
}
504506
};
505507
let layout = self.ecx.layout_of(ty).ok()?;
506508
ImmTy::from_immediate(pointer, layout).into()

‎compiler/rustc_mir_transform/src/large_enums.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt {
125125
source_info,
126126
kind: StatementKind::Assign(Box::new((
127127
dst,
128-
Rvalue::RawPtr(Mutability::Mut, *lhs),
128+
Rvalue::RawPtr(RawPtrKind::Mut, *lhs),
129129
))),
130130
};
131131

@@ -146,7 +146,7 @@ impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt {
146146
source_info,
147147
kind: StatementKind::Assign(Box::new((
148148
src,
149-
Rvalue::RawPtr(Mutability::Not, *rhs),
149+
Rvalue::RawPtr(RawPtrKind::Not, *rhs),
150150
))),
151151
};
152152

‎compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,11 @@ use std::iter;
22

33
use itertools::Itertools;
44
use rustc_abi::{FieldIdx, VariantIdx};
5-
use rustc_ast::Mutability;
65
use rustc_const_eval::interpret;
76
use rustc_hir::def_id::DefId;
87
use rustc_hir::lang_items::LangItem;
98
use rustc_index::{Idx, IndexVec};
10-
use rustc_middle::mir::{
11-
BasicBlock, BasicBlockData, Body, CallSource, CastKind, CoercionSource, Const, ConstOperand,
12-
ConstValue, Local, LocalDecl, MirSource, Operand, Place, PlaceElem, RETURN_PLACE, Rvalue,
13-
SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, UnwindAction,
14-
UnwindTerminateReason,
15-
};
9+
use rustc_middle::mir::*;
1610
use rustc_middle::ty::adjustment::PointerCoercion;
1711
use rustc_middle::ty::util::{AsyncDropGlueMorphology, Discr};
1812
use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -345,7 +339,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
345339
.tcx
346340
.mk_place_elems(&[PlaceElem::Deref, PlaceElem::Field(field, field_ty)]),
347341
};
348-
self.put_temp_rvalue(Rvalue::RawPtr(Mutability::Mut, place))
342+
self.put_temp_rvalue(Rvalue::RawPtr(RawPtrKind::Mut, place))
349343
}
350344

351345
/// If given Self is an enum puts `to_drop: *mut FieldTy` on top of
@@ -365,7 +359,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
365359
PlaceElem::Field(field, field_ty),
366360
]),
367361
};
368-
self.put_temp_rvalue(Rvalue::RawPtr(Mutability::Mut, place))
362+
self.put_temp_rvalue(Rvalue::RawPtr(RawPtrKind::Mut, place))
369363
}
370364

371365
/// If given Self is an enum puts `to_drop: *mut FieldTy` on top of

‎compiler/rustc_smir/src/rustc_smir/convert/mir.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,18 @@ impl<'tcx> Stable<'tcx> for mir::Mutability {
232232
}
233233
}
234234

235+
impl<'tcx> Stable<'tcx> for mir::RawPtrKind {
236+
type T = stable_mir::mir::RawPtrKind;
237+
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
238+
use mir::RawPtrKind::*;
239+
match *self {
240+
Not => stable_mir::mir::RawPtrKind::Not,
241+
Mut => stable_mir::mir::RawPtrKind::Mut,
242+
FakeForPtrMetadata => stable_mir::mir::RawPtrKind::FakeForPtrMetadata,
243+
}
244+
}
245+
}
246+
235247
impl<'tcx> Stable<'tcx> for mir::BorrowKind {
236248
type T = stable_mir::mir::BorrowKind;
237249
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {

‎compiler/rustc_span/src/hygiene.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,9 +1163,6 @@ pub enum DesugaringKind {
11631163
WhileLoop,
11641164
/// `async Fn()` bound modifier
11651165
BoundModifier,
1166-
/// Marks a `&raw const *_1` needed as part of getting the length of a mutable
1167-
/// slice for the bounds check, so that MIRI's retag handling can recognize it.
1168-
IndexBoundsCheckReborrow,
11691166
}
11701167

11711168
impl DesugaringKind {
@@ -1182,7 +1179,6 @@ impl DesugaringKind {
11821179
DesugaringKind::ForLoop => "`for` loop",
11831180
DesugaringKind::WhileLoop => "`while` loop",
11841181
DesugaringKind::BoundModifier => "trait bound modifier",
1185-
DesugaringKind::IndexBoundsCheckReborrow => "slice indexing",
11861182
}
11871183
}
11881184
}

‎compiler/stable_mir/src/mir/body.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ pub enum Rvalue {
457457
///
458458
/// This is generated by pointer casts like `&v as *const _` or raw address of expressions like
459459
/// `&raw v` or `addr_of!(v)`.
460-
AddressOf(Mutability, Place),
460+
AddressOf(RawPtrKind, Place),
461461

462462
/// Creates an aggregate value, like a tuple or struct.
463463
///
@@ -577,7 +577,7 @@ impl Rvalue {
577577
}
578578
Rvalue::AddressOf(mutability, place) => {
579579
let place_ty = place.ty(locals)?;
580-
Ok(Ty::new_ptr(place_ty, *mutability))
580+
Ok(Ty::new_ptr(place_ty, mutability.to_mutable_lossy()))
581581
}
582582
Rvalue::Len(..) => Ok(Ty::usize_ty()),
583583
Rvalue::Cast(.., ty) => Ok(*ty),
@@ -903,6 +903,24 @@ impl BorrowKind {
903903
}
904904
}
905905

906+
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
907+
pub enum RawPtrKind {
908+
Mut,
909+
Not,
910+
FakeForPtrMetadata,
911+
}
912+
913+
impl RawPtrKind {
914+
pub fn to_mutable_lossy(self) -> Mutability {
915+
match self {
916+
RawPtrKind::Mut { .. } => Mutability::Mut,
917+
RawPtrKind::Not => Mutability::Not,
918+
// FIXME: There's no type corresponding to a shallow borrow, so use `&` as an approximation.
919+
RawPtrKind::FakeForPtrMetadata => Mutability::Not,
920+
}
921+
}
922+
}
923+
906924
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
907925
pub enum MutBorrowKind {
908926
Default,

‎compiler/stable_mir/src/mir/pretty.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ use std::{fmt, io, iter};
66
use fmt::{Display, Formatter};
77

88
use super::{AggregateKind, AssertMessage, BinOp, BorrowKind, FakeBorrowKind, TerminatorKind};
9-
use crate::mir::{Operand, Place, Rvalue, StatementKind, UnwindAction, VarDebugInfoContents};
9+
use crate::mir::{
10+
Operand, Place, RawPtrKind, Rvalue, StatementKind, UnwindAction, VarDebugInfoContents,
11+
};
1012
use crate::ty::{AdtKind, IndexedVal, MirConst, Ty, TyConst};
1113
use crate::{Body, CrateDef, Mutability, with};
1214

@@ -325,7 +327,7 @@ fn pretty_ty_const(ct: &TyConst) -> String {
325327
fn pretty_rvalue<W: Write>(writer: &mut W, rval: &Rvalue) -> io::Result<()> {
326328
match rval {
327329
Rvalue::AddressOf(mutability, place) => {
328-
write!(writer, "&raw {} {:?}", pretty_mut(*mutability), place)
330+
write!(writer, "&raw {} {:?}", pretty_raw_ptr_kind(*mutability), place)
329331
}
330332
Rvalue::Aggregate(aggregate_kind, operands) => {
331333
// FIXME: Add pretty_aggregate function that returns a pretty string
@@ -437,3 +439,11 @@ fn pretty_mut(mutability: Mutability) -> &'static str {
437439
Mutability::Mut => "mut ",
438440
}
439441
}
442+
443+
fn pretty_raw_ptr_kind(kind: RawPtrKind) -> &'static str {
444+
match kind {
445+
RawPtrKind::Not => "const",
446+
RawPtrKind::Mut => "mut",
447+
RawPtrKind::FakeForPtrMetadata => "const (fake)",
448+
}
449+
}

‎compiler/stable_mir/src/mir/visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ pub trait MirVisitor {
308308
fn super_rvalue(&mut self, rvalue: &Rvalue, location: Location) {
309309
match rvalue {
310310
Rvalue::AddressOf(mutability, place) => {
311-
let pcx = PlaceContext { is_mut: *mutability == Mutability::Mut };
311+
let pcx = PlaceContext { is_mut: *mutability == RawPtrKind::Mut };
312312
self.visit_place(place, pcx, location);
313313
}
314314
Rvalue::Aggregate(_, operands) => {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// This is a regression test for issue #135671 where a MIR refactor about arrays and their lengths
2+
// unexpectedly caused borrowck errors for disjoint borrows of array elements, for which we had no
3+
// tests. This is a collection of a few code samples from that issue.
4+
5+
//@revisions: stack tree
6+
//@[tree]compile-flags: -Zmiri-tree-borrows
7+
8+
struct Test {
9+
a: i32,
10+
b: i32,
11+
}
12+
13+
fn one() {
14+
let inputs: &mut [_] = &mut [Test { a: 0, b: 0 }];
15+
let a = &mut inputs[0].a;
16+
let b = &mut inputs[0].b;
17+
18+
*a = 0;
19+
*b = 1;
20+
}
21+
22+
fn two() {
23+
let slice = &mut [(0, 0)][..];
24+
std::mem::swap(&mut slice[0].0, &mut slice[0].1);
25+
}
26+
27+
fn three(a: &mut [(i32, i32)], i: usize, j: usize) -> (&mut i32, &mut i32) {
28+
(&mut a[i].0, &mut a[j].1)
29+
}
30+
31+
fn main() {
32+
one();
33+
two();
34+
three(&mut [(1, 2), (3, 4)], 0, 1);
35+
}

‎tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fn index_custom(_1: &WithSliceTail, _2: usize) -> &i32 {
1414
StorageLive(_3);
1515
StorageLive(_4);
1616
_4 = copy _2;
17-
_5 = &raw const ((*_1).1: [i32]);
17+
_5 = &raw const (fake) ((*_1).1: [i32]);
1818
_6 = PtrMetadata(move _5);
1919
_7 = Lt(copy _4, copy _6);
2020
assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb2];

‎tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fn index_mut_slice(_1: &mut [i32], _2: usize) -> &i32 {
1414
StorageLive(_3);
1515
StorageLive(_4);
1616
_4 = copy _2;
17-
_5 = &raw const (*_1);
17+
_5 = &raw const (fake) (*_1);
1818
_6 = PtrMetadata(move _5);
1919
_7 = Lt(copy _4, copy _6);
2020
assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb2];

‎tests/mir-opt/building/index_array_and_slice.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ struct WithSliceTail(f64, [i32]);
5454
// EMIT_MIR index_array_and_slice.index_custom.built.after.mir
5555
fn index_custom(custom: &WithSliceTail, index: usize) -> &i32 {
5656
// CHECK: bb0:
57-
// CHECK: [[PTR:_.+]] = &raw const ((*_1).1: [i32]);
57+
// CHECK: [[PTR:_.+]] = &raw const (fake) ((*_1).1: [i32]);
5858
// CHECK: [[LEN:_.+]] = PtrMetadata(move [[PTR]]);
5959
// CHECK: [[LT:_.+]] = Lt(copy _2, copy [[LEN]]);
6060
// CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _2) -> [success: bb1,

‎tests/mir-opt/issue_91633.foo.built.after.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ fn foo(_1: Box<[T]>) -> T {
1818
StorageLive(_3);
1919
StorageLive(_4);
2020
_4 = const 0_usize;
21-
_5 = &raw const (*_1);
21+
_5 = &raw const (fake) (*_1);
2222
_6 = PtrMetadata(move _5);
2323
_7 = Lt(copy _4, copy _6);
2424
assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb5];

0 commit comments

Comments
 (0)
Please sign in to comment.