about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-10-16 16:19:12 -0700
committerBrian Anderson <banderson@mozilla.com>2011-10-20 18:23:48 -0700
commit391e12124b4ee96849b8b5959c2cab824400a384 (patch)
tree3fa064c4121e80f29bdd779575f29707e5f61201 /src
parent342a400e79c44e8035b944129617734009a5abcb (diff)
downloadrust-391e12124b4ee96849b8b5959c2cab824400a384.tar.gz
rust-391e12124b4ee96849b8b5959c2cab824400a384.zip
Tweak typecheck to enforce covariance on higher-order function arguments
Diffstat (limited to 'src')
-rw-r--r--src/comp/middle/ty.rs5
-rw-r--r--src/test/compile-fail/block-coerce-no-2.rs14
2 files changed, 18 insertions, 1 deletions
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index 71521abb538..84532e718e5 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -2004,8 +2004,11 @@ mod unify {
                     (ures_err(terr_mode_mismatch(expected_input.mode,
                                                  actual_input.mode)));
             } else { expected_input.mode };
+            // The variance changes (flips basically) when descending
+            // into arguments of function types
             let result = unify_step(
-                cx, expected_input.ty, actual_input.ty, variance);
+                cx, expected_input.ty, actual_input.ty,
+                variance_transform(variance, contravariant));
             alt result {
               ures_ok(rty) { result_ins += [{mode: result_mode, ty: rty}]; }
               _ { ret fn_common_res_err(result); }
diff --git a/src/test/compile-fail/block-coerce-no-2.rs b/src/test/compile-fail/block-coerce-no-2.rs
new file mode 100644
index 00000000000..926e39529ea
--- /dev/null
+++ b/src/test/compile-fail/block-coerce-no-2.rs
@@ -0,0 +1,14 @@
+// error-pattern: mismatched types
+
+// Make sure that fn-to-block coercion isn't incorrectly lifted over
+// other tycons.
+
+fn main() {
+    fn f(f: fn(fn(fn()))) {
+    }
+
+    fn g(f: fn(block())) {
+    }
+
+    f(g);
+}