-
Notifications
You must be signed in to change notification settings - Fork 13.3k
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
Conversation
@bors r+ |
|
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 } |
There was a problem hiding this comment.
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
?
@bors r- I see a failure in run-pass, investigating. Also, what @jakub- said. |
Actually, there is a more serious problem here. In particular, it's not covering the case of |
1a9439d
to
559bc4a
Compare
@pnkfelix ok I pushed a more comprehensive fix. See the comment. |
Definitely wants re-review. |
result | ||
} | ||
|
||
/// Checks if the pattern contains any patterns that bind something to |
There was a problem hiding this comment.
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.
r? @pnkfelix |
r? @nrc |
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.
559bc4a
to
45fae88
Compare
rebased, addressed nit by @jakub- |
…=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
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
- Successful merges: rust-lang#22954, rust-lang#23119, rust-lang#23509, rust-lang#23561, rust-lang#23590, rust-lang#23607, rust-lang#23608, rust-lang#23618, rust-lang#23622, rust-lang#23639, rust-lang#23641 - Failed merges: rust-lang#23401
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