Skip to content

Commit b148f42

Browse files
committed
clarify tests
1 parent e7b19ad commit b148f42

File tree

7 files changed

+137
-78
lines changed

7 files changed

+137
-78
lines changed

tests/fail/tree_borrows/kill-copies.default.stderr renamed to tests/fail/tree_borrows/children-can-alias.default.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error: Undefined Behavior: entering unreachable code
2-
--> $DIR/kill-copies.rs:LL:CC
2+
--> $DIR/children-can-alias.rs:LL:CC
33
|
44
LL | std::hint::unreachable_unchecked();
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ entering unreachable code
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
99
= note: BACKTRACE:
10-
= note: inside `main` at $DIR/kill-copies.rs:LL:CC
10+
= note: inside `main` at $DIR/children-can-alias.rs:LL:CC
1111

1212
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
1313

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//@revisions: default uniq
2+
//@compile-flags: -Zmiri-tree-borrows
3+
//@[uniq]compile-flags: -Zmiri-unique-is-unique
4+
5+
//! This is NOT intended behavior.
6+
//! We should eventually find a solution so that the version with `Unique` passes too,
7+
//! otherwise `Unique` is more strict than `&mut`!
8+
9+
#![feature(ptr_internals)]
10+
11+
use core::ptr::addr_of_mut;
12+
use core::ptr::Unique;
13+
14+
fn main() {
15+
let mut data = 0u8;
16+
let raw = addr_of_mut!(data);
17+
unsafe {
18+
raw_children_of_refmut_can_alias(&mut *raw);
19+
raw_children_of_unique_can_alias(Unique::new_unchecked(raw));
20+
21+
// Ultimately the intended behavior is that both above tests would
22+
// succeed.
23+
std::hint::unreachable_unchecked();
24+
//~[default]^ ERROR: entering unreachable code
25+
}
26+
}
27+
28+
unsafe fn raw_children_of_refmut_can_alias(x: &mut u8) {
29+
let child1 = addr_of_mut!(*x);
30+
let child2 = addr_of_mut!(*x);
31+
// We create two raw aliases of `x`: they have the exact same
32+
// tag and can be used interchangeably.
33+
child1.write(1);
34+
child2.write(2);
35+
child1.write(1);
36+
child2.write(2);
37+
}
38+
39+
unsafe fn raw_children_of_unique_can_alias(x: Unique<u8>) {
40+
let child1 = x.as_ptr();
41+
let child2 = x.as_ptr();
42+
// Under `-Zmiri-unique-is-unique`, `Unique` accidentally offers more guarantees
43+
// than `&mut`. Not because it responds differently to accesses but because
44+
// there is no way to obtain a copy with the same tag.
45+
//
46+
// The closest attempt (and one that works without `-Zmiri-unique-is-unique`)
47+
// is two calls to `as_ptr` that return cousin pointers, not writeable
48+
// interchangeably.
49+
// This is an unexpected consequence of retagging all `Unique` and we
50+
// should find a way to make `Unique` no more strict than `&mut`.
51+
child1.write(1);
52+
child2.write(2);
53+
//~[uniq]^ ERROR: /write access through .* is forbidden/
54+
child1.write(1);
55+
child2.write(2);
56+
}

