• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)]
52 const 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)]
74 const 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)]
96 const 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)]
118 const REFCELL_REFMUT_INTO_MUT_SLICE: () = ();
119