Skip to content

Don't allow upcasting to a supertype in the type of the match #23119

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

Merged
merged 1 commit into from
Mar 24, 2015

Conversation

nikomatsakis
Copy link
Contributor

Don't allow upcasting to a supertype in the type of the match discriminant. Fixes #23116.

This is a [breaking-change] in that it closes a type hole that previously existed.

r? @pnkfelix

@pnkfelix
Copy link
Member

pnkfelix commented Mar 6, 2015

@bors r+

@bors
Copy link
Collaborator

bors commented Mar 6, 2015

@bors r=pnkfelix 1a9439d

struct S<'b>(&'b i32);
impl<'b> S<'b> {
fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
match self.0 { ref mut x => x }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this have an error message directive //~ ERROR?

@nikomatsakis
Copy link
Contributor Author

@bors r- I see a failure in run-pass, investigating. Also, what @jakub- said.

@nikomatsakis
Copy link
Contributor Author

Actually, there is a more serious problem here. In particular, it's not covering the case of let ref mut x = ..., which has a similar bug.

@nikomatsakis nikomatsakis force-pushed the issue-23116-ref-mut branch from 1a9439d to 559bc4a Compare March 6, 2015 20:39
@nikomatsakis
Copy link
Contributor Author

@pnkfelix ok I pushed a more comprehensive fix. See the comment.

@nikomatsakis
Copy link
Contributor Author

Definitely wants re-review.

result
}

/// Checks if the pattern contains any patterns that bind something to
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment seems wrong? It talks about by-value bindings.

@nikomatsakis
Copy link
Contributor Author

r? @pnkfelix

@nikomatsakis
Copy link
Contributor Author

r? @nrc

@rust-highfive rust-highfive assigned nrc and unassigned pnkfelix Mar 17, 2015
@nrc nrc assigned ghost and unassigned nrc Mar 17, 2015
@nrc
Copy link
Member

nrc commented Mar 17, 2015

lgtm, but I have no idea about match checking so probably better for Jakub to r? this

contains ref-bindings, do not permit any upcasting from the type of
the value being matched. Similarly, do not permit coercion in a `let`.

This is a [breaking-change] in that it closes a type hole that
previously existed, and in that coercion is not performed. You should
be able to work around the latter by converting:

```rust
let ref mut x: T = expr;
```

into

```rust
let x: T = expr;
let ref mut x = x;
```

Restricting coercion not to apply in the case of `let ref` or `let ref mut` is sort
of unexciting to me, but seems the best solution:

1. Mixing coercion and `let ref` or `let ref mut` is a bit odd, because you are taking
   the address of a (coerced) temporary, but only sometimes. It's not syntactically evident,
   in other words, what's going on. When you're doing a coercion, you're kind of

2. Put another way, I would like to preserve the relationship that
   `equality <= subtyping <= coercion <= as-coercion`, where this is
   an indication of the number of `(T1,T2)` pairs that are accepted by
   the various relations. Trying to mix `let ref mut` and coercion
   would create another kind of relation that is like coercion, but
   acts differently in the case where a precise match is needed.

3. In any case, this is strictly more conservative than what we had
   before and we can undo it in the future if we find a way to make
   coercion mix with type equality.

The change to match I feel ok about but similarly unthrilled. There is
some subtle text already concerning whether to use eqtype or subtype
for identifier bindings. The best fix I think would be to always have
match use strict equality but use subtyping on identifier bindings,
but the comment `(*)` explains why that's not working at the moment.
As above, I think we can change this as we clean up the code there.
@nikomatsakis
Copy link
Contributor Author

rebased, addressed nit by @jakub-

@pnkfelix
Copy link
Member

@bors r+ 45fae88 rollup

steveklabnik added a commit to steveklabnik/rust that referenced this pull request Mar 23, 2015
…=pnkfelix

Don't allow upcasting to a supertype in the type of the match discriminant. Fixes rust-lang#23116.

This is a [breaking-change] in that it closes a type hole that previously existed.

r? @pnkfelix
alexcrichton added a commit to alexcrichton/rust that referenced this pull request Mar 23, 2015
Don't allow upcasting to a supertype in the type of the match discriminant. Fixes rust-lang#23116.

This is a [breaking-change] in that it closes a type hole that previously existed.

r? @pnkfelix
@bors bors merged commit 45fae88 into rust-lang:master Mar 24, 2015
@nikomatsakis nikomatsakis deleted the issue-23116-ref-mut branch March 30, 2016 16:14
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.

ref mut bindings fail to enforce invariance
4 participants