tests/fail/tree_borrows/kill-copies.uniq.stderr renamed to tests/fail/tree_borrows/children-can-alias.uniq.stderr

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
11
error: Undefined Behavior: write access through <TAG> is forbidden
2-
--> $DIR/kill-copies.rs:LL:CC
2+
--> $DIR/children-can-alias.rs:LL:CC
33
|
4-
LL | *cp = 2;
5-
| ^^^^^^^ write access through <TAG> is forbidden
4+
LL | child2.write(2);
5+
| ^^^^^^^^^^^^^^^ write access through <TAG> is forbidden
66
|
77
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
88
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
99
= help: the conflicting tag <TAG> has state Disabled which forbids this child write access
1010
help: the accessed tag <TAG> was created here
11-
--> $DIR/kill-copies.rs:LL:CC
11+
--> $DIR/children-can-alias.rs:LL:CC
1212
|
13-
LL | let cp = x.as_ptr();
14-
| ^^^^^^^^^^
13+
LL | let child2 = x.as_ptr();
14+
| ^^^^^^^^^^
1515
help: the conflicting tag <TAG> was created here, in the initial state Reserved
16-
--> $DIR/kill-copies.rs:LL:CC
16+
--> $DIR/children-can-alias.rs:LL:CC
1717
|
18-
LL | let cp = x.as_ptr();
19-
| ^
18+
LL | let child2 = x.as_ptr();
19+
| ^
2020
help: the conflicting tag <TAG> later transitioned to Disabled due to a foreign write access at offsets [0x0..0x1]
21-
--> $DIR/kill-copies.rs:LL:CC
21+
--> $DIR/children-can-alias.rs:LL:CC
2222
|
23-
LL | *x.as_ptr() = 1;
23+
LL | child1.write(1);
2424
| ^^^^^^^^^^^^^^^
2525
= help: this transition corresponds to a loss of read and write permissions
2626
= note: BACKTRACE (of the first span):
27-
= note: inside `unique_keeps_copies` at $DIR/kill-copies.rs:LL:CC
27+
= note: inside `raw_children_of_unique_can_alias` at $DIR/children-can-alias.rs:LL:CC
2828
note: inside `main`
29-
--> $DIR/kill-copies.rs:LL:CC
29+
--> $DIR/children-can-alias.rs:LL:CC
3030
|
31-
LL | unique_keeps_copies(Unique::new_unchecked(raw));
32-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31+
LL | raw_children_of_unique_can_alias(Unique::new_unchecked(raw));
32+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3333

3434
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
3535

tests/fail/tree_borrows/kill-copies.rs

Lines changed: 0 additions & 43 deletions
This file was deleted.

