-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
implement feature gate bind_by_move_pattern_guards #42088
Conversation
implementation of issue rust-lang#15287
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @frewsxcv (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
I think that this is all that is needed. but I have some concerns about the error messages, shall the old be used or shall a new refering to the feature gate be added? |
Thanks for the PR @andjo403! It looks like there may be a failing test on Travis though?
I'll also change this to r? @eddyb, a random member from the compiler team. |
do not know how I missed that, may be too eager to send my first PR to rust :) |
r? @nikomatsakis or @arielb1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have to think a bit about how I'd prefer to move forward here. It might be that deploying the ExprUseVisitor
(and changing nothing else) suffices for now. But it might be that we want to handle this a bit more comprehensively. If the former, I'll try to write some notes shortly on what to do.
@@ -486,7 +486,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, | |||
"cannot bind by-move with sub-bindings") | |||
.span_label(p.span, "binds an already bound by-move value by moving it") | |||
.emit(); | |||
} else if has_guard { | |||
} else if has_guard && !cx.tcx.sess.features.borrow().bind_by_move_pattern_guards { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I think that this doesn't suffice. Specifically, there are cases we want to disallow, such as this:
let x = Some(vec![1, 2, 3]);
match x {
Some(v) if { mem::drop(v); true } => { println!("empty"); }
Some(v) => { println!("not-empty: {:?}", v); }
None => { println!("None!"); }
}
The danger is that v
the vector will get freed after the first guard is executed.
I think that the RFC specifically stated that we should allow this but only if the guard only uses the value "by reference" (or if it only copies).
One way to do this analysis would be to deploy the ExprUseVisitor
. I think the option I prefer at this point is to say that, when the guard executes, we treat the bound values as if there was an implicit shared reference (much like how a closure works). This probably requires an RFC, though I think it's backwards compatible.
In the example above, that would mean that references to v
in the pattern guard would be treated as equivalent to *v0
where v0
is a synthetic variable with type &Vec<i32>
; hence the mem::drop(v)
guard would be equivalent to mem::drop(*v0)
, which would mean that it'd be an error (since you are moving through a borrowed reference).
☔ The latest upstream changes (presumably #42058) made this pull request unmergeable. Please resolve the merge conflicts. |
I do not know how to continue with this PR. Shall I try to implement a check with ExprUseVisitor? the other prefered solution I have no ide of how to do so there I needs some more info to get started. |
ping @nikomatsakis, do you have thoughts on @andjo403's last comment? |
Sorry, I've started writing up a few responses but never finished them. I'm not sure the best path either. I suspect that the right answer here lies in leveraging a MIR-based borrowck, but it's not necessarily the case that the right code will just "fall out'. Let me put this another way: with a MIR-based borrowck, I think that we could remove the various hard-coded rules about guards and everything would work just in terms of being sound, but we might accept programs we did not intend to. Basically, we might be tying out hands to details of how we lower match statements that we do not want to. This is one of the "to be addressed" use cases that the first PR will not handle. Probably the right thing is to close this particular PR, but @andjo403 it'd be very cool to try and start afresh while working on the MIR. I'm not sure exactly what that entails though, there's a bit of discussion still needed I fear. |
no problem I close this I missed that the hard case did not work. thougth that the issue hade been solved by all changes in the last year of the compiler and only forgotten. |
implementation of issue #15287