zerocopy/post_monomorphization_compile_fail_tests.rs
1// Copyright 2018 The Fuchsia Authors
2//
3// Licensed under the 2-Clause BSD License <LICENSE-BSD or
4// https://opensource.org/license/bsd-2-clause>, Apache License, Version 2.0
5// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
6// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
7// This file may not be copied, modified, or distributed except according to
8// those terms.
9
10//! Code that should fail to compile during the post-monomorphization compiler
11//! pass.
12//!
13//! Due to [a limitation with the `trybuild` crate][trybuild-issue], we cannot
14//! use our UI testing framework to test compilation failures that are
15//! encountered after monomorphization has complated. This module has one item
16//! for each such test we would prefer to have as a UI test, with the code in
17//! question appearing as a rustdoc example which is marked with `compile_fail`.
18//! This has the effect of causing doctests to fail if any of these examples
19//! compile successfully.
20//!
21//! This is very much a hack and not a complete replacement for UI tests - most
22//! notably because this only provides a single "compile vs fail" bit of
23//! information, but does not allow us to depend upon the specific error that
24//! causes compilation to fail.
25//!
26//! [trybuild-issue]: https://github.com/dtolnay/trybuild/issues/241
27
28// Miri doesn't detect post-monimorphization failures as compile-time failures,
29// but instead as runtime failures.
30#![cfg(not(miri))]
31
32/// ```compile_fail
33/// use core::cell::{Ref, RefCell};
34///
35/// let refcell = RefCell::new([0u8, 1, 2, 3]);
36/// let core_ref = refcell.borrow();
37/// let core_ref = Ref::map(core_ref, |bytes| &bytes[..]);
38///
39/// // `zc_ref` now stores `core_ref` internally.
40/// let zc_ref = zerocopy::Ref::<_, u32>::new(core_ref).unwrap();
41///
42/// // This causes `core_ref` to get dropped and synthesizes a Rust
43/// // reference to the memory `core_ref` was pointing at.
44/// let rust_ref = zc_ref.into_ref();
45///
46/// // UB!!! This mutates `rust_ref`'s referent while it's alive.
47/// *refcell.borrow_mut() = [0, 0, 0, 0];
48///
49/// println!("{}", rust_ref);
50/// ```
51#[allow(unused)]
52const REFCELL_REF_INTO_REF: () = ();
53
54/// ```compile_fail
55/// use core::cell::{RefCell, RefMut};
56///
57/// let refcell = RefCell::new([0u8, 1, 2, 3]);
58/// let core_ref_mut = refcell.borrow_mut();
59/// let core_ref_mut = RefMut::map(core_ref_mut, |bytes| &mut bytes[..]);
60///
61/// // `zc_ref` now stores `core_ref_mut` internally.
62/// let zc_ref = zerocopy::Ref::<_, u32>::new(core_ref_mut).unwrap();
63///
64/// // This causes `core_ref_mut` to get dropped and synthesizes a Rust
65/// // reference to the memory `core_ref` was pointing at.
66/// let rust_ref_mut = zc_ref.into_mut();
67///
68/// // UB!!! This mutates `rust_ref_mut`'s referent while it's alive.
69/// *refcell.borrow_mut() = [0, 0, 0, 0];
70///
71/// println!("{}", rust_ref_mut);
72/// ```
73#[allow(unused)]
74const REFCELL_REFMUT_INTO_MUT: () = ();
75
76/// ```compile_fail
77/// use core::cell::{Ref, RefCell};
78///
79/// let refcell = RefCell::new([0u8, 1, 2, 3]);
80/// let core_ref = refcell.borrow();
81/// let core_ref = Ref::map(core_ref, |bytes| &bytes[..]);
82///
83/// // `zc_ref` now stores `core_ref` internally.
84/// let zc_ref = zerocopy::Ref::<_, [u16]>::new_slice(core_ref).unwrap();
85///
86/// // This causes `core_ref` to get dropped and synthesizes a Rust
87/// // reference to the memory `core_ref` was pointing at.
88/// let rust_ref = zc_ref.into_slice();
89///
90/// // UB!!! This mutates `rust_ref`'s referent while it's alive.
91/// *refcell.borrow_mut() = [0, 0, 0, 0];
92///
93/// println!("{:?}", rust_ref);
94/// ```
95#[allow(unused)]
96const REFCELL_REFMUT_INTO_SLICE: () = ();
97
98/// ```compile_fail
99/// use core::cell::{RefCell, RefMut};
100///
101/// let refcell = RefCell::new([0u8, 1, 2, 3]);
102/// let core_ref_mut = refcell.borrow_mut();
103/// let core_ref_mut = RefMut::map(core_ref_mut, |bytes| &mut bytes[..]);
104///
105/// // `zc_ref` now stores `core_ref_mut` internally.
106/// let zc_ref = zerocopy::Ref::<_, [u16]>::new_slice(core_ref_mut).unwrap();
107///
108/// // This causes `core_ref_mut` to get dropped and synthesizes a Rust
109/// // reference to the memory `core_ref` was pointing at.
110/// let rust_ref_mut = zc_ref.into_mut_slice();
111///
112/// // UB!!! This mutates `rust_ref_mut`'s referent while it's alive.
113/// *refcell.borrow_mut() = [0, 0, 0, 0];
114///
115/// println!("{:?}", rust_ref_mut);
116/// ```
117#[allow(unused)]
118const REFCELL_REFMUT_INTO_MUT_SLICE: () = ();