tests/pass/tree_borrows/unique.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,35 @@ fn main() {
2424
// We create a `Unique` and expect it to have a fresh tag
2525
// and uninitialized permissions.
2626
let uniq = Unique::new_unchecked(raw);
27-
let intermediate = if cfg!(uniq) { 2 } else { 0 };
28-
name!(uniq.as_ptr()=>intermediate, "uniq");
29-
name!(uniq.as_ptr()=>intermediate, "uniq");
27+
28+
// The usage of `-Zmiri-unique-is-unique` disturbs the internal
29+
// structure of the tree: pointers that used to have the same tag
30+
// under `-Zmiri-tree-borrows` are now cousins under
31+
// `-Zmiri-tree-borrows -Zmiri-unique-is-unique`.
32+
//
33+
// This is an unintended consequence of the way we currently
34+
// retag `Unique`, and we should look for a way to make these return
35+
// the same pointer. In the meantime we hardcode the distance at which
36+
// we expect the nearest common ancestor to be (which is the tag of
37+
// the actual root `Unique` pointer) and name that.
38+
//
39+
// (We name it twice so that we have an indicator in the output of
40+
// whether we got the distance correct:
41+
//
42+
// If the output shows
43+
//
44+
// |- <XYZ: uniq>
45+
// '- <XYZ: uniq>
46+
//
47+
// then `nth_parent` is not big enough.
48+
// The correct value for `nth_parent` should be the minimum
49+
// integer for which the output shows
50+
//
51+
// '- <XYZ: uniq, uniq>
52+
// )
53+
let nth_parent = if cfg!(uniq) { 2 } else { 0 };
54+
name!(uniq.as_ptr()=>nth_parent, "uniq");
55+
name!(uniq.as_ptr()=>nth_parent, "uniq");
3056
print_state!(alloc_id);
3157

3258
// We can activate the Unique and use it mutably.

tests/pass/tree_borrows/vec_unique.rs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,40 @@ fn main() {
1717
let base = vec![0u8, 1];
1818
let alloc_id = alloc_id!(base.as_ptr());
1919

20-
// Doing this twice to illustrate how treating `Unique` differently
21-
// changes `as_ptr`:
22-
// - with `default`, `as_ptr` always returns the same pointer without
23-
// extra reborrow: two `as_ptr` from the same `Vec` retun the *same pointer*,
24-
// - with `uniq` however, the two returned pointers are now cousins.
25-
// This is probably problematic.
26-
let intermediate = if cfg!(uniq) { 2 } else { 0 };
27-
name!(base.as_ptr()=>intermediate);
28-
name!(base.as_ptr()=>intermediate);
20+
// The usage of `-Zmiri-unique-is-unique` disturbs the internal
21+
// structure of the tree: pointers that used to have the same tag
22+
// under `-Zmiri-tree-borrows` are now cousins under
23+
// `-Zmiri-tree-borrows -Zmiri-unique-is-unique`.
24+
//
25+
// This is an unintended consequence of the way we currently
26+
// retag `Unique`, and we should look for a way to make these return
27+
// the same pointer. In the meantime we hardcode the distance at which
28+
// we expect the nearest common ancestor to be (which is the tag of
29+
// the actual root `Unique` pointer) and name that.
30+
//
31+
// (We name it twice so that we have an indicator in the output of
32+
// whether we got the distance correct:
33+
//
34+
// If the output shows
35+
//
36+
// |- <XYZ: base.as_ptr()>
37+
// '- <XYZ: base.as_ptr()>
38+
//
39+
// then `nth_parent` is not big enough.
40+
// The correct value for `nth_parent` should be the minimum
41+
// integer for which the output shows
42+
//
43+
// '- <XYZ: base.as_ptr(), base.as_ptr()>
44+
// )
45+
let nth_parent = if cfg!(uniq) { 2 } else { 0 };
46+
name!(base.as_ptr()=>nth_parent);
47+
name!(base.as_ptr()=>nth_parent);
2948

3049
// Destruct the `Vec`
3150
let (ptr, len, cap) = base.into_raw_parts();
3251

3352
// Expect this to be again the same pointer as the one obtained from `as_ptr`.
53+
// Under `-Zmiri-unique-is-unique`, this will be a strict child.
3454
name!(ptr, "raw_parts.0");
3555

3656
// This is where the presence of `Unique` has implications,
@@ -40,8 +60,8 @@ fn main() {
4060

4161
// The `as_ptr` here (twice for the same reason as above) return either
4262
// the same pointer once more (default) or a strict child (uniq).
43-
name!(reconstructed.as_ptr()=>intermediate);
44-
name!(reconstructed.as_ptr()=>intermediate);
63+
name!(reconstructed.as_ptr()=>nth_parent);
64+
name!(reconstructed.as_ptr()=>nth_parent);
4565

4666
print_state!(alloc_id, false);
4767
}

tests/utils/macros.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ macro_rules! name {
4747
($ptr:expr) => {
4848
crate::utils::macros::name!($ptr => 0, stringify!($ptr));
4949
};
50-
($ptr:expr => $nb:expr) => {
51-
crate::utils::macros::name!($ptr => $nb, stringify!($ptr));
50+
($ptr:expr => $nth_parent:expr) => {
51+
crate::utils::macros::name!($ptr => $nth_parent, stringify!($ptr));
5252
};
53-
($ptr:expr => $nb:expr, $name:expr) => {
53+
($ptr:expr => $nth_parent:expr, $name:expr) => {
5454
let name = $name.as_bytes();
55-
crate::utils::miri_extern::miri_pointer_name($ptr as *const u8 as *const (), $nb, name);
55+
crate::utils::miri_extern::miri_pointer_name($ptr as *const u8 as *const (), $nth_parent, name);
5656
};
5757
}
5858

0 commit comments

Comments
 (0)