about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-10-18 10:35:33 -0700
committerBrian Anderson <banderson@mozilla.com>2011-10-18 10:37:04 -0700
commit314c011d71c699291361870e13892b4e5867d046 (patch)
treef0c57d6737e882e8511a4f51202e0060d52877ce /src/comp
parent71a4a661359dbe92493f7321f8b3677dec734df9 (diff)
downloadrust-314c011d71c699291361870e13892b4e5867d046.tar.gz
rust-314c011d71c699291361870e13892b4e5867d046.zip
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.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/ty.rs13
1 files changed, 10 insertions, 3 deletions
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index dde4237aa48..1288de9fa22 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -1947,9 +1947,16 @@ mod unify {
                  variance: variance) ->
        option::t<(ast::mutability, variance)> {
 
-        // If you're unifying mutability then the thing inside
-        // will be invariant on anything it contains
-        let newvariance = variance_transform(variance, invariant);
+        // If you're unifying on something mutable then we have to
+        // be invariant on the inner type
+        let newvariance = alt expected {
+          ast::mut. {
+            variance_transform(variance, invariant)
+          }
+          _ {
+            variance_transform(variance, covariant)
+          }
+        };
 
         if expected == actual { ret some((expected, newvariance)); }
         if variance == covariant {