Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent evaluation order for assignment operations #27868

Closed
eefriedman opened this issue Aug 17, 2015 · 10 comments · Fixed by #64221
Closed

Inconsistent evaluation order for assignment operations #27868

eefriedman opened this issue Aug 17, 2015 · 10 comments · Fixed by #64221
Labels
A-borrow-checker Area: The borrow checker A-NLL Area: Non Lexical Lifetimes (NLL) C-bug Category: This is a bug. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness NLL-fixed-by-NLL Bugs fixed, but only when NLL is enabled. P-medium Medium priority T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@eefriedman
Copy link
Contributor

eefriedman commented Aug 17, 2015

UPDATE: This is fixed by the MIR-based borrow checker and just needs a test. See the mentoring instructions below.


Currently, the borrow checker thinks that the RHS of += is evaluated before the LHS. trans thinks that the LHS is evaluated before the RHS. The disagreement leads to bad results.

fn main() {
    let x = Box::new(0);
    let mut y = 0;
    *{ drop(x); &mut y } += *x;
    assert_eq!(y, 0);
}
@nrc
Copy link
Member

nrc commented Nov 19, 2015

triage: P-medium

Also fixed by MIR (almost a dup of #28160, but not quite)/

@rust-highfive rust-highfive added the P-medium Medium priority label Nov 19, 2015
@brson brson added E-hard Call for participation: Hard difficulty. Experience needed to fix: A lot. A-lang A-borrow-checker Area: The borrow checker labels Aug 4, 2016
@nikomatsakis
Copy link
Contributor

@steveklabnik steveklabnik added T-lang Relevant to the language team, which will review and decide on the PR/issue. and removed A-lang labels Mar 24, 2017
@Mark-Simulacrum
Copy link
Member

So the internals thread says this: "before MIR, we were actually quite inconsistent here, in that borrowck and trans disagreed on some of the particulars. MIR eliminated that inconsistency, but there are still some matters that we should try to resolve -- and quick!" If that's the case, then this should be closed. @nikomatsakis Is this the case?

@nikomatsakis
Copy link
Contributor

Well, we're not yet running the borrowck on MIR, so I'm not sure.

@nikomatsakis
Copy link
Contributor

But certainly the example seems to work ok now.

@RalfJung
Copy link
Member

RalfJung commented Jun 15, 2017

Assignment operators are still wrong, which can lead to use-after-free:

use std::ops::AddAssign;

struct MyVec<T>(Vec<T>);

impl <T> Drop for MyVec<T> {
    fn drop(&mut self) {
        println!("Being dropped.");
    }
}

impl<T> AddAssign<T> for MyVec<T> {
    fn add_assign(&mut self, _elem: T) {
        println!("In add_assign.");
    }
}

fn main() {
    let mut vec = MyVec(vec![0]);
    let mut vecvec = vec![vec];

    vecvec[0] += {
        vecvec = vec![];
        0
    };
}

Prints

Being dropped.
In add_assign.

Credit to @xfix for bringing this up in rust-lang/rfcs#2025 (comment), I just weaponized it.

@nikomatsakis nikomatsakis added the I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness label Jun 15, 2017
@Mark-Simulacrum Mark-Simulacrum added C-bug Category: This is a bug. and removed I-wrong labels Jul 22, 2017
@pnkfelix pnkfelix added A-NLL Area: Non Lexical Lifetimes (NLL) WG-compiler-nll labels Dec 21, 2017
@nikomatsakis
Copy link
Contributor

@RalfJung's example gets an error with MIR borrowck enabled (as expected):

https://play.rust-lang.org/?gist=761478ea89b3cd1df50ee274cb7a909d&version=nightly

I am filing this under "bugs fixed by MIR borrowck" #47366

@nikomatsakis nikomatsakis added E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. and removed E-hard Call for participation: Hard difficulty. Experience needed to fix: A lot. labels Apr 3, 2018
@nikomatsakis
Copy link
Contributor

nikomatsakis commented Apr 3, 2018

Marking as E-needstest and E-mentor:

Since this code works now, what we need to do is add it to our test-suite. To do that, you would create a file in src/test/ui/nll named issue-27868.rs containing the example I linked to here. There are general instructions for adding new tests here.

memoryruins added a commit to memoryruins/rust that referenced this issue Aug 14, 2018
frewsxcv added a commit to frewsxcv/rust that referenced this issue Aug 17, 2018
…omatsakis

[nll] add regression test for issue rust-lang#27868

Adds a test for rust-lang#27868 ``Inconsistent evaluation order for assignment operations``

apart of rust-lang#47366 ``tracking issue for bugs fixed by the MIR borrow checker or NLL``

r? @nikomatsakis
bors added a commit that referenced this issue Aug 17, 2018
Rollup of 11 pull requests

Successful merges:

 - #52858 (Implement Iterator::size_hint for Elaborator.)
 - #53321 (Fix usage of `wasm_target_feature`)
 - #53326 ([nll] add regression test for issue #27868)
 - #53347 (rustc_resolve: don't allow paths starting with `::crate`.)
 - #53349 ([nll] add tests for #48697 and #30104)
 - #53357 (Pretty print btreemap for GDB)
 - #53358 (`{to,from}_{ne,le,be}_bytes` for unsigned integer types)
 - #53406 (Do not suggest conversion method that is already there)
 - #53407 (make more ported compile fail tests more robust w.r.t. NLL)
 - #53413 (Warn that `#![feature(rust_2018_preview)]` is implied when the edition is set to Rust 2018.)
 - #53434 (wasm: Remove --strip-debug argument to LLD)

Failed merges:

r? @ghost
@pnkfelix
Copy link
Member

Apparently PR #53326 added the desired test here. So this is NLL-fixed-by-NLL now, I think.

@pnkfelix pnkfelix added NLL-fixed-by-NLL Bugs fixed, but only when NLL is enabled. and removed E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. NLL-deferred labels Oct 26, 2018
@pnkfelix
Copy link
Member

NLL (migrate mode) is enabled in all editions as of PR #59114.

The only policy question is that, under migrate mode, we only emit a warning on this (unsound) test case. Therefore, I am not 100% sure whether we should close this until that warning has been turned into a hard-error under our (still in development) future-compatibility lint policy.

Centril added a commit to Centril/rust that referenced this issue Sep 25, 2019
Centril added a commit to Centril/rust that referenced this issue Sep 26, 2019
…hewjasper

 Rust 2015: No longer downgrade NLL errors

As per decision on a language team meeting as described in rust-lang#63565 (comment), in Rust 2015, we refuse to downgrade NLL errors, that AST borrowck accepts, into warnings and keep them as hard errors.

The remaining work to throw out AST borrowck and adjust some tests still remains after this PR.

Fixes rust-lang#38899
Fixes rust-lang#53432
Fixes rust-lang#45157
Fixes rust-lang#31567
Fixes rust-lang#27868
Fixes rust-lang#47366

r? @matthewjasper
Centril added a commit to Centril/rust that referenced this issue Sep 26, 2019
…hewjasper

 Rust 2015: No longer downgrade NLL errors

As per decision on a language team meeting as described in rust-lang#63565 (comment), in Rust 2015, we refuse to downgrade NLL errors, that AST borrowck accepts, into warnings and keep them as hard errors.

The remaining work to throw out AST borrowck and adjust some tests still remains after this PR.

Fixes rust-lang#38899
Fixes rust-lang#53432
Fixes rust-lang#45157
Fixes rust-lang#31567
Fixes rust-lang#27868
Fixes rust-lang#47366

r? @matthewjasper
Centril added a commit to Centril/rust that referenced this issue Sep 26, 2019
Centril added a commit to Centril/rust that referenced this issue Sep 26, 2019
…hewjasper

 Rust 2015: No longer downgrade NLL errors

As per decision on a language team meeting as described in rust-lang#63565 (comment), in Rust 2015, we refuse to downgrade NLL errors, that AST borrowck accepts, into warnings and keep them as hard errors.

The remaining work to throw out AST borrowck and adjust some tests still remains after this PR.

Fixes rust-lang#38899
Fixes rust-lang#53432
Fixes rust-lang#45157
Fixes rust-lang#31567
Fixes rust-lang#27868
Fixes rust-lang#47366

r? @matthewjasper
@bors bors closed this as completed in 3b5fbb6 Sep 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-borrow-checker Area: The borrow checker A-NLL Area: Non Lexical Lifetimes (NLL) C-bug Category: This is a bug. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness NLL-fixed-by-NLL Bugs fixed, but only when NLL is enabled. P-medium Medium priority T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants