Skip to content

[MIR Borrowck] Handle borrows of array elements #46014

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

Closed
wants to merge 4 commits into from

Conversation

sinkuu
Copy link
Contributor

@sinkuu sinkuu commented Nov 15, 2017

Fixes #45537.

@kennytm kennytm added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 16, 2017
@nikomatsakis
Copy link
Contributor

r? @arielb1


// `&a[i][j]` borrows entire `a`
while let mir::Lvalue::Projection(ref proj) = *lvalue {
if let mir::ProjectionElem::Index(_) = proj.elem {
Copy link
Member

@pnkfelix pnkfelix Nov 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we need to recur on walk down other variants of ProjectionElem as well here? E.g. what if we there is a Field-access or a Downcast mixed into the projection?

Copy link
Member

@pnkfelix pnkfelix Nov 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking more about it, the real bug here may be the use of Lvalue within the struct BorrowData. It probably needs to be an abstraction of Lvalue, in order to unify cases like a[0] with a[1] while still allowing us to differentiate cases like a[0].foo and a[0].bar...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is a concrete example that this PR does not currently handle:

    struct S<T> { x: T, y: T, }
    let mut v = [S { x: 1, y: 2 },
                 S { x: 3, y: 4 },
                 S { x: 5, y: 6 }];
    let p = &v[0].x;
    if true {
        use_x(*p);
    } else {
        use_x(22);
    }
    v[0].x += 1; //[ast]~ ERROR cannot assign to `v[..]`

Copy link
Member

@pnkfelix pnkfelix Nov 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that when I said "It probably needs to be an abstraction of Lvalue", I was basically talking about what the move paths code does; see here: https://github.com/rust-lang/rust/blob/master/src/librustc_mir/dataflow/move_paths/abs_domain.rs (and here)

@sinkuu sinkuu force-pushed the mir-borrowck-array-elem branch 3 times, most recently from 1a17080 to 26fc1f8 Compare November 18, 2017 13:56
@bors
Copy link
Collaborator

bors commented Nov 18, 2017

☔ The latest upstream changes (presumably #46032) made this pull request unmergeable. Please resolve the merge conflicts.

@sinkuu sinkuu force-pushed the mir-borrowck-array-elem branch from 8e72c70 to 919bc8e Compare November 19, 2017 04:06
@sinkuu sinkuu force-pushed the mir-borrowck-array-elem branch from 919bc8e to c55200a Compare November 19, 2017 04:08
@pnkfelix
Copy link
Member

pnkfelix commented Nov 22, 2017

So, to start off: I have not read this version of the PR in depth yet. To be honest I was actually expecting a change to the struct BorrowData like replacing the lvalue it holds with a MovePathIndex. (I know I didn't suggest such a thing; it was just something that's been sitting in the back of my head.)

Skimming over this version of the change, I'm a little surprised by the need to revise how the various kinds of prefixes are handled.

Well, let me put it another way: I thought the previous version of the code was pretty readable, in terms of being able to tell immediately, at each iterator, which kind of iteration was being performed. This new version is doing calculations involving ps.len() - bps.len(), and I would feel pretty scared trying to modify those for loops as they are written here.

  • (If we want to stick with the new representation (with these extra fields in BorrowData), then I would want to at least encapsulate this representational choice? E.g. keep the existing enum for selecting what kind of prefix-set we want to iterate over, and have the iterator itself do these machinations with the various lengths. BUT: first I want to figure out if this representation is something we want to adopt.)

@pnkfelix
Copy link
Member

Hi @sinkuu by the way, thank you for working on this Pull Request, and sorry it took so long for me to look at your revised version

I just spoke with @arielb1 and it sounds like they have a more general fix in the works for this bug, so I am going to close this Pull Request.

If you would like to help out with other issues related to the NLL work, I invite you to join the WG-compiler-nll gitter instance ( https://gitter.im/rust-impl-period/WG-compiler-nll ) so that we can all coordinate work accordingly.

@pnkfelix pnkfelix closed this Nov 22, 2017
@sinkuu sinkuu deleted the mir-borrowck-array-elem branch November 22, 2017 23:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants