From 314c011d71c699291361870e13892b4e5867d046 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 18 Oct 2011 10:35:33 -0700 Subject: [PATCH] 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. --- src/comp/middle/ty.rs | 13 ++++++++++--- src/test/run-pass/mutable-huh-variance-vec1.rs | 13 +++++++++++++ src/test/run-pass/mutable-huh-variance-vec2.rs | 13 +++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 src/test/run-pass/mutable-huh-variance-vec1.rs create mode 100644 src/test/run-pass/mutable-huh-variance-vec2.rs 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 { diff --git a/src/test/run-pass/mutable-huh-variance-vec1.rs b/src/test/run-pass/mutable-huh-variance-vec1.rs new file mode 100644 index 00000000000..5fb49cf88ce --- /dev/null +++ b/src/test/run-pass/mutable-huh-variance-vec1.rs @@ -0,0 +1,13 @@ +// error-pattern: mismatched types + +fn main() { + let v = [[0]]; + + // This is ok because the outer vec is covariant with respect + // to the inner vec. If the outer vec was mutable then we + // couldn't do this. + fn f(&&v: [[mutable? int]]) { + } + + f(v); +} diff --git a/src/test/run-pass/mutable-huh-variance-vec2.rs b/src/test/run-pass/mutable-huh-variance-vec2.rs new file mode 100644 index 00000000000..1e254e86806 --- /dev/null +++ b/src/test/run-pass/mutable-huh-variance-vec2.rs @@ -0,0 +1,13 @@ +// error-pattern: mismatched types + +fn main() { + let v = [[0]]; + + // This is ok because the outer vec is covariant with respect + // to the inner vec. If the outer vec was mutable then we + // couldn't do this. + fn f(&&v: [mutable? [mutable? int]]) { + } + + f(v); +}