Skip to content

Dropped non-Send incorrectly reported as living, resulting in non-Send Future #136060

Closed as duplicate of#63768
@TommasoTricker

Description

@TommasoTricker

This:

struct NonSend(*const ());

impl NonSend {
	fn noop(&self) {}
}

fn main() {
	assert_send(async {
		let x = NonSend(core::ptr::null());
		x.noop();
		drop(x);
		async {}.await;
	});
}

fn assert_send(_: impl Send) {}

Playground

Errors with:

error: future cannot be sent between threads safely
  --> src/main.rs:8:2
   |
8  | /     assert_send(async {
9  | |         let x = NonSend(core::ptr::null());
10 | |         x.noop();
11 | |         drop(x);
12 | |         async {}.await;
13 | |     });
   | |______^ future created by async block is not `Send`
   |
   = help: within `{async block@src/main.rs:8:14: 8:19}`, the trait `Send` is not implemented for `*const ()`
note: future is not `Send` as this value is used across an await
  --> src/main.rs:12:12
   |
9  |         let x = NonSend(core::ptr::null());
   |             - has type `NonSend` which is not `Send`
...
12 |         async {}.await;
   |                  ^^^^^ await occurs here, with `x` maybe used later
note: required by a bound in `assert_send`
  --> src/main.rs:16:24
   |
16 | fn assert_send(_: impl Send) {}
   |                        ^^^^ required by this bound in `assert_send`

error: could not compile `playground` (bin "playground") due to 1 previous error

It states that the non-Send x might be used across the await; however, this is not possible, as it has been dropped.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions