Skip to content

Commit 314c011

Browse files
committed
Immutable and mutable? are covariant on their inner types
Whereas [mutable T] is invariant with respect to T, [T] and [mutable? T] are covariant with respect to T.
1 parent 71a4a66 commit 314c011

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

src/comp/middle/ty.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1947,9 +1947,16 @@ mod unify {
19471947
variance: variance) ->
19481948
option::t<(ast::mutability, variance)> {
19491949

1950-
// If you're unifying mutability then the thing inside
1951-
// will be invariant on anything it contains
1952-
let newvariance = variance_transform(variance, invariant);
1950+
// If you're unifying on something mutable then we have to
1951+
// be invariant on the inner type
1952+
let newvariance = alt expected {
1953+
ast::mut. {
1954+
variance_transform(variance, invariant)
1955+
}
1956+
_ {
1957+
variance_transform(variance, covariant)
1958+
}
1959+
};
19531960

19541961
if expected == actual { ret some((expected, newvariance)); }
19551962
if variance == covariant {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// error-pattern: mismatched types
2+
3+
fn main() {
4+
let v = [[0]];
5+
6+
// This is ok because the outer vec is covariant with respect
7+
// to the inner vec. If the outer vec was mutable then we
8+
// couldn't do this.
9+
fn f(&&v: [[mutable? int]]) {
10+
}
11+
12+
f(v);
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// error-pattern: mismatched types
2+
3+
fn main() {
4+
let v = [[0]];
5+
6+
// This is ok because the outer vec is covariant with respect
7+
// to the inner vec. If the outer vec was mutable then we
8+
// couldn't do this.
9+
fn f(&&v: [mutable? [mutable? int]]) {
10+
}
11+
12+
f(v);
13+
}

0 commit comments

Comments
 (0)