├── .gitignore ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── run-clippy-all ├── run-clippy-all-msrv ├── run-doc-all ├── run-feature-combinations ├── run-test-all ├── run-test-all-msrv ├── src ├── assertions.rs ├── doctest_lcell.rs ├── doctest_lcell_generativity.rs ├── doctest_qcell.rs ├── doctest_qcell_noalloc.rs ├── doctest_tcell.rs ├── doctest_tlcell.rs ├── lcell.rs ├── lib.rs ├── qcell.rs ├── tcell.rs └── tlcell.rs ├── trybuild-qcell ├── Cargo.toml ├── README.md └── src │ ├── compiletest │ ├── lcell-00.rs │ ├── lcell-00.stderr │ ├── lcell-01.rs │ ├── lcell-01.stderr │ ├── lcell-02.rs │ ├── lcell-02.stderr │ ├── lcell-03.rs │ ├── lcell-03.stderr │ ├── lcell-04.rs │ ├── lcell-04.stderr │ ├── lcell-05.rs │ ├── lcell-05.stderr │ ├── lcell-06.rs │ ├── lcell-06.stderr │ ├── lcell-07.rs │ ├── lcell-07.stderr │ ├── lcell-08.rs │ ├── lcell-08.stderr │ ├── lcell-09.rs │ ├── lcell-09.stderr │ ├── lcell-10.rs │ ├── lcell-10.stderr │ ├── lcell-11.rs │ ├── lcell-11.stderr │ ├── lcell-12.rs │ ├── lcell-12.stderr │ ├── lcell-13.rs │ ├── lcell-13.stderr │ ├── lcell-14.rs │ ├── lcell-14.stderr │ ├── lcell-15.rs │ ├── lcell-15.stderr │ ├── lcell-16.rs │ ├── lcell-16.stderr │ ├── lcell-17.rs │ ├── lcell-17.stderr │ ├── lcell-18.rs │ ├── lcell-18.stderr │ ├── lcell-19.rs │ ├── lcell-19.stderr │ ├── lcell-20.rs │ ├── lcell-20.stderr │ ├── lcell_generativity-00.rs │ ├── lcell_generativity-00.stderr │ ├── lcell_generativity-01.rs │ ├── lcell_generativity-01.stderr │ ├── lcell_generativity-02.rs │ ├── lcell_generativity-02.stderr │ ├── lcell_generativity-03.rs │ ├── lcell_generativity-03.stderr │ ├── lcell_generativity-04.rs │ ├── lcell_generativity-04.stderr │ ├── lcell_generativity-05.rs │ ├── lcell_generativity-05.stderr │ ├── lcell_generativity-06.rs │ ├── lcell_generativity-06.stderr │ ├── lcell_generativity-07.rs │ ├── lcell_generativity-07.stderr │ ├── lcell_generativity-08.rs │ ├── lcell_generativity-08.stderr │ ├── lcell_generativity-09.rs │ ├── lcell_generativity-09.stderr │ ├── lcell_generativity-10.rs │ ├── lcell_generativity-10.stderr │ ├── lcell_generativity-11.rs │ ├── lcell_generativity-11.stderr │ ├── lcell_generativity-12.rs │ ├── lcell_generativity-12.stderr │ ├── lcell_generativity-13.rs │ ├── lcell_generativity-13.stderr │ ├── lcell_generativity-14.rs │ ├── lcell_generativity-14.stderr │ ├── lcell_generativity-15.rs │ ├── lcell_generativity-15.stderr │ ├── qcell-00.rs │ ├── qcell-00.stderr │ ├── qcell-01.rs │ ├── qcell-01.stderr │ ├── qcell-02.rs │ ├── qcell-02.stderr │ ├── qcell-03.rs │ ├── qcell-03.stderr │ ├── qcell-04.rs │ ├── qcell-04.stderr │ ├── qcell-05.rs │ ├── qcell-05.stderr │ ├── qcell-06.rs │ ├── qcell-06.stderr │ ├── qcell-07.rs │ ├── qcell-07.stderr │ ├── qcell-08.rs │ ├── qcell-08.stderr │ ├── qcell-09.rs │ ├── qcell-09.stderr │ ├── qcell-10.rs │ ├── qcell-10.stderr │ ├── qcell-11.rs │ ├── qcell-11.stderr │ ├── qcell-12.rs │ ├── qcell-12.stderr │ ├── qcell-13.rs │ ├── qcell-13.stderr │ ├── qcell-14.rs │ ├── qcell-14.stderr │ ├── qcell-15.rs │ ├── qcell-15.stderr │ ├── qcell-16.rs │ ├── qcell-16.stderr │ ├── qcell-17.rs │ ├── qcell-17.stderr │ ├── qcell-18.rs │ ├── qcell-18.stderr │ ├── qcell_noalloc-00.rs │ ├── qcell_noalloc-00.stderr │ ├── qcell_noalloc-01.rs │ ├── qcell_noalloc-01.stderr │ ├── qcell_noalloc-02.rs │ ├── qcell_noalloc-02.stderr │ ├── qcell_noalloc-03.rs │ ├── qcell_noalloc-03.stderr │ ├── qcell_noalloc-04.rs │ ├── qcell_noalloc-04.stderr │ ├── qcell_noalloc-05.rs │ ├── qcell_noalloc-05.stderr │ ├── qcell_noalloc-06.rs │ ├── qcell_noalloc-06.stderr │ ├── qcell_noalloc-07.rs │ ├── qcell_noalloc-07.stderr │ ├── qcell_noalloc-08.rs │ ├── qcell_noalloc-08.stderr │ ├── qcell_noalloc-09.rs │ ├── qcell_noalloc-09.stderr │ ├── qcell_noalloc-10.rs │ ├── qcell_noalloc-10.stderr │ ├── qcell_noalloc-11.rs │ ├── qcell_noalloc-11.stderr │ ├── qcell_noalloc-12.rs │ ├── qcell_noalloc-12.stderr │ ├── qcell_noalloc-13.rs │ ├── qcell_noalloc-13.stderr │ ├── qcell_noalloc-14.rs │ ├── qcell_noalloc-14.stderr │ ├── qcell_noalloc-15.rs │ ├── qcell_noalloc-15.stderr │ ├── qcell_noalloc-16.rs │ ├── qcell_noalloc-16.stderr │ ├── tcell-00.rs │ ├── tcell-00.stderr │ ├── tcell-01.rs │ ├── tcell-01.stderr │ ├── tcell-02.rs │ ├── tcell-02.stderr │ ├── tcell-03.rs │ ├── tcell-03.stderr │ ├── tcell-04.rs │ ├── tcell-04.stderr │ ├── tcell-05.rs │ ├── tcell-05.stderr │ ├── tcell-06.rs │ ├── tcell-06.stderr │ ├── tcell-07.rs │ ├── tcell-07.stderr │ ├── tcell-08.rs │ ├── tcell-08.stderr │ ├── tcell-09.rs │ ├── tcell-09.stderr │ ├── tcell-10.rs │ ├── tcell-10.stderr │ ├── tcell-11.rs │ ├── tcell-11.stderr │ ├── tcell-12.rs │ ├── tcell-12.stderr │ ├── tcell-13.rs │ ├── tcell-13.stderr │ ├── tcell-14.rs │ ├── tcell-14.stderr │ ├── tcell-15.rs │ ├── tcell-15.stderr │ ├── tcell-16.rs │ ├── tcell-16.stderr │ ├── tcell-17.rs │ ├── tcell-17.stderr │ ├── tcell-18.rs │ ├── tcell-18.stderr │ ├── tcell-19.rs │ ├── tcell-19.stderr │ ├── tcell-20.rs │ ├── tcell-20.stderr │ ├── tcell-21.rs │ ├── tcell-21.stderr │ ├── tlcell-00.rs │ ├── tlcell-00.stderr │ ├── tlcell-01.rs │ ├── tlcell-01.stderr │ ├── tlcell-02.rs │ ├── tlcell-02.stderr │ ├── tlcell-03.rs │ ├── tlcell-03.stderr │ ├── tlcell-04.rs │ ├── tlcell-04.stderr │ ├── tlcell-05.rs │ ├── tlcell-05.stderr │ ├── tlcell-06.rs │ ├── tlcell-06.stderr │ ├── tlcell-07.rs │ ├── tlcell-07.stderr │ ├── tlcell-08.rs │ ├── tlcell-08.stderr │ ├── tlcell-09.rs │ ├── tlcell-09.stderr │ ├── tlcell-10.rs │ ├── tlcell-10.stderr │ ├── tlcell-11.rs │ ├── tlcell-11.stderr │ ├── tlcell-12.rs │ ├── tlcell-12.stderr │ ├── tlcell-13.rs │ ├── tlcell-13.stderr │ ├── tlcell-14.rs │ ├── tlcell-14.stderr │ ├── tlcell-15.rs │ ├── tlcell-15.stderr │ ├── tlcell-16.rs │ ├── tlcell-16.stderr │ ├── tlcell-17.rs │ ├── tlcell-17.stderr │ ├── tlcell-18.rs │ ├── tlcell-18.stderr │ ├── tlcell-19.rs │ ├── tlcell-19.stderr │ ├── tlcell-20.rs │ ├── tlcell-20.stderr │ ├── tlcell-21.rs │ └── tlcell-21.stderr │ └── lib.rs └── update-compiletest-from-doctest.pl /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | **/*~ -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Significant feature changes and additions 2 | 3 | This project follows Rust semantic versioning. 4 | 5 | 6 | 7 | ## 0.5.4 (2023-07-13) 8 | 9 | ### Added 10 | 11 | - `no_std` support for `TCell`, contributed by [Violet 12 | Leonard](https://github.com/geeklint). 13 | - `Default` for `TCell`, `TLCell` and `LCell` 14 | - Formalize MSRV of 1.60, and test 15 | 16 | 17 | ## 0.5.3 (2023-01-15) 18 | 19 | ### Added 20 | 21 | - `Hash`, `Eq` and `PartialEq` implementations for QCellOwnerID. 22 | These changes were contributed by [Simon 23 | Ask](https://github.com/simonask) and 24 | [LegionMammal978](https://github.com/LegionMammal978) 25 | 26 | 27 | ## 0.5.2 (2022-06-11) 28 | 29 | ### Added 30 | 31 | - `#[repr(transparent)]` added to `LCell`, `TCell` and `TLCell` 32 | - `get_mut` and `into_inner` added to all cell types which better 33 | supports beginning/end-of-life of the cell 34 | 35 | [Troy Hinckley](https://github.com/CeleritasCelery) contributed to 36 | this point release. 37 | 38 | 39 | ## 0.5.1 (2022-04-19) 40 | 41 | ### Added 42 | 43 | - `LCellOwner` can now be created from a 44 | [**generativity**](https://crates.io/crates/generativity) guard, 45 | which makes `LCellOwner` creation more convenient. This change was 46 | contributed by [Troy Hinckley](https://github.com/CeleritasCelery). 47 | 48 | 49 | ## 0.5.0 (2022-01-23) 50 | 51 | ### Changed 52 | 53 | - `QCellOwner` is now based on IDs derived from the addresses of 54 | heap-allocated objects. This change was contributed by [Violet 55 | Leonard](https://github.com/geeklint). This offloads maintaining 56 | lists of in-use IDs to the allocator, which improves `no_std` 57 | compatibility. 58 | 59 | ### Added 60 | 61 | - `no_std` support in `QCell` and `LCell`, contributed by [Violet 62 | Leonard](https://github.com/geeklint). 63 | 64 | - `QCellOwnerPinned` (contributed by [Violet 65 | Leonard](https://github.com/geeklint)), and `QCellOwnerSeq`. These 66 | now form a family of ID-based owners along with `QCellOwner`. 67 | 68 | ### Breaking 69 | 70 | - `QCellOwner::fast_new` is replaced by `QCellOwnerSeq::new` 71 | 72 | 73 | ## 0.4.3 (2021-09-20) 74 | 75 | ### Fixed 76 | 77 | - It is now no longer possible for a malicious coder to cheat the 78 | singleton check in `TCellOwner` and `TLCellOwner` by using covariant 79 | subtypes. Thanks to [Frank Steffahn](https://github.com/steffahn) 80 | for noticing the bug, and for providing the PR to fix the issue. 81 | 82 | ### Testing 83 | 84 | - Check common traits using `static_assertions` 85 | 86 | 87 | ## 0.4.2 (2021-08-20) 88 | 89 | ### Added 90 | 91 | - `?Sized` / unsized types / DST support, e.g. `QCell` 92 | - `cell.rw(owner)` and `cell.ro(owner)` 93 | - `TCellOwner::try_new` and `TCellOwner::wait_for_new`, contributed by 94 | [Michiel De Muycnk](https://github.com/Migi) 95 | 96 | 97 | ## 0.4.1 (2020-06-25) 98 | 99 | (internal changes) 100 | 101 | 102 | ## 0.4.0 (2019-12-24) 103 | 104 | ### Added 105 | 106 | - `Send` and `Sync` support, with full reasoning, thanks to a 107 | contribution from [Michiel de Muycnk](https://github.com/Migi) 108 | 109 | ### Breaking 110 | 111 | - `TCell` and `TLCell` are now split into separate types and the 112 | previous 'no-thread-local' feature has been removed 113 | 114 | ### Testing 115 | 116 | - `trybuild` testing of all compile_fail tests, to ensure that they're 117 | failing for the right reasons 118 | 119 | 120 | ## 0.3.0 (2019-07-24) 121 | 122 | ### Breaking 123 | 124 | - `TCell` is now thread-local-based by default, with a cargo feature 125 | to switch on old global behaviour 126 | 127 | 128 | ## 0.2.0 (2019-03-20) 129 | 130 | ### Breaking 131 | 132 | - Switch from `get()` and `get_mut()` to `ro()` and `rw()` to access 133 | cell contents 134 | 135 | - No longer require the owner to be specified when creating `TCell` 136 | and `LCell` instances. 137 | 138 | ### Added 139 | 140 | - `QCellOwnerID` for creating cells when the owner is not available 141 | 142 | 143 | ## 0.1.2 (2019-03-18) 144 | 145 | ### Added 146 | 147 | - `LCell` lifetime-based cell 148 | 149 | 150 | ## 0.1.1 (2019-03-07) 151 | 152 | ### Fixed 153 | 154 | - Make `QCellOwner::new()` completely safe. Old code that could be 155 | used maliciously to create undefined behaviour is moved to 156 | `QCellOwner::fast_new()` and marked as `unsafe`. 157 | 158 | 159 | ## 0.1.0 (2019-02-28) 160 | 161 | (first public release) 162 | 163 | 164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "qcell" 3 | version = "0.5.4" 4 | authors = ["Jim Peters "] 5 | edition = "2018" 6 | rust-version = "1.60.0" 7 | 8 | description = "Statically-checked alternatives to RefCell and RwLock" 9 | license = "MIT/Apache-2.0" 10 | readme = "README.md" 11 | 12 | repository = "https://github.com/uazu/qcell" 13 | documentation = "https://docs.rs/qcell" 14 | 15 | keywords = ["cell","refcell","borrow","borrowing","rc"] 16 | categories = [ "data-structures", "memory-management", "rust-patterns" ] 17 | 18 | [features] 19 | default = ["std"] 20 | std = ["alloc", "once_cell", "exclusion-set?/std"] 21 | alloc = [] 22 | 23 | [dependencies] 24 | once_cell = { version = "1.4.0", optional = true } 25 | generativity = { version = "1.0.0", optional = true } 26 | exclusion-set = { version = "0.1.2", optional = true } 27 | 28 | [dev-dependencies] 29 | crossbeam = "0.8" 30 | once_cell = "1.4.0" 31 | pin-project = "1" 32 | pin-utils = "0.1" 33 | rand = "0.8" 34 | static_assertions = "1.0" 35 | 36 | 37 | # For docs.rs, build docs with feature labels. Search for `docsrs` in 38 | # source to see the things that are labelled. To test this use: 39 | # RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features 40 | [package.metadata.docs.rs] 41 | all-features = true 42 | rustdoc-args = ["--cfg", "docsrs"] 43 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019-2021 Jim Peters 2 | Copyright (c) 2019-2021 `qcell` crate contributors 3 | 4 | Permission is hereby granted, free of charge, to any 5 | person obtaining a copy of this software and associated 6 | documentation files (the "Software"), to deal in the 7 | Software without restriction, including without 8 | limitation the rights to use, copy, modify, merge, 9 | publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software 11 | is furnished to do so, subject to the following 12 | conditions: 13 | 14 | The above copyright notice and this permission notice 15 | shall be included in all copies or substantial portions 16 | of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 19 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 20 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 21 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 22 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 24 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 25 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Statically-checked alternatives to RefCell or RwLock 2 | 3 | Cell types that instead of panicking at runtime as with `RefCell` will 4 | give compilation errors instead, or that exchange fine-grained locking 5 | with `RwLock` for coarser-grained locking of a separate owner object. 6 | 7 | ### Documentation 8 | 9 | See the [crate documentation](http://docs.rs/qcell). 10 | 11 | # License 12 | 13 | This project is licensed under either the Apache License version 2 or 14 | the MIT license, at your option. (See 15 | [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT)). 16 | 17 | ### Contribution 18 | 19 | Unless you explicitly state otherwise, any contribution intentionally 20 | submitted for inclusion in this crate by you, as defined in the 21 | Apache-2.0 license, shall be dual licensed as above, without any 22 | additional terms or conditions. 23 | -------------------------------------------------------------------------------- /run-clippy-all: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./run-feature-combinations | 4 | while read msrv features 5 | do 6 | echo "=== Features: $features" 7 | cargo clippy --no-default-features --features "$features" || exit 1 8 | done 9 | -------------------------------------------------------------------------------- /run-clippy-all-msrv: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./run-feature-combinations | 4 | while read msrv features 5 | do 6 | echo "=== $msrv: Features: $features" 7 | cargo +$msrv clippy --no-default-features --features "$features" || exit 1 8 | done 9 | -------------------------------------------------------------------------------- /run-doc-all: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # First build with all combinations of features to check for doc 4 | # issues (bad links etc, e.g. especially references to QCellOwner from 5 | # no_std docs). Then finally build as docs.rs sees it to visually 6 | # check the "std" and "alloc" annotations on some types. 7 | 8 | ./run-feature-combinations | 9 | while read msrv features 10 | do 11 | echo "=== Features: $features" 12 | cargo doc --no-default-features --features "$features" || exit 1 13 | done 14 | 15 | echo "=== Docs.rs output" 16 | RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features 17 | -------------------------------------------------------------------------------- /run-feature-combinations: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # You can't have 'std' without 'alloc', since 'std' depends on it 4 | for a in '' 'alloc,' 'std,alloc,'; do 5 | # These two affect independent sections of code so can be tested 6 | # together 7 | for b in '' 'generativity,exclusion-set,'; do 8 | all="$a$b" 9 | case "$all" in 10 | *exclusion-set*) MSRV=1.65;; 11 | *) MSRV=1.60;; 12 | esac 13 | echo "$MSRV ${all%,}" 14 | done 15 | done 16 | -------------------------------------------------------------------------------- /run-test-all: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./run-feature-combinations | 4 | while read msrv features 5 | do 6 | echo "=== Features: $features" 7 | cargo test --no-default-features --features "$features" || exit 1 8 | done 9 | 10 | echo SUCCESS 11 | -------------------------------------------------------------------------------- /run-test-all-msrv: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./run-feature-combinations | 4 | while read msrv features 5 | do 6 | echo "=== $msrv: Features: $features" 7 | cargo +$msrv test --no-default-features --features "$features" || exit 1 8 | done 9 | 10 | echo SUCCESS 11 | -------------------------------------------------------------------------------- /src/assertions.rs: -------------------------------------------------------------------------------- 1 | use static_assertions::assert_impl_all; 2 | use static_assertions::assert_not_impl_any; 3 | 4 | use std::cell::Cell; 5 | use std::panic::RefUnwindSafe; 6 | use std::panic::UnwindSafe; 7 | use std::rc::Rc; 8 | 9 | use crate::{LCell, LCellOwner, QCell, QCellOwnerPinned}; 10 | 11 | #[cfg(features = "alloc")] 12 | use crate::QCellOwner; 13 | 14 | #[cfg(feature = "std")] 15 | use crate::{TCell, TCellOwner, TLCell, TLCellOwner}; 16 | 17 | // Doesn't do anything, but shows up in list to prove that this file 18 | // has compiled 19 | #[test] 20 | fn test_static_assertions() {} 21 | 22 | #[allow(dead_code)] 23 | struct Q; 24 | 25 | // Check owners 26 | assert_impl_all!(LCellOwner<'_>: Send, Sync, Unpin, UnwindSafe, RefUnwindSafe); 27 | #[cfg(features = "alloc")] 28 | assert_impl_all!(QCellOwner: Send, Sync, Unpin, UnwindSafe, RefUnwindSafe); 29 | assert_impl_all!(QCellOwnerPinned: Send, Sync, UnwindSafe, RefUnwindSafe); 30 | assert_not_impl_any!(QCellOwnerPinned: Unpin); 31 | #[cfg(feature = "std")] 32 | assert_impl_all!(TCellOwner: Send, Sync, Unpin, UnwindSafe, RefUnwindSafe); 33 | #[cfg(feature = "std")] 34 | assert_impl_all!(TLCellOwner: Unpin, UnwindSafe, RefUnwindSafe); 35 | #[cfg(feature = "std")] 36 | assert_not_impl_any!(TLCellOwner: Send, Sync); 37 | 38 | // Check cells for simple type: i32 39 | assert_impl_all!(LCell<'_, i32>: Send, Sync, Unpin, UnwindSafe); 40 | assert_impl_all!(QCell: Send, Sync, Unpin, UnwindSafe); 41 | #[cfg(feature = "std")] 42 | assert_impl_all!(TCell: Send, Sync, Unpin, UnwindSafe); 43 | #[cfg(feature = "std")] 44 | assert_impl_all!(TLCell: Send, Unpin, UnwindSafe); 45 | #[cfg(feature = "std")] 46 | assert_not_impl_any!(TLCell: Sync); 47 | 48 | // Check cells for a !Send !Sync type: Rc 49 | assert_impl_all!(LCell<'_, Rc>: Unpin, UnwindSafe); 50 | assert_impl_all!(QCell>: Unpin, UnwindSafe); 51 | assert_not_impl_any!(LCell<'_, Rc>: Send, Sync); 52 | assert_not_impl_any!(QCell>: Send, Sync); 53 | #[cfg(feature = "std")] 54 | assert_impl_all!(TCell>: Unpin, UnwindSafe); 55 | #[cfg(feature = "std")] 56 | assert_impl_all!(TLCell>: Unpin, UnwindSafe); 57 | #[cfg(feature = "std")] 58 | assert_not_impl_any!(TCell>: Send, Sync); 59 | #[cfg(feature = "std")] 60 | assert_not_impl_any!(TLCell>: Send, Sync); 61 | 62 | // Check cells for a Send !Sync type: Cell 63 | assert_impl_all!(LCell<'_, Cell>: Send, Unpin, UnwindSafe); 64 | assert_impl_all!(QCell>: Send, Unpin, UnwindSafe); 65 | assert_not_impl_any!(LCell<'_, Cell>: Sync); 66 | assert_not_impl_any!(QCell>: Sync); 67 | #[cfg(feature = "std")] 68 | assert_impl_all!(TCell>: Send, Unpin, UnwindSafe); 69 | #[cfg(feature = "std")] 70 | assert_impl_all!(TLCell>: Send, Unpin, UnwindSafe); 71 | #[cfg(feature = "std")] 72 | assert_not_impl_any!(TCell>: Sync); 73 | #[cfg(feature = "std")] 74 | assert_not_impl_any!(TLCell>: Sync); 75 | 76 | // Check cells for a !Send Sync type 77 | struct Test(*const i32); 78 | unsafe impl Sync for Test {} 79 | assert_impl_all!(LCell<'_, Test>: Unpin, UnwindSafe); 80 | assert_impl_all!(QCell: Unpin, UnwindSafe); 81 | assert_not_impl_any!(LCell<'_, Test>: Send, Sync); 82 | assert_not_impl_any!(QCell: Send, Sync); 83 | #[cfg(feature = "std")] 84 | assert_impl_all!(TCell: Unpin, UnwindSafe); 85 | #[cfg(feature = "std")] 86 | assert_impl_all!(TLCell: Unpin, UnwindSafe); 87 | #[cfg(feature = "std")] 88 | assert_not_impl_any!(TCell: Send, Sync); 89 | #[cfg(feature = "std")] 90 | assert_not_impl_any!(TLCell: Send, Sync); 91 | -------------------------------------------------------------------------------- /src/doctest_lcell_generativity.rs: -------------------------------------------------------------------------------- 1 | // Run ./update-compiletest-from-doctest.pl in crate base directory 2 | // after making any modification to compile_fail tests here. 3 | 4 | //! This tests the `LCell` implementation when using `generativity`. 5 | //! 6 | //! It should be impossible to copy a `&mut LCellOwner`: 7 | //! 8 | //! ```compile_fail 9 | //!# use qcell::{LCell, LCellOwner, generativity::make_guard}; 10 | //!# use std::rc::Rc; 11 | //! make_guard!(guard1); 12 | //! let mut owner1 = LCellOwner::new(guard1); 13 | //! let owner2 = owner1; 14 | //! let rc = Rc::new(owner1.cell(100u32)); // Compile fail 15 | //! ``` 16 | //! 17 | //! It should be impossible to clone an LCellOwner: 18 | //! 19 | //! ```compile_fail 20 | //!# use qcell::{LCell, LCellOwner, generativity::make_guard}; 21 | //!# use std::rc::Rc; 22 | //! make_guard!(guard1); 23 | //! let mut owner1 = LCellOwner::new(guard1); 24 | //! let owner2 = owner1.clone(); // Compile fail 25 | //! ``` 26 | //! 27 | //! Two different owners can't borrow each other's cells immutably: 28 | //! 29 | //! ```compile_fail 30 | //!# use qcell::{LCell, LCellOwner, generativity::make_guard}; 31 | //!# use std::rc::Rc; 32 | //! make_guard!(guard1); 33 | //! make_guard!(guard2); 34 | //! let mut owner1 = LCellOwner::new(guard1); 35 | //! let mut owner2 = LCellOwner::new(guard2); 36 | //! let c1 = Rc::new(LCell::new(100u32)); 37 | //! let c1ref1 = owner1.ro(&c1); 38 | //! let c1ref2 = owner2.ro(&c1); // Compile error 39 | //! println!("{}", *c1ref2); 40 | //! ``` 41 | //! 42 | //! Or mutably: 43 | //! 44 | //! ```compile_fail 45 | //!# use qcell::{LCell, LCellOwner, generativity::make_guard}; 46 | //!# use std::rc::Rc; 47 | //! make_guard!(guard1); 48 | //! make_guard!(guard2); 49 | //! let mut owner1 = LCellOwner::new(guard1); 50 | //! let mut owner2 = LCellOwner::new(guard2); 51 | //! let c1 = Rc::new(owner1.cell(100u32)); 52 | //! let c1mutref2 = owner2.rw(&c1); // Compile error 53 | //! println!("{}", *c1mutref2); 54 | //! ``` 55 | //! 56 | //! You can't have two separate mutable borrows active on the same 57 | //! owner at the same time: 58 | //! 59 | //! ```compile_fail 60 | //!# use qcell::{LCell, LCellOwner, generativity::make_guard}; 61 | //!# use std::rc::Rc; 62 | //! make_guard!(guard); 63 | //! let mut owner = LCellOwner::new(guard); 64 | //! let c1 = Rc::new(LCell::new(100u32)); 65 | //! let c2 = Rc::new(LCell::new(200u32)); 66 | //! 67 | //! let c1mutref = owner.rw(&c1); 68 | //! let c2mutref = owner.rw(&c2); // Compile error 69 | //! *c1mutref += 1; 70 | //! *c2mutref += 2; 71 | //! ``` 72 | //! 73 | //! However with `rw2()` you can do two mutable borrows at the 74 | //! same time, since this call checks at runtime that the two 75 | //! references don't refer to the same memory: 76 | //! 77 | //! ``` 78 | //!# use qcell::{LCell, LCellOwner, generativity::make_guard}; 79 | //!# use std::rc::Rc; 80 | //! make_guard!(guard); 81 | //! let mut owner = LCellOwner::new(guard); 82 | //! let c1 = Rc::new(LCell::new(100u32)); 83 | //! let c2 = Rc::new(LCell::new(200u32)); 84 | //! let (c1mutref, c2mutref) = owner.rw2(&c1, &c2); 85 | //! *c1mutref += 1; 86 | //! *c2mutref += 2; 87 | //! assert_eq!(303, owner.ro(&c1) + owner.ro(&c2)); // Success! 88 | //! ``` 89 | //! 90 | //! You can't have a mutable borrow at the same time as an immutable 91 | //! borrow: 92 | //! 93 | //! ```compile_fail 94 | //!# use qcell::{LCell, LCellOwner, generativity::make_guard}; 95 | //!# use std::rc::Rc; 96 | //! make_guard!(guard); 97 | //! let mut owner = LCellOwner::new(guard); 98 | //! let c1 = Rc::new(LCell::new(100u32)); 99 | //! let c2 = Rc::new(LCell::new(200u32)); 100 | //! let c1ref = owner.ro(&c1); 101 | //! let c1mutref = owner.rw(&c1); // Compile error 102 | //! println!("{}", *c1ref); 103 | //! ``` 104 | //! 105 | //! Not even if it's borrowing a different object: 106 | //! 107 | //! ```compile_fail 108 | //!# use qcell::{LCell, LCellOwner, generativity::make_guard}; 109 | //!# use std::rc::Rc; 110 | //! make_guard!(guard); 111 | //! let mut owner = LCellOwner::new(guard); 112 | //! let c1 = Rc::new(LCell::new(100u32)); 113 | //! let c2 = Rc::new(LCell::new(200u32)); 114 | //! let c1mutref = owner.rw(&c1); 115 | //! let c2ref = owner.ro(&c2); // Compile error 116 | //! *c1mutref += 1; 117 | //! ``` 118 | //! 119 | //! Many immutable borrows at the same time is fine: 120 | //! 121 | //! ``` 122 | //!# use qcell::{LCell, LCellOwner, generativity::make_guard}; 123 | //!# use std::rc::Rc; 124 | //! make_guard!(guard); 125 | //! let mut owner = LCellOwner::new(guard); 126 | //! let c1 = Rc::new(LCell::new(100u32)); 127 | //! let c2 = Rc::new(LCell::new(200u32)); 128 | //! let c1ref = owner.ro(&c1); 129 | //! let c2ref = owner.ro(&c2); 130 | //! let c1ref2 = owner.ro(&c1); 131 | //! let c2ref2 = owner.ro(&c2); 132 | //! assert_eq!(600, *c1ref + *c2ref + *c1ref2 + *c2ref2); // Success! 133 | //! ``` 134 | //! 135 | //! Whilst a reference is active, it's impossible to drop the `Rc`: 136 | //! 137 | //! ```compile_fail 138 | //!# use qcell::{LCell, LCellOwner, generativity::make_guard}; 139 | //!# use std::rc::Rc; 140 | //! make_guard!(guard); 141 | //! let mut owner = LCellOwner::new(guard); 142 | //! let c1 = Rc::new(LCell::new(100u32)); 143 | //! let c1ref = owner.ro(&c1); 144 | //! drop(c1); // Compile error 145 | //! println!("{}", *c1ref); 146 | //! ``` 147 | //! 148 | //! Also, whilst a reference is active, it's impossible to call 149 | //! anything else that uses the `owner` in an incompatible way, 150 | //! e.g. `&mut` when there's a `&` reference: 151 | //! 152 | //! ```compile_fail 153 | //!# use qcell::{LCell, LCellOwner, generativity::make_guard}; 154 | //!# use std::rc::Rc; 155 | //! make_guard!(guard); 156 | //! let mut owner = LCellOwner::new(guard); 157 | //! let c1 = Rc::new(LCell::new(100u32)); 158 | //! fn test(o: &mut LCellOwner) {} 159 | //! 160 | //! let c1ref = owner.ro(&c1); 161 | //! test(&mut owner); // Compile error 162 | //! println!("{}", *c1ref); 163 | //! ``` 164 | //! 165 | //! Or `&` when there's a `&mut` reference: 166 | //! 167 | //! ```compile_fail 168 | //!# use qcell::{LCell, LCellOwner, generativity::make_guard}; 169 | //!# use std::rc::Rc; 170 | //! make_guard!(guard); 171 | //! let mut owner = LCellOwner::new(guard); 172 | //! let c1 = Rc::new(LCell::new(100u32)); 173 | //! fn test(o: &LCellOwner) {} 174 | //! 175 | //! let c1mutref = owner.rw(&c1); 176 | //! test(&owner); // Compile error 177 | //! *c1mutref += 1; 178 | //! ``` 179 | //! 180 | //! Two examples of passing owners and cells in function arguments. 181 | //! This needs lifetime annotations. 182 | //! 183 | //! ``` 184 | //! use qcell::{LCell, LCellOwner, generativity::make_guard}; 185 | //! use std::rc::Rc; 186 | //! make_guard!(guard); 187 | //! let mut owner = LCellOwner::new(guard); 188 | //! let c1 = Rc::new(LCell::new(100u32)); 189 | //! fn test<'id>(o: &mut LCellOwner<'id>, rc: &Rc>) { 190 | //! *o.rw(rc) += 1; 191 | //! } 192 | //! 193 | //! test(&mut owner, &c1); 194 | //! let c1mutref = owner.rw(&c1); 195 | //! *c1mutref += 1; 196 | //! ``` 197 | //! 198 | //! ``` 199 | //! use qcell::{LCell, LCellOwner, generativity::make_guard}; 200 | //! use std::rc::Rc; 201 | //! make_guard!(guard); 202 | //! let mut owner = LCellOwner::new(guard); 203 | //! struct Context<'id> { owner: LCellOwner<'id>, } 204 | //! let c1 = Rc::new(LCell::new(100u32)); 205 | //! let mut ct = Context { owner }; 206 | //! fn test<'id>(ct: &mut Context<'id>, rc: &Rc>) { 207 | //! *ct.owner.rw(rc) += 1; 208 | //! } 209 | //! 210 | //! test(&mut ct, &c1); 211 | //! let c1mutref = ct.owner.rw(&c1); 212 | //! *c1mutref += 2; 213 | //! ``` 214 | //! 215 | //! `LCellOwner` and `LCell` should be both `Send` and `Sync` by default: 216 | //! 217 | //! ``` 218 | //!# use qcell::{LCellOwner, LCell}; 219 | //! fn is_send_sync() {} 220 | //! is_send_sync::>(); 221 | //! is_send_sync::>(); 222 | //! ``` 223 | //! 224 | //! So for example we can share a cell ref between threads (Sync), and 225 | //! pass an owner back and forth (Send): 226 | //! 227 | //! ``` 228 | //!# use qcell::{LCellOwner, LCell, generativity::make_guard}; 229 | //! make_guard!(guard); 230 | //! let mut owner = LCellOwner::new(guard); 231 | //! let cell = LCell::new(100); 232 | //! 233 | //! *owner.rw(&cell) += 1; 234 | //! let cell_ref = &cell; 235 | //! let mut owner = crossbeam::scope(move |s| { 236 | //! s.spawn(move |_| { 237 | //! *owner.rw(cell_ref) += 2; 238 | //! owner 239 | //! }).join().unwrap() 240 | //! }).unwrap(); 241 | //! *owner.rw(&cell) += 4; 242 | //! assert_eq!(*owner.ro(&cell), 107); 243 | //! ``` 244 | //! 245 | //! However you can't send a cell that's still borrowed: 246 | //! 247 | //! ```compile_fail 248 | //!# use qcell::{LCellOwner, LCell, generativity::make_guard}; 249 | //! make_guard!(guard); 250 | //! let mut owner = LCellOwner::new(guard); 251 | //! let cell = LCell::new(100); 252 | //! let val_ref = owner.ro(&cell); 253 | //! crossbeam::scope(move |s| { 254 | //! s.spawn(move |_| assert_eq!(*owner.ro(&cell), 100)).join().unwrap(); // Compile fail 255 | //! }).unwrap(); 256 | //! assert_eq!(*val_ref, 100); 257 | //! ``` 258 | //! 259 | //! If the contained type isn't `Sync`, though, then `LCell` shouldn't 260 | //! be `Sync` either: 261 | //! 262 | //! ```compile_fail 263 | //!# use qcell::LCell; 264 | //!# use std::cell::Cell; 265 | //! fn is_sync() {} 266 | //! is_sync::>>(); // Compile fail 267 | //! ``` 268 | //! 269 | //! ```compile_fail 270 | //!# use qcell::{LCell, LCellOwner, generativity::make_guard}; 271 | //!# use std::cell::Cell; 272 | //! make_guard!(guard); 273 | //! let mut owner = LCellOwner::new(guard); 274 | //! let cell = LCell::new(Cell::new(100)); 275 | //! 276 | //! // This would likely be a data race if it compiled 277 | //! crossbeam::scope(|s| { // Compile fail 278 | //! let handle = s.spawn(|_| owner.ro(&cell).set(200)); 279 | //! owner.ro(&cell).set(300); 280 | //! handle.join().unwrap(); 281 | //! }).unwrap(); 282 | //! ``` 283 | //! 284 | //! If the contained type isn't `Send`, the `LCell` should be neither 285 | //! `Sync` nor `Send`: 286 | //! 287 | //! ```compile_fail 288 | //!# use qcell::LCell; 289 | //!# use std::rc::Rc; 290 | //! fn is_sync() {} 291 | //! is_sync::>>(); // Compile fail 292 | //! ``` 293 | //! 294 | //! ```compile_fail 295 | //!# use qcell::LCell; 296 | //!# use std::rc::Rc; 297 | //! fn is_send() {} 298 | //! is_send::>>(); // Compile fail 299 | //! ``` 300 | //! 301 | //! ```compile_fail 302 | //!# use qcell::{LCell, LCellOwner, generativity::make_guard}; 303 | //!# use std::rc::Rc; 304 | //! make_guard!(guard); 305 | //! let mut owner = LCellOwner::new(guard); 306 | //! let cell = LCell::new(Rc::new(100)); 307 | //! 308 | //! // We aren't permitted to move the Rc to another thread 309 | //! crossbeam::scope(move |s| { 310 | //! s.spawn(move |_| assert_eq!(100, **owner.ro(&cell))).join().unwrap(); // Compile fail 311 | //! }).unwrap(); 312 | //! ``` 313 | -------------------------------------------------------------------------------- /src/doctest_qcell.rs: -------------------------------------------------------------------------------- 1 | // Run ./update-compiletest-from-doctest.pl in crate base directory 2 | // after making any modification to compile_fail tests here. 3 | 4 | //! This tests the `QCell` implementation. 5 | //! 6 | //! It should be impossible to copy a QCellOwner: 7 | //! 8 | //! ```compile_fail 9 | //!# use qcell::{QCell, QCellOwner}; 10 | //!# use std::rc::Rc; 11 | //! let mut owner1 = QCellOwner::new(); 12 | //! let mut owner2 = owner1; 13 | //! let rc = Rc::new(QCell::new(&owner1, 100u32)); // Compile fail 14 | //! ``` 15 | //! 16 | //! It should be impossible to clone a QCellOwner: 17 | //! 18 | //! ```compile_fail 19 | //!# use qcell::{QCell, QCellOwner}; 20 | //!# use std::rc::Rc; 21 | //! let mut owner1 = QCellOwner::new(); 22 | //! let owner2 = owner1.clone(); // Compile fail 23 | //! ``` 24 | //! 25 | //! Two different owners can't borrow each other's cells immutably: 26 | //! 27 | //! ```should_panic 28 | //!# use qcell::{QCell, QCellOwner}; 29 | //!# use std::rc::Rc; 30 | //! let mut owner1 = QCellOwner::new(); 31 | //! let mut owner2 = QCellOwner::new(); 32 | //! let c1 = Rc::new(QCell::new(&owner1, 100u32)); 33 | //! 34 | //! let c1ref = owner2.ro(&c1); // Panics here 35 | //! println!("{}", *c1ref); 36 | //! ``` 37 | //! 38 | //! Or mutably: 39 | //! 40 | //! ```should_panic 41 | //!# use qcell::{QCell, QCellOwner}; 42 | //!# use std::rc::Rc; 43 | //! let mut owner1 = QCellOwner::new(); 44 | //! let mut owner2 = QCellOwner::new(); 45 | //! let c1 = Rc::new(QCell::new(&owner1, 100u32)); 46 | //! 47 | //! let c1mutref = owner2.rw(&c1); // Panics here 48 | //! println!("{}", *c1mutref); 49 | //! ``` 50 | //! 51 | //! You can't have two separate mutable borrows active on the same 52 | //! owner at the same time: 53 | //! 54 | //! ```compile_fail 55 | //!# use qcell::{QCell, QCellOwner}; 56 | //!# use std::rc::Rc; 57 | //! let mut owner = QCellOwner::new(); 58 | //! let c1 = Rc::new(QCell::new(&owner, 100u32)); 59 | //! let c2 = Rc::new(QCell::new(&owner, 200u32)); 60 | //! 61 | //! let c1mutref = owner.rw(&c1); 62 | //! let c2mutref= owner.rw(&c2); // Compile error 63 | //! *c1mutref += 1; 64 | //! *c2mutref += 2; 65 | //! ``` 66 | //! 67 | //! However with `rw2()` you can do two mutable borrows at the 68 | //! same time, since this call checks at runtime that the two 69 | //! references don't refer to the same memory: 70 | //! 71 | //! ``` 72 | //!# use qcell::{QCell, QCellOwner}; 73 | //!# use std::rc::Rc; 74 | //!# let mut owner = QCellOwner::new(); 75 | //!# let c1 = Rc::new(QCell::new(&owner, 100u32)); 76 | //!# let c2 = Rc::new(QCell::new(&owner, 200u32)); 77 | //! let (c1mutref, c2mutref) = owner.rw2(&c1, &c2); 78 | //! *c1mutref += 1; 79 | //! *c2mutref += 2; 80 | //! assert_eq!(303, owner.ro(&c1) + owner.ro(&c2)); // Success! 81 | //! ``` 82 | //! 83 | //! You can't have a mutable borrow at the same time as an immutable 84 | //! borrow: 85 | //! 86 | //! ```compile_fail 87 | //!# use qcell::{QCell, QCellOwner}; 88 | //!# use std::rc::Rc; 89 | //!# let mut owner = QCellOwner::new(); 90 | //!# let c1 = Rc::new(QCell::new(&owner, 100u32)); 91 | //!# let c2 = Rc::new(QCell::new(&owner, 200u32)); 92 | //! let c1ref = owner.ro(&c1); 93 | //! let c1mutref = owner.rw(&c1); // Compile error 94 | //! println!("{}", *c1ref); 95 | //! ``` 96 | //! 97 | //! Not even if it's borrowing a different object: 98 | //! 99 | //! ```compile_fail 100 | //!# use qcell::{QCell, QCellOwner}; 101 | //!# use std::rc::Rc; 102 | //!# let mut owner = QCellOwner::new(); 103 | //!# let c1 = Rc::new(QCell::new(&owner, 100u32)); 104 | //!# let c2 = Rc::new(QCell::new(&owner, 200u32)); 105 | //! let c1mutref = owner.rw(&c1); 106 | //! let c2ref = owner.ro(&c2); // Compile error 107 | //! *c1mutref += 1; 108 | //! ``` 109 | //! 110 | //! Many immutable borrows at the same time is fine: 111 | //! 112 | //! ``` 113 | //!# use qcell::{QCell, QCellOwner}; 114 | //!# use std::rc::Rc; 115 | //!# let mut owner = QCellOwner::new(); 116 | //!# let c1 = Rc::new(QCell::new(&owner, 100u32)); 117 | //!# let c2 = Rc::new(QCell::new(&owner, 200u32)); 118 | //! let c1ref = owner.ro(&c1); 119 | //! let c2ref = owner.ro(&c2); 120 | //! let c1ref2 = owner.ro(&c1); 121 | //! let c2ref2 = owner.ro(&c2); 122 | //! assert_eq!(600, *c1ref + *c2ref + *c1ref2 + *c2ref2); // Success! 123 | //! ``` 124 | //! 125 | //! Whilst a reference is active, it's impossible to drop the `Rc`: 126 | //! 127 | //! ```compile_fail 128 | //!# use qcell::{QCell, QCellOwner}; 129 | //!# use std::rc::Rc; 130 | //!# let mut owner = QCellOwner::new(); 131 | //!# let c1 = Rc::new(QCell::new(&owner, 100u32)); 132 | //!# let c2 = Rc::new(QCell::new(&owner, 200u32)); 133 | //! let c1ref = owner.ro(&c1); 134 | //! drop(c1); // Compile error 135 | //! println!("{}", *c1ref); 136 | //! ``` 137 | //! 138 | //! Also, whilst a reference is active, it's impossible to call 139 | //! anything else that uses the `owner` in an incompatible way, 140 | //! e.g. `&mut` when there's a `&` reference: 141 | //! 142 | //! ```compile_fail 143 | //!# use qcell::{QCell, QCellOwner}; 144 | //!# use std::rc::Rc; 145 | //!# let mut owner = QCellOwner::new(); 146 | //!# let c1 = Rc::new(QCell::new(&owner, 100u32)); 147 | //!# let c2 = Rc::new(QCell::new(&owner, 200u32)); 148 | //! fn test(o: &mut QCellOwner) {} 149 | //! 150 | //! let c1ref = owner.ro(&c1); 151 | //! test(&mut owner); // Compile error 152 | //! println!("{}", *c1ref); 153 | //! ``` 154 | //! 155 | //! Or `&` when there's a `&mut` reference: 156 | //! 157 | //! ```compile_fail 158 | //!# use qcell::{QCell, QCellOwner}; 159 | //!# use std::rc::Rc; 160 | //!# let mut owner = QCellOwner::new(); 161 | //!# let c1 = Rc::new(QCell::new(&owner, 100u32)); 162 | //!# let c2 = Rc::new(QCell::new(&owner, 200u32)); 163 | //! fn test(o: &QCellOwner) {} 164 | //! 165 | //! let c1mutref = owner.rw(&c1); 166 | //! test(&owner); // Compile error 167 | //! *c1mutref += 1; 168 | //! ``` 169 | //! 170 | //! `QCellOwner` and `QCell` should be both `Send` and `Sync` by default: 171 | //! 172 | //! ``` 173 | //!# use qcell::{QCellOwner, QCell}; 174 | //! fn is_send_sync() {} 175 | //! is_send_sync::(); 176 | //! is_send_sync::>(); 177 | //! ``` 178 | //! 179 | //! So for example we can share a cell ref between threads (Sync), and 180 | //! pass an owner back and forth (Send): 181 | //! 182 | //! ``` 183 | //!# use qcell::{QCellOwner, QCell}; 184 | //! let mut owner = QCellOwner::new(); 185 | //! let cell = QCell::new(&owner, 100_i32); 186 | //! 187 | //! *owner.rw(&cell) += 1; 188 | //! let cell_ref = &cell; 189 | //! let mut owner = crossbeam::scope(move |s| { 190 | //! s.spawn(move |_| { 191 | //! *owner.rw(cell_ref) += 2; 192 | //! owner 193 | //! }).join().unwrap() 194 | //! }).unwrap(); 195 | //! *owner.rw(&cell) += 4; 196 | //! assert_eq!(*owner.ro(&cell), 107); 197 | //! ``` 198 | //! 199 | //! However you can't send a cell that's still borrowed: 200 | //! 201 | //! ```compile_fail 202 | //!# use qcell::{QCellOwner, QCell}; 203 | //! let owner = QCellOwner::new(); 204 | //! let cell = QCell::new(&owner, 100); 205 | //! let val_ref = owner.ro(&cell); 206 | //! std::thread::spawn(move || { 207 | //! assert_eq!(*owner.ro(&cell), 100); 208 | //! }).join(); 209 | //! assert_eq!(*val_ref, 100); 210 | //! ``` 211 | //! 212 | //! If the contained type isn't `Sync`, though, then `QCell` shouldn't 213 | //! be `Sync` either: 214 | //! 215 | //! ```compile_fail 216 | //!# use qcell::QCell; 217 | //!# use std::cell::Cell; 218 | //! fn is_sync() {} 219 | //! is_sync::>>(); // Compile fail 220 | //! ``` 221 | //! 222 | //! ```compile_fail 223 | //!# use qcell::{QCell, QCellOwner}; 224 | //!# use std::cell::Cell; 225 | //! let owner = QCellOwner::new(); 226 | //! let cell = QCell::new(&owner, Cell::new(100)); 227 | //! 228 | //! // This would be a data race if the compiler permitted it, but it doesn't 229 | //! std::thread::spawn(|| owner.ro(&cell).set(200)); // Compile fail 230 | //! owner.ro(&cell).set(300); 231 | //! ``` 232 | //! 233 | //! If the contained type isn't `Send`, the `QCell` should be neither 234 | //! `Sync` nor `Send`: 235 | //! 236 | //! ```compile_fail 237 | //!# use qcell::QCell; 238 | //!# use std::rc::Rc; 239 | //! fn is_sync() {} 240 | //! is_sync::>>(); // Compile fail 241 | //! ``` 242 | //! 243 | //! ```compile_fail 244 | //!# use qcell::QCell; 245 | //!# use std::rc::Rc; 246 | //! fn is_send() {} 247 | //! is_send::>>(); // Compile fail 248 | //! ``` 249 | //! 250 | //! ```compile_fail 251 | //!# use qcell::{QCell, QCellOwner}; 252 | //!# use std::rc::Rc; 253 | //! let owner = QCellOwner::new(); 254 | //! let cell = QCell::new(&owner, Rc::new(100)); 255 | //! 256 | //! // We aren't permitted to move the Rc to another thread 257 | //! std::thread::spawn(move || { // Compile fail 258 | //! assert_eq!(100, **owner.ro(&cell)); 259 | //! }).join(); 260 | //! ``` 261 | //! 262 | //! A reference obtained using `get_mut` should exclude any other kind 263 | //! of borrowing. 264 | //! 265 | //! ```compile_fail 266 | //!# use qcell::{QCell, QCellOwner}; 267 | //! let owner = QCellOwner::new(); 268 | //! let mut cell = QCell::new(&owner, 100); 269 | //! let cell_ref = cell.get_mut(); 270 | //! assert_eq!(100, *owner.ro(&cell)); // Compile fail 271 | //! *cell_ref = 50; 272 | //! ``` 273 | //! 274 | //! ```compile_fail 275 | //!# use qcell::{QCell, QCellOwner}; 276 | //! let mut owner = QCellOwner::new(); 277 | //! let mut cell = QCell::new(&owner, 100); 278 | //! let cell_ref = cell.get_mut(); 279 | //! assert_eq!(100, *owner.rw(&cell)); // Compile fail 280 | //! *cell_ref = 50; 281 | //! ``` 282 | //! 283 | //! ```compile_fail 284 | //!# use qcell::{QCell, QCellOwner}; 285 | //! let owner = QCellOwner::new(); 286 | //! let mut cell = QCell::new(&owner, 100); 287 | //! let cell_ref = owner.ro(&cell); 288 | //! *cell.get_mut() = 50; // Compile fail 289 | //! assert_eq!(100, *cell_ref); 290 | //! ``` 291 | //! 292 | //! ```compile_fail 293 | //!# use qcell::{QCell, QCellOwner}; 294 | //! let mut owner = QCellOwner::new(); 295 | //! let mut cell = QCell::new(&owner, 100); 296 | //! let cell_ref = owner.rw(&cell); 297 | //! *cell.get_mut() = 50; // Compile fail 298 | //! assert_eq!(100, *cell_ref); 299 | //! ``` 300 | //! 301 | //! `Default` is not implemented for `QCell`, since the owner must be 302 | //! provided explicity: 303 | //! 304 | //! ```compile_fail 305 | //!# use qcell::QCell; 306 | //! let mut cell: QCell = QCell::default(); 307 | //! ``` 308 | -------------------------------------------------------------------------------- /src/doctest_qcell_noalloc.rs: -------------------------------------------------------------------------------- 1 | // Run ./update-compiletest-from-doctest.pl in crate base directory 2 | // after making any modification to compile_fail tests here. 3 | 4 | //! This tests the `QCell` implementation without the `alloc` feature. 5 | //! 6 | //! You should not be able to use QCellOwnerPinned without pinning it first 7 | //! 8 | //! ```compile_fail 9 | //!# use qcell::{QCell, QCellOwnerPinned}; 10 | //! let mut owner1 = QCellOwnerPinned::new(); 11 | //! let id = owner1.id(); 12 | //! ``` 13 | //! 14 | //! QCellOwnerPinned should be `!Unpin` 15 | //! 16 | //! ```compile_fail 17 | //!# use qcell::QCellOwnerPinned; 18 | //! fn is_unpin() {} 19 | //! is_unpin::(); 20 | //! ``` 21 | //! 22 | //! It should be impossible to copy a QCellOwnerPinned: 23 | //! 24 | //! ```compile_fail 25 | //!# use qcell::{QCell, QCellOwnerPinned}; 26 | //!# use std::rc::Rc; 27 | //!# use pin_utils::pin_mut; 28 | //! let mut owner1 = QCellOwnerPinned::new(); 29 | //! let mut owner2 = owner1; 30 | //! pin_mut!(owner1); // Compile fail 31 | //! let rc = Rc::new(owner1.as_ref().cell(100u32)); 32 | //! ``` 33 | //! 34 | //! Including after it was pinned: 35 | //! 36 | //! ```compile_fail 37 | //!# use qcell::{QCell, QCellOwnerPinned}; 38 | //!# use std::rc::Rc; 39 | //!# use pin_utils::pin_mut; 40 | //! let mut owner1 = QCellOwnerPinned::new(); 41 | //! pin_mut!(owner1); 42 | //! let mut owner2 = owner1; 43 | //! let rc = Rc::new(owner1.as_ref().cell(100u32)); // Compile fail 44 | //! ``` 45 | //! 46 | //! It should be impossible to clone a QCellOwnerPinned: 47 | //! 48 | //! ```compile_fail 49 | //!# use qcell::{QCell, QCellOwnerPinned}; 50 | //!# use std::rc::Rc; 51 | //! let mut owner1 = QCellOwnerPinned::new(); 52 | //! let owner2 = owner1.clone(); // Compile fail 53 | //! ``` 54 | //! 55 | //! Including after it was pinned: 56 | //! 57 | //! ```compile_fail 58 | //!# use qcell::{QCell, QCellOwnerPinned}; 59 | //!# use std::rc::Rc; 60 | //!# use pin_utils::pin_mut; 61 | //! let mut owner1 = QCellOwnerPinned::new(); 62 | //! pin_mut!(owner1); 63 | //! let owner2 = owner1.clone(); // Compile fail 64 | //! ``` 65 | //! 66 | //! Two different owners can't borrow each other's cells immutably: 67 | //! 68 | //! ```should_panic 69 | //!# use qcell::{QCell, QCellOwnerPinned}; 70 | //!# use std::rc::Rc; 71 | //!# use pin_utils::pin_mut; 72 | //! let mut owner1 = QCellOwnerPinned::new(); 73 | //! let mut owner2 = QCellOwnerPinned::new(); 74 | //! pin_mut!(owner1); 75 | //! pin_mut!(owner2); 76 | //! let c1 = Rc::new(owner1.as_ref().cell(100u32)); 77 | //! 78 | //! let c1ref = owner2.as_ref().ro(&c1); // Panics here 79 | //! println!("{}", *c1ref); 80 | //! ``` 81 | //! 82 | //! Or mutably: 83 | //! 84 | //! ```should_panic 85 | //!# use qcell::{QCell, QCellOwnerPinned}; 86 | //!# use std::rc::Rc; 87 | //!# use pin_utils::pin_mut; 88 | //! let mut owner1 = QCellOwnerPinned::new(); 89 | //! let mut owner2 = QCellOwnerPinned::new(); 90 | //! pin_mut!(owner1); 91 | //! pin_mut!(owner2); 92 | //! let c1 = Rc::new(owner1.as_ref().cell(100u32)); 93 | //! 94 | //! let c1mutref = owner2.as_mut().rw(&c1); // Panics here 95 | //! println!("{}", *c1mutref); 96 | //! ``` 97 | //! 98 | //! You can't have two separate mutable borrows active on the same 99 | //! owner at the same time: 100 | //! 101 | //! ```compile_fail 102 | //!# use qcell::{QCell, QCellOwnerPinned}; 103 | //!# use std::rc::Rc; 104 | //!# use pin_utils::pin_mut; 105 | //! let mut owner = QCellOwnerPinned::new(); 106 | //! pin_mut!(owner); 107 | //! let c1 = Rc::new(owner.as_ref().cell(100u32)); 108 | //! let c2 = Rc::new(owner.as_ref().cell(200u32)); 109 | //! 110 | //! let c1mutref = owner.as_mut().rw(&c1); 111 | //! let c2mutref= owner.as_mut().rw(&c2); // Compile error 112 | //! *c1mutref += 1; 113 | //! *c2mutref += 2; 114 | //! ``` 115 | //! 116 | //! However with `rw2()` you can do two mutable borrows at the 117 | //! same time, since this call checks at runtime that the two 118 | //! references don't refer to the same memory: 119 | //! 120 | //! ``` 121 | //!# use qcell::{QCell, QCellOwnerPinned}; 122 | //!# use std::rc::Rc; 123 | //!# use pin_utils::pin_mut; 124 | //!# let mut owner = QCellOwnerPinned::new(); 125 | //!# pin_mut!(owner); 126 | //!# let c1 = Rc::new(owner.as_ref().cell(100u32)); 127 | //!# let c2 = Rc::new(owner.as_ref().cell(200u32)); 128 | //! let (c1mutref, c2mutref) = owner.as_mut().rw2(&c1, &c2); 129 | //! *c1mutref += 1; 130 | //! *c2mutref += 2; 131 | //! assert_eq!(303, owner.as_ref().ro(&c1) + owner.as_ref().ro(&c2)); // Success! 132 | //! ``` 133 | //! 134 | //! You can't have a mutable borrow at the same time as an immutable 135 | //! borrow: 136 | //! 137 | //! ```compile_fail 138 | //!# use qcell::{QCell, QCellOwnerPinned}; 139 | //!# use std::rc::Rc; 140 | //!# use pin_utils::pin_mut; 141 | //!# let mut owner = QCellOwnerPinned::new(); 142 | //!# pin_mut!(owner); 143 | //!# let c1 = Rc::new(owner.as_ref().cell(100u32)); 144 | //!# let c2 = Rc::new(owner.as_ref().cell(200u32)); 145 | //! let c1ref = owner.as_ref().ro(&c1); 146 | //! let c1mutref = owner.as_mut().rw(&c1); // Compile error 147 | //! println!("{}", *c1ref); 148 | //! ``` 149 | //! 150 | //! Not even if it's borrowing a different object: 151 | //! 152 | //! ```compile_fail 153 | //!# use qcell::{QCell, QCellOwnerPinned}; 154 | //!# use std::rc::Rc; 155 | //!# use pin_utils::pin_mut; 156 | //!# let mut owner = QCellOwnerPinned::new(); 157 | //!# pin_mut!(owner); 158 | //!# let c1 = Rc::new(owner.as_ref().cell(100u32)); 159 | //!# let c2 = Rc::new(owner.as_ref().cell(200u32)); 160 | //! let c1mutref = owner.as_mut().rw(&c1); 161 | //! let c2ref = owner.as_ref().ro(&c2); // Compile error 162 | //! *c1mutref += 1; 163 | //! ``` 164 | //! 165 | //! Many immutable borrows at the same time is fine: 166 | //! 167 | //! ``` 168 | //!# use qcell::{QCell, QCellOwnerPinned}; 169 | //!# use std::rc::Rc; 170 | //!# use pin_utils::pin_mut; 171 | //!# let mut owner = QCellOwnerPinned::new(); 172 | //!# pin_mut!(owner); 173 | //!# let c1 = Rc::new(owner.as_ref().cell(100u32)); 174 | //!# let c2 = Rc::new(owner.as_ref().cell(200u32)); 175 | //! let c1ref = owner.as_ref().ro(&c1); 176 | //! let c2ref = owner.as_ref().ro(&c2); 177 | //! let c1ref2 = owner.as_ref().ro(&c1); 178 | //! let c2ref2 = owner.as_ref().ro(&c2); 179 | //! assert_eq!(600, *c1ref + *c2ref + *c1ref2 + *c2ref2); // Success! 180 | //! ``` 181 | //! 182 | //! Whilst a reference is active, it's impossible to drop the `Rc`: 183 | //! 184 | //! ```compile_fail 185 | //!# use qcell::{QCell, QCellOwnerPinned}; 186 | //!# use std::rc::Rc; 187 | //!# use pin_utils::pin_mut; 188 | //!# let mut owner = QCellOwnerPinned::new(); 189 | //!# pin_mut!(owner); 190 | //!# let c1 = Rc::new(owner.as_ref().cell(100u32)); 191 | //!# let c2 = Rc::new(owner.as_ref().cell(200u32)); 192 | //! let c1ref = owner.as_ref().ro(&c1); 193 | //! drop(c1); // Compile error 194 | //! println!("{}", *c1ref); 195 | //! ``` 196 | //! 197 | //! Also, whilst a reference is active, it's impossible to call 198 | //! anything else that uses the `owner` in an incompatible way, 199 | //! e.g. `&mut` when there's a `&` reference: 200 | //! 201 | //! ```compile_fail 202 | //!# use qcell::{QCell, QCellOwnerPinned}; 203 | //!# use std::{rc::Rc, pin::Pin}; 204 | //!# use pin_utils::pin_mut; 205 | //!# let mut owner = QCellOwnerPinned::new(); 206 | //!# pin_mut!(owner); 207 | //!# let c1 = Rc::new(owner.as_ref().cell(100u32)); 208 | //!# let c2 = Rc::new(owner.as_ref().cell(200u32)); 209 | //! fn test(o: Pin<&mut QCellOwnerPinned>) {} 210 | //! 211 | //! let c1ref = owner.as_ref().ro(&c1); 212 | //! test(owner.as_mut()); // Compile error 213 | //! println!("{}", *c1ref); 214 | //! ``` 215 | //! 216 | //! Or `&` when there's a `&mut` reference: 217 | //! 218 | //! ```compile_fail 219 | //!# use qcell::{QCell, QCellOwnerPinned}; 220 | //!# use std::{rc::Rc, pin::Pin}; 221 | //!# use pin_utils::pin_mut; 222 | //!# let mut owner = QCellOwnerPinned::new(); 223 | //!# pin_mut!(owner); 224 | //!# let c1 = Rc::new(owner.as_ref().cell(100u32)); 225 | //!# let c2 = Rc::new(owner.as_ref().cell(200u32)); 226 | //! fn test(o: Pin<&QCellOwnerPinned>) {} 227 | //! 228 | //! let c1mutref = owner.as_mut().rw(&c1); 229 | //! test(owner.as_ref()); // Compile error 230 | //! *c1mutref += 1; 231 | //! ``` 232 | //! 233 | //! `QCellOwnerPinned` and `QCell` should be both 234 | //! `Send` and `Sync` by default: 235 | //! 236 | //! ``` 237 | //!# use qcell::{QCell, QCellOwnerPinned}; 238 | //! fn is_send_sync() {} 239 | //! is_send_sync::(); 240 | //! is_send_sync::>(); 241 | //! ``` 242 | //! 243 | //! So for example we can share a cell ref between threads (Sync), and 244 | //! pass an owner back and forth (Send): 245 | //! 246 | //! ``` 247 | //!# use qcell::{QCellOwnerPinned, QCell}; 248 | //!# use pin_utils::pin_mut; 249 | //! let mut owner = QCellOwnerPinned::new(); 250 | //! pin_mut!(owner); 251 | //! let cell = owner.as_ref().cell(100_i32); 252 | //! 253 | //! *owner.as_mut().rw(&cell) += 1; 254 | //! let cell_ref = &cell; 255 | //! let mut owner = crossbeam::scope(move |s| { 256 | //! s.spawn(move |_| { 257 | //! *owner.as_mut().rw(cell_ref) += 2; 258 | //! owner 259 | //! }).join().unwrap() 260 | //! }).unwrap(); 261 | //! *owner.as_mut().rw(&cell) += 4; 262 | //! assert_eq!(*owner.as_ref().ro(&cell), 107); 263 | //! ``` 264 | //! 265 | //! However you can't send a cell that's still borrowed: 266 | //! 267 | //! ```compile_fail 268 | //!# use qcell::{QCellOwnerPinned, QCell}; 269 | //! let mut owner = Box::pin(QCellOwnerPinned::new()); 270 | //! let cell = owner.as_ref().cell(100); 271 | //! let val_ref = owner.as_ref().ro(&cell); 272 | //! std::thread::spawn(move || { 273 | //! assert_eq!(*owner.as_ref().ro(&cell), 100); 274 | //! }).join(); 275 | //! assert_eq!(*val_ref, 100); 276 | //! ``` 277 | //! 278 | //! If the contained type isn't `Sync`, though, then `QCell` shouldn't 279 | //! be `Sync` either: 280 | //! 281 | //! ```compile_fail 282 | //!# use qcell::QCell; 283 | //!# use std::cell::Cell; 284 | //! fn is_sync() {} 285 | //! is_sync::>>(); // Compile fail 286 | //! ``` 287 | //! 288 | //! If the contained type isn't `Send`, the `QCell` should be neither 289 | //! `Sync` nor `Send`: 290 | //! 291 | //! ```compile_fail 292 | //!# use qcell::QCell; 293 | //!# use std::rc::Rc; 294 | //! fn is_sync() {} 295 | //! is_sync::>>(); // Compile fail 296 | //! ``` 297 | //! 298 | //! ```compile_fail 299 | //!# use qcell::QCell; 300 | //!# use std::rc::Rc; 301 | //! fn is_send() {} 302 | //! is_send::>>(); // Compile fail 303 | //! ``` 304 | //! 305 | //! ```compile_fail 306 | //!# use qcell::{QCell, QCellOwnerPinned}; 307 | //!# use std::rc::Rc; 308 | //! let mut owner = Box::pin(QCellOwnerPinned::new()); 309 | //! let cell = owner.as_ref().cell(Rc::new(100)); 310 | //! 311 | //! // We aren't permitted to move the Rc to another thread 312 | //! std::thread::spawn(move || { // Compile fail 313 | //! assert_eq!(100, **owner.as_ref().ro(&cell)); 314 | //! }).join(); 315 | //! ``` 316 | -------------------------------------------------------------------------------- /trybuild-qcell/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "trybuild-qcell" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | qcell = { path = "..", features = ["generativity"] } 8 | 9 | [dev-dependencies] 10 | trybuild = "1.0" 11 | rustversion = "1.0" 12 | crossbeam = "0.7" 13 | pin-utils = "0.1" 14 | -------------------------------------------------------------------------------- /trybuild-qcell/README.md: -------------------------------------------------------------------------------- 1 | These `trybuild` compile-tests double-check that the `compile_fail` 2 | tests in the doctests in the main crate actually fail for the reason 3 | intended, not for some other reason. This is most useful to check 4 | when making changes to the crate that may have broken something. 5 | However since the compiler error messages change from one Rust release 6 | to the next, the test output only remains valid for a certain range of 7 | compiler versions. 8 | 9 | Procedure: 10 | 11 | - Get a clean git status by checking in any in-progress changes 12 | - Update the Rust version numbers in `src/lib.rs` to the current version 13 | - Run `TRYBUILD=overwrite cargo test` 14 | - Examine any modified files noticed by git 15 | 16 | Any error output that has changed will show up as modified files under 17 | `src/compiletest`. Check through these manually to see that the 18 | failure is the same as before. Mostly the top line of the error 19 | message will be the same and there will be changes in the formatting 20 | or hints provided by the compiler. If all is okay, check in the 21 | changes. 22 | 23 | The reason for having this in a separate crate is to run `trybuild` in 24 | an environment with all `qcell` features enabled, since `trybuild` 25 | seems to have problems running tests that depend on optional features. 26 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-00.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner}; 6 | use std::rc::Rc; 7 | LCellOwner::scope(|mut owner1| { 8 | let owner2 = owner1; 9 | let rc = Rc::new(owner1.cell(100u32)); // Compile fail 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-00.stderr: -------------------------------------------------------------------------------- 1 | error[E0382]: borrow of moved value: `owner1` 2 | --> src/compiletest/lcell-00.rs:9:26 3 | | 4 | 7 | LCellOwner::scope(|mut owner1| { 5 | | ---------- move occurs because `owner1` has type `LCellOwner<'_>`, which does not implement the `Copy` trait 6 | 8 | let owner2 = owner1; 7 | | ------ value moved here 8 | 9 | let rc = Rc::new(owner1.cell(100u32)); // Compile fail 9 | | ^^^^^^^^^^^^^^^^^^^ value borrowed here after move 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-01.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner}; 6 | use std::rc::Rc; 7 | LCellOwner::scope(|mut owner1| { 8 | let owner2 = owner1.clone(); // Compile fail 9 | }); 10 | } 11 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-01.stderr: -------------------------------------------------------------------------------- 1 | error[E0599]: no method named `clone` found for struct `LCellOwner` in the current scope 2 | --> src/compiletest/lcell-01.rs:8:29 3 | | 4 | 8 | let owner2 = owner1.clone(); // Compile fail 5 | | ^^^^^ method not found in `LCellOwner<'_>` 6 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-02.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner}; 6 | use std::rc::Rc; 7 | LCellOwner::scope(|mut owner1| { 8 | LCellOwner::scope(|mut owner2| { 9 | let c1 = Rc::new(LCell::new(100u32)); 10 | let c1ref1 = owner1.ro(&c1); 11 | let c1ref2 = owner2.ro(&c1); // Compile error 12 | println!("{}", *c1ref2); 13 | }); 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-02.stderr: -------------------------------------------------------------------------------- 1 | error[E0521]: borrowed data escapes outside of closure 2 | --> src/compiletest/lcell-02.rs:11:26 3 | | 4 | 7 | LCellOwner::scope(|mut owner1| { 5 | | ---------- `owner1` declared here, outside of the closure body 6 | 8 | LCellOwner::scope(|mut owner2| { 7 | | ---------- `owner2` is a reference that is only valid in the closure body 8 | ... 9 | 11 | let c1ref2 = owner2.ro(&c1); // Compile error 10 | | ^^^^^^^^^^^^^^ `owner2` escapes the closure body here 11 | | 12 | = note: requirement occurs because of the type `LCellOwner<'_>`, which makes the generic argument `'_` invariant 13 | = note: the struct `LCellOwner<'id>` is invariant over the parameter `'id` 14 | = help: see for more information about variance 15 | 16 | error[E0521]: borrowed data escapes outside of closure 17 | --> src/compiletest/lcell-02.rs:10:26 18 | | 19 | 7 | LCellOwner::scope(|mut owner1| { 20 | | ---------- 21 | | | 22 | | `owner1` is a reference that is only valid in the closure body 23 | | has type `LCellOwner<'1>` 24 | ... 25 | 10 | let c1ref1 = owner1.ro(&c1); 26 | | ^^^^^^^^^^^^^^ 27 | | | 28 | | `owner1` escapes the closure body here 29 | | argument requires that `'1` must outlive `'static` 30 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-03.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner}; 6 | use std::rc::Rc; 7 | LCellOwner::scope(|mut owner1| { 8 | LCellOwner::scope(|mut owner2| { 9 | let c1 = Rc::new(owner1.cell(100u32)); 10 | let c1mutref2 = owner2.rw(&c1); // Compile error 11 | println!("{}", *c1mutref2); 12 | }); 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-03.stderr: -------------------------------------------------------------------------------- 1 | error[E0521]: borrowed data escapes outside of closure 2 | --> src/compiletest/lcell-03.rs:9:30 3 | | 4 | 7 | LCellOwner::scope(|mut owner1| { 5 | | ---------- `owner1` declared here, outside of the closure body 6 | 8 | LCellOwner::scope(|mut owner2| { 7 | | ---------- `owner2` is a reference that is only valid in the closure body 8 | 9 | let c1 = Rc::new(owner1.cell(100u32)); 9 | | ^^^^^^^^^^^^^^^^^^^ `owner2` escapes the closure body here 10 | | 11 | = note: requirement occurs because of the type `LCellOwner<'_>`, which makes the generic argument `'_` invariant 12 | = note: the struct `LCellOwner<'id>` is invariant over the parameter `'id` 13 | = help: see for more information about variance 14 | 15 | error[E0521]: borrowed data escapes outside of closure 16 | --> src/compiletest/lcell-03.rs:9:30 17 | | 18 | 7 | LCellOwner::scope(|mut owner1| { 19 | | ---------- 20 | | | 21 | | `owner1` is a reference that is only valid in the closure body 22 | | has type `LCellOwner<'1>` 23 | 8 | LCellOwner::scope(|mut owner2| { 24 | 9 | let c1 = Rc::new(owner1.cell(100u32)); 25 | | ^^^^^^^^^^^^^^^^^^^ 26 | | | 27 | | `owner1` escapes the closure body here 28 | | argument requires that `'1` must outlive `'static` 29 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-04.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner}; 6 | use std::rc::Rc; 7 | LCellOwner::scope(|mut owner| { 8 | let c1 = Rc::new(LCell::new(100u32)); 9 | let c2 = Rc::new(LCell::new(200u32)); 10 | 11 | let c1mutref = owner.rw(&c1); 12 | let c2mutref = owner.rw(&c2); // Compile error 13 | *c1mutref += 1; 14 | *c2mutref += 2; 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-04.stderr: -------------------------------------------------------------------------------- 1 | error[E0499]: cannot borrow `owner` as mutable more than once at a time 2 | --> src/compiletest/lcell-04.rs:12:24 3 | | 4 | 11 | let c1mutref = owner.rw(&c1); 5 | | ------------- first mutable borrow occurs here 6 | 12 | let c2mutref = owner.rw(&c2); // Compile error 7 | | ^^^^^^^^^^^^^ second mutable borrow occurs here 8 | 13 | *c1mutref += 1; 9 | | -------------- first borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-05.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner}; 6 | use std::rc::Rc; 7 | LCellOwner::scope(|mut owner| { 8 | let c1 = Rc::new(LCell::new(100u32)); 9 | let c2 = Rc::new(LCell::new(200u32)); 10 | let c1ref = owner.ro(&c1); 11 | let c1mutref = owner.rw(&c1); // Compile error 12 | println!("{}", *c1ref); 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-05.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/lcell-05.rs:11:24 3 | | 4 | 10 | let c1ref = owner.ro(&c1); 5 | | ------------- immutable borrow occurs here 6 | 11 | let c1mutref = owner.rw(&c1); // Compile error 7 | | ^^^^^^^^^^^^^ mutable borrow occurs here 8 | 12 | println!("{}", *c1ref); 9 | | ------ immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-06.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner}; 6 | use std::rc::Rc; 7 | LCellOwner::scope(|mut owner| { 8 | let c1 = Rc::new(LCell::new(100u32)); 9 | let c2 = Rc::new(LCell::new(200u32)); 10 | let c1mutref = owner.rw(&c1); 11 | let c2ref = owner.ro(&c2); // Compile error 12 | *c1mutref += 1; 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-06.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/lcell-06.rs:11:21 3 | | 4 | 10 | let c1mutref = owner.rw(&c1); 5 | | ------------- mutable borrow occurs here 6 | 11 | let c2ref = owner.ro(&c2); // Compile error 7 | | ^^^^^^^^^^^^^ immutable borrow occurs here 8 | 12 | *c1mutref += 1; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-07.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner}; 6 | use std::rc::Rc; 7 | LCellOwner::scope(|mut owner| { 8 | let c1 = Rc::new(LCell::new(100u32)); 9 | let c1ref = owner.ro(&c1); 10 | drop(c1); // Compile error 11 | println!("{}", *c1ref); 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-07.stderr: -------------------------------------------------------------------------------- 1 | error[E0505]: cannot move out of `c1` because it is borrowed 2 | --> src/compiletest/lcell-07.rs:10:14 3 | | 4 | 8 | let c1 = Rc::new(LCell::new(100u32)); 5 | | -- binding `c1` declared here 6 | 9 | let c1ref = owner.ro(&c1); 7 | | --- borrow of `c1` occurs here 8 | 10 | drop(c1); // Compile error 9 | | ^^ move out of `c1` occurs here 10 | 11 | println!("{}", *c1ref); 11 | | ------ borrow later used here 12 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-08.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner}; 6 | use std::rc::Rc; 7 | LCellOwner::scope(|mut owner| { 8 | let c1 = Rc::new(LCell::new(100u32)); 9 | fn test(o: &mut LCellOwner) {} 10 | 11 | let c1ref = owner.ro(&c1); 12 | test(&mut owner); // Compile error 13 | println!("{}", *c1ref); 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-08.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/lcell-08.rs:12:14 3 | | 4 | 11 | let c1ref = owner.ro(&c1); 5 | | ------------- immutable borrow occurs here 6 | 12 | test(&mut owner); // Compile error 7 | | ^^^^^^^^^^ mutable borrow occurs here 8 | 13 | println!("{}", *c1ref); 9 | | ------ immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-09.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner}; 6 | use std::rc::Rc; 7 | LCellOwner::scope(|mut owner| { 8 | let c1 = Rc::new(LCell::new(100u32)); 9 | fn test(o: &LCellOwner) {} 10 | 11 | let c1mutref = owner.rw(&c1); 12 | test(&owner); // Compile error 13 | *c1mutref += 1; 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-09.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/lcell-09.rs:12:14 3 | | 4 | 11 | let c1mutref = owner.rw(&c1); 5 | | ------------- mutable borrow occurs here 6 | 12 | test(&owner); // Compile error 7 | | ^^^^^^ immutable borrow occurs here 8 | 13 | *c1mutref += 1; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-10.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCellOwner, LCell}; 6 | LCellOwner::scope(|mut owner| { 7 | let cell = LCell::new(100); 8 | let val_ref = owner.ro(&cell); 9 | crossbeam::scope(move |s| { 10 | s.spawn(move |_| assert_eq!(*owner.ro(&cell), 100)).join().unwrap(); // Compile fail 11 | }).unwrap(); 12 | assert_eq!(*val_ref, 100); 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-10.stderr: -------------------------------------------------------------------------------- 1 | error[E0505]: cannot move out of `owner` because it is borrowed 2 | --> src/compiletest/lcell-10.rs:9:26 3 | | 4 | 6 | LCellOwner::scope(|mut owner| { 5 | | --------- binding `owner` declared here 6 | 7 | let cell = LCell::new(100); 7 | 8 | let val_ref = owner.ro(&cell); 8 | | --------------- borrow of `owner` occurs here 9 | 9 | crossbeam::scope(move |s| { 10 | | ^^^^^^^^ move out of `owner` occurs here 11 | 10 | s.spawn(move |_| assert_eq!(*owner.ro(&cell), 100)).join().unwrap(); // Compile fail 12 | | ----- move occurs due to use in closure 13 | 11 | }).unwrap(); 14 | 12 | assert_eq!(*val_ref, 100); 15 | | ------------------------- borrow later used here 16 | 17 | error[E0505]: cannot move out of `cell` because it is borrowed 18 | --> src/compiletest/lcell-10.rs:9:26 19 | | 20 | 7 | let cell = LCell::new(100); 21 | | ---- binding `cell` declared here 22 | 8 | let val_ref = owner.ro(&cell); 23 | | ----- borrow of `cell` occurs here 24 | 9 | crossbeam::scope(move |s| { 25 | | ^^^^^^^^ move out of `cell` occurs here 26 | 10 | s.spawn(move |_| assert_eq!(*owner.ro(&cell), 100)).join().unwrap(); // Compile fail 27 | | ---- move occurs due to use in closure 28 | 11 | }).unwrap(); 29 | 12 | assert_eq!(*val_ref, 100); 30 | | ------------------------- borrow later used here 31 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-11.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::LCell; 6 | use std::cell::Cell; 7 | fn is_sync() {} 8 | is_sync::>>(); // Compile fail 9 | } 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-11.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Cell` cannot be shared between threads safely 2 | --> src/compiletest/lcell-11.rs:8:15 3 | | 4 | 8 | is_sync::>>(); // Compile fail 5 | | ^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely 6 | | 7 | = help: the trait `Sync` is not implemented for `Cell` 8 | = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead 9 | = note: required for `LCell<'_, Cell>` to implement `Sync` 10 | note: required by a bound in `is_sync` 11 | --> src/compiletest/lcell-11.rs:7:19 12 | | 13 | 7 | fn is_sync() {} 14 | | ^^^^ required by this bound in `is_sync` 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-12.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner}; 6 | use std::cell::Cell; 7 | LCellOwner::scope(|owner| { 8 | let cell = LCell::new(Cell::new(100)); 9 | 10 | // This would likely be a data race if it compiled 11 | crossbeam::scope(|s| { // Compile fail 12 | let handle = s.spawn(|_| owner.ro(&cell).set(200)); 13 | owner.ro(&cell).set(300); 14 | handle.join().unwrap(); 15 | }).unwrap(); 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-12.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Cell` cannot be shared between threads safely 2 | --> src/compiletest/lcell-12.rs:12:34 3 | | 4 | 12 | let handle = s.spawn(|_| owner.ro(&cell).set(200)); 5 | | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely 6 | | | 7 | | required by a bound introduced by this call 8 | | 9 | = help: the trait `Sync` is not implemented for `Cell` 10 | = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead 11 | = note: required for `LCell<'_, Cell>` to implement `Sync` 12 | = note: required for `&LCell<'_, Cell>` to implement `Send` 13 | note: required because it's used within this closure 14 | --> src/compiletest/lcell-12.rs:12:34 15 | | 16 | 12 | let handle = s.spawn(|_| owner.ro(&cell).set(200)); 17 | | ^^^ 18 | note: required by a bound in `crossbeam::thread::Scope::<'env>::spawn` 19 | --> /home/jim/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-utils-0.7.2/src/thread.rs:243:12 20 | | 21 | 240 | pub fn spawn<'scope, F, T>(&'scope self, f: F) -> ScopedJoinHandle<'scope, T> 22 | | ----- required by a bound in this associated function 23 | ... 24 | 243 | F: Send + 'env, 25 | | ^^^^ required by this bound in `Scope::<'env>::spawn` 26 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-13.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::LCell; 6 | use std::rc::Rc; 7 | struct Marker; 8 | fn is_sync() {} 9 | is_sync::>>(); // Compile fail 10 | } 11 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-13.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Rc<()>` cannot be sent between threads safely 2 | --> src/compiletest/lcell-13.rs:9:15 3 | | 4 | 9 | is_sync::>>(); // Compile fail 5 | | ^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely 6 | | 7 | = help: the trait `Send` is not implemented for `Rc<()>` 8 | = note: required for `LCell<'_, Rc<()>>` to implement `Sync` 9 | note: required by a bound in `is_sync` 10 | --> src/compiletest/lcell-13.rs:8:19 11 | | 12 | 8 | fn is_sync() {} 13 | | ^^^^ required by this bound in `is_sync` 14 | 15 | error[E0277]: `Rc<()>` cannot be shared between threads safely 16 | --> src/compiletest/lcell-13.rs:9:15 17 | | 18 | 9 | is_sync::>>(); // Compile fail 19 | | ^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be shared between threads safely 20 | | 21 | = help: the trait `Sync` is not implemented for `Rc<()>` 22 | = note: required for `LCell<'_, Rc<()>>` to implement `Sync` 23 | note: required by a bound in `is_sync` 24 | --> src/compiletest/lcell-13.rs:8:19 25 | | 26 | 8 | fn is_sync() {} 27 | | ^^^^ required by this bound in `is_sync` 28 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-14.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::LCell; 6 | use std::rc::Rc; 7 | struct Marker; 8 | fn is_send() {} 9 | is_send::>>(); // Compile fail 10 | } 11 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-14.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Rc<()>` cannot be sent between threads safely 2 | --> src/compiletest/lcell-14.rs:9:15 3 | | 4 | 9 | is_send::>>(); // Compile fail 5 | | ^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely 6 | | 7 | = help: within `LCell<'_, Rc<()>>`, the trait `Send` is not implemented for `Rc<()>` 8 | note: required because it appears within the type `UnsafeCell>` 9 | --> $RUST/core/src/cell.rs 10 | | 11 | | pub struct UnsafeCell { 12 | | ^^^^^^^^^^ 13 | note: required because it appears within the type `LCell<'_, Rc<()>>` 14 | --> $QCELL/src/lcell.rs 15 | | 16 | | pub struct LCell<'id, T: ?Sized> { 17 | | ^^^^^ 18 | note: required by a bound in `is_send` 19 | --> src/compiletest/lcell-14.rs:8:19 20 | | 21 | 8 | fn is_send() {} 22 | | ^^^^ required by this bound in `is_send` 23 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-15.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner}; 6 | use std::rc::Rc; 7 | LCellOwner::scope(|owner| { 8 | let cell = LCell::new(Rc::new(100)); 9 | 10 | // We aren't permitted to move the Rc to another thread 11 | crossbeam::scope(move |s| { 12 | s.spawn(move |_| assert_eq!(100, **owner.ro(&cell))).join().unwrap(); // Compile fail 13 | }).unwrap(); 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-15.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Rc` cannot be sent between threads safely 2 | --> src/compiletest/lcell-15.rs:12:21 3 | | 4 | 12 | s.spawn(move |_| assert_eq!(100, **owner.ro(&cell))).join().unwrap(); // Compile fail 5 | | ----- --------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 6 | | | | 7 | | | `Rc` cannot be sent between threads safely 8 | | | within this `[closure@$DIR/src/compiletest/lcell-15.rs:12:21: 12:29]` 9 | | required by a bound introduced by this call 10 | | 11 | = help: within `[closure@$DIR/src/compiletest/lcell-15.rs:12:21: 12:29]`, the trait `Send` is not implemented for `Rc` 12 | note: required because it appears within the type `UnsafeCell>` 13 | --> $RUST/core/src/cell.rs 14 | | 15 | | pub struct UnsafeCell { 16 | | ^^^^^^^^^^ 17 | note: required because it appears within the type `LCell<'_, Rc>` 18 | --> $QCELL/src/lcell.rs 19 | | 20 | | pub struct LCell<'id, T: ?Sized> { 21 | | ^^^^^ 22 | note: required because it's used within this closure 23 | --> src/compiletest/lcell-15.rs:12:21 24 | | 25 | 12 | s.spawn(move |_| assert_eq!(100, **owner.ro(&cell))).join().unwrap(); // Compile fail 26 | | ^^^^^^^^ 27 | note: required by a bound in `crossbeam::thread::Scope::<'env>::spawn` 28 | --> /home/jim/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-utils-0.7.2/src/thread.rs:243:12 29 | | 30 | 240 | pub fn spawn<'scope, F, T>(&'scope self, f: F) -> ScopedJoinHandle<'scope, T> 31 | | ----- required by a bound in this associated function 32 | ... 33 | 243 | F: Send + 'env, 34 | | ^^^^ required by this bound in `Scope::<'env>::spawn` 35 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-16.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner}; 6 | LCellOwner::scope(|owner| { 7 | let mut cell = LCell::new(100); 8 | let cell_ref = cell.get_mut(); 9 | assert_eq!(100, *owner.ro(&cell)); // Compile fail 10 | *cell_ref = 50; 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-16.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `cell` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/lcell-16.rs:9:35 3 | | 4 | 8 | let cell_ref = cell.get_mut(); 5 | | -------------- mutable borrow occurs here 6 | 9 | assert_eq!(100, *owner.ro(&cell)); // Compile fail 7 | | ^^^^^ immutable borrow occurs here 8 | 10 | *cell_ref = 50; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-17.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner}; 6 | LCellOwner::scope(|mut owner| { 7 | let mut cell = LCell::new(100); 8 | let cell_ref = cell.get_mut(); 9 | assert_eq!(100, *owner.rw(&cell)); // Compile fail 10 | *cell_ref = 50; 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-17.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `cell` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/lcell-17.rs:9:35 3 | | 4 | 8 | let cell_ref = cell.get_mut(); 5 | | -------------- mutable borrow occurs here 6 | 9 | assert_eq!(100, *owner.rw(&cell)); // Compile fail 7 | | ^^^^^ immutable borrow occurs here 8 | 10 | *cell_ref = 50; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-18.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner}; 6 | LCellOwner::scope(|owner| { 7 | let mut cell = LCell::new(100); 8 | let cell_ref = owner.ro(&cell); 9 | *cell.get_mut() = 50; // Compile fail 10 | assert_eq!(100, *cell_ref); 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-18.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `cell` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/lcell-18.rs:9:10 3 | | 4 | 8 | let cell_ref = owner.ro(&cell); 5 | | ----- immutable borrow occurs here 6 | 9 | *cell.get_mut() = 50; // Compile fail 7 | | ^^^^^^^^^^^^^^ mutable borrow occurs here 8 | 10 | assert_eq!(100, *cell_ref); 9 | | -------------------------- immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-19.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner}; 6 | LCellOwner::scope(|mut owner| { 7 | let mut cell = LCell::new(100); 8 | let cell_ref = owner.rw(&cell); 9 | *cell.get_mut() = 50; // Compile fail 10 | assert_eq!(100, *cell_ref); 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-19.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `cell` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/lcell-19.rs:9:10 3 | | 4 | 8 | let cell_ref = owner.rw(&cell); 5 | | ----- immutable borrow occurs here 6 | 9 | *cell.get_mut() = 50; // Compile fail 7 | | ^^^^^^^^^^^^^^ mutable borrow occurs here 8 | 10 | assert_eq!(100, *cell_ref); 9 | | -------------------------- immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-20.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner}; 6 | LCellOwner::scope(|mut owner| { 7 | struct NoDefault(i32); 8 | let mut cell: LCell = LCell::default(); // Compile fail 9 | assert_eq!(0, owner.ro(&cell).0); 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell-20.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: the trait bound `NoDefault: Default` is not satisfied 2 | --> src/compiletest/lcell-20.rs:8:42 3 | | 4 | 8 | let mut cell: LCell = LCell::default(); // Compile fail 5 | | ^^^^^^^^^^^^^^ the trait `Default` is not implemented for `NoDefault` 6 | | 7 | = help: the trait `Default` is implemented for `LCell<'id, T>` 8 | = note: required for `LCell<'_, NoDefault>` to implement `Default` 9 | help: consider annotating `NoDefault` with `#[derive(Default)]` 10 | | 11 | 7 + #[derive(Default)] 12 | 8 | struct NoDefault(i32); 13 | | 14 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-00.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner, generativity::make_guard}; 6 | use std::rc::Rc; 7 | make_guard!(guard1); 8 | let mut owner1 = LCellOwner::new(guard1); 9 | let owner2 = owner1; 10 | let rc = Rc::new(owner1.cell(100u32)); // Compile fail 11 | } 12 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-00.stderr: -------------------------------------------------------------------------------- 1 | error[E0382]: borrow of moved value: `owner1` 2 | --> src/compiletest/lcell_generativity-00.rs:10:22 3 | | 4 | 8 | let mut owner1 = LCellOwner::new(guard1); 5 | | ---------- move occurs because `owner1` has type `LCellOwner<'_>`, which does not implement the `Copy` trait 6 | 9 | let owner2 = owner1; 7 | | ------ value moved here 8 | 10 | let rc = Rc::new(owner1.cell(100u32)); // Compile fail 9 | | ^^^^^^^^^^^^^^^^^^^ value borrowed here after move 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-01.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner, generativity::make_guard}; 6 | use std::rc::Rc; 7 | make_guard!(guard1); 8 | let mut owner1 = LCellOwner::new(guard1); 9 | let owner2 = owner1.clone(); // Compile fail 10 | } 11 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-01.stderr: -------------------------------------------------------------------------------- 1 | error[E0599]: no method named `clone` found for struct `LCellOwner` in the current scope 2 | --> src/compiletest/lcell_generativity-01.rs:9:25 3 | | 4 | 9 | let owner2 = owner1.clone(); // Compile fail 5 | | ^^^^^ method not found in `LCellOwner<'_>` 6 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-02.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner, generativity::make_guard}; 6 | use std::rc::Rc; 7 | make_guard!(guard1); 8 | make_guard!(guard2); 9 | let mut owner1 = LCellOwner::new(guard1); 10 | let mut owner2 = LCellOwner::new(guard2); 11 | let c1 = Rc::new(LCell::new(100u32)); 12 | let c1ref1 = owner1.ro(&c1); 13 | let c1ref2 = owner2.ro(&c1); // Compile error 14 | println!("{}", *c1ref2); 15 | } 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-02.stderr: -------------------------------------------------------------------------------- 1 | error[E0597]: `tag` does not live long enough 2 | --> src/compiletest/lcell_generativity-02.rs:8:5 3 | | 4 | 8 | make_guard!(guard2); 5 | | ^^^^^^^^^^^^^^^^^^^ 6 | | | 7 | | borrowed value does not live long enough 8 | | binding `tag` declared here 9 | ... 10 | 15 | } 11 | | - 12 | | | 13 | | `tag` dropped here while still borrowed 14 | | borrow might be used here, when `_guard` is dropped and runs the `Drop` code for type `main::make_guard` 15 | | 16 | = note: values in a scope are dropped in the opposite order they are defined 17 | = note: this error originates in the macro `make_guard` (in Nightly builds, run with -Z macro-backtrace for more info) 18 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-03.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner, generativity::make_guard}; 6 | use std::rc::Rc; 7 | make_guard!(guard1); 8 | make_guard!(guard2); 9 | let mut owner1 = LCellOwner::new(guard1); 10 | let mut owner2 = LCellOwner::new(guard2); 11 | let c1 = Rc::new(owner1.cell(100u32)); 12 | let c1mutref2 = owner2.rw(&c1); // Compile error 13 | println!("{}", *c1mutref2); 14 | } 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-03.stderr: -------------------------------------------------------------------------------- 1 | error[E0597]: `tag` does not live long enough 2 | --> src/compiletest/lcell_generativity-03.rs:8:5 3 | | 4 | 8 | make_guard!(guard2); 5 | | ^^^^^^^^^^^^^^^^^^^ 6 | | | 7 | | borrowed value does not live long enough 8 | | binding `tag` declared here 9 | ... 10 | 14 | } 11 | | - 12 | | | 13 | | `tag` dropped here while still borrowed 14 | | borrow might be used here, when `_guard` is dropped and runs the `Drop` code for type `main::make_guard` 15 | | 16 | = note: values in a scope are dropped in the opposite order they are defined 17 | = note: this error originates in the macro `make_guard` (in Nightly builds, run with -Z macro-backtrace for more info) 18 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-04.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner, generativity::make_guard}; 6 | use std::rc::Rc; 7 | make_guard!(guard); 8 | let mut owner = LCellOwner::new(guard); 9 | let c1 = Rc::new(LCell::new(100u32)); 10 | let c2 = Rc::new(LCell::new(200u32)); 11 | 12 | let c1mutref = owner.rw(&c1); 13 | let c2mutref = owner.rw(&c2); // Compile error 14 | *c1mutref += 1; 15 | *c2mutref += 2; 16 | } 17 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-04.stderr: -------------------------------------------------------------------------------- 1 | error[E0499]: cannot borrow `owner` as mutable more than once at a time 2 | --> src/compiletest/lcell_generativity-04.rs:13:20 3 | | 4 | 12 | let c1mutref = owner.rw(&c1); 5 | | ------------- first mutable borrow occurs here 6 | 13 | let c2mutref = owner.rw(&c2); // Compile error 7 | | ^^^^^^^^^^^^^ second mutable borrow occurs here 8 | 14 | *c1mutref += 1; 9 | | -------------- first borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-05.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner, generativity::make_guard}; 6 | use std::rc::Rc; 7 | make_guard!(guard); 8 | let mut owner = LCellOwner::new(guard); 9 | let c1 = Rc::new(LCell::new(100u32)); 10 | let c2 = Rc::new(LCell::new(200u32)); 11 | let c1ref = owner.ro(&c1); 12 | let c1mutref = owner.rw(&c1); // Compile error 13 | println!("{}", *c1ref); 14 | } 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-05.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/lcell_generativity-05.rs:12:20 3 | | 4 | 11 | let c1ref = owner.ro(&c1); 5 | | ------------- immutable borrow occurs here 6 | 12 | let c1mutref = owner.rw(&c1); // Compile error 7 | | ^^^^^^^^^^^^^ mutable borrow occurs here 8 | 13 | println!("{}", *c1ref); 9 | | ------ immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-06.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner, generativity::make_guard}; 6 | use std::rc::Rc; 7 | make_guard!(guard); 8 | let mut owner = LCellOwner::new(guard); 9 | let c1 = Rc::new(LCell::new(100u32)); 10 | let c2 = Rc::new(LCell::new(200u32)); 11 | let c1mutref = owner.rw(&c1); 12 | let c2ref = owner.ro(&c2); // Compile error 13 | *c1mutref += 1; 14 | } 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-06.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/lcell_generativity-06.rs:12:17 3 | | 4 | 11 | let c1mutref = owner.rw(&c1); 5 | | ------------- mutable borrow occurs here 6 | 12 | let c2ref = owner.ro(&c2); // Compile error 7 | | ^^^^^^^^^^^^^ immutable borrow occurs here 8 | 13 | *c1mutref += 1; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-07.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner, generativity::make_guard}; 6 | use std::rc::Rc; 7 | make_guard!(guard); 8 | let mut owner = LCellOwner::new(guard); 9 | let c1 = Rc::new(LCell::new(100u32)); 10 | let c1ref = owner.ro(&c1); 11 | drop(c1); // Compile error 12 | println!("{}", *c1ref); 13 | } 14 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-07.stderr: -------------------------------------------------------------------------------- 1 | error[E0505]: cannot move out of `c1` because it is borrowed 2 | --> src/compiletest/lcell_generativity-07.rs:11:10 3 | | 4 | 9 | let c1 = Rc::new(LCell::new(100u32)); 5 | | -- binding `c1` declared here 6 | 10 | let c1ref = owner.ro(&c1); 7 | | --- borrow of `c1` occurs here 8 | 11 | drop(c1); // Compile error 9 | | ^^ move out of `c1` occurs here 10 | 12 | println!("{}", *c1ref); 11 | | ------ borrow later used here 12 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-08.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner, generativity::make_guard}; 6 | use std::rc::Rc; 7 | make_guard!(guard); 8 | let mut owner = LCellOwner::new(guard); 9 | let c1 = Rc::new(LCell::new(100u32)); 10 | fn test(o: &mut LCellOwner) {} 11 | 12 | let c1ref = owner.ro(&c1); 13 | test(&mut owner); // Compile error 14 | println!("{}", *c1ref); 15 | } 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-08.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/lcell_generativity-08.rs:13:10 3 | | 4 | 12 | let c1ref = owner.ro(&c1); 5 | | ------------- immutable borrow occurs here 6 | 13 | test(&mut owner); // Compile error 7 | | ^^^^^^^^^^ mutable borrow occurs here 8 | 14 | println!("{}", *c1ref); 9 | | ------ immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-09.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner, generativity::make_guard}; 6 | use std::rc::Rc; 7 | make_guard!(guard); 8 | let mut owner = LCellOwner::new(guard); 9 | let c1 = Rc::new(LCell::new(100u32)); 10 | fn test(o: &LCellOwner) {} 11 | 12 | let c1mutref = owner.rw(&c1); 13 | test(&owner); // Compile error 14 | *c1mutref += 1; 15 | } 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-09.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/lcell_generativity-09.rs:13:10 3 | | 4 | 12 | let c1mutref = owner.rw(&c1); 5 | | ------------- mutable borrow occurs here 6 | 13 | test(&owner); // Compile error 7 | | ^^^^^^ immutable borrow occurs here 8 | 14 | *c1mutref += 1; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-10.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCellOwner, LCell, generativity::make_guard}; 6 | make_guard!(guard); 7 | let mut owner = LCellOwner::new(guard); 8 | let cell = LCell::new(100); 9 | let val_ref = owner.ro(&cell); 10 | crossbeam::scope(move |s| { 11 | s.spawn(move |_| assert_eq!(*owner.ro(&cell), 100)).join().unwrap(); // Compile fail 12 | }).unwrap(); 13 | assert_eq!(*val_ref, 100); 14 | } 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-10.stderr: -------------------------------------------------------------------------------- 1 | error[E0505]: cannot move out of `owner` because it is borrowed 2 | --> src/compiletest/lcell_generativity-10.rs:10:22 3 | | 4 | 7 | let mut owner = LCellOwner::new(guard); 5 | | --------- binding `owner` declared here 6 | 8 | let cell = LCell::new(100); 7 | 9 | let val_ref = owner.ro(&cell); 8 | | --------------- borrow of `owner` occurs here 9 | 10 | crossbeam::scope(move |s| { 10 | | ^^^^^^^^ move out of `owner` occurs here 11 | 11 | s.spawn(move |_| assert_eq!(*owner.ro(&cell), 100)).join().unwrap(); // Compile fail 12 | | ----- move occurs due to use in closure 13 | 12 | }).unwrap(); 14 | 13 | assert_eq!(*val_ref, 100); 15 | | ------------------------- borrow later used here 16 | 17 | error[E0505]: cannot move out of `cell` because it is borrowed 18 | --> src/compiletest/lcell_generativity-10.rs:10:22 19 | | 20 | 8 | let cell = LCell::new(100); 21 | | ---- binding `cell` declared here 22 | 9 | let val_ref = owner.ro(&cell); 23 | | ----- borrow of `cell` occurs here 24 | 10 | crossbeam::scope(move |s| { 25 | | ^^^^^^^^ move out of `cell` occurs here 26 | 11 | s.spawn(move |_| assert_eq!(*owner.ro(&cell), 100)).join().unwrap(); // Compile fail 27 | | ---- move occurs due to use in closure 28 | 12 | }).unwrap(); 29 | 13 | assert_eq!(*val_ref, 100); 30 | | ------------------------- borrow later used here 31 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-11.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::LCell; 6 | use std::cell::Cell; 7 | fn is_sync() {} 8 | is_sync::>>(); // Compile fail 9 | } 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-11.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Cell` cannot be shared between threads safely 2 | --> src/compiletest/lcell_generativity-11.rs:8:15 3 | | 4 | 8 | is_sync::>>(); // Compile fail 5 | | ^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely 6 | | 7 | = help: the trait `Sync` is not implemented for `Cell` 8 | = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead 9 | = note: required for `LCell<'_, Cell>` to implement `Sync` 10 | note: required by a bound in `is_sync` 11 | --> src/compiletest/lcell_generativity-11.rs:7:19 12 | | 13 | 7 | fn is_sync() {} 14 | | ^^^^ required by this bound in `is_sync` 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-12.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner, generativity::make_guard}; 6 | use std::cell::Cell; 7 | make_guard!(guard); 8 | let mut owner = LCellOwner::new(guard); 9 | let cell = LCell::new(Cell::new(100)); 10 | 11 | // This would likely be a data race if it compiled 12 | crossbeam::scope(|s| { // Compile fail 13 | let handle = s.spawn(|_| owner.ro(&cell).set(200)); 14 | owner.ro(&cell).set(300); 15 | handle.join().unwrap(); 16 | }).unwrap(); 17 | } 18 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-12.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Cell` cannot be shared between threads safely 2 | --> src/compiletest/lcell_generativity-12.rs:13:30 3 | | 4 | 13 | let handle = s.spawn(|_| owner.ro(&cell).set(200)); 5 | | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely 6 | | | 7 | | required by a bound introduced by this call 8 | | 9 | = help: the trait `Sync` is not implemented for `Cell` 10 | = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead 11 | = note: required for `LCell<'_, Cell>` to implement `Sync` 12 | = note: required for `&LCell<'_, Cell>` to implement `Send` 13 | note: required because it's used within this closure 14 | --> src/compiletest/lcell_generativity-12.rs:13:30 15 | | 16 | 13 | let handle = s.spawn(|_| owner.ro(&cell).set(200)); 17 | | ^^^ 18 | note: required by a bound in `crossbeam::thread::Scope::<'env>::spawn` 19 | --> /home/jim/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-utils-0.7.2/src/thread.rs:243:12 20 | | 21 | 240 | pub fn spawn<'scope, F, T>(&'scope self, f: F) -> ScopedJoinHandle<'scope, T> 22 | | ----- required by a bound in this associated function 23 | ... 24 | 243 | F: Send + 'env, 25 | | ^^^^ required by this bound in `Scope::<'env>::spawn` 26 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-13.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::LCell; 6 | use std::rc::Rc; 7 | fn is_sync() {} 8 | is_sync::>>(); // Compile fail 9 | } 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-13.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Rc<()>` cannot be sent between threads safely 2 | --> src/compiletest/lcell_generativity-13.rs:8:15 3 | | 4 | 8 | is_sync::>>(); // Compile fail 5 | | ^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely 6 | | 7 | = help: the trait `Send` is not implemented for `Rc<()>` 8 | = note: required for `LCell<'_, Rc<()>>` to implement `Sync` 9 | note: required by a bound in `is_sync` 10 | --> src/compiletest/lcell_generativity-13.rs:7:19 11 | | 12 | 7 | fn is_sync() {} 13 | | ^^^^ required by this bound in `is_sync` 14 | 15 | error[E0277]: `Rc<()>` cannot be shared between threads safely 16 | --> src/compiletest/lcell_generativity-13.rs:8:15 17 | | 18 | 8 | is_sync::>>(); // Compile fail 19 | | ^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be shared between threads safely 20 | | 21 | = help: the trait `Sync` is not implemented for `Rc<()>` 22 | = note: required for `LCell<'_, Rc<()>>` to implement `Sync` 23 | note: required by a bound in `is_sync` 24 | --> src/compiletest/lcell_generativity-13.rs:7:19 25 | | 26 | 7 | fn is_sync() {} 27 | | ^^^^ required by this bound in `is_sync` 28 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-14.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::LCell; 6 | use std::rc::Rc; 7 | fn is_send() {} 8 | is_send::>>(); // Compile fail 9 | } 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-14.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Rc<()>` cannot be sent between threads safely 2 | --> src/compiletest/lcell_generativity-14.rs:8:15 3 | | 4 | 8 | is_send::>>(); // Compile fail 5 | | ^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely 6 | | 7 | = help: within `LCell<'_, Rc<()>>`, the trait `Send` is not implemented for `Rc<()>` 8 | note: required because it appears within the type `UnsafeCell>` 9 | --> $RUST/core/src/cell.rs 10 | | 11 | | pub struct UnsafeCell { 12 | | ^^^^^^^^^^ 13 | note: required because it appears within the type `LCell<'_, Rc<()>>` 14 | --> $QCELL/src/lcell.rs 15 | | 16 | | pub struct LCell<'id, T: ?Sized> { 17 | | ^^^^^ 18 | note: required by a bound in `is_send` 19 | --> src/compiletest/lcell_generativity-14.rs:7:19 20 | | 21 | 7 | fn is_send() {} 22 | | ^^^^ required by this bound in `is_send` 23 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-15.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{LCell, LCellOwner, generativity::make_guard}; 6 | use std::rc::Rc; 7 | make_guard!(guard); 8 | let mut owner = LCellOwner::new(guard); 9 | let cell = LCell::new(Rc::new(100)); 10 | 11 | // We aren't permitted to move the Rc to another thread 12 | crossbeam::scope(move |s| { 13 | s.spawn(move |_| assert_eq!(100, **owner.ro(&cell))).join().unwrap(); // Compile fail 14 | }).unwrap(); 15 | } 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/lcell_generativity-15.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Rc` cannot be sent between threads safely 2 | --> src/compiletest/lcell_generativity-15.rs:13:17 3 | | 4 | 13 | s.spawn(move |_| assert_eq!(100, **owner.ro(&cell))).join().unwrap(); // Compile fail 5 | | ----- --------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 6 | | | | 7 | | | `Rc` cannot be sent between threads safely 8 | | | within this `[closure@$DIR/src/compiletest/lcell_generativity-15.rs:13:17: 13:25]` 9 | | required by a bound introduced by this call 10 | | 11 | = help: within `[closure@$DIR/src/compiletest/lcell_generativity-15.rs:13:17: 13:25]`, the trait `Send` is not implemented for `Rc` 12 | note: required because it appears within the type `UnsafeCell>` 13 | --> $RUST/core/src/cell.rs 14 | | 15 | | pub struct UnsafeCell { 16 | | ^^^^^^^^^^ 17 | note: required because it appears within the type `LCell<'_, Rc>` 18 | --> $QCELL/src/lcell.rs 19 | | 20 | | pub struct LCell<'id, T: ?Sized> { 21 | | ^^^^^ 22 | note: required because it's used within this closure 23 | --> src/compiletest/lcell_generativity-15.rs:13:17 24 | | 25 | 13 | s.spawn(move |_| assert_eq!(100, **owner.ro(&cell))).join().unwrap(); // Compile fail 26 | | ^^^^^^^^ 27 | note: required by a bound in `crossbeam::thread::Scope::<'env>::spawn` 28 | --> /home/jim/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-utils-0.7.2/src/thread.rs:243:12 29 | | 30 | 240 | pub fn spawn<'scope, F, T>(&'scope self, f: F) -> ScopedJoinHandle<'scope, T> 31 | | ----- required by a bound in this associated function 32 | ... 33 | 243 | F: Send + 'env, 34 | | ^^^^ required by this bound in `Scope::<'env>::spawn` 35 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-00.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwner}; 6 | use std::rc::Rc; 7 | let mut owner1 = QCellOwner::new(); 8 | let mut owner2 = owner1; 9 | let rc = Rc::new(QCell::new(&owner1, 100u32)); // Compile fail 10 | } 11 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-00.stderr: -------------------------------------------------------------------------------- 1 | error[E0382]: borrow of moved value: `owner1` 2 | --> src/compiletest/qcell-00.rs:9:33 3 | | 4 | 7 | let mut owner1 = QCellOwner::new(); 5 | | ---------- move occurs because `owner1` has type `QCellOwner`, which does not implement the `Copy` trait 6 | 8 | let mut owner2 = owner1; 7 | | ------ value moved here 8 | 9 | let rc = Rc::new(QCell::new(&owner1, 100u32)); // Compile fail 9 | | ^^^^^^^ value borrowed here after move 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-01.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwner}; 6 | use std::rc::Rc; 7 | let mut owner1 = QCellOwner::new(); 8 | let owner2 = owner1.clone(); // Compile fail 9 | } 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-01.stderr: -------------------------------------------------------------------------------- 1 | error[E0599]: no method named `clone` found for struct `QCellOwner` in the current scope 2 | --> src/compiletest/qcell-01.rs:8:25 3 | | 4 | 8 | let owner2 = owner1.clone(); // Compile fail 5 | | ^^^^^ method not found in `QCellOwner` 6 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-02.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwner}; 6 | use std::rc::Rc; 7 | let mut owner = QCellOwner::new(); 8 | let c1 = Rc::new(QCell::new(&owner, 100u32)); 9 | let c2 = Rc::new(QCell::new(&owner, 200u32)); 10 | 11 | let c1mutref = owner.rw(&c1); 12 | let c2mutref= owner.rw(&c2); // Compile error 13 | *c1mutref += 1; 14 | *c2mutref += 2; 15 | } 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-02.stderr: -------------------------------------------------------------------------------- 1 | error[E0499]: cannot borrow `owner` as mutable more than once at a time 2 | --> src/compiletest/qcell-02.rs:12:20 3 | | 4 | 11 | let c1mutref = owner.rw(&c1); 5 | | ------------- first mutable borrow occurs here 6 | 12 | let c2mutref= owner.rw(&c2); // Compile error 7 | | ^^^^^^^^^^^^^ second mutable borrow occurs here 8 | 13 | *c1mutref += 1; 9 | | -------------- first borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-03.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwner}; 6 | use std::rc::Rc; 7 | let mut owner = QCellOwner::new(); 8 | let c1 = Rc::new(QCell::new(&owner, 100u32)); 9 | let c2 = Rc::new(QCell::new(&owner, 200u32)); 10 | let c1ref = owner.ro(&c1); 11 | let c1mutref = owner.rw(&c1); // Compile error 12 | println!("{}", *c1ref); 13 | } 14 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-03.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/qcell-03.rs:11:20 3 | | 4 | 10 | let c1ref = owner.ro(&c1); 5 | | ------------- immutable borrow occurs here 6 | 11 | let c1mutref = owner.rw(&c1); // Compile error 7 | | ^^^^^^^^^^^^^ mutable borrow occurs here 8 | 12 | println!("{}", *c1ref); 9 | | ------ immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-04.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwner}; 6 | use std::rc::Rc; 7 | let mut owner = QCellOwner::new(); 8 | let c1 = Rc::new(QCell::new(&owner, 100u32)); 9 | let c2 = Rc::new(QCell::new(&owner, 200u32)); 10 | let c1mutref = owner.rw(&c1); 11 | let c2ref = owner.ro(&c2); // Compile error 12 | *c1mutref += 1; 13 | } 14 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-04.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/qcell-04.rs:11:17 3 | | 4 | 10 | let c1mutref = owner.rw(&c1); 5 | | ------------- mutable borrow occurs here 6 | 11 | let c2ref = owner.ro(&c2); // Compile error 7 | | ^^^^^^^^^^^^^ immutable borrow occurs here 8 | 12 | *c1mutref += 1; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-05.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwner}; 6 | use std::rc::Rc; 7 | let mut owner = QCellOwner::new(); 8 | let c1 = Rc::new(QCell::new(&owner, 100u32)); 9 | let c2 = Rc::new(QCell::new(&owner, 200u32)); 10 | let c1ref = owner.ro(&c1); 11 | drop(c1); // Compile error 12 | println!("{}", *c1ref); 13 | } 14 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-05.stderr: -------------------------------------------------------------------------------- 1 | error[E0505]: cannot move out of `c1` because it is borrowed 2 | --> src/compiletest/qcell-05.rs:11:10 3 | | 4 | 8 | let c1 = Rc::new(QCell::new(&owner, 100u32)); 5 | | -- binding `c1` declared here 6 | 9 | let c2 = Rc::new(QCell::new(&owner, 200u32)); 7 | 10 | let c1ref = owner.ro(&c1); 8 | | --- borrow of `c1` occurs here 9 | 11 | drop(c1); // Compile error 10 | | ^^ move out of `c1` occurs here 11 | 12 | println!("{}", *c1ref); 12 | | ------ borrow later used here 13 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-06.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwner}; 6 | use std::rc::Rc; 7 | let mut owner = QCellOwner::new(); 8 | let c1 = Rc::new(QCell::new(&owner, 100u32)); 9 | let c2 = Rc::new(QCell::new(&owner, 200u32)); 10 | fn test(o: &mut QCellOwner) {} 11 | 12 | let c1ref = owner.ro(&c1); 13 | test(&mut owner); // Compile error 14 | println!("{}", *c1ref); 15 | } 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-06.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/qcell-06.rs:13:10 3 | | 4 | 12 | let c1ref = owner.ro(&c1); 5 | | ------------- immutable borrow occurs here 6 | 13 | test(&mut owner); // Compile error 7 | | ^^^^^^^^^^ mutable borrow occurs here 8 | 14 | println!("{}", *c1ref); 9 | | ------ immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-07.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwner}; 6 | use std::rc::Rc; 7 | let mut owner = QCellOwner::new(); 8 | let c1 = Rc::new(QCell::new(&owner, 100u32)); 9 | let c2 = Rc::new(QCell::new(&owner, 200u32)); 10 | fn test(o: &QCellOwner) {} 11 | 12 | let c1mutref = owner.rw(&c1); 13 | test(&owner); // Compile error 14 | *c1mutref += 1; 15 | } 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-07.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/qcell-07.rs:13:10 3 | | 4 | 12 | let c1mutref = owner.rw(&c1); 5 | | ------------- mutable borrow occurs here 6 | 13 | test(&owner); // Compile error 7 | | ^^^^^^ immutable borrow occurs here 8 | 14 | *c1mutref += 1; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-08.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCellOwner, QCell}; 6 | let owner = QCellOwner::new(); 7 | let cell = QCell::new(&owner, 100); 8 | let val_ref = owner.ro(&cell); 9 | std::thread::spawn(move || { 10 | assert_eq!(*owner.ro(&cell), 100); 11 | }).join(); 12 | assert_eq!(*val_ref, 100); 13 | } 14 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-08.stderr: -------------------------------------------------------------------------------- 1 | error[E0505]: cannot move out of `owner` because it is borrowed 2 | --> src/compiletest/qcell-08.rs:9:24 3 | | 4 | 6 | let owner = QCellOwner::new(); 5 | | ----- binding `owner` declared here 6 | 7 | let cell = QCell::new(&owner, 100); 7 | 8 | let val_ref = owner.ro(&cell); 8 | | --------------- borrow of `owner` occurs here 9 | 9 | std::thread::spawn(move || { 10 | | ^^^^^^^ move out of `owner` occurs here 11 | 10 | assert_eq!(*owner.ro(&cell), 100); 12 | | ----- move occurs due to use in closure 13 | 11 | }).join(); 14 | 12 | assert_eq!(*val_ref, 100); 15 | | ------------------------- borrow later used here 16 | 17 | error[E0505]: cannot move out of `cell` because it is borrowed 18 | --> src/compiletest/qcell-08.rs:9:24 19 | | 20 | 7 | let cell = QCell::new(&owner, 100); 21 | | ---- binding `cell` declared here 22 | 8 | let val_ref = owner.ro(&cell); 23 | | ----- borrow of `cell` occurs here 24 | 9 | std::thread::spawn(move || { 25 | | ^^^^^^^ move out of `cell` occurs here 26 | 10 | assert_eq!(*owner.ro(&cell), 100); 27 | | ---- move occurs due to use in closure 28 | 11 | }).join(); 29 | 12 | assert_eq!(*val_ref, 100); 30 | | ------------------------- borrow later used here 31 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-09.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::QCell; 6 | use std::cell::Cell; 7 | fn is_sync() {} 8 | is_sync::>>(); // Compile fail 9 | } 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-09.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Cell` cannot be shared between threads safely 2 | --> src/compiletest/qcell-09.rs:8:15 3 | | 4 | 8 | is_sync::>>(); // Compile fail 5 | | ^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely 6 | | 7 | = help: the trait `Sync` is not implemented for `Cell` 8 | = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead 9 | = note: required for `QCell>` to implement `Sync` 10 | note: required by a bound in `is_sync` 11 | --> src/compiletest/qcell-09.rs:7:19 12 | | 13 | 7 | fn is_sync() {} 14 | | ^^^^ required by this bound in `is_sync` 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-10.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwner}; 6 | use std::cell::Cell; 7 | let owner = QCellOwner::new(); 8 | let cell = QCell::new(&owner, Cell::new(100)); 9 | 10 | // This would be a data race if the compiler permitted it, but it doesn't 11 | std::thread::spawn(|| owner.ro(&cell).set(200)); // Compile fail 12 | owner.ro(&cell).set(300); 13 | } 14 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-10.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Cell` cannot be shared between threads safely 2 | --> src/compiletest/qcell-10.rs:11:24 3 | | 4 | 11 | std::thread::spawn(|| owner.ro(&cell).set(200)); // Compile fail 5 | | ------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely 6 | | | 7 | | required by a bound introduced by this call 8 | | 9 | = help: the trait `Sync` is not implemented for `Cell` 10 | = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead 11 | = note: required for `QCell>` to implement `Sync` 12 | = note: required for `&QCell>` to implement `Send` 13 | note: required because it's used within this closure 14 | --> src/compiletest/qcell-10.rs:11:24 15 | | 16 | 11 | std::thread::spawn(|| owner.ro(&cell).set(200)); // Compile fail 17 | | ^^ 18 | note: required by a bound in `spawn` 19 | --> $RUST/std/src/thread/mod.rs 20 | | 21 | | pub fn spawn(f: F) -> JoinHandle 22 | | ----- required by a bound in this function 23 | ... 24 | | F: Send + 'static, 25 | | ^^^^ required by this bound in `spawn` 26 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-11.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::QCell; 6 | use std::rc::Rc; 7 | fn is_sync() {} 8 | is_sync::>>(); // Compile fail 9 | } 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-11.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Rc<()>` cannot be sent between threads safely 2 | --> src/compiletest/qcell-11.rs:8:15 3 | | 4 | 8 | is_sync::>>(); // Compile fail 5 | | ^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely 6 | | 7 | = help: the trait `Send` is not implemented for `Rc<()>` 8 | = note: required for `QCell>` to implement `Sync` 9 | note: required by a bound in `is_sync` 10 | --> src/compiletest/qcell-11.rs:7:19 11 | | 12 | 7 | fn is_sync() {} 13 | | ^^^^ required by this bound in `is_sync` 14 | 15 | error[E0277]: `Rc<()>` cannot be shared between threads safely 16 | --> src/compiletest/qcell-11.rs:8:15 17 | | 18 | 8 | is_sync::>>(); // Compile fail 19 | | ^^^^^^^^^^^^^ `Rc<()>` cannot be shared between threads safely 20 | | 21 | = help: the trait `Sync` is not implemented for `Rc<()>` 22 | = note: required for `QCell>` to implement `Sync` 23 | note: required by a bound in `is_sync` 24 | --> src/compiletest/qcell-11.rs:7:19 25 | | 26 | 7 | fn is_sync() {} 27 | | ^^^^ required by this bound in `is_sync` 28 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-12.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::QCell; 6 | use std::rc::Rc; 7 | fn is_send() {} 8 | is_send::>>(); // Compile fail 9 | } 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-12.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Rc<()>` cannot be sent between threads safely 2 | --> src/compiletest/qcell-12.rs:8:15 3 | | 4 | 8 | is_send::>>(); // Compile fail 5 | | ^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely 6 | | 7 | = help: within `QCell>`, the trait `Send` is not implemented for `Rc<()>` 8 | note: required because it appears within the type `UnsafeCell>` 9 | --> $RUST/core/src/cell.rs 10 | | 11 | | pub struct UnsafeCell { 12 | | ^^^^^^^^^^ 13 | note: required because it appears within the type `QCell>` 14 | --> $QCELL/src/qcell.rs 15 | | 16 | | pub struct QCell { 17 | | ^^^^^ 18 | note: required by a bound in `is_send` 19 | --> src/compiletest/qcell-12.rs:7:19 20 | | 21 | 7 | fn is_send() {} 22 | | ^^^^ required by this bound in `is_send` 23 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-13.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwner}; 6 | use std::rc::Rc; 7 | let owner = QCellOwner::new(); 8 | let cell = QCell::new(&owner, Rc::new(100)); 9 | 10 | // We aren't permitted to move the Rc to another thread 11 | std::thread::spawn(move || { // Compile fail 12 | assert_eq!(100, **owner.ro(&cell)); 13 | }).join(); 14 | } 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-13.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Rc` cannot be sent between threads safely 2 | --> src/compiletest/qcell-13.rs:11:24 3 | | 4 | 11 | std::thread::spawn(move || { // Compile fail 5 | | ------------------ ^------ 6 | | | | 7 | | _____|__________________within this `[closure@$DIR/src/compiletest/qcell-13.rs:11:24: 11:31]` 8 | | | | 9 | | | required by a bound introduced by this call 10 | 12 | | assert_eq!(100, **owner.ro(&cell)); 11 | 13 | | }).join(); 12 | | |_____^ `Rc` cannot be sent between threads safely 13 | | 14 | = help: within `[closure@$DIR/src/compiletest/qcell-13.rs:11:24: 11:31]`, the trait `Send` is not implemented for `Rc` 15 | note: required because it appears within the type `UnsafeCell>` 16 | --> $RUST/core/src/cell.rs 17 | | 18 | | pub struct UnsafeCell { 19 | | ^^^^^^^^^^ 20 | note: required because it appears within the type `QCell>` 21 | --> $QCELL/src/qcell.rs 22 | | 23 | | pub struct QCell { 24 | | ^^^^^ 25 | note: required because it's used within this closure 26 | --> src/compiletest/qcell-13.rs:11:24 27 | | 28 | 11 | std::thread::spawn(move || { // Compile fail 29 | | ^^^^^^^ 30 | note: required by a bound in `spawn` 31 | --> $RUST/std/src/thread/mod.rs 32 | | 33 | | pub fn spawn(f: F) -> JoinHandle 34 | | ----- required by a bound in this function 35 | ... 36 | | F: Send + 'static, 37 | | ^^^^ required by this bound in `spawn` 38 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-14.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwner}; 6 | let owner = QCellOwner::new(); 7 | let mut cell = QCell::new(&owner, 100); 8 | let cell_ref = cell.get_mut(); 9 | assert_eq!(100, *owner.ro(&cell)); // Compile fail 10 | *cell_ref = 50; 11 | } 12 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-14.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `cell` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/qcell-14.rs:9:31 3 | | 4 | 8 | let cell_ref = cell.get_mut(); 5 | | -------------- mutable borrow occurs here 6 | 9 | assert_eq!(100, *owner.ro(&cell)); // Compile fail 7 | | ^^^^^ immutable borrow occurs here 8 | 10 | *cell_ref = 50; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-15.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwner}; 6 | let mut owner = QCellOwner::new(); 7 | let mut cell = QCell::new(&owner, 100); 8 | let cell_ref = cell.get_mut(); 9 | assert_eq!(100, *owner.rw(&cell)); // Compile fail 10 | *cell_ref = 50; 11 | } 12 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-15.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `cell` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/qcell-15.rs:9:31 3 | | 4 | 8 | let cell_ref = cell.get_mut(); 5 | | -------------- mutable borrow occurs here 6 | 9 | assert_eq!(100, *owner.rw(&cell)); // Compile fail 7 | | ^^^^^ immutable borrow occurs here 8 | 10 | *cell_ref = 50; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-16.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwner}; 6 | let owner = QCellOwner::new(); 7 | let mut cell = QCell::new(&owner, 100); 8 | let cell_ref = owner.ro(&cell); 9 | *cell.get_mut() = 50; // Compile fail 10 | assert_eq!(100, *cell_ref); 11 | } 12 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-16.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `cell` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/qcell-16.rs:9:6 3 | | 4 | 8 | let cell_ref = owner.ro(&cell); 5 | | ----- immutable borrow occurs here 6 | 9 | *cell.get_mut() = 50; // Compile fail 7 | | ^^^^^^^^^^^^^^ mutable borrow occurs here 8 | 10 | assert_eq!(100, *cell_ref); 9 | | -------------------------- immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-17.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwner}; 6 | let mut owner = QCellOwner::new(); 7 | let mut cell = QCell::new(&owner, 100); 8 | let cell_ref = owner.rw(&cell); 9 | *cell.get_mut() = 50; // Compile fail 10 | assert_eq!(100, *cell_ref); 11 | } 12 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-17.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `cell` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/qcell-17.rs:9:6 3 | | 4 | 8 | let cell_ref = owner.rw(&cell); 5 | | ----- immutable borrow occurs here 6 | 9 | *cell.get_mut() = 50; // Compile fail 7 | | ^^^^^^^^^^^^^^ mutable borrow occurs here 8 | 10 | assert_eq!(100, *cell_ref); 9 | | -------------------------- immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-18.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::QCell; 6 | let mut cell: QCell = QCell::default(); 7 | } 8 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell-18.stderr: -------------------------------------------------------------------------------- 1 | error[E0599]: no function or associated item named `default` found for struct `QCell` in the current scope 2 | --> src/compiletest/qcell-18.rs:6:39 3 | | 4 | 6 | let mut cell: QCell = QCell::default(); 5 | | ^^^^^^^ function or associated item not found in `QCell<_>` 6 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-00.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwnerPinned}; 6 | let mut owner1 = QCellOwnerPinned::new(); 7 | let id = owner1.id(); 8 | } 9 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-00.stderr: -------------------------------------------------------------------------------- 1 | error[E0599]: no method named `id` found for struct `QCellOwnerPinned` in the current scope 2 | --> src/compiletest/qcell_noalloc-00.rs:7:21 3 | | 4 | 7 | let id = owner1.id(); 5 | | ^^ method not found in `QCellOwnerPinned` 6 | | 7 | ::: $QCELL/src/qcell.rs 8 | | 9 | | pub fn id(self: Pin<&Self>) -> QCellOwnerID { 10 | | -- the method is available for `Pin<&QCellOwnerPinned>` here 11 | | 12 | help: consider wrapping the receiver expression with the appropriate type 13 | | 14 | 7 | let id = Pin::new(&owner1).id(); 15 | | ++++++++++ + 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-01.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::QCellOwnerPinned; 6 | fn is_unpin() {} 7 | is_unpin::(); 8 | } 9 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-01.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `PhantomPinned` cannot be unpinned 2 | --> src/compiletest/qcell_noalloc-01.rs:7:16 3 | | 4 | 7 | is_unpin::(); 5 | | ^^^^^^^^^^^^^^^^ within `QCellOwnerPinned`, the trait `Unpin` is not implemented for `PhantomPinned` 6 | | 7 | = note: consider using the `pin!` macro 8 | consider using `Box::pin` if you need to access the pinned value outside of the current scope 9 | note: required because it appears within the type `QCellOwnerPinned` 10 | --> $QCELL/src/qcell.rs 11 | | 12 | | pub struct QCellOwnerPinned { 13 | | ^^^^^^^^^^^^^^^^ 14 | note: required by a bound in `is_unpin` 15 | --> src/compiletest/qcell_noalloc-01.rs:6:20 16 | | 17 | 6 | fn is_unpin() {} 18 | | ^^^^^ required by this bound in `is_unpin` 19 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-02.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwnerPinned}; 6 | use std::rc::Rc; 7 | use pin_utils::pin_mut; 8 | let mut owner1 = QCellOwnerPinned::new(); 9 | let mut owner2 = owner1; 10 | pin_mut!(owner1); // Compile fail 11 | let rc = Rc::new(owner1.as_ref().cell(100u32)); 12 | } 13 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-02.stderr: -------------------------------------------------------------------------------- 1 | error[E0382]: use of moved value: `owner1` 2 | --> src/compiletest/qcell_noalloc-02.rs:10:5 3 | | 4 | 8 | let mut owner1 = QCellOwnerPinned::new(); 5 | | ---------- move occurs because `owner1` has type `QCellOwnerPinned`, which does not implement the `Copy` trait 6 | 9 | let mut owner2 = owner1; 7 | | ------ value moved here 8 | 10 | pin_mut!(owner1); // Compile fail 9 | | ^^^^^^^^^^^^^^^^ value used here after move 10 | | 11 | = note: this error originates in the macro `pin_mut` (in Nightly builds, run with -Z macro-backtrace for more info) 12 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-03.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwnerPinned}; 6 | use std::rc::Rc; 7 | use pin_utils::pin_mut; 8 | let mut owner1 = QCellOwnerPinned::new(); 9 | pin_mut!(owner1); 10 | let mut owner2 = owner1; 11 | let rc = Rc::new(owner1.as_ref().cell(100u32)); // Compile fail 12 | } 13 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-03.stderr: -------------------------------------------------------------------------------- 1 | error[E0382]: borrow of moved value: `owner1` 2 | --> src/compiletest/qcell_noalloc-03.rs:11:22 3 | | 4 | 9 | pin_mut!(owner1); 5 | | ---------------- move occurs because `owner1` has type `Pin<&mut QCellOwnerPinned>`, which does not implement the `Copy` trait 6 | 10 | let mut owner2 = owner1; 7 | | ------ value moved here 8 | 11 | let rc = Rc::new(owner1.as_ref().cell(100u32)); // Compile fail 9 | | ^^^^^^^^^^^^^^^ value borrowed here after move 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-04.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwnerPinned}; 6 | use std::rc::Rc; 7 | let mut owner1 = QCellOwnerPinned::new(); 8 | let owner2 = owner1.clone(); // Compile fail 9 | } 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-04.stderr: -------------------------------------------------------------------------------- 1 | error[E0599]: no method named `clone` found for struct `QCellOwnerPinned` in the current scope 2 | --> src/compiletest/qcell_noalloc-04.rs:8:25 3 | | 4 | 8 | let owner2 = owner1.clone(); // Compile fail 5 | | ^^^^^ method not found in `QCellOwnerPinned` 6 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-05.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwnerPinned}; 6 | use std::rc::Rc; 7 | use pin_utils::pin_mut; 8 | let mut owner1 = QCellOwnerPinned::new(); 9 | pin_mut!(owner1); 10 | let owner2 = owner1.clone(); // Compile fail 11 | } 12 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-05.stderr: -------------------------------------------------------------------------------- 1 | error[E0599]: the method `clone` exists for struct `Pin<&mut QCellOwnerPinned>`, but its trait bounds were not satisfied 2 | --> src/compiletest/qcell_noalloc-05.rs:10:25 3 | | 4 | 10 | let owner2 = owner1.clone(); // Compile fail 5 | | ^^^^^ method cannot be called on `Pin<&mut QCellOwnerPinned>` due to unsatisfied trait bounds 6 | | 7 | ::: $RUST/core/src/pin.rs 8 | | 9 | | pub struct Pin

{ 10 | | ----------------- doesn't satisfy `Pin<&mut QCellOwnerPinned>: Clone` 11 | | 12 | = note: the following trait bounds were not satisfied: 13 | `&mut QCellOwnerPinned: Clone` 14 | which is required by `Pin<&mut QCellOwnerPinned>: Clone` 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-06.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwnerPinned}; 6 | use std::rc::Rc; 7 | use pin_utils::pin_mut; 8 | let mut owner = QCellOwnerPinned::new(); 9 | pin_mut!(owner); 10 | let c1 = Rc::new(owner.as_ref().cell(100u32)); 11 | let c2 = Rc::new(owner.as_ref().cell(200u32)); 12 | 13 | let c1mutref = owner.as_mut().rw(&c1); 14 | let c2mutref= owner.as_mut().rw(&c2); // Compile error 15 | *c1mutref += 1; 16 | *c2mutref += 2; 17 | } 18 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-06.stderr: -------------------------------------------------------------------------------- 1 | error[E0499]: cannot borrow `owner` as mutable more than once at a time 2 | --> src/compiletest/qcell_noalloc-06.rs:14:20 3 | | 4 | 13 | let c1mutref = owner.as_mut().rw(&c1); 5 | | -------------- first mutable borrow occurs here 6 | 14 | let c2mutref= owner.as_mut().rw(&c2); // Compile error 7 | | ^^^^^^^^^^^^^^ second mutable borrow occurs here 8 | 15 | *c1mutref += 1; 9 | | -------------- first borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-07.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwnerPinned}; 6 | use std::rc::Rc; 7 | use pin_utils::pin_mut; 8 | let mut owner = QCellOwnerPinned::new(); 9 | pin_mut!(owner); 10 | let c1 = Rc::new(owner.as_ref().cell(100u32)); 11 | let c2 = Rc::new(owner.as_ref().cell(200u32)); 12 | let c1ref = owner.as_ref().ro(&c1); 13 | let c1mutref = owner.as_mut().rw(&c1); // Compile error 14 | println!("{}", *c1ref); 15 | } 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-07.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/qcell_noalloc-07.rs:13:20 3 | | 4 | 12 | let c1ref = owner.as_ref().ro(&c1); 5 | | -------------- immutable borrow occurs here 6 | 13 | let c1mutref = owner.as_mut().rw(&c1); // Compile error 7 | | ^^^^^^^^^^^^^^ mutable borrow occurs here 8 | 14 | println!("{}", *c1ref); 9 | | ------ immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-08.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwnerPinned}; 6 | use std::rc::Rc; 7 | use pin_utils::pin_mut; 8 | let mut owner = QCellOwnerPinned::new(); 9 | pin_mut!(owner); 10 | let c1 = Rc::new(owner.as_ref().cell(100u32)); 11 | let c2 = Rc::new(owner.as_ref().cell(200u32)); 12 | let c1mutref = owner.as_mut().rw(&c1); 13 | let c2ref = owner.as_ref().ro(&c2); // Compile error 14 | *c1mutref += 1; 15 | } 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-08.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/qcell_noalloc-08.rs:13:17 3 | | 4 | 12 | let c1mutref = owner.as_mut().rw(&c1); 5 | | -------------- mutable borrow occurs here 6 | 13 | let c2ref = owner.as_ref().ro(&c2); // Compile error 7 | | ^^^^^^^^^^^^^^ immutable borrow occurs here 8 | 14 | *c1mutref += 1; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-09.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwnerPinned}; 6 | use std::rc::Rc; 7 | use pin_utils::pin_mut; 8 | let mut owner = QCellOwnerPinned::new(); 9 | pin_mut!(owner); 10 | let c1 = Rc::new(owner.as_ref().cell(100u32)); 11 | let c2 = Rc::new(owner.as_ref().cell(200u32)); 12 | let c1ref = owner.as_ref().ro(&c1); 13 | drop(c1); // Compile error 14 | println!("{}", *c1ref); 15 | } 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-09.stderr: -------------------------------------------------------------------------------- 1 | error[E0505]: cannot move out of `c1` because it is borrowed 2 | --> src/compiletest/qcell_noalloc-09.rs:13:10 3 | | 4 | 10 | let c1 = Rc::new(owner.as_ref().cell(100u32)); 5 | | -- binding `c1` declared here 6 | 11 | let c2 = Rc::new(owner.as_ref().cell(200u32)); 7 | 12 | let c1ref = owner.as_ref().ro(&c1); 8 | | --- borrow of `c1` occurs here 9 | 13 | drop(c1); // Compile error 10 | | ^^ move out of `c1` occurs here 11 | 14 | println!("{}", *c1ref); 12 | | ------ borrow later used here 13 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-10.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwnerPinned}; 6 | use std::{rc::Rc, pin::Pin}; 7 | use pin_utils::pin_mut; 8 | let mut owner = QCellOwnerPinned::new(); 9 | pin_mut!(owner); 10 | let c1 = Rc::new(owner.as_ref().cell(100u32)); 11 | let c2 = Rc::new(owner.as_ref().cell(200u32)); 12 | fn test(o: Pin<&mut QCellOwnerPinned>) {} 13 | 14 | let c1ref = owner.as_ref().ro(&c1); 15 | test(owner.as_mut()); // Compile error 16 | println!("{}", *c1ref); 17 | } 18 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-10.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/qcell_noalloc-10.rs:15:10 3 | | 4 | 14 | let c1ref = owner.as_ref().ro(&c1); 5 | | -------------- immutable borrow occurs here 6 | 15 | test(owner.as_mut()); // Compile error 7 | | ^^^^^^^^^^^^^^ mutable borrow occurs here 8 | 16 | println!("{}", *c1ref); 9 | | ------ immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-11.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwnerPinned}; 6 | use std::{rc::Rc, pin::Pin}; 7 | use pin_utils::pin_mut; 8 | let mut owner = QCellOwnerPinned::new(); 9 | pin_mut!(owner); 10 | let c1 = Rc::new(owner.as_ref().cell(100u32)); 11 | let c2 = Rc::new(owner.as_ref().cell(200u32)); 12 | fn test(o: Pin<&QCellOwnerPinned>) {} 13 | 14 | let c1mutref = owner.as_mut().rw(&c1); 15 | test(owner.as_ref()); // Compile error 16 | *c1mutref += 1; 17 | } 18 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-11.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/qcell_noalloc-11.rs:15:10 3 | | 4 | 14 | let c1mutref = owner.as_mut().rw(&c1); 5 | | -------------- mutable borrow occurs here 6 | 15 | test(owner.as_ref()); // Compile error 7 | | ^^^^^^^^^^^^^^ immutable borrow occurs here 8 | 16 | *c1mutref += 1; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-12.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCellOwnerPinned, QCell}; 6 | let mut owner = Box::pin(QCellOwnerPinned::new()); 7 | let cell = owner.as_ref().cell(100); 8 | let val_ref = owner.as_ref().ro(&cell); 9 | std::thread::spawn(move || { 10 | assert_eq!(*owner.as_ref().ro(&cell), 100); 11 | }).join(); 12 | assert_eq!(*val_ref, 100); 13 | } 14 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-12.stderr: -------------------------------------------------------------------------------- 1 | error[E0505]: cannot move out of `owner` because it is borrowed 2 | --> src/compiletest/qcell_noalloc-12.rs:9:24 3 | | 4 | 6 | let mut owner = Box::pin(QCellOwnerPinned::new()); 5 | | --------- binding `owner` declared here 6 | 7 | let cell = owner.as_ref().cell(100); 7 | 8 | let val_ref = owner.as_ref().ro(&cell); 8 | | -------------- borrow of `owner` occurs here 9 | 9 | std::thread::spawn(move || { 10 | | ^^^^^^^ move out of `owner` occurs here 11 | 10 | assert_eq!(*owner.as_ref().ro(&cell), 100); 12 | | ----- move occurs due to use in closure 13 | 11 | }).join(); 14 | 12 | assert_eq!(*val_ref, 100); 15 | | ------------------------- borrow later used here 16 | 17 | error[E0505]: cannot move out of `cell` because it is borrowed 18 | --> src/compiletest/qcell_noalloc-12.rs:9:24 19 | | 20 | 7 | let cell = owner.as_ref().cell(100); 21 | | ---- binding `cell` declared here 22 | 8 | let val_ref = owner.as_ref().ro(&cell); 23 | | ----- borrow of `cell` occurs here 24 | 9 | std::thread::spawn(move || { 25 | | ^^^^^^^ move out of `cell` occurs here 26 | 10 | assert_eq!(*owner.as_ref().ro(&cell), 100); 27 | | ---- move occurs due to use in closure 28 | 11 | }).join(); 29 | 12 | assert_eq!(*val_ref, 100); 30 | | ------------------------- borrow later used here 31 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-13.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::QCell; 6 | use std::cell::Cell; 7 | fn is_sync() {} 8 | is_sync::>>(); // Compile fail 9 | } 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-13.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Cell` cannot be shared between threads safely 2 | --> src/compiletest/qcell_noalloc-13.rs:8:15 3 | | 4 | 8 | is_sync::>>(); // Compile fail 5 | | ^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely 6 | | 7 | = help: the trait `Sync` is not implemented for `Cell` 8 | = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead 9 | = note: required for `QCell>` to implement `Sync` 10 | note: required by a bound in `is_sync` 11 | --> src/compiletest/qcell_noalloc-13.rs:7:19 12 | | 13 | 7 | fn is_sync() {} 14 | | ^^^^ required by this bound in `is_sync` 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-14.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::QCell; 6 | use std::rc::Rc; 7 | fn is_sync() {} 8 | is_sync::>>(); // Compile fail 9 | } 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-14.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Rc<()>` cannot be sent between threads safely 2 | --> src/compiletest/qcell_noalloc-14.rs:8:15 3 | | 4 | 8 | is_sync::>>(); // Compile fail 5 | | ^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely 6 | | 7 | = help: the trait `Send` is not implemented for `Rc<()>` 8 | = note: required for `QCell>` to implement `Sync` 9 | note: required by a bound in `is_sync` 10 | --> src/compiletest/qcell_noalloc-14.rs:7:19 11 | | 12 | 7 | fn is_sync() {} 13 | | ^^^^ required by this bound in `is_sync` 14 | 15 | error[E0277]: `Rc<()>` cannot be shared between threads safely 16 | --> src/compiletest/qcell_noalloc-14.rs:8:15 17 | | 18 | 8 | is_sync::>>(); // Compile fail 19 | | ^^^^^^^^^^^^^ `Rc<()>` cannot be shared between threads safely 20 | | 21 | = help: the trait `Sync` is not implemented for `Rc<()>` 22 | = note: required for `QCell>` to implement `Sync` 23 | note: required by a bound in `is_sync` 24 | --> src/compiletest/qcell_noalloc-14.rs:7:19 25 | | 26 | 7 | fn is_sync() {} 27 | | ^^^^ required by this bound in `is_sync` 28 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-15.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::QCell; 6 | use std::rc::Rc; 7 | fn is_send() {} 8 | is_send::>>(); // Compile fail 9 | } 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-15.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Rc<()>` cannot be sent between threads safely 2 | --> src/compiletest/qcell_noalloc-15.rs:8:15 3 | | 4 | 8 | is_send::>>(); // Compile fail 5 | | ^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely 6 | | 7 | = help: within `QCell>`, the trait `Send` is not implemented for `Rc<()>` 8 | note: required because it appears within the type `UnsafeCell>` 9 | --> $RUST/core/src/cell.rs 10 | | 11 | | pub struct UnsafeCell { 12 | | ^^^^^^^^^^ 13 | note: required because it appears within the type `QCell>` 14 | --> $QCELL/src/qcell.rs 15 | | 16 | | pub struct QCell { 17 | | ^^^^^ 18 | note: required by a bound in `is_send` 19 | --> src/compiletest/qcell_noalloc-15.rs:7:19 20 | | 21 | 7 | fn is_send() {} 22 | | ^^^^ required by this bound in `is_send` 23 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-16.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{QCell, QCellOwnerPinned}; 6 | use std::rc::Rc; 7 | let mut owner = Box::pin(QCellOwnerPinned::new()); 8 | let cell = owner.as_ref().cell(Rc::new(100)); 9 | 10 | // We aren't permitted to move the Rc to another thread 11 | std::thread::spawn(move || { // Compile fail 12 | assert_eq!(100, **owner.as_ref().ro(&cell)); 13 | }).join(); 14 | } 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/qcell_noalloc-16.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Rc` cannot be sent between threads safely 2 | --> src/compiletest/qcell_noalloc-16.rs:11:24 3 | | 4 | 11 | std::thread::spawn(move || { // Compile fail 5 | | ------------------ ^------ 6 | | | | 7 | | _____|__________________within this `[closure@$DIR/src/compiletest/qcell_noalloc-16.rs:11:24: 11:31]` 8 | | | | 9 | | | required by a bound introduced by this call 10 | 12 | | assert_eq!(100, **owner.as_ref().ro(&cell)); 11 | 13 | | }).join(); 12 | | |_____^ `Rc` cannot be sent between threads safely 13 | | 14 | = help: within `[closure@$DIR/src/compiletest/qcell_noalloc-16.rs:11:24: 11:31]`, the trait `Send` is not implemented for `Rc` 15 | note: required because it appears within the type `UnsafeCell>` 16 | --> $RUST/core/src/cell.rs 17 | | 18 | | pub struct UnsafeCell { 19 | | ^^^^^^^^^^ 20 | note: required because it appears within the type `QCell>` 21 | --> $QCELL/src/qcell.rs 22 | | 23 | | pub struct QCell { 24 | | ^^^^^ 25 | note: required because it's used within this closure 26 | --> src/compiletest/qcell_noalloc-16.rs:11:24 27 | | 28 | 11 | std::thread::spawn(move || { // Compile fail 29 | | ^^^^^^^ 30 | note: required by a bound in `spawn` 31 | --> $RUST/std/src/thread/mod.rs 32 | | 33 | | pub fn spawn(f: F) -> JoinHandle 34 | | ----- required by a bound in this function 35 | ... 36 | | F: Send + 'static, 37 | | ^^^^ required by this bound in `spawn` 38 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-00.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCell, TCellOwner}; 6 | use std::rc::Rc; 7 | struct Marker; 8 | type ACell = TCell; 9 | type ACellOwner = TCellOwner; 10 | let mut owner1 = ACellOwner::new(); 11 | let mut owner2 = owner1; 12 | let rc = Rc::new(owner1.cell(100u32)); // Compile fail 13 | } 14 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-00.stderr: -------------------------------------------------------------------------------- 1 | error[E0382]: borrow of moved value: `owner1` 2 | --> src/compiletest/tcell-00.rs:12:22 3 | | 4 | 10 | let mut owner1 = ACellOwner::new(); 5 | | ---------- move occurs because `owner1` has type `TCellOwner`, which does not implement the `Copy` trait 6 | 11 | let mut owner2 = owner1; 7 | | ------ value moved here 8 | 12 | let rc = Rc::new(owner1.cell(100u32)); // Compile fail 9 | | ^^^^^^^^^^^^^^^^^^^ value borrowed here after move 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-01.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCell, TCellOwner}; 6 | use std::rc::Rc; 7 | struct Marker; 8 | type ACellOwner = TCellOwner; 9 | let mut owner1 = ACellOwner::new(); 10 | let owner2 = owner1.clone(); // Compile fail 11 | } 12 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-01.stderr: -------------------------------------------------------------------------------- 1 | error[E0599]: no method named `clone` found for struct `TCellOwner` in the current scope 2 | --> src/compiletest/tcell-01.rs:10:25 3 | | 4 | 10 | let owner2 = owner1.clone(); // Compile fail 5 | | ^^^^^ method not found in `TCellOwner` 6 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-02.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCell, TCellOwner}; 6 | use std::rc::Rc; 7 | struct MarkerA; 8 | type ACellOwner = TCellOwner; 9 | type ACell = TCell; 10 | struct MarkerB; 11 | type BCellOwner = TCellOwner; 12 | type BCell = TCell; 13 | 14 | let mut owner_a = ACellOwner::new(); 15 | let mut owner_b = BCellOwner::new(); 16 | let c1 = Rc::new(ACell::new(100u32)); 17 | 18 | let c1ref = owner_b.ro(&*c1); // Compile error 19 | println!("{}", *c1ref); 20 | } 21 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-02.stderr: -------------------------------------------------------------------------------- 1 | error[E0308]: mismatched types 2 | --> src/compiletest/tcell-02.rs:18:28 3 | | 4 | 18 | let c1ref = owner_b.ro(&*c1); // Compile error 5 | | -- ^^^^ expected `&TCell`, found `&TCell` 6 | | | 7 | | arguments to this method are incorrect 8 | | 9 | = note: expected reference `&TCell` 10 | found reference `&TCell` 11 | note: method defined here 12 | --> $QCELL/src/tcell.rs 13 | | 14 | | pub fn ro<'a, T: ?Sized>(&'a self, tc: &'a TCell) -> &'a T { 15 | | ^^ 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-03.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCell, TCellOwner}; 6 | use std::rc::Rc; 7 | struct MarkerA; 8 | type ACellOwner = TCellOwner; 9 | type ACell = TCell; 10 | struct MarkerB; 11 | type BCellOwner = TCellOwner; 12 | type BCell = TCell; 13 | let mut owner_a = ACellOwner::new(); 14 | let mut owner_b = BCellOwner::new(); 15 | let c1 = Rc::new(ACell::new(100u32)); 16 | 17 | let c1mutref = owner_b.rw(&*c1); // Compile error 18 | println!("{}", *c1mutref); 19 | } 20 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-03.stderr: -------------------------------------------------------------------------------- 1 | error[E0308]: mismatched types 2 | --> src/compiletest/tcell-03.rs:17:31 3 | | 4 | 17 | let c1mutref = owner_b.rw(&*c1); // Compile error 5 | | -- ^^^^ expected `&TCell`, found `&TCell` 6 | | | 7 | | arguments to this method are incorrect 8 | | 9 | = note: expected reference `&TCell` 10 | found reference `&TCell` 11 | note: method defined here 12 | --> $QCELL/src/tcell.rs 13 | | 14 | | pub fn rw<'a, T: ?Sized>(&'a mut self, tc: &'a TCell) -> &'a mut T { 15 | | ^^ 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-04.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCell, TCellOwner}; 6 | use std::rc::Rc; 7 | struct Marker; 8 | type ACellOwner = TCellOwner; 9 | type ACell = TCell; 10 | let mut owner = ACellOwner::new(); 11 | let c1 = Rc::new(ACell::new(100u32)); 12 | let c2 = Rc::new(ACell::new(200u32)); 13 | 14 | let c1mutref = owner.rw(&c1); 15 | let c2mutref = owner.rw(&c2); // Compile error 16 | *c1mutref += 1; 17 | *c2mutref += 2; 18 | } 19 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-04.stderr: -------------------------------------------------------------------------------- 1 | error[E0499]: cannot borrow `owner` as mutable more than once at a time 2 | --> src/compiletest/tcell-04.rs:15:20 3 | | 4 | 14 | let c1mutref = owner.rw(&c1); 5 | | ------------- first mutable borrow occurs here 6 | 15 | let c2mutref = owner.rw(&c2); // Compile error 7 | | ^^^^^^^^^^^^^ second mutable borrow occurs here 8 | 16 | *c1mutref += 1; 9 | | -------------- first borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-05.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCell, TCellOwner}; 6 | use std::rc::Rc; 7 | struct Marker; 8 | type ACellOwner = TCellOwner; 9 | type ACell = TCell; 10 | let mut owner = ACellOwner::new(); 11 | let c1 = Rc::new(ACell::new(100u32)); 12 | let c2 = Rc::new(ACell::new(200u32)); 13 | 14 | let c1ref = owner.ro(&c1); 15 | let c1mutref = owner.rw(&c1); // Compile error 16 | println!("{}", *c1ref); 17 | } 18 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-05.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/tcell-05.rs:15:20 3 | | 4 | 14 | let c1ref = owner.ro(&c1); 5 | | ------------- immutable borrow occurs here 6 | 15 | let c1mutref = owner.rw(&c1); // Compile error 7 | | ^^^^^^^^^^^^^ mutable borrow occurs here 8 | 16 | println!("{}", *c1ref); 9 | | ------ immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-06.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCell, TCellOwner}; 6 | use std::rc::Rc; 7 | struct Marker; 8 | type ACellOwner = TCellOwner; 9 | type ACell = TCell; 10 | let mut owner = ACellOwner::new(); 11 | let c1 = Rc::new(ACell::new(100u32)); 12 | let c2 = Rc::new(ACell::new(200u32)); 13 | 14 | let c1mutref = owner.rw(&c1); 15 | let c2ref = owner.ro(&c2); // Compile error 16 | *c1mutref += 1; 17 | } 18 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-06.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/tcell-06.rs:15:17 3 | | 4 | 14 | let c1mutref = owner.rw(&c1); 5 | | ------------- mutable borrow occurs here 6 | 15 | let c2ref = owner.ro(&c2); // Compile error 7 | | ^^^^^^^^^^^^^ immutable borrow occurs here 8 | 16 | *c1mutref += 1; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-07.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCell, TCellOwner}; 6 | use std::rc::Rc; 7 | struct Marker; 8 | type ACellOwner = TCellOwner; 9 | type ACell = TCell; 10 | let mut owner = ACellOwner::new(); 11 | let c1 = Rc::new(ACell::new(100u32)); 12 | let c2 = Rc::new(ACell::new(200u32)); 13 | 14 | let c1ref = owner.ro(&c1); 15 | drop(c1); // Compile error 16 | println!("{}", *c1ref); 17 | } 18 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-07.stderr: -------------------------------------------------------------------------------- 1 | error[E0505]: cannot move out of `c1` because it is borrowed 2 | --> src/compiletest/tcell-07.rs:15:10 3 | | 4 | 11 | let c1 = Rc::new(ACell::new(100u32)); 5 | | -- binding `c1` declared here 6 | ... 7 | 14 | let c1ref = owner.ro(&c1); 8 | | --- borrow of `c1` occurs here 9 | 15 | drop(c1); // Compile error 10 | | ^^ move out of `c1` occurs here 11 | 16 | println!("{}", *c1ref); 12 | | ------ borrow later used here 13 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-08.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCell, TCellOwner}; 6 | use std::rc::Rc; 7 | struct Marker; 8 | type ACellOwner = TCellOwner; 9 | type ACell = TCell; 10 | let mut owner = ACellOwner::new(); 11 | let c1 = Rc::new(ACell::new(100u32)); 12 | let c2 = Rc::new(ACell::new(200u32)); 13 | 14 | fn test(o: &mut ACellOwner) {} 15 | 16 | let c1ref = owner.ro(&c1); 17 | test(&mut owner); // Compile error 18 | println!("{}", *c1ref); 19 | } 20 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-08.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/tcell-08.rs:17:10 3 | | 4 | 16 | let c1ref = owner.ro(&c1); 5 | | ------------- immutable borrow occurs here 6 | 17 | test(&mut owner); // Compile error 7 | | ^^^^^^^^^^ mutable borrow occurs here 8 | 18 | println!("{}", *c1ref); 9 | | ------ immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-09.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCell, TCellOwner}; 6 | use std::rc::Rc; 7 | struct Marker; 8 | type ACellOwner = TCellOwner; 9 | type ACell = TCell; 10 | let mut owner = ACellOwner::new(); 11 | let c1 = Rc::new(ACell::new(100u32)); 12 | let c2 = Rc::new(ACell::new(200u32)); 13 | 14 | fn test(o: &ACellOwner) {} 15 | 16 | let c1mutref = owner.rw(&c1); 17 | test(&owner); // Compile error 18 | *c1mutref += 1; 19 | } 20 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-09.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/tcell-09.rs:17:10 3 | | 4 | 16 | let c1mutref = owner.rw(&c1); 5 | | ------------- mutable borrow occurs here 6 | 17 | test(&owner); // Compile error 7 | | ^^^^^^ immutable borrow occurs here 8 | 18 | *c1mutref += 1; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-10.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCellOwner, TCell}; 6 | struct Marker; 7 | type ACellOwner = TCellOwner; 8 | type ACell = TCell; 9 | let owner = ACellOwner::new(); 10 | let cell = ACell::new(100); 11 | let val_ref = owner.ro(&cell); 12 | std::thread::spawn(move || { 13 | assert_eq!(*owner.ro(&cell), 100); 14 | }).join(); 15 | assert_eq!(*val_ref, 100); 16 | } 17 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-10.stderr: -------------------------------------------------------------------------------- 1 | error[E0505]: cannot move out of `owner` because it is borrowed 2 | --> src/compiletest/tcell-10.rs:12:24 3 | | 4 | 9 | let owner = ACellOwner::new(); 5 | | ----- binding `owner` declared here 6 | 10 | let cell = ACell::new(100); 7 | 11 | let val_ref = owner.ro(&cell); 8 | | --------------- borrow of `owner` occurs here 9 | 12 | std::thread::spawn(move || { 10 | | ^^^^^^^ move out of `owner` occurs here 11 | 13 | assert_eq!(*owner.ro(&cell), 100); 12 | | ----- move occurs due to use in closure 13 | 14 | }).join(); 14 | 15 | assert_eq!(*val_ref, 100); 15 | | ------------------------- borrow later used here 16 | 17 | error[E0505]: cannot move out of `cell` because it is borrowed 18 | --> src/compiletest/tcell-10.rs:12:24 19 | | 20 | 10 | let cell = ACell::new(100); 21 | | ---- binding `cell` declared here 22 | 11 | let val_ref = owner.ro(&cell); 23 | | ----- borrow of `cell` occurs here 24 | 12 | std::thread::spawn(move || { 25 | | ^^^^^^^ move out of `cell` occurs here 26 | 13 | assert_eq!(*owner.ro(&cell), 100); 27 | | ---- move occurs due to use in closure 28 | 14 | }).join(); 29 | 15 | assert_eq!(*val_ref, 100); 30 | | ------------------------- borrow later used here 31 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-11.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::TCell; 6 | use std::cell::Cell; 7 | struct Marker; 8 | fn is_sync() {} 9 | is_sync::>>(); // Compile fail 10 | } 11 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-11.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Cell` cannot be shared between threads safely 2 | --> src/compiletest/tcell-11.rs:9:15 3 | | 4 | 9 | is_sync::>>(); // Compile fail 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely 6 | | 7 | = help: the trait `Sync` is not implemented for `Cell` 8 | = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead 9 | = note: required for `TCell>` to implement `Sync` 10 | note: required by a bound in `is_sync` 11 | --> src/compiletest/tcell-11.rs:8:19 12 | | 13 | 8 | fn is_sync() {} 14 | | ^^^^ required by this bound in `is_sync` 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-12.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCell, TCellOwner}; 6 | use std::cell::Cell; 7 | struct Marker; 8 | type ACellOwner = TCellOwner; 9 | type ACell = TCell>; 10 | 11 | let owner = ACellOwner::new(); 12 | let cell = ACell::new(Cell::new(100)); 13 | 14 | // This would be a data race if the compiler permitted it, but it doesn't 15 | std::thread::spawn(|| owner.ro(&cell).set(200)); // Compile fail 16 | owner.ro(&cell).set(300); 17 | } 18 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-12.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Cell` cannot be shared between threads safely 2 | --> src/compiletest/tcell-12.rs:15:24 3 | | 4 | 15 | std::thread::spawn(|| owner.ro(&cell).set(200)); // Compile fail 5 | | ------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely 6 | | | 7 | | required by a bound introduced by this call 8 | | 9 | = help: the trait `Sync` is not implemented for `Cell` 10 | = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead 11 | = note: required for `TCell>` to implement `Sync` 12 | = note: required for `&TCell>` to implement `Send` 13 | note: required because it's used within this closure 14 | --> src/compiletest/tcell-12.rs:15:24 15 | | 16 | 15 | std::thread::spawn(|| owner.ro(&cell).set(200)); // Compile fail 17 | | ^^ 18 | note: required by a bound in `spawn` 19 | --> $RUST/std/src/thread/mod.rs 20 | | 21 | | pub fn spawn(f: F) -> JoinHandle 22 | | ----- required by a bound in this function 23 | ... 24 | | F: Send + 'static, 25 | | ^^^^ required by this bound in `spawn` 26 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-13.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::TCell; 6 | use std::rc::Rc; 7 | struct Marker; 8 | fn is_sync() {} 9 | is_sync::>>(); // Compile fail 10 | } 11 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-13.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Rc<()>` cannot be sent between threads safely 2 | --> src/compiletest/tcell-13.rs:9:15 3 | | 4 | 9 | is_sync::>>(); // Compile fail 5 | | ^^^^^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely 6 | | 7 | = help: the trait `Send` is not implemented for `Rc<()>` 8 | = note: required for `TCell>` to implement `Sync` 9 | note: required by a bound in `is_sync` 10 | --> src/compiletest/tcell-13.rs:8:19 11 | | 12 | 8 | fn is_sync() {} 13 | | ^^^^ required by this bound in `is_sync` 14 | 15 | error[E0277]: `Rc<()>` cannot be shared between threads safely 16 | --> src/compiletest/tcell-13.rs:9:15 17 | | 18 | 9 | is_sync::>>(); // Compile fail 19 | | ^^^^^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be shared between threads safely 20 | | 21 | = help: the trait `Sync` is not implemented for `Rc<()>` 22 | = note: required for `TCell>` to implement `Sync` 23 | note: required by a bound in `is_sync` 24 | --> src/compiletest/tcell-13.rs:8:19 25 | | 26 | 8 | fn is_sync() {} 27 | | ^^^^ required by this bound in `is_sync` 28 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-14.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::TCell; 6 | use std::rc::Rc; 7 | struct Marker; 8 | fn is_send() {} 9 | is_send::>>(); // Compile fail 10 | } 11 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-14.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Rc<()>` cannot be sent between threads safely 2 | --> src/compiletest/tcell-14.rs:9:15 3 | | 4 | 9 | is_send::>>(); // Compile fail 5 | | ^^^^^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely 6 | | 7 | = help: within `TCell>`, the trait `Send` is not implemented for `Rc<()>` 8 | note: required because it appears within the type `UnsafeCell>` 9 | --> $RUST/core/src/cell.rs 10 | | 11 | | pub struct UnsafeCell { 12 | | ^^^^^^^^^^ 13 | note: required because it appears within the type `TCell>` 14 | --> $QCELL/src/tcell.rs 15 | | 16 | | pub struct TCell { 17 | | ^^^^^ 18 | note: required by a bound in `is_send` 19 | --> src/compiletest/tcell-14.rs:8:19 20 | | 21 | 8 | fn is_send() {} 22 | | ^^^^ required by this bound in `is_send` 23 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-15.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCell, TCellOwner}; 6 | use std::rc::Rc; 7 | struct Marker; 8 | type ACellOwner = TCellOwner; 9 | type ACell = TCell>; 10 | 11 | let owner = ACellOwner::new(); 12 | let cell = ACell::new(Rc::new(100)); 13 | 14 | // We aren't permitted to move the Rc to another thread 15 | std::thread::spawn(move || { // Compile fail 16 | assert_eq!(100, **owner.ro(&cell)); 17 | }).join(); 18 | } 19 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-15.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Rc` cannot be sent between threads safely 2 | --> src/compiletest/tcell-15.rs:15:24 3 | | 4 | 15 | std::thread::spawn(move || { // Compile fail 5 | | ------------------ ^------ 6 | | | | 7 | | _____|__________________within this `[closure@$DIR/src/compiletest/tcell-15.rs:15:24: 15:31]` 8 | | | | 9 | | | required by a bound introduced by this call 10 | 16 | | assert_eq!(100, **owner.ro(&cell)); 11 | 17 | | }).join(); 12 | | |_____^ `Rc` cannot be sent between threads safely 13 | | 14 | = help: within `[closure@$DIR/src/compiletest/tcell-15.rs:15:24: 15:31]`, the trait `Send` is not implemented for `Rc` 15 | note: required because it appears within the type `UnsafeCell>` 16 | --> $RUST/core/src/cell.rs 17 | | 18 | | pub struct UnsafeCell { 19 | | ^^^^^^^^^^ 20 | note: required because it appears within the type `TCell>` 21 | --> $QCELL/src/tcell.rs 22 | | 23 | | pub struct TCell { 24 | | ^^^^^ 25 | note: required because it's used within this closure 26 | --> src/compiletest/tcell-15.rs:15:24 27 | | 28 | 15 | std::thread::spawn(move || { // Compile fail 29 | | ^^^^^^^ 30 | note: required by a bound in `spawn` 31 | --> $RUST/std/src/thread/mod.rs 32 | | 33 | | pub fn spawn(f: F) -> JoinHandle 34 | | ----- required by a bound in this function 35 | ... 36 | | F: Send + 'static, 37 | | ^^^^ required by this bound in `spawn` 38 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-16.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCell, TCellOwner}; 6 | type MarkerA = fn(&()); 7 | type MarkerB = fn(&'static ()); 8 | 9 | let mut owner1 = TCellOwner::::new() as TCellOwner; // Compile fail 10 | let mut owner2 = TCellOwner::::new(); 11 | let cell = TCell::::new(1234); 12 | let ref1 = owner1.rw(&cell); 13 | let ref2 = owner2.rw(&cell); 14 | *ref1 = 1; // Two mutable refs at the same time! Unsound! 15 | *ref2 = 2; 16 | } 17 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-16.stderr: -------------------------------------------------------------------------------- 1 | error[E0308]: mismatched types 2 | --> src/compiletest/tcell-16.rs:9:22 3 | | 4 | 9 | let mut owner1 = TCellOwner::::new() as TCellOwner; // Compile fail 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other 6 | | 7 | = note: expected struct `TCellOwner` 8 | found struct `TCellOwner fn(&'a ())>` 9 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-17.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCell, TCellOwner}; 6 | struct Marker; 7 | type ACell = TCell; 8 | type ACellOwner = TCellOwner; 9 | let owner = ACellOwner::new(); 10 | let mut cell = ACell::new(100); 11 | let cell_ref = cell.get_mut(); 12 | assert_eq!(100, *owner.ro(&cell)); // Compile fail 13 | *cell_ref = 50; 14 | } 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-17.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `cell` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/tcell-17.rs:12:31 3 | | 4 | 11 | let cell_ref = cell.get_mut(); 5 | | -------------- mutable borrow occurs here 6 | 12 | assert_eq!(100, *owner.ro(&cell)); // Compile fail 7 | | ^^^^^ immutable borrow occurs here 8 | 13 | *cell_ref = 50; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-18.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCell, TCellOwner}; 6 | struct Marker; 7 | type ACell = TCell; 8 | type ACellOwner = TCellOwner; 9 | let mut owner = ACellOwner::new(); 10 | let mut cell = ACell::new(100); 11 | let cell_ref = cell.get_mut(); 12 | assert_eq!(100, *owner.rw(&cell)); // Compile fail 13 | *cell_ref = 50; 14 | } 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-18.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `cell` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/tcell-18.rs:12:31 3 | | 4 | 11 | let cell_ref = cell.get_mut(); 5 | | -------------- mutable borrow occurs here 6 | 12 | assert_eq!(100, *owner.rw(&cell)); // Compile fail 7 | | ^^^^^ immutable borrow occurs here 8 | 13 | *cell_ref = 50; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-19.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCell, TCellOwner}; 6 | struct Marker; 7 | type ACell = TCell; 8 | type ACellOwner = TCellOwner; 9 | let owner = ACellOwner::new(); 10 | let mut cell = ACell::new(100); 11 | let cell_ref = owner.ro(&cell); 12 | *cell.get_mut() = 50; // Compile fail 13 | assert_eq!(100, *cell_ref); 14 | } 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-19.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `cell` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/tcell-19.rs:12:6 3 | | 4 | 11 | let cell_ref = owner.ro(&cell); 5 | | ----- immutable borrow occurs here 6 | 12 | *cell.get_mut() = 50; // Compile fail 7 | | ^^^^^^^^^^^^^^ mutable borrow occurs here 8 | 13 | assert_eq!(100, *cell_ref); 9 | | -------------------------- immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-20.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCell, TCellOwner}; 6 | struct Marker; 7 | type ACell = TCell; 8 | type ACellOwner = TCellOwner; 9 | let mut owner = ACellOwner::new(); 10 | let mut cell = ACell::new(100); 11 | let cell_ref = owner.rw(&cell); 12 | *cell.get_mut() = 50; // Compile fail 13 | assert_eq!(100, *cell_ref); 14 | } 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-20.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `cell` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/tcell-20.rs:12:6 3 | | 4 | 11 | let cell_ref = owner.rw(&cell); 5 | | ----- immutable borrow occurs here 6 | 12 | *cell.get_mut() = 50; // Compile fail 7 | | ^^^^^^^^^^^^^^ mutable borrow occurs here 8 | 13 | assert_eq!(100, *cell_ref); 9 | | -------------------------- immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-21.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TCell, TCellOwner}; 6 | struct Marker; 7 | type ACell = TCell; 8 | type ACellOwner = TCellOwner; 9 | struct NoDefault(i32); 10 | let mut owner = ACellOwner::new(); 11 | let mut cell: ACell = ACell::default(); // Compile fail 12 | assert_eq!(0, owner.ro(&cell).0); 13 | } 14 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tcell-21.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: the trait bound `NoDefault: Default` is not satisfied 2 | --> src/compiletest/tcell-21.rs:11:38 3 | | 4 | 11 | let mut cell: ACell = ACell::default(); // Compile fail 5 | | ^^^^^^^^^^^^^^ the trait `Default` is not implemented for `NoDefault` 6 | | 7 | = help: the trait `Default` is implemented for `TCell` 8 | = note: required for `TCell` to implement `Default` 9 | help: consider annotating `NoDefault` with `#[derive(Default)]` 10 | | 11 | 9 + #[derive(Default)] 12 | 10 | struct NoDefault(i32); 13 | | 14 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-00.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TLCell, TLCellOwner}; 6 | use std::rc::Rc; 7 | struct Marker; 8 | type ACell = TLCell; 9 | type ACellOwner = TLCellOwner; 10 | let mut owner1 = ACellOwner::new(); 11 | let mut owner2 = owner1; 12 | let rc = Rc::new(owner1.cell(100u32)); // Compile fail 13 | } 14 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-00.stderr: -------------------------------------------------------------------------------- 1 | error[E0382]: borrow of moved value: `owner1` 2 | --> src/compiletest/tlcell-00.rs:12:22 3 | | 4 | 10 | let mut owner1 = ACellOwner::new(); 5 | | ---------- move occurs because `owner1` has type `TLCellOwner`, which does not implement the `Copy` trait 6 | 11 | let mut owner2 = owner1; 7 | | ------ value moved here 8 | 12 | let rc = Rc::new(owner1.cell(100u32)); // Compile fail 9 | | ^^^^^^^^^^^^^^^^^^^ value borrowed here after move 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-01.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TLCell, TLCellOwner}; 6 | use std::rc::Rc; 7 | struct Marker; 8 | type ACellOwner = TLCellOwner; 9 | let mut owner1 = ACellOwner::new(); 10 | let owner2 = owner1.clone(); // Compile fail 11 | } 12 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-01.stderr: -------------------------------------------------------------------------------- 1 | error[E0599]: no method named `clone` found for struct `TLCellOwner` in the current scope 2 | --> src/compiletest/tlcell-01.rs:10:25 3 | | 4 | 10 | let owner2 = owner1.clone(); // Compile fail 5 | | ^^^^^ method not found in `TLCellOwner` 6 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-02.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TLCell, TLCellOwner}; 6 | use std::rc::Rc; 7 | struct MarkerA; 8 | type ACellOwner = TLCellOwner; 9 | type ACell = TLCell; 10 | struct MarkerB; 11 | type BCellOwner = TLCellOwner; 12 | type BCell = TLCell; 13 | 14 | let mut owner_a = ACellOwner::new(); 15 | let mut owner_b = BCellOwner::new(); 16 | let c1 = Rc::new(ACell::new(100u32)); 17 | 18 | let c1ref = owner_b.ro(&*c1); // Compile error 19 | println!("{}", *c1ref); 20 | } 21 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-02.stderr: -------------------------------------------------------------------------------- 1 | error[E0308]: mismatched types 2 | --> src/compiletest/tlcell-02.rs:18:28 3 | | 4 | 18 | let c1ref = owner_b.ro(&*c1); // Compile error 5 | | -- ^^^^ expected `&TLCell`, found `&TLCell` 6 | | | 7 | | arguments to this method are incorrect 8 | | 9 | = note: expected reference `&TLCell` 10 | found reference `&TLCell` 11 | note: method defined here 12 | --> $QCELL/src/tlcell.rs 13 | | 14 | | pub fn ro<'a, T: ?Sized>(&'a self, tc: &'a TLCell) -> &'a T { 15 | | ^^ 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-03.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TLCell, TLCellOwner}; 6 | use std::rc::Rc; 7 | struct MarkerA; 8 | type ACellOwner = TLCellOwner; 9 | type ACell = TLCell; 10 | struct MarkerB; 11 | type BCellOwner = TLCellOwner; 12 | type BCell = TLCell; 13 | let mut owner_a = ACellOwner::new(); 14 | let mut owner_b = BCellOwner::new(); 15 | let c1 = Rc::new(ACell::new(100u32)); 16 | 17 | let c1mutref = owner_b.rw(&*c1); // Compile error 18 | println!("{}", *c1mutref); 19 | } 20 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-03.stderr: -------------------------------------------------------------------------------- 1 | error[E0308]: mismatched types 2 | --> src/compiletest/tlcell-03.rs:17:31 3 | | 4 | 17 | let c1mutref = owner_b.rw(&*c1); // Compile error 5 | | -- ^^^^ expected `&TLCell`, found `&TLCell` 6 | | | 7 | | arguments to this method are incorrect 8 | | 9 | = note: expected reference `&TLCell` 10 | found reference `&TLCell` 11 | note: method defined here 12 | --> $QCELL/src/tlcell.rs 13 | | 14 | | pub fn rw<'a, T: ?Sized>(&'a mut self, tc: &'a TLCell) -> &'a mut T { 15 | | ^^ 16 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-04.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TLCell, TLCellOwner}; 6 | use std::rc::Rc; 7 | struct Marker; 8 | type ACellOwner = TLCellOwner; 9 | type ACell = TLCell; 10 | let mut owner = ACellOwner::new(); 11 | let c1 = Rc::new(ACell::new(100u32)); 12 | let c2 = Rc::new(ACell::new(200u32)); 13 | 14 | let c1mutref = owner.rw(&c1); 15 | let c2mutref = owner.rw(&c2); // Compile error 16 | *c1mutref += 1; 17 | *c2mutref += 2; 18 | } 19 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-04.stderr: -------------------------------------------------------------------------------- 1 | error[E0499]: cannot borrow `owner` as mutable more than once at a time 2 | --> src/compiletest/tlcell-04.rs:15:20 3 | | 4 | 14 | let c1mutref = owner.rw(&c1); 5 | | ------------- first mutable borrow occurs here 6 | 15 | let c2mutref = owner.rw(&c2); // Compile error 7 | | ^^^^^^^^^^^^^ second mutable borrow occurs here 8 | 16 | *c1mutref += 1; 9 | | -------------- first borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-05.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TLCell, TLCellOwner}; 6 | use std::rc::Rc; 7 | struct Marker; 8 | type ACellOwner = TLCellOwner; 9 | type ACell = TLCell; 10 | let mut owner = ACellOwner::new(); 11 | let c1 = Rc::new(ACell::new(100u32)); 12 | let c2 = Rc::new(ACell::new(200u32)); 13 | 14 | let c1ref = owner.ro(&c1); 15 | let c1mutref = owner.rw(&c1); // Compile error 16 | println!("{}", *c1ref); 17 | } 18 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-05.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/tlcell-05.rs:15:20 3 | | 4 | 14 | let c1ref = owner.ro(&c1); 5 | | ------------- immutable borrow occurs here 6 | 15 | let c1mutref = owner.rw(&c1); // Compile error 7 | | ^^^^^^^^^^^^^ mutable borrow occurs here 8 | 16 | println!("{}", *c1ref); 9 | | ------ immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-06.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TLCell, TLCellOwner}; 6 | use std::rc::Rc; 7 | struct Marker; 8 | type ACellOwner = TLCellOwner; 9 | type ACell = TLCell; 10 | let mut owner = ACellOwner::new(); 11 | let c1 = Rc::new(ACell::new(100u32)); 12 | let c2 = Rc::new(ACell::new(200u32)); 13 | 14 | let c1mutref = owner.rw(&c1); 15 | let c2ref = owner.ro(&c2); // Compile error 16 | *c1mutref += 1; 17 | } 18 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-06.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/tlcell-06.rs:15:17 3 | | 4 | 14 | let c1mutref = owner.rw(&c1); 5 | | ------------- mutable borrow occurs here 6 | 15 | let c2ref = owner.ro(&c2); // Compile error 7 | | ^^^^^^^^^^^^^ immutable borrow occurs here 8 | 16 | *c1mutref += 1; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-07.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TLCell, TLCellOwner}; 6 | use std::rc::Rc; 7 | struct Marker; 8 | type ACellOwner = TLCellOwner; 9 | type ACell = TLCell; 10 | let mut owner = ACellOwner::new(); 11 | let c1 = Rc::new(ACell::new(100u32)); 12 | let c2 = Rc::new(ACell::new(200u32)); 13 | 14 | let c1ref = owner.ro(&c1); 15 | drop(c1); // Compile error 16 | println!("{}", *c1ref); 17 | } 18 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-07.stderr: -------------------------------------------------------------------------------- 1 | error[E0505]: cannot move out of `c1` because it is borrowed 2 | --> src/compiletest/tlcell-07.rs:15:10 3 | | 4 | 11 | let c1 = Rc::new(ACell::new(100u32)); 5 | | -- binding `c1` declared here 6 | ... 7 | 14 | let c1ref = owner.ro(&c1); 8 | | --- borrow of `c1` occurs here 9 | 15 | drop(c1); // Compile error 10 | | ^^ move out of `c1` occurs here 11 | 16 | println!("{}", *c1ref); 12 | | ------ borrow later used here 13 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-08.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TLCell, TLCellOwner}; 6 | use std::rc::Rc; 7 | struct Marker; 8 | type ACellOwner = TLCellOwner; 9 | type ACell = TLCell; 10 | let mut owner = ACellOwner::new(); 11 | let c1 = Rc::new(ACell::new(100u32)); 12 | let c2 = Rc::new(ACell::new(200u32)); 13 | 14 | fn test(o: &mut ACellOwner) {} 15 | 16 | let c1ref = owner.ro(&c1); 17 | test(&mut owner); // Compile error 18 | println!("{}", *c1ref); 19 | } 20 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-08.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/tlcell-08.rs:17:10 3 | | 4 | 16 | let c1ref = owner.ro(&c1); 5 | | ------------- immutable borrow occurs here 6 | 17 | test(&mut owner); // Compile error 7 | | ^^^^^^^^^^ mutable borrow occurs here 8 | 18 | println!("{}", *c1ref); 9 | | ------ immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-09.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TLCell, TLCellOwner}; 6 | use std::rc::Rc; 7 | struct Marker; 8 | type ACellOwner = TLCellOwner; 9 | type ACell = TLCell; 10 | let mut owner = ACellOwner::new(); 11 | let c1 = Rc::new(ACell::new(100u32)); 12 | let c2 = Rc::new(ACell::new(200u32)); 13 | 14 | fn test(o: &ACellOwner) {} 15 | 16 | let c1mutref = owner.rw(&c1); 17 | test(&owner); // Compile error 18 | *c1mutref += 1; 19 | } 20 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-09.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `owner` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/tlcell-09.rs:17:10 3 | | 4 | 16 | let c1mutref = owner.rw(&c1); 5 | | ------------- mutable borrow occurs here 6 | 17 | test(&owner); // Compile error 7 | | ^^^^^^ immutable borrow occurs here 8 | 18 | *c1mutref += 1; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-10.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::TLCellOwner; 6 | struct Marker; 7 | fn is_send() {} 8 | is_send::>(); // Compile fail 9 | } 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-10.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `*const ()` cannot be sent between threads safely 2 | --> src/compiletest/tlcell-10.rs:8:15 3 | | 4 | 8 | is_send::>(); // Compile fail 5 | | ^^^^^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely 6 | | 7 | = help: within `TLCellOwner`, the trait `Send` is not implemented for `*const ()` 8 | note: required because it appears within the type `NotSendOrSync` 9 | --> $QCELL/src/tlcell.rs 10 | | 11 | | struct NotSendOrSync(*const ()); 12 | | ^^^^^^^^^^^^^ 13 | note: required because it appears within the type `PhantomData` 14 | --> $RUST/core/src/marker.rs 15 | | 16 | | pub struct PhantomData; 17 | | ^^^^^^^^^^^ 18 | note: required because it appears within the type `TLCellOwner` 19 | --> $QCELL/src/tlcell.rs 20 | | 21 | | pub struct TLCellOwner { 22 | | ^^^^^^^^^^^ 23 | note: required by a bound in `is_send` 24 | --> src/compiletest/tlcell-10.rs:7:19 25 | | 26 | 7 | fn is_send() {} 27 | | ^^^^ required by this bound in `is_send` 28 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-11.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::TLCellOwner; 6 | struct Marker; 7 | fn is_sync() {} 8 | is_sync::>(); // Compile fail 9 | } 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-11.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `*const ()` cannot be shared between threads safely 2 | --> src/compiletest/tlcell-11.rs:8:15 3 | | 4 | 8 | is_sync::>(); // Compile fail 5 | | ^^^^^^^^^^^^^^^^^^^ `*const ()` cannot be shared between threads safely 6 | | 7 | = help: within `TLCellOwner`, the trait `Sync` is not implemented for `*const ()` 8 | note: required because it appears within the type `NotSendOrSync` 9 | --> $QCELL/src/tlcell.rs 10 | | 11 | | struct NotSendOrSync(*const ()); 12 | | ^^^^^^^^^^^^^ 13 | note: required because it appears within the type `PhantomData` 14 | --> $RUST/core/src/marker.rs 15 | | 16 | | pub struct PhantomData; 17 | | ^^^^^^^^^^^ 18 | note: required because it appears within the type `TLCellOwner` 19 | --> $QCELL/src/tlcell.rs 20 | | 21 | | pub struct TLCellOwner { 22 | | ^^^^^^^^^^^ 23 | note: required by a bound in `is_sync` 24 | --> src/compiletest/tlcell-11.rs:7:19 25 | | 26 | 7 | fn is_sync() {} 27 | | ^^^^ required by this bound in `is_sync` 28 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-12.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::TLCell; 6 | struct Marker; 7 | fn is_sync() {} 8 | is_sync::>(); // Compile fail 9 | } 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-12.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `UnsafeCell<()>` cannot be shared between threads safely 2 | --> src/compiletest/tlcell-12.rs:8:15 3 | | 4 | 8 | is_sync::>(); // Compile fail 5 | | ^^^^^^^^^^^^^^^^^^ `UnsafeCell<()>` cannot be shared between threads safely 6 | | 7 | = help: within `TLCell`, the trait `Sync` is not implemented for `UnsafeCell<()>` 8 | note: required because it appears within the type `TLCell` 9 | --> $QCELL/src/tlcell.rs 10 | | 11 | | pub struct TLCell { 12 | | ^^^^^^ 13 | note: required by a bound in `is_sync` 14 | --> src/compiletest/tlcell-12.rs:7:19 15 | | 16 | 7 | fn is_sync() {} 17 | | ^^^^ required by this bound in `is_sync` 18 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-13.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TLCellOwner, TLCell}; 6 | struct Marker; 7 | type ACellOwner = TLCellOwner; 8 | type ACell = TLCell; 9 | let owner = ACellOwner::new(); 10 | let cell = ACell::new(100); 11 | let val_ref = owner.ro(&cell); 12 | std::thread::spawn(move || { 13 | assert_eq!(*owner.ro(&cell), 100); 14 | }).join(); 15 | assert_eq!(*val_ref, 100); 16 | } 17 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-13.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `*const ()` cannot be sent between threads safely 2 | --> src/compiletest/tlcell-13.rs:12:24 3 | | 4 | 12 | std::thread::spawn(move || { 5 | | ------------------ ^------ 6 | | | | 7 | | _____|__________________within this `[closure@$DIR/src/compiletest/tlcell-13.rs:12:24: 12:31]` 8 | | | | 9 | | | required by a bound introduced by this call 10 | 13 | | assert_eq!(*owner.ro(&cell), 100); 11 | 14 | | }).join(); 12 | | |_____^ `*const ()` cannot be sent between threads safely 13 | | 14 | = help: within `[closure@$DIR/src/compiletest/tlcell-13.rs:12:24: 12:31]`, the trait `Send` is not implemented for `*const ()` 15 | note: required because it appears within the type `NotSendOrSync` 16 | --> $QCELL/src/tlcell.rs 17 | | 18 | | struct NotSendOrSync(*const ()); 19 | | ^^^^^^^^^^^^^ 20 | note: required because it appears within the type `PhantomData` 21 | --> $RUST/core/src/marker.rs 22 | | 23 | | pub struct PhantomData; 24 | | ^^^^^^^^^^^ 25 | note: required because it appears within the type `TLCellOwner` 26 | --> $QCELL/src/tlcell.rs 27 | | 28 | | pub struct TLCellOwner { 29 | | ^^^^^^^^^^^ 30 | note: required because it's used within this closure 31 | --> src/compiletest/tlcell-13.rs:12:24 32 | | 33 | 12 | std::thread::spawn(move || { 34 | | ^^^^^^^ 35 | note: required by a bound in `spawn` 36 | --> $RUST/std/src/thread/mod.rs 37 | | 38 | | pub fn spawn(f: F) -> JoinHandle 39 | | ----- required by a bound in this function 40 | ... 41 | | F: Send + 'static, 42 | | ^^^^ required by this bound in `spawn` 43 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-14.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::TLCell; 6 | use std::rc::Rc; 7 | struct Marker; 8 | fn is_send() {} 9 | is_send::>>(); // Compile fail 10 | } 11 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-14.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Rc<()>` cannot be sent between threads safely 2 | --> src/compiletest/tlcell-14.rs:9:15 3 | | 4 | 9 | is_send::>>(); // Compile fail 5 | | ^^^^^^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely 6 | | 7 | = help: within `TLCell>`, the trait `Send` is not implemented for `Rc<()>` 8 | note: required because it appears within the type `UnsafeCell>` 9 | --> $RUST/core/src/cell.rs 10 | | 11 | | pub struct UnsafeCell { 12 | | ^^^^^^^^^^ 13 | note: required because it appears within the type `TLCell>` 14 | --> $QCELL/src/tlcell.rs 15 | | 16 | | pub struct TLCell { 17 | | ^^^^^^ 18 | note: required by a bound in `is_send` 19 | --> src/compiletest/tlcell-14.rs:8:19 20 | | 21 | 8 | fn is_send() {} 22 | | ^^^^ required by this bound in `is_send` 23 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-15.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TLCell, TLCellOwner}; 6 | use std::rc::Rc; 7 | struct Marker; 8 | type ACellOwner = TLCellOwner; 9 | type ACell = TLCell>; 10 | 11 | let owner = ACellOwner::new(); 12 | let cell = ACell::new(Rc::new(100)); 13 | 14 | // We aren't permitted to move the Rc to another thread 15 | std::thread::spawn(move || { // Compile fail 16 | assert_eq!(100, **owner.ro(&cell)); 17 | }).join(); 18 | } 19 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-15.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: `Rc` cannot be sent between threads safely 2 | --> src/compiletest/tlcell-15.rs:15:24 3 | | 4 | 15 | std::thread::spawn(move || { // Compile fail 5 | | ------------------ ^------ 6 | | | | 7 | | _____|__________________within this `[closure@$DIR/src/compiletest/tlcell-15.rs:15:24: 15:31]` 8 | | | | 9 | | | required by a bound introduced by this call 10 | 16 | | assert_eq!(100, **owner.ro(&cell)); 11 | 17 | | }).join(); 12 | | |_____^ `Rc` cannot be sent between threads safely 13 | | 14 | = help: within `[closure@$DIR/src/compiletest/tlcell-15.rs:15:24: 15:31]`, the trait `Send` is not implemented for `Rc` 15 | note: required because it appears within the type `UnsafeCell>` 16 | --> $RUST/core/src/cell.rs 17 | | 18 | | pub struct UnsafeCell { 19 | | ^^^^^^^^^^ 20 | note: required because it appears within the type `TLCell>` 21 | --> $QCELL/src/tlcell.rs 22 | | 23 | | pub struct TLCell { 24 | | ^^^^^^ 25 | note: required because it's used within this closure 26 | --> src/compiletest/tlcell-15.rs:15:24 27 | | 28 | 15 | std::thread::spawn(move || { // Compile fail 29 | | ^^^^^^^ 30 | note: required by a bound in `spawn` 31 | --> $RUST/std/src/thread/mod.rs 32 | | 33 | | pub fn spawn(f: F) -> JoinHandle 34 | | ----- required by a bound in this function 35 | ... 36 | | F: Send + 'static, 37 | | ^^^^ required by this bound in `spawn` 38 | 39 | error[E0277]: `*const ()` cannot be sent between threads safely 40 | --> src/compiletest/tlcell-15.rs:15:24 41 | | 42 | 15 | std::thread::spawn(move || { // Compile fail 43 | | ------------------ ^------ 44 | | | | 45 | | _____|__________________within this `[closure@$DIR/src/compiletest/tlcell-15.rs:15:24: 15:31]` 46 | | | | 47 | | | required by a bound introduced by this call 48 | 16 | | assert_eq!(100, **owner.ro(&cell)); 49 | 17 | | }).join(); 50 | | |_____^ `*const ()` cannot be sent between threads safely 51 | | 52 | = help: within `[closure@$DIR/src/compiletest/tlcell-15.rs:15:24: 15:31]`, the trait `Send` is not implemented for `*const ()` 53 | note: required because it appears within the type `NotSendOrSync` 54 | --> $QCELL/src/tlcell.rs 55 | | 56 | | struct NotSendOrSync(*const ()); 57 | | ^^^^^^^^^^^^^ 58 | note: required because it appears within the type `PhantomData` 59 | --> $RUST/core/src/marker.rs 60 | | 61 | | pub struct PhantomData; 62 | | ^^^^^^^^^^^ 63 | note: required because it appears within the type `TLCellOwner` 64 | --> $QCELL/src/tlcell.rs 65 | | 66 | | pub struct TLCellOwner { 67 | | ^^^^^^^^^^^ 68 | note: required because it's used within this closure 69 | --> src/compiletest/tlcell-15.rs:15:24 70 | | 71 | 15 | std::thread::spawn(move || { // Compile fail 72 | | ^^^^^^^ 73 | note: required by a bound in `spawn` 74 | --> $RUST/std/src/thread/mod.rs 75 | | 76 | | pub fn spawn(f: F) -> JoinHandle 77 | | ----- required by a bound in this function 78 | ... 79 | | F: Send + 'static, 80 | | ^^^^ required by this bound in `spawn` 81 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-16.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TLCell, TLCellOwner}; 6 | type MarkerA = fn(&()); 7 | type MarkerB = fn(&'static ()); 8 | 9 | let mut owner1 = TLCellOwner::::new() as TLCellOwner; // Compile fail 10 | let mut owner2 = TLCellOwner::::new(); 11 | let cell = TLCell::::new(1234); 12 | let ref1 = owner1.rw(&cell); 13 | let ref2 = owner2.rw(&cell); 14 | *ref1 = 1; // Two mutable refs at the same time! Unsound! 15 | *ref2 = 2; 16 | } 17 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-16.stderr: -------------------------------------------------------------------------------- 1 | error[E0308]: mismatched types 2 | --> src/compiletest/tlcell-16.rs:9:22 3 | | 4 | 9 | let mut owner1 = TLCellOwner::::new() as TLCellOwner; // Compile fail 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other 6 | | 7 | = note: expected struct `TLCellOwner` 8 | found struct `TLCellOwner fn(&'a ())>` 9 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-17.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TLCell, TLCellOwner}; 6 | struct Marker; 7 | type ACell = TLCell; 8 | type ACellOwner = TLCellOwner; 9 | let owner = ACellOwner::new(); 10 | let mut cell = ACell::new(100); 11 | let cell_ref = cell.get_mut(); 12 | assert_eq!(100, *owner.ro(&cell)); // Compile fail 13 | *cell_ref = 50; 14 | } 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-17.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `cell` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/tlcell-17.rs:12:31 3 | | 4 | 11 | let cell_ref = cell.get_mut(); 5 | | -------------- mutable borrow occurs here 6 | 12 | assert_eq!(100, *owner.ro(&cell)); // Compile fail 7 | | ^^^^^ immutable borrow occurs here 8 | 13 | *cell_ref = 50; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-18.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TLCell, TLCellOwner}; 6 | struct Marker; 7 | type ACell = TLCell; 8 | type ACellOwner = TLCellOwner; 9 | let mut owner = ACellOwner::new(); 10 | let mut cell = ACell::new(100); 11 | let cell_ref = cell.get_mut(); 12 | assert_eq!(100, *owner.rw(&cell)); // Compile fail 13 | *cell_ref = 50; 14 | } 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-18.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `cell` as immutable because it is also borrowed as mutable 2 | --> src/compiletest/tlcell-18.rs:12:31 3 | | 4 | 11 | let cell_ref = cell.get_mut(); 5 | | -------------- mutable borrow occurs here 6 | 12 | assert_eq!(100, *owner.rw(&cell)); // Compile fail 7 | | ^^^^^ immutable borrow occurs here 8 | 13 | *cell_ref = 50; 9 | | -------------- mutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-19.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TLCell, TLCellOwner}; 6 | struct Marker; 7 | type ACell = TLCell; 8 | type ACellOwner = TLCellOwner; 9 | let owner = ACellOwner::new(); 10 | let mut cell = ACell::new(100); 11 | let cell_ref = owner.ro(&cell); 12 | *cell.get_mut() = 50; // Compile fail 13 | assert_eq!(100, *cell_ref); 14 | } 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-19.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `cell` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/tlcell-19.rs:12:6 3 | | 4 | 11 | let cell_ref = owner.ro(&cell); 5 | | ----- immutable borrow occurs here 6 | 12 | *cell.get_mut() = 50; // Compile fail 7 | | ^^^^^^^^^^^^^^ mutable borrow occurs here 8 | 13 | assert_eq!(100, *cell_ref); 9 | | -------------------------- immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-20.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TLCell, TLCellOwner}; 6 | struct Marker; 7 | type ACell = TLCell; 8 | type ACellOwner = TLCellOwner; 9 | let mut owner = ACellOwner::new(); 10 | let mut cell = ACell::new(100); 11 | let cell_ref = owner.rw(&cell); 12 | *cell.get_mut() = 50; // Compile fail 13 | assert_eq!(100, *cell_ref); 14 | } 15 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-20.stderr: -------------------------------------------------------------------------------- 1 | error[E0502]: cannot borrow `cell` as mutable because it is also borrowed as immutable 2 | --> src/compiletest/tlcell-20.rs:12:6 3 | | 4 | 11 | let cell_ref = owner.rw(&cell); 5 | | ----- immutable borrow occurs here 6 | 12 | *cell.get_mut() = 50; // Compile fail 7 | | ^^^^^^^^^^^^^^ mutable borrow occurs here 8 | 13 | assert_eq!(100, *cell_ref); 9 | | -------------------------- immutable borrow later used here 10 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-21.rs: -------------------------------------------------------------------------------- 1 | extern crate qcell; 2 | 3 | #[allow(warnings)] 4 | fn main() { 5 | use qcell::{TLCell, TLCellOwner}; 6 | struct Marker; 7 | type ACell = TLCell; 8 | type ACellOwner = TLCellOwner; 9 | struct NoDefault(i32); 10 | let mut owner = ACellOwner::new(); 11 | let mut cell: ACell = ACell::default(); // Compile fail 12 | assert_eq!(0, owner.ro(&cell).0); 13 | } 14 | -------------------------------------------------------------------------------- /trybuild-qcell/src/compiletest/tlcell-21.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: the trait bound `NoDefault: Default` is not satisfied 2 | --> src/compiletest/tlcell-21.rs:11:38 3 | | 4 | 11 | let mut cell: ACell = ACell::default(); // Compile fail 5 | | ^^^^^^^^^^^^^^ the trait `Default` is not implemented for `NoDefault` 6 | | 7 | = help: the trait `Default` is implemented for `TLCell` 8 | = note: required for `TLCell` to implement `Default` 9 | help: consider annotating `NoDefault` with `#[derive(Default)]` 10 | | 11 | 9 + #[derive(Default)] 12 | 10 | struct NoDefault(i32); 13 | | 14 | -------------------------------------------------------------------------------- /trybuild-qcell/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | pub mod compiletest { 3 | #[rustversion::all(stable, since(1.71), before(1.72))] 4 | #[test] 5 | fn ui() { 6 | let t = trybuild::TestCases::new(); 7 | t.compile_fail("src/compiletest/*.rs"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /update-compiletest-from-doctest.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | # This extracts the `compile_fail` tests from the doctests and puts 4 | # them in a folder for `trybuild` to test. `trybuild` lets us verify 5 | # that the errors generated are what are expected. This should be 6 | # re-run after any change to the doctests, and the results should be 7 | # checked in along with any new `.stderr` files. 8 | 9 | die "Running in wrong directory" unless -f "../qcell/Cargo.toml"; 10 | 11 | $/ = undef; 12 | 13 | for my $in () { 14 | my $prefix = $in; 15 | $prefix =~ s|^.*doctest_(.*?)\.rs$|trybuild-qcell/src/compiletest/$1|; 16 | 17 | die "Can't read $in" unless open IN, "<$in"; 18 | my $data = ; 19 | die "Can't read $in" unless close IN; 20 | 21 | my @tests = (); 22 | my %index = (); 23 | while (1) { 24 | last unless $data =~ s/```compile_fail(.*?)```//s; 25 | my $test = $1; 26 | 27 | $test =~ s|//!#?||sg; 28 | $test =~ s/^/ /mg; 29 | $test =~ s/^[ \t]*\n//s; # Remove initial empty line 30 | $test =~ s/\s*$//s; 31 | 32 | my $testdata = <<"EOF"; 33 | extern crate qcell; 34 | 35 | #[allow(warnings)] 36 | fn main() { 37 | $test 38 | } 39 | EOF 40 | push @tests, $testdata; 41 | $index{$testdata} = @tests-1; 42 | } 43 | 44 | for my $fnam (<$prefix-*.rs>) { 45 | die "Can't read $in" unless open IN, "<$fnam"; 46 | my $data = ; 47 | die "Can't read $in" unless close IN; 48 | 49 | # Keep the file if it is still identical to a test still 50 | # required, else delete it 51 | my $match = $index{$data}; 52 | if (defined $match) { 53 | $tests[$match] = ''; 54 | } else { 55 | print "Deleting $fnam ...\n"; 56 | die "Can't delete file: $fnam" unless unlink $fnam; 57 | 58 | # Also delete error file if present 59 | my $stderr = $fnam; 60 | $stderr =~ s/\.rs$/.stderr/; 61 | unlink $stderr; 62 | } 63 | } 64 | 65 | # Output the rest in a sequential order 66 | my $cnt = 0; 67 | for $data (@tests) { 68 | next if $data eq ''; 69 | 70 | while (1) { 71 | my $out = sprintf("%s-%02d.rs", $prefix, $cnt++); 72 | next if -f $out; 73 | print "Writing $out ...\n"; 74 | die "Can't create file: $out" unless open OUT, ">$out"; 75 | print OUT $data; 76 | die "Can't write file: $out" unless close OUT; 77 | last; 78 | } 79 | } 80 | } 81 | --------------------------------------------------------------------------------