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

Mutable borrows in an else if after an if let are disallowed #28449

Closed
ftxqxd opened this issue Sep 16, 2015 · 4 comments
Closed

Mutable borrows in an else if after an if let are disallowed #28449

ftxqxd opened this issue Sep 16, 2015 · 4 comments

Comments

@ftxqxd
Copy link
Contributor

ftxqxd commented Sep 16, 2015

fn main() {
    let mut f = Some(1);
    if let Some(a) = f {
    } else if f.as_mut().is_some() {}
}

Gives:

<anon>:4:15: 4:16 error: cannot mutably borrow in a pattern guard [E0301]
<anon>:4     } else if f.as_mut().is_some() {}
                       ^
note: in expansion of if let expansion
<anon>:3:5: 4:38 note: expansion site

This is an unexpected result of how if let desugaring works, presumably. It’s unexpected because mutable borrowing is normally allowed in else if conditions, but because if let seems to desugar a following else if into a pattern guard, this is disallowed.

To me it would make more sense for this to be treated like any other else if, and be permitted, or at the very least have a clearer message (because it’s not obvious (and is really just an implementation detail) how an else if condition is a pattern guard).

@sfackler
Copy link
Member

if let desugars to a match, which is how that error message is showing up:

match f {
    Some(a) => {}
    _ if f.as_mut().is_some() {}
    _ => {}
}

@arielb1
Copy link
Contributor

arielb1 commented Sep 17, 2015

duplicate #6393

@arielb1 arielb1 closed this as completed Sep 17, 2015
@arielb1
Copy link
Contributor

arielb1 commented Sep 17, 2015

actually, not.

Why is this a pattern guard rather than an if in the _ anyway?

@arielb1 arielb1 reopened this Sep 17, 2015
@Aatch
Copy link
Contributor

Aatch commented Sep 18, 2015

@arielb1 it's a pattern guard because this works:

if let Some(1) = foo {

} else if check(&foo) {

} else if let Some(a) = foo {

}

Obviously this doesn't require desugaring to a single match, but it does explain why it does right now.

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

No branches or pull requests

4 participants