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