1
+ // compile-flags: -Zmiri-track-raw-pointers
2
+
1
3
fn empty ( ) -> & ' static str {
2
4
""
3
5
}
@@ -23,6 +25,32 @@ fn str_indexing() {
23
25
let _v = & mut x[ ..3 ] ; // Test IndexMut on String.
24
26
}
25
27
28
+ fn unique_aliasing ( ) {
29
+ // This is a regression test for the aliasing rules of a `Unique<T>` pointer.
30
+ // At the time of writing this test case, Miri does not treat `Unique<T>`
31
+ // pointers as a special case, these are treated like any other raw pointer.
32
+ // However, there are existing Github issues which may lead to `Unique<T>`
33
+ // becoming a special case through asserting unique ownership over the pointee:
34
+ // - https://github.com/rust-lang/unsafe-code-guidelines/issues/258
35
+ // - https://github.com/rust-lang/unsafe-code-guidelines/issues/262
36
+ // Below, the calls to `String::remove` and `String::insert[_str]` follow
37
+ // code paths that would trigger undefined behavior in case `Unique<T>`
38
+ // would ever assert semantic ownership over the pointee. Internally,
39
+ // these methods call `self.vec.as_ptr()` and `self.vec.as_mut_ptr()` on
40
+ // the vector of bytes that are backing the `String`. That `Vec<u8>` holds a
41
+ // `Unique<u8>` internally. The second call to `Vec::as_mut_ptr(&mut self)`
42
+ // would then invalidate the pointers derived from `Vec::as_ptr(&self)`.
43
+ // Note that as long as `Unique<T>` is treated like any other raw pointer,
44
+ // this test case should pass. It is merely here as a canary test for
45
+ // potential future undefined behavior.
46
+ let mut x = String :: from ( "Hello" ) ;
47
+ assert_eq ! ( x. remove( 0 ) , 'H' ) ;
48
+ x. insert ( 0 , 'H' ) ;
49
+ assert_eq ! ( x, "Hello" ) ;
50
+ x. insert_str ( x. len ( ) , ", world!" ) ;
51
+ assert_eq ! ( x, "Hello, world!" ) ;
52
+ }
53
+
26
54
fn main ( ) {
27
55
assert_eq ! ( empty( ) , "" ) ;
28
56
assert_eq ! ( hello( ) , "Hello, world!" ) ;
@@ -31,4 +59,5 @@ fn main() {
31
59
32
60
fat_pointer_on_32_bit ( ) ; // Should run without crashing.
33
61
str_indexing ( ) ;
62
+ unique_aliasing ( ) ;
34
63
}
0 commit comments