Skip to content

Change check_loans to use ExprUseVisitor #14318

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

Merged
merged 9 commits into from
Jun 6, 2014
Merged

Change check_loans to use ExprUseVisitor #14318

merged 9 commits into from
Jun 6, 2014

Conversation

zwarich
Copy link

@zwarich zwarich commented May 21, 2014

I tried to split up the less mechanical changes into separate commits so they are easier to review. One thing I'm not quite sure of is whether MoveReason should just be replaced with move_data::MoveKind.

@zwarich zwarich mentioned this pull request May 21, 2014
@zwarich
Copy link
Author

zwarich commented May 21, 2014

r? @nikomatsakis

@zwarich
Copy link
Author

zwarich commented May 21, 2014

Maybe it would make more sense for the mutate() callback to ignore all mutations with a MutateMode of Init than just ignoring them for function arguments? All tests pass that way and it seems correct.

@zwarich
Copy link
Author

zwarich commented May 23, 2014

Going over the patch again, I realize that the changed results in src/test/compile-fail/borrowck-use-in-index-lvalue.rs indicate a real problem. I have a fix, which I will push after verifying that a full make check still passes.

@zwarich
Copy link
Author

zwarich commented May 23, 2014

I pushed my changes. The only difference is in the mutate implementation.

@huonw
Copy link
Member

huonw commented May 23, 2014

(Needs a rebase.)

@zwarich
Copy link
Author

zwarich commented May 23, 2014

Rebased to account for the string refactoring.

@nikomatsakis
Copy link
Contributor

@zwarich I added some comments, a few things concern me, can you let me know what you think?

@zwarich
Copy link
Author

zwarich commented May 23, 2014

I replied to your comments, although I can't seem to find them outside of my email inbox since they were on a pre-rebase version of my changes (is this just some GitHub UI issue?). The most concerning issue (the new incorrect test result) was fixed in a newer version of the changes, and I left questions for you about the others. Let me know what you think and I'll update my changes again.

@zwarich
Copy link
Author

zwarich commented May 25, 2014

@nikomatsakis I pushed some updated commits to my branch. I changed some things in response to your previous comments:

  • I renamed the variants of MoveReason to DirectRefMove, PatBindingMove, and CaptureMove.
  • I changed check_loans to not use MoveReason at all; it is now able to determine whether moves are captures purely from the move data itself. This also simplifies the code.
  • In the implementation of mutate I check whether a path contains any derefs to determine whether the JustWrite case is safe without considering moves. Your suggestion to use the superpath didn't work because of the check for interfering paths in FlowedMoveData's each_move_of. As you can see from the new test cases I added, this check combined with switching to ExprUseVisitor enables a lot of field-sensitivity. The only case remaining is realizing that assigning to a field after a move of the aggregate invalidates the move of the field.
  • I renamed the equivalent of check_move_out_from_id to check_for_move_of_borrowed_value, because that name makes a lot more sense.
  • I added a lot more tests, both failing and passing, including moving all of the now-passing cases from compile-fail to a new test in run-pass.

@zwarich
Copy link
Author

zwarich commented May 25, 2014

I made two small changes to my branch. I noticed that all of the code in consume and consume_pat was basically identical, and moved it into consume_common. I also renamed check_for_move_of_borrowed_value to check_for_move_of_borrowed_path, since that name makes a bit more sense in this context.

let y = &mut x.a;
let z = &mut x.a; //~ ERROR cannot borrow `x.a` as mutable more than once at a time
drop(*y);
drop(*z);
Copy link
Contributor

Choose a reason for hiding this comment

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

I am surprised that we can drop *y and *z, as that is borrowed content. Is this simply an artifact of us not reporting an error for some other reason?

Copy link
Author

Choose a reason for hiding this comment

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

It's fine because *y and *z are integers, and they seem to get copied rather than moved. This code compiles fine:

fn foo() {
    let mut x = A { a: 1, b: box 2 };
    let y = &mut x.a;
    drop(*y);
}

but if I use the x.b field, which is a Box<int>, like this:

fn bar() {
    let mut x = A { a: 1, b: box 2 };
    let y = &mut x.b;
    drop(*y);
}

then I get an error:

test.rs:24:10: 24:12 error: cannot move out of dereference of `&mut`-pointer
test.rs:24     drop(*y);
                    ^~

Copy link
Contributor

Choose a reason for hiding this comment

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

On Wed, May 28, 2014 at 12:46:04PM -0700, Cameron Zwarich wrote:

It's fine because *y and *z are integers, and they seem to get copied rather than moved.

Indeed. I overlooked that.

Cameron Zwarich added 9 commits June 6, 2014 11:59
Refactor a number of functions in check_loans to take node IDs and spans
rather than taking expressions directly. Also rename some variables to
make them less ambiguous.

This is the first step towards using ExprUseVisitor in check_loans, as
now some of the interfaces more closely match those used in
ExprUseVisitor.
Currently mem_categorization categorizes an AutoObject adjustment the
same as the original expression. This can cause two moves to be
generated for the same underlying expression. Currently this isn't a
problem in practice, since check_loans doesn't rely on ExprUseVisitor.
This isn't necessary right now, but check_loans needs to be able to
distinguish between initialization and writes in the ExprUseVisitor
mutate callback.
Currently it is not possible to distinguish moves caused by captures
in the ExprUseVisitor interface. Since check_Loans needs to make that
distinction for generating good diagnostics, this is necessary for
check_loans to switch to ExprUseVisitor.
When converting check_loans to use ExprUseVisitor I encountered a few
issues where the wrong number of errors were being emitted for multiple
closure captures, but there is no existing test for this.
bors added a commit that referenced this pull request Jun 6, 2014
I tried to split up the less mechanical changes into separate commits so they are easier to review. One thing I'm not quite sure of is whether `MoveReason` should just be replaced with `move_data::MoveKind`.
@bors bors closed this Jun 6, 2014
@bors bors merged commit f1542a6 into rust-lang:master Jun 6, 2014
bors added a commit that referenced this pull request Jun 7, 2014
After sitting down to build on the work merged in #14318, I realized that some of the test names were not clear, others probably weren't testing the right thing, and they were also not as exhaustive as they could have been.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants