alexcrichton / futures-await

Apache License 2.0
734 stars 55 forks source link

unsafe allowed inside `#[async]` functions #74

Closed Nemo157 closed 6 years ago

Nemo157 commented 6 years ago

As an example, running this will segfault without any warnings:

#![feature(proc_macro, conservative_impl_trait, generators)]

extern crate futures_await as futures;

use futures::prelude::async;

#[async]
fn glass() -> Result<u32, futures::Never> {
    Ok(*(::std::ptr::null() as *const u32))
}

fn main() {
    futures::stable::block_on_stable(glass()).unwrap();
}

while the same example with s/async/async_move/ will fail to compile:

error[E0133]: dereference of raw pointer requires unsafe function or block
 --> examples/safety.rs:9:8
  |
9 |     Ok(*(::std::ptr::null() as *const u32))
  |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereference of raw pointer

This appears to be caused by this unhygenic unsafe block, I assume this has something to do with self-referential generators, but I'm hoping there's some way to fix this to avoid accidental unsafety.

withoutboats commented 6 years ago

Ugh this is quite problematic! Once Pin stuff lands, we can make changes to generators so that this unsafe block should be going away, but until then... cc @cramertj

Arnavion commented 6 years ago

Please backport this to 0.1.x while 0.2.x is still alpha.

   Compiling futures-await v0.1.0
error[E0133]: call to unsafe function requires unsafe function or block
   --> C:\Users\Arnavion\.cargo\registry\src\github.com-1ecc6299db9ec823\futures-await-0.1.0\src\lib.rs:123:19
    |
123 |             match self.0.resume() {
    |                   ^^^^^^^^^^^^^^^ call to unsafe function

error[E0133]: call to unsafe function requires unsafe function or block
   --> C:\Users\Arnavion\.cargo\registry\src\github.com-1ecc6299db9ec823\futures-await-0.1.0\src\lib.rs:143:19
    |
143 |             match self.gen.resume() {
    |                   ^^^^^^^^^^^^^^^^^ call to unsafe function
Nemo157 commented 6 years ago

See #79, this is actually about the inverse problem where you could use unsafe functions without adding an unsafe block to your code.