Skip to content

Commit 612e89a

Browse files
authored
Rollup merge of #105301 - RalfJung:miri, r=oli-obk
update Miri Let's ship the work-around for rust-lang/unsafe-code-guidelines#381.
2 parents 4ebbb20 + 552b63c commit 612e89a

File tree

5 files changed

+117
-55
lines changed

5 files changed

+117
-55
lines changed

src/tools/miri/rust-version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
cef44f53034eac46be3a0e3eec7b2b3d4ef5140b
1+
203c8765ea33c65d888febe0e8219c4bb11b0d89

src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs

+14-9
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ pub struct Stacks {
4545
/// new pointer.
4646
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
4747
enum RefKind {
48-
/// `&mut` and `Box`.
48+
/// `Box`.
49+
Box,
50+
/// `&mut`.
4951
Unique { two_phase: bool },
5052
/// `&` with or without interior mutability.
5153
Shared,
@@ -56,6 +58,7 @@ enum RefKind {
5658
impl fmt::Display for RefKind {
5759
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5860
match self {
61+
RefKind::Box => write!(f, "Box"),
5962
RefKind::Unique { two_phase: false } => write!(f, "unique reference"),
6063
RefKind::Unique { two_phase: true } => write!(f, "unique reference (two-phase)"),
6164
RefKind::Shared => write!(f, "shared reference"),
@@ -654,15 +657,17 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
654657
let (perm, access) = match kind {
655658
RefKind::Unique { two_phase } => {
656659
// Permission is Unique only if the type is `Unpin` and this is not twophase
657-
let perm = if !two_phase && place.layout.ty.is_unpin(*this.tcx, this.param_env()) {
658-
Permission::Unique
660+
if !two_phase && place.layout.ty.is_unpin(*this.tcx, this.param_env()) {
661+
(Permission::Unique, Some(AccessKind::Write))
659662
} else {
660-
Permission::SharedReadWrite
661-
};
662-
// We do an access for all full borrows, even if `!Unpin`.
663-
let access = if !two_phase { Some(AccessKind::Write) } else { None };
664-
(perm, access)
663+
// FIXME: We emit `dereferenceable` for `!Unpin` mutable references, so we
664+
// should do fake accesses here. But then we run into
665+
// <https://github.com/rust-lang/unsafe-code-guidelines/issues/381>, so for now
666+
// we don't do that.
667+
(Permission::SharedReadWrite, None)
668+
}
665669
}
670+
RefKind::Box => (Permission::Unique, Some(AccessKind::Write)),
666671
RefKind::Raw { mutable: true } => {
667672
// Creating a raw ptr does not count as an access
668673
(Permission::SharedReadWrite, None)
@@ -853,7 +858,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
853858
// Boxes get a weak protectors, since they may be deallocated.
854859
self.retag_place(
855860
place,
856-
RefKind::Unique { two_phase: false },
861+
RefKind::Box,
857862
self.retag_cause,
858863
/*protector*/
859864
(self.kind == RetagKind::FnEntry).then_some(ProtectorKind::WeakProtector),

src/tools/miri/tests/fail/stacked_borrows/notunpin_dereferenceable_fakeread.rs

-17
This file was deleted.

src/tools/miri/tests/fail/stacked_borrows/notunpin_dereferenceable_fakeread.stderr

-28
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#![feature(pin_macro)]
2+
3+
use std::future::*;
4+
use std::marker::PhantomPinned;
5+
use std::pin::*;
6+
use std::ptr;
7+
use std::task::*;
8+
9+
struct Delay {
10+
delay: usize,
11+
}
12+
13+
impl Delay {
14+
fn new(delay: usize) -> Self {
15+
Delay { delay }
16+
}
17+
}
18+
19+
impl Future for Delay {
20+
type Output = ();
21+
fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<()> {
22+
if self.delay > 0 {
23+
self.delay -= 1;
24+
Poll::Pending
25+
} else {
26+
Poll::Ready(())
27+
}
28+
}
29+
}
30+
31+
async fn do_stuff() {
32+
(&mut Delay::new(1)).await;
33+
}
34+
35+
// Same thing implemented by hand
36+
struct DoStuff {
37+
state: usize,
38+
delay: Delay,
39+
delay_ref: *mut Delay,
40+
_marker: PhantomPinned,
41+
}
42+
43+
impl DoStuff {
44+
fn new() -> Self {
45+
DoStuff {
46+
state: 0,
47+
delay: Delay::new(1),
48+
delay_ref: ptr::null_mut(),
49+
_marker: PhantomPinned,
50+
}
51+
}
52+
}
53+
54+
impl Future for DoStuff {
55+
type Output = ();
56+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
57+
unsafe {
58+
let this = self.get_unchecked_mut();
59+
match this.state {
60+
0 => {
61+
// Set up self-ref.
62+
this.delay_ref = &mut this.delay;
63+
// Move to next state.
64+
this.state = 1;
65+
Poll::Pending
66+
}
67+
1 => {
68+
let delay = &mut *this.delay_ref;
69+
Pin::new_unchecked(delay).poll(cx)
70+
}
71+
_ => unreachable!(),
72+
}
73+
}
74+
}
75+
}
76+
77+
fn run_fut<T>(fut: impl Future<Output = T>) -> T {
78+
use std::sync::Arc;
79+
80+
struct MyWaker;
81+
impl Wake for MyWaker {
82+
fn wake(self: Arc<Self>) {
83+
unimplemented!()
84+
}
85+
}
86+
87+
let waker = Waker::from(Arc::new(MyWaker));
88+
let mut context = Context::from_waker(&waker);
89+
90+
let mut pinned = pin!(fut);
91+
loop {
92+
match pinned.as_mut().poll(&mut context) {
93+
Poll::Pending => continue,
94+
Poll::Ready(v) => return v,
95+
}
96+
}
97+
}
98+
99+
fn main() {
100+
run_fut(do_stuff());
101+
run_fut(DoStuff::new());
102+
}

0 commit comments

Comments
 (0)