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

Variables bound with different modes in patterns #23610

Open
Stebalien opened this issue Mar 22, 2015 · 8 comments
Open

Variables bound with different modes in patterns #23610

Stebalien opened this issue Mar 22, 2015 · 8 comments
Labels
A-borrow-checker Area: The borrow checker C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Stebalien
Copy link
Contributor

The following doesn't compile:

enum Test<'a> {
    A(&'a u64),
    B(u64),
}
fn foo(test: Test) {
    match test {
        Test::A(r) | Test::B(ref r) => println!("{}", r)
    }
}
fn main() {
    foo(Test::A(&0));
    foo(Test::B(1));
}

failing with the following error:

test.rs:7:30: 7:35 error: variable `r` is bound with different mode in pattern #2 than in pattern #1
test.rs:7         Test::A(r) | Test::B(ref r) => println!("{}", r)
                                       ^~~~~
error: aborting due to previous error

However, the following does work:

enum Test<'a> {
    A(&'a u64),
    B(u64),
}
fn foo(test: Test) {
    match test {
        Test::A(&ref r) | Test::B(ref r) => println!("{}", r)
    }
}
fn main() {
    foo(Test::A(&0));
    foo(Test::B(1));
}

Is there any reason rust can't just perform this reborrow automatically? &ref is a very cryptic pattern.

@steveklabnik steveklabnik added the A-borrow-checker Area: The borrow checker label Mar 22, 2015
@ghost
Copy link

ghost commented Mar 24, 2015

Is there any reason we put in this restriction in the first place in a6a5c48? Seems like the type equality restriction on bindings should be enough.

cc @nikomatsakis

@kdeeee
Copy link

kdeeee commented Sep 30, 2016

this error still occur in rustc 1.11.0 (9b21dcd 2016-08-15)

@Mark-Simulacrum
Copy link
Member

@nikomatsakis Is there a chance the &ref pattern is actually bypassing the match checking that is intended to not allow binding both by-move and by-reference in the same arm? It seems to be, so... perhaps this is a problem in a wider sense?

@nikomatsakis
Copy link
Contributor

@Mark-Simulacrum

Is there a chance the &ref pattern is actually bypassing the match checking that is intended to not allow binding both by-move and by-reference in the same arm?

I don't understand what you mean here -- we have two bindings, both are "by reference", so how is the current code mixing by-move and by-ref in the same pattern?

@nikomatsakis
Copy link
Contributor

I think that in principle we do not need to require all bindings to be in the same mode; in that sense I agree with @ghost. However, I'm not sure how hard it would be to keep current code "up and going" without that simplifying restriction. I'd have to dig in in more detail. I think that once we are doing borrowck on MIR, things ought to be simpler, since most of the rules we have to keep borrowck + match sound could go away.

@Mark-Simulacrum
Copy link
Member

Oh, I think I misread about the two bindings being by-move and by-reference -- never mind.

I agree that we should probably leave this for after MIR borrowck (which might in its implementation resolve these sorts of issues on its own, I don't know).

@Mark-Simulacrum Mark-Simulacrum added the C-feature-request Category: A feature request, i.e: not implemented / a PR. label Jul 22, 2017
@steveklabnik
Copy link
Member

Triage: MIR borrowcheck has now landed, but this still gives this error.

@crlf0710 crlf0710 added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Jun 11, 2020
@Dylan-DPC Dylan-DPC added C-bug Category: This is a bug. and removed C-feature-request Category: A feature request, i.e: not implemented / a PR. labels Nov 19, 2023
@Dylan-DPC
Copy link
Member

Current error:

error[E0409]: variable `r` is bound inconsistently across alternatives separated by `|`
 --> src/main.rs:7:34
  |
7 |         Test::A(r) | Test::B(ref r) => println!("{}", r)
  |                 - first binding  ^ bound in different ways

For more information about this error, try `rustc --explain E0409`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-borrow-checker Area: The borrow checker C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants