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

RFC: Pattern Guards with Bind-By-Move #107

Merged
merged 3 commits into from
Jun 30, 2014
Merged

RFC: Pattern Guards with Bind-By-Move #107

merged 3 commits into from
Jun 30, 2014

Conversation

zwarich
Copy link

@zwarich zwarich commented Jun 6, 2014

@huonw
Copy link
Member

huonw commented Jun 6, 2014

What is the validity of these:

// A
match x {
    A(v) if { drop(v); true } => 1,
    _ => 2
}
// B
match x {
    A(v) if { drop(v); true } => 1,
    A(v) => v.len() 
}
// C
match x {
     A(v) if true => v,
     A(v) => v
}
// D
enum Foo { X(Box<int>), Y }
match some_foo {
    X(b) if { drop(b); true } => (),
    Y => {}
    _ => {}
}

I assume that A, C and D are valid, but B is not.

(I ask these since all your examples have only one non-_ arm, and there's no example that's valid and that moves out in the guard itself.)

@Florob
Copy link

Florob commented Jun 6, 2014

@huonw Is that based on the assumption that a value is not moved, when it is not used in the match arm? That is not currently the case. I would expect only C to be valid, since all others move into the match arm and inside the pattern guard, equivalently to the rejected example in the RFC.

@zwarich
Copy link
Author

zwarich commented Jun 6, 2014

@huonw No moves of a bound-by-move value would be permitted in the guard, because there is a move between the guard and the expression, and any move in the guard would result in a double move. The only example that would be valid is C. Maybe I'll update the examples in the RFC to mention this.

@kmcallister
Copy link
Contributor

+1, this would be very useful to me in the HTML parser, e.g.

token @ StartTag(ref tag) if named!(tag, html)
    => self.step(states::InBody, token)  // pass by move to another state

@nikomatsakis
Copy link
Contributor

This has definite interaction with the plans to remove zero flags.

@zwarich
Copy link
Author

zwarich commented Jun 19, 2014

@kmcallister, your exact example would also need nonlexical borrow scopes to be accepted. With the current system, the borrow for ref tag would conflict with the move into token.

@zwarich
Copy link
Author

zwarich commented Jun 24, 2014

@nikomatsakis, what is the interaction with removing zero flags here? Removing zero flags will require checking that each control-flow merge point has the same moved paths. Since there is no new move here (just clarification about when it occurs), I don't see how it could complicate anything.

In the Rust meeting it was decided that this should go in behind a
feature gate. I arbitrarily chose the `bind_by_move_pattern_guards`
name.
@alexcrichton
Copy link
Member

This was discussed at a recent meeting and it was concluded that we would like to merge this with the condition that a feature gate was mentioned in the RFC.

The RFC has been updated, so I'm merging.

@alexcrichton alexcrichton merged commit 5e30b71 into rust-lang:master Jun 30, 2014
@eminence
Copy link
Contributor

eminence commented Oct 4, 2015

Now that this RFC is merged, the above "rendered view" link is broken. The text of this RFC can now be found here:

https://github.com/rust-lang/rfcs/blob/master/text/0107-pattern-guards-with-bind-by-move.md

withoutboats pushed a commit to withoutboats/rfcs that referenced this pull request Jan 15, 2017
@Centril Centril added A-patterns Pattern matching related proposals & ideas A-control-flow Proposals relating to control flow. A-borrowck Borrow checker related proposals & ideas A-syntax Syntax related proposals & ideas labels Nov 23, 2018
wycats pushed a commit to wycats/rust-rfcs that referenced this pull request Mar 5, 2019
@Pzixel
Copy link

Pzixel commented Oct 14, 2019

Any ideas/progress on that? I think this is perfectly valid code:

fn f(x: Option<String>) {
    match x {
        Some(a) if &a == "Hello" => println!("x is Hello"),
        Some(b) => println!("x is not Hello but {}", b),
        None => println!("none"),
    }
}

But borrowcheker currently won't accept it

The thumb rule here is if we only use matched values by-reference they could be logically moved back to x if guard didn't pass the check.

@CryZe
Copy link

CryZe commented Oct 14, 2019

This works just fine in 1.39, which is currently in Beta.

@Pzixel
Copy link

Pzixel commented Oct 14, 2019

Wow, guys, you're so quick.

I wonder if I ask about GAT and they appear in 2 minutes thereafter... 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-borrowck Borrow checker related proposals & ideas A-control-flow Proposals relating to control flow. A-patterns Pattern matching related proposals & ideas A-syntax Syntax related proposals & ideas
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants