Skip to content

MIR-borrowck: add permisson checks to fn access_lvalue #44837

Closed
@pnkfelix

Description

@pnkfelix
Member

As noted in a comment by arielb1, the fn access_lvalue needs to check somewhere that the accessor actually has sufficient permissions for the operation being requested, aka no mutable borrows of immutable references or moves through a non-Box reference.

Activity

added
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Oct 4, 2017
pnkfelix

pnkfelix commented on Oct 9, 2017

@pnkfelix
MemberAuthor

To elaborate, here are some examples of the kinds of scenarios we are worried about:

&mut of imm ref

For mutable borrows of immutable references, here is a case that mir-borrowck today does not properly catch (and, I think, none of the PR's in flight will fix):

fn main() {
    let mut x = &3;
    let rw = &mut *x;
    *rw = 4;
    println!("x: {:?}", x);
}

Compiling this with -Z borrowck-mir on today's master yields this single error from the AST-borrowck alone:

error[E0596]: cannot borrow immutable borrowed content `*x` as mutable
 --> check-access-lvalue.rs:3:19
  |
3 |     let rw = &mut *x;
  |                   ^^ cannot borrow as mutable

error: aborting due to previous error

Move through non-Box ref

... hmm... I am having trouble constructing an example of this where AST-borrowck and MIR-borrowck differ in behavior. (Which is strange because I thought there was significant portions of box-support that remained to be implemented. I'll have to look more deeply into this.)

pnkfelix

pnkfelix commented on Oct 9, 2017

@pnkfelix
MemberAuthor

@zilbuz also notes this example (though I think it might a bit different thing to check, since this AFAICT is about checking that the local _a has a let mut declaration...)

fn main() {
    let a = 1;
    let _a = &a;
    let __a = &mut _a;
}
nikomatsakis

nikomatsakis commented on Nov 9, 2017

@nikomatsakis
Contributor

Here is some pseudocode for the various permissions I think we might want to check:

https://gist.github.com/nikomatsakis/90102114e8ba5792d4e28a6960942ae6

In each case, there is a function that, given an lvalue, tells you whether it can be mutated or whether it can be moved from. The function returns Err(lv) if the action is illegal, in which case lv is the lvalue we can "blame" for that.

added a commit that references this issue on Nov 13, 2017

Auto merge of #45436 - zilbuz:issue-44837, r=nikomatsakis

212d74f
arielb1

arielb1 commented on Nov 15, 2017

@arielb1
Contributor

The permission checks still let you assign/mutate through an immutable reference:

fn main() {
    let a = &5;
    *a = 6; // no MIR error !!!
}

e.g. the test compile-fail/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs

2 remaining items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-borrow-checkerArea: The borrow checkerC-bugCategory: This is a bug.T-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

        Participants

        @nikomatsakis@pnkfelix@TimNN@arielb1

        Issue actions

          MIR-borrowck: add permisson checks to `fn access_lvalue` · Issue #44837 · rust-lang/rust