Skip to content

NLL migrate mode erroneously downgrades error with nested closures, yielding use-after-free #58776

Closed
@RalfJung

Description

@RalfJung

The following code compiles with the 2018 edition on stable, beta and nightly, and produces this error:

Execution operation failed: Output was not valid UTF-8: invalid utf-8 sequence of 1 bytes from index 1813

Code:

use std::marker::PhantomData;

struct Scope<'env> {
    invariant: PhantomData<fn(&'env ()) -> &'env ()>
}

fn scope<'env, F, T>(f: F) -> T
where
    F:  FnOnce(&Scope<'env>) -> T
{
    f(&Scope { invariant: PhantomData })
}

impl<'env> Scope<'env> {
    fn spawn<'scope, F, T>(&'scope self, f: F) -> T
    where
        F: FnOnce() -> T + Send + 'env,
        T: Send + 'env
    {
        f()
    }
}

fn main() {
    let mut greeting = "Hello world!".to_string();
    let res = scope(|s| s.spawn(|| &greeting));

    greeting = "DEALLOCATED".to_string();
    drop(greeting);

    println!("thread result: {:?}", res);
}

And indeed there's a use-after-free here.

Interestingly, in the 2015 edition this is correctly detected as incorrect, though the error is not quite what I would have expected:

   Compiling playground v0.0.1 (/playground)
error[E0597]: `*greeting` does not live long enough
  --> src/main.rs:26:37
   |
26 |     let res = scope(|s| s.spawn(|| &greeting));
   |                                 --  ^^^^^^^^ - borrowed value only lives until here
   |                                 |   |
   |                                 |   borrowed value does not live long enough
   |                                 capture occurs here
...
32 | }
   | - borrowed value needs to live until here

I would have expected a complaint at the re-assignment of greeting.

(I found this while modifying an example by @stjepang and failing to reproduce some code that gets a migration warning on 2018...)

Metadata

Metadata

Labels

A-NLLArea: Non-lexical lifetimes (NLL)I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessNLL-soundWorking towards the "invalid code does not compile" goalP-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions