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

librustc: Forbid pattern bindings after @s, for memory safety. #16053

Merged
merged 1 commit into from
Aug 1, 2014

Conversation

pcwalton
Copy link
Contributor

This is an alternative to upgrading the way rvalues are handled in the
borrow check. Making rvalues handled more like lvalues in the borrow
check caused numerous problems related to double mutable borrows and
rvalue scopes. Rather than come up with more borrow check rules to try
to solve these problems, I decided to just forbid pattern bindings after
@. This affected fewer than 10 lines of code in the compiler and
libraries.

This breaks code like:

match x {
    y @ z => { ... }
}

match a {
    b @ Some(c) => { ... }
}

Change this code to use nested match or let expressions. For
example:

match x {
    y => {
        let z = y;
        ...
    }
}

match a {
    Some(c) => {
        let b = Some(c);
        ...
    }
}

Closes #14587.

[breaking-change]

May need discussion at the meeting, but r? @nikomatsakis anyway

@pcwalton
Copy link
Contributor Author

Rebased.

@pcwalton
Copy link
Contributor Author

@nikomatsakis I'm happy to punt to @pnkfelix if you'd like.

@pnkfelix
Copy link
Member

pnkfelix commented Aug 1, 2014

(reviewing now)

@pnkfelix
Copy link
Member

pnkfelix commented Aug 1, 2014

This seems like a pretty severe weakening of @-patterns; so I just want to point out to on-lookers that the decision at the weekly meeting was to put this change in for now, with the expectation/hope that we'll fix things and re-enable bindings in the rhs of @ at some later point.

@pnkfelix
Copy link
Member

pnkfelix commented Aug 1, 2014

@nikomatsakis do you think we should be deleting the tests as the current PR does, or mark them as ignored? (I'm assuming that the ignore flag should suffice, its not like those tests will stop parsing due to this change...)

I guess as long as the hypothetical re-implementor of @-pattern with rhs-binding support does their due-diligence, they should know to re-enable the tests.

This is an alternative to upgrading the way rvalues are handled in the
borrow check. Making rvalues handled more like lvalues in the borrow
check caused numerous problems related to double mutable borrows and
rvalue scopes. Rather than come up with more borrow check rules to try
to solve these problems, I decided to just forbid pattern bindings after
`@`. This affected fewer than 10 lines of code in the compiler and
libraries.

This breaks code like:

    match x {
        y @ z => { ... }
    }

    match a {
        b @ Some(c) => { ... }
    }

Change this code to use nested `match` or `let` expressions. For
example:

    match x {
        y => {
            let z = y;
            ...
        }
    }

    match a {
        Some(c) => {
            let b = Some(c);
            ...
        }
    }

Closes rust-lang#14587.

[breaking-change]
bors added a commit that referenced this pull request Aug 1, 2014
This is an alternative to upgrading the way rvalues are handled in the
borrow check. Making rvalues handled more like lvalues in the borrow
check caused numerous problems related to double mutable borrows and
rvalue scopes. Rather than come up with more borrow check rules to try
to solve these problems, I decided to just forbid pattern bindings after
`@`. This affected fewer than 10 lines of code in the compiler and
libraries.

This breaks code like:

    match x {
        y @ z => { ... }
    }

    match a {
        b @ Some(c) => { ... }
    }

Change this code to use nested `match` or `let` expressions. For
example:

    match x {
        y => {
            let z = y;
            ...
        }
    }

    match a {
        Some(c) => {
            let b = Some(c);
            ...
        }
    }

Closes #14587.

[breaking-change]

May need discussion at the meeting, but r? @nikomatsakis anyway
@bors bors closed this Aug 1, 2014
@bors bors merged commit 5b85c8c into rust-lang:master Aug 1, 2014
pnkfelix added a commit to pnkfelix/rust that referenced this pull request Sep 22, 2014
Note that due to PR rust-lang#16053, we only actually deal with `a @ Var(_)`
here, (as opposed to a hypothetical `a @ Var(ref b)`, which cannot
currenty arise, and maybe will never be supported for non-copy data).
@chpio
Copy link
Contributor

chpio commented Jan 2, 2017

This breaks code like:

match x {
   y @ z => { ... }
}

match a {
    b @ Some(c) => { ... }
}

Change this code to use nested match or let expressions. For
example:

match x {
   y => {
       let z = y;
       ...
   }
}

match a {
   Some(c) => {
       let b = Some(c);
       ...
   }
}

ok, but how to fix this:

match a {
  Some(b @ &MyEnum::Foo(ref c)) => {
  }
}

Foo can only take values, no refs. So this wouldn't work:

match a {
  Some(&MyEnum::Foo(ref c)) => {
    let b = MyEnum::Foo(c);
    // mismatched types
    // expected type `Bar`
    //    found type `&Bar`
  }
}

i can think only of this workaround:

match a {
  Some(b @ MyEnum::Foo(..)) => {
    let c = match b {
      &MyEnum::Foo(ref c) => c,
      _ => unreachable!(),
    };
  }
}

@nikomatsakis
Copy link
Contributor

i can think only of this workaround:

Yeah, that seems about right. It'd be nice to fix this in a better way (internal refactorings to use MIR ought to help here).

@ozkriff
Copy link

ozkriff commented Dec 20, 2018

Are there any plans to implement a correct handling of these bindings for Copy types?

bors added a commit that referenced this pull request Dec 23, 2019
Initial implementation of `#![feature(bindings_after_at)]`

Following up on #16053, under the gate `#![feature(bindings_after_at)]`, `x @ Some(y)` is allowed subject to restrictions necessary for soundness.

The implementation and test suite should be fairly complete now.

One aspect that is not covered is the interaction with nested `#![feature(or_patterns)]`.
This is not possible to test at the moment in a good way because that feature has not progressed sufficiently and has fatal errors in MIR building. We should make sure to add such tests before we stabilize both features (but shipping one of them is fine).

r? @pnkfelix
cc @nikomatsakis @matthewjasper @pcwalton
cc #65490
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.

Binding subpattern with @ allows for illegal mutation
6 participants