]> git.lizzy.rs Git - rust.git/blob - src/tools/miri/tests/pass/strings.rs
Rollup merge of #103084 - inquisitivecrystal:control-flow, r=scottmcm
[rust.git] / src / tools / miri / tests / pass / strings.rs
1 //@compile-flags: -Zmiri-strict-provenance
2
3 fn empty() -> &'static str {
4     ""
5 }
6
7 fn hello() -> &'static str {
8     "Hello, world!"
9 }
10
11 fn hello_bytes() -> &'static [u8; 13] {
12     b"Hello, world!"
13 }
14
15 fn hello_bytes_fat() -> &'static [u8] {
16     b"Hello, world!"
17 }
18
19 fn fat_pointer_on_32_bit() {
20     Some(5).expect("foo");
21 }
22
23 fn str_indexing() {
24     let mut x = "Hello".to_string();
25     let _v = &mut x[..3]; // Test IndexMut on String.
26 }
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
54 fn main() {
55     assert_eq!(empty(), "");
56     assert_eq!(hello(), "Hello, world!");
57     assert_eq!(hello_bytes(), b"Hello, world!");
58     assert_eq!(hello_bytes_fat(), b"Hello, world!");
59
60     fat_pointer_on_32_bit(); // Should run without crashing.
61     str_indexing();
62     unique_aliasing();
63 }