Skip to content

Commit

Permalink
Merge pull request #36 from moka-rs/get-or-try-insert-tests
Browse files Browse the repository at this point in the history
Add UI tests for `get_or_try_insert_with`
  • Loading branch information
tatsuya6502 committed Sep 7, 2021
2 parents 33f2a5f + 86d26a3 commit 988816a
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 0 deletions.
24 changes: 24 additions & 0 deletions tests/ui/future/try_get_with_non_send_future.rs
@@ -0,0 +1,24 @@
// https://github.com/moka-rs/moka/issues/31

use moka::future::Cache;
use std::rc::Rc;

#[tokio::main]
async fn main() {
let cache: Cache<_, String> = Cache::new(100);

// Rc is !Send.
let data = Rc::new("zero".to_string());
let data1 = Rc::clone(&data);

cache
.get_or_try_insert_with(0, async move {
// A data race may occur.
// The async block can be executed by a different thread
// but Rc's internal reference counters are not thread safe.
Ok(data1.to_string())
})
.await;

println!("{:?}", data);
}
12 changes: 12 additions & 0 deletions tests/ui/future/try_get_with_non_send_future.stderr
@@ -0,0 +1,12 @@
error: future cannot be sent between threads safely
--> $DIR/try_get_with_non_send_future.rs:15:10
|
15 | .get_or_try_insert_with(0, async move {
| ^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
|
= help: within `impl Future`, the trait `Send` is not implemented for `Rc<String>`
note: captured value is not `Send`
--> $DIR/try_get_with_non_send_future.rs:19:16
|
19 | Ok(data1.to_string())
| ^^^^^ has type `Rc<String>` which is not `Send`
25 changes: 25 additions & 0 deletions tests/ui/future/try_get_with_non_static_future.rs
@@ -0,0 +1,25 @@
// https://github.com/moka-rs/moka/issues/31

use moka::future::Cache;

#[tokio::main]
async fn main() {
let cache: Cache<_, String> = Cache::new(100);

let data = "zero".to_string();
{
// Not 'static.
let data_ref = &data;

cache
.get_or_try_insert_with(0, async {
// This may become a dangling pointer.
// The async block can be executed by a different thread so
// the captured reference `data_ref` may outlive its value.
Ok(data_ref.to_string())
})
.await;
}

println!("{:?}", data);
}
41 changes: 41 additions & 0 deletions tests/ui/future/try_get_with_non_static_future.stderr
@@ -0,0 +1,41 @@
error[E0597]: `data` does not live long enough
--> $DIR/try_get_with_non_static_future.rs:12:24
|
12 | let data_ref = &data;
| ^^^^^ borrowed value does not live long enough
...
15 | .get_or_try_insert_with(0, async {
| ________________________________________-
16 | | // This may become a dangling pointer.
17 | | // The async block can be executed by a different thread so
18 | | // the captured reference `data_ref` may outlive its value.
19 | | Ok(data_ref.to_string())
20 | | })
| |_____________- argument requires that `data` is borrowed for `'static`
...
25 | }
| - `data` dropped here while still borrowed

error[E0373]: async block may outlive the current function, but it borrows `data_ref`, which is owned by the current function
--> $DIR/try_get_with_non_static_future.rs:15:46
|
15 | .get_or_try_insert_with(0, async {
| ______________________________________________^
16 | | // This may become a dangling pointer.
17 | | // The async block can be executed by a different thread so
18 | | // the captured reference `data_ref` may outlive its value.
19 | | Ok(data_ref.to_string())
| | -------- `data_ref` is borrowed here
20 | | })
| |_____________^ may outlive borrowed value `data_ref`
|
= note: async blocks are not executed immediately and must either take a reference or ownership of outside variables they use
help: to force the async block to take ownership of `data_ref` (and any other referenced variables), use the `move` keyword
|
15 | .get_or_try_insert_with(0, async move {
16 | // This may become a dangling pointer.
17 | // The async block can be executed by a different thread so
18 | // the captured reference `data_ref` may outlive its value.
19 | Ok(data_ref.to_string())
20 | })
|

0 comments on commit 988816a

Please sign in to comment.