]> git.lizzy.rs Git - rust.git/commit
When matching against a pattern (either via `match` or `let`) that
authorNiko Matsakis <niko@alum.mit.edu>
Fri, 6 Mar 2015 15:14:12 +0000 (10:14 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Mon, 23 Mar 2015 09:30:43 +0000 (05:30 -0400)
commit45fae882568d9bf36ade39f210a2721d05e556dd
tree6f8d8d31843e3239b827013024a0d35d2d4f05e6
parentb0aad7dd4fad8d7e2e2f877a511a637258949597
When matching against a pattern (either via `match` or `let`) that
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.
src/librustc/middle/pat_util.rs
src/librustc/middle/ty.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/mod.rs
src/test/compile-fail/match-ref-mut-invariance.rs [new file with mode: 0644]
src/test/compile-fail/match-ref-mut-let-invariance.rs [new file with mode: 0644]