Skip to content

NLL migration mode is accepting code that both NLL and AST-borrowck reject! #53026

Closed
@pnkfelix

Description

@pnkfelix

D'oh: while investigating #52979, I found a case where we are downgrading the NLL errors to warnings (due to the migration mode added in #52681), but AST-borrowck issues an error for the test! (This may explain #53004, at least in part...)

Namely, ui/borrowck/issue-45983.rs. Here is the test:

fn give_any<F: for<'r> FnOnce(&'r ())>(f: F) {
f(&());
}
fn main() {
let x = None;
give_any(|y| x = Some(y));
//~^ ERROR borrowed data cannot be stored outside of its closure
}

Here is the AST-borrowck output (a hard error):

error: borrowed data cannot be stored outside of its closure
--> $DIR/issue-45983.rs:17:27
|
LL | let x = None;
| - borrowed data cannot be stored into here...
LL | give_any(|y| x = Some(y));
| --- ^ cannot be stored outside of its closure
| |
| ...because it cannot outlive this closure
error: aborting due to previous error

And here is the NLL output (another hard error):

warning: not reporting region error due to nll
--> $DIR/issue-45983.rs:17:27
|
LL | give_any(|y| x = Some(y));
| ^
error: borrowed data escapes outside of closure
--> $DIR/issue-45983.rs:17:18
|
LL | let x = None;
| - `x` is declared here, outside of the closure body
LL | give_any(|y| x = Some(y));
| - ^^^^^^^^^^^ `y` escapes the closure body here
| |
| `y` is a reference that is only valid in the closure body
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/issue-45983.rs:17:18
|
LL | let x = None;
| - help: consider changing this to be mutable: `mut x`
LL | give_any(|y| x = Some(y));
| ^^^^^^^^^^^ cannot assign
error: aborting due to 2 previous errors

But here is the output from -Z borrowck=migrate -Z two-phase-borrows:

warning: not reporting region error due to nll
  --> ../src/test/ui/borrowck/issue-45983.rs:17:27
   |
17 |     give_any(|y| x = Some(y));
   |                           ^

warning: borrowed data escapes outside of closure
  --> ../src/test/ui/borrowck/issue-45983.rs:17:18
   |
16 |     let x = None;
   |         - `x` is declared here, outside of the closure body
17 |     give_any(|y| x = Some(y));
   |               -  ^^^^^^^^^^^ `y` escapes the closure body here
   |               |
   |               `y` is a reference that is only valid in the closure body
   |
   = warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
           It represents potential unsoundness in your code.
           This warning will become a hard error in the future.

warning[E0594]: cannot assign to `x`, as it is not declared as mutable
  --> ../src/test/ui/borrowck/issue-45983.rs:17:18
   |
16 |     let x = None;
   |         - help: consider changing this to be mutable: `mut x`
17 |     give_any(|y| x = Some(y));
   |                  ^^^^^^^^^^^ cannot assign
   |
   = warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
           It represents potential unsoundness in your code.
           This warning will become a hard error in the future.

ui/borrowck/issue-45983.rs is one particular instance of this, but now that I've found one, I'm certain there are more.

This is pretty bad. Very high priority to fix.

Metadata

Metadata

Assignees

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 priority

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions