about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <andersrb@gmail.com>2011-04-05 23:42:33 -0400
committerBrian Anderson <andersrb@gmail.com>2011-04-07 21:58:36 -0400
commitd2d42fd4c746b10cffa4116ade9629340fdc4a5c (patch)
tree24ad8ee5b2bfb51da69e97d9c722c4773789444a
parented14ea1d3f4f12bc132fcf1bed3bcc0ac4b7da16 (diff)
downloadrust-d2d42fd4c746b10cffa4116ade9629340fdc4a5c.tar.gz
rust-d2d42fd4c746b10cffa4116ade9629340fdc4a5c.zip
Make block results work for generic types
I think just about every type can be used as a block result now. There's quite
a proliferation of tests here, but they all test slightly different things and
some are split out to remain XFAILed. The tests of generic vectors are still
XFAILed because generic aliased boxes still don't work in general.
-rw-r--r--src/comp/middle/trans.rs31
-rw-r--r--src/test/run-pass/expr-alt-generic-box1.rs25
-rw-r--r--src/test/run-pass/expr-alt-generic-box2.rs26
-rw-r--r--src/test/run-pass/expr-alt-generic.rs35
-rw-r--r--src/test/run-pass/expr-block-generic-box1.rs23
-rw-r--r--src/test/run-pass/expr-block-generic-box2.rs22
-rw-r--r--src/test/run-pass/expr-block-generic.rs20
-rw-r--r--src/test/run-pass/expr-if-generic-box1.rs21
-rw-r--r--src/test/run-pass/expr-if-generic-box2.rs22
-rw-r--r--src/test/run-pass/expr-if-generic.rs20
10 files changed, 191 insertions, 54 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 28b22ea2a5e..09dad4bc765 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -5215,20 +5215,25 @@ fn init_local(@block_ctxt cx, @ast.local local) -> result {
             }
         }
         case (_) {
-            if (middle.ty.type_has_dynamic_size(ty)) {
-                auto llsz = size_of(bcx, ty);
-                bcx = call_bzero(llsz.bcx, llptr, llsz.val).bcx;
-
-            } else {
-                auto llty = type_of(bcx.fcx.ccx, ty);
-                auto null = lib.llvm.llvm.LLVMConstNull(llty);
-                bcx.build.Store(null, llptr);
-            }
+            bcx = zero_alloca(bcx, llptr, ty).bcx;
         }
     }
     ret res(bcx, llptr);
 }
 
+fn zero_alloca(@block_ctxt cx, ValueRef llptr, @ty.t t) -> result {
+    auto bcx = cx;
+    if (ty.type_has_dynamic_size(t)) {
+        auto llsz = size_of(bcx, t);
+        bcx = call_bzero(llsz.bcx, llptr, llsz.val).bcx;
+    } else {
+        auto llty = type_of(bcx.fcx.ccx, t);
+        auto null = lib.llvm.llvm.LLVMConstNull(llty);
+        bcx.build.Store(null, llptr);
+    }
+    ret res(bcx, llptr);
+ }
+
 fn trans_stmt(@block_ctxt cx, &ast.stmt s) -> result {
     auto bcx = cx;
     alt (s.node) {
@@ -5407,8 +5412,7 @@ fn trans_block(@block_ctxt cx, &ast.block b) -> result {
                 ret r;
             } else {
                 auto r_ty = ty.expr_ty(e);
-
-                if (ty.type_is_boxed(r_ty)) {
+                if (!ty.type_is_nil(r_ty)) {
                     // The value resulting from the block gets copied into an
                     // alloca created in an outer scope and its refcount
                     // bumped so that it can escape this block. This means
@@ -5424,9 +5428,8 @@ fn trans_block(@block_ctxt cx, &ast.block b) -> result {
                     // NB: Here we're building and initalizing the alloca in
                     // the alloca context, not this block's context.
                     auto res_alloca = alloc_ty(bcx, r_ty);
-                    auto alloca_ty = type_of(bcx.fcx.ccx, r_ty);
-                    auto builder = new_builder(bcx.fcx.llallocas);
-                    builder.Store(C_null(alloca_ty), res_alloca.val);
+                    auto llbcx = llallocas_block_ctxt(bcx.fcx);
+                    zero_alloca(llbcx, res_alloca.val, r_ty);
 
                     // Now we're working in our own block context again
                     auto res_copy = copy_ty(bcx, INIT,
diff --git a/src/test/run-pass/expr-alt-generic-box1.rs b/src/test/run-pass/expr-alt-generic-box1.rs
new file mode 100644
index 00000000000..314ae7fd888
--- /dev/null
+++ b/src/test/run-pass/expr-alt-generic-box1.rs
@@ -0,0 +1,25 @@
+// xfail-boot
+// -*- rust -*-
+
+type compare[T] = fn(@T t1, @T t2) -> bool;
+
+fn test_generic[T](@T expected, &compare[T] eq) {
+  let @T actual = alt (true) {
+    case (true) {
+      expected
+    }
+  };
+  check (eq(expected, actual));
+}
+
+fn test_box() {
+  fn compare_box(@bool b1, @bool b2) -> bool {
+    ret *b1 == b2;
+  }
+  auto eq = bind compare_box(_, _);
+  test_generic[bool](@true, eq);
+}
+
+fn main() {
+  test_box();
+}
diff --git a/src/test/run-pass/expr-alt-generic-box2.rs b/src/test/run-pass/expr-alt-generic-box2.rs
new file mode 100644
index 00000000000..196ceafcb43
--- /dev/null
+++ b/src/test/run-pass/expr-alt-generic-box2.rs
@@ -0,0 +1,26 @@
+// xfail-boot
+// xfail-stage0
+// -*- rust -*-
+
+type compare[T] = fn(&T t1, &T t2) -> bool;
+
+fn test_generic[T](&T expected, &compare[T] eq) {
+  let T actual = alt (true) {
+    case (true) {
+      expected
+    }
+  };
+  check (eq(expected, actual));
+}
+
+fn test_vec() {
+  fn compare_vec(vec[int] v1, vec[int] v2) -> bool {
+    ret v1 == v2;
+  }
+  auto eq = bind compare_vec(_, _);
+  test_generic[vec[int]](vec(1, 2, 3), eq);
+}
+
+fn main() {
+  test_vec();
+}
diff --git a/src/test/run-pass/expr-alt-generic.rs b/src/test/run-pass/expr-alt-generic.rs
new file mode 100644
index 00000000000..6668105955d
--- /dev/null
+++ b/src/test/run-pass/expr-alt-generic.rs
@@ -0,0 +1,35 @@
+// xfail-boot
+// -*- rust -*-
+
+type compare[T] = fn(&T t1, &T t2) -> bool;
+
+fn test_generic[T](&T expected, &compare[T] eq) {
+  let T actual = alt (true) {
+    case (true) {
+      expected
+    }
+  };
+  check (eq(expected, actual));
+}
+
+fn test_bool() {
+  fn compare_bool(&bool b1, &bool b2) -> bool {
+    ret b1 == b2;
+  }
+  auto eq = bind compare_bool(_, _);
+  test_generic[bool](true, eq);
+}
+
+fn test_tup() {
+  type t = tup(int, int);
+  fn compare_tup(&t t1, &t t2) -> bool {
+    ret t1 == t2;
+  }
+  auto eq = bind compare_tup(_, _);
+  test_generic[t](tup(1, 2), eq);
+}
+
+fn main() {
+  test_bool();
+  test_tup();
+}
\ No newline at end of file
diff --git a/src/test/run-pass/expr-block-generic-box1.rs b/src/test/run-pass/expr-block-generic-box1.rs
new file mode 100644
index 00000000000..57487fd617d
--- /dev/null
+++ b/src/test/run-pass/expr-block-generic-box1.rs
@@ -0,0 +1,23 @@
+// xfail-boot
+// -*- rust -*-
+
+type compare[T] = fn(@T t1, @T t2) -> bool;
+
+fn test_generic[T](@T expected, &compare[T] eq) {
+  let @T actual = { expected };
+  check (eq(expected, actual));
+}
+
+fn test_box() {
+  fn compare_box(@bool b1, @bool b2) -> bool {
+    log *b1;
+    log *b2;
+    ret *b1 == *b2;
+  }
+  auto eq = bind compare_box(_, _);
+  test_generic[bool](@true, eq);
+}
+
+fn main() {
+  test_box();
+}
\ No newline at end of file
diff --git a/src/test/run-pass/expr-block-generic-box2.rs b/src/test/run-pass/expr-block-generic-box2.rs
new file mode 100644
index 00000000000..a129755db58
--- /dev/null
+++ b/src/test/run-pass/expr-block-generic-box2.rs
@@ -0,0 +1,22 @@
+// xfail-boot
+// xfail-stage0
+// -*- rust -*-
+
+type compare[T] = fn(&T t1, &T t2) -> bool;
+
+fn test_generic[T](&T expected, &compare[T] eq) {
+  let T actual = { expected };
+  check (eq(expected, actual));
+}
+
+fn test_vec() {
+  fn compare_vec(&vec[int] v1, &vec[int] v2) -> bool {
+    ret v1 == v2;
+  }
+  auto eq = bind compare_vec(_, _);
+  test_generic[vec[int]](vec(1, 2), eq);
+}
+
+fn main() {
+  test_vec();
+}
\ No newline at end of file
diff --git a/src/test/run-pass/expr-block-generic.rs b/src/test/run-pass/expr-block-generic.rs
index fc34d112419..ded3b620704 100644
--- a/src/test/run-pass/expr-block-generic.rs
+++ b/src/test/run-pass/expr-block-generic.rs
@@ -1,5 +1,4 @@
 // xfail-boot
-// xfail-stage0
 // -*- rust -*-
 
 // Tests for standalone blocks as expressions with dynamic type sizes
@@ -29,28 +28,9 @@ fn test_tup() {
   test_generic[t](tup(1, 2), eq);
 }
 
-fn test_vec() {
-  fn compare_vec(&vec[int] v1, &vec[int] v2) -> bool {
-    ret v1 == v2;
-  }
-  auto eq = bind compare_vec(_, _);
-  test_generic[vec[int]](vec(1, 2), eq);
-}
-
-fn test_box() {
-  fn compare_box(&@bool b1, &@bool b2) -> bool {
-    ret *b1 == *b2;
-  }
-  auto eq = bind compare_box(_, _);
-  test_generic[@bool](@true, eq);
-}
-
 fn main() {
   test_bool();
   test_tup();
-  // FIXME: These two don't pass yet
-  test_vec();
-  test_box();
 }
 
 
diff --git a/src/test/run-pass/expr-if-generic-box1.rs b/src/test/run-pass/expr-if-generic-box1.rs
new file mode 100644
index 00000000000..32aea8bb72f
--- /dev/null
+++ b/src/test/run-pass/expr-if-generic-box1.rs
@@ -0,0 +1,21 @@
+// xfail-boot
+// -*- rust -*-
+
+type compare[T] = fn(@T t1, @T t2) -> bool;
+
+fn test_generic[T](@T expected, @T not_expected, &compare[T] eq) {
+  let @T actual = if (true) { expected } else { not_expected };
+  check (eq(expected, actual));
+}
+
+fn test_box() {
+  fn compare_box(@bool b1, @bool b2) -> bool {
+    ret *b1 == *b2;
+  }
+  auto eq = bind compare_box(_, _);
+  test_generic[bool](@true, @false, eq);
+}
+
+fn main() {
+  test_box();
+}
\ No newline at end of file
diff --git a/src/test/run-pass/expr-if-generic-box2.rs b/src/test/run-pass/expr-if-generic-box2.rs
new file mode 100644
index 00000000000..a1559cf9895
--- /dev/null
+++ b/src/test/run-pass/expr-if-generic-box2.rs
@@ -0,0 +1,22 @@
+// xfail-boot
+// xfail-stage0
+// -*- rust -*-
+
+type compare[T] = fn(&T t1, &T t2) -> bool;
+
+fn test_generic[T](&T expected, &T not_expected, &compare[T] eq) {
+  let T actual = if (true) { expected } else { not_expected };
+  check (eq(expected, actual));
+}
+
+fn test_vec() {
+  fn compare_vec(&vec[int] v1, &vec[int] v2) -> bool {
+    ret v1 == v2;
+  }
+  auto eq = bind compare_vec(_, _);
+  test_generic[vec[int]](vec(1, 2), vec(2, 3), eq);
+}
+
+fn main() {
+  test_vec();
+}
\ No newline at end of file
diff --git a/src/test/run-pass/expr-if-generic.rs b/src/test/run-pass/expr-if-generic.rs
index f23ce23a6b7..0a0db2ddfde 100644
--- a/src/test/run-pass/expr-if-generic.rs
+++ b/src/test/run-pass/expr-if-generic.rs
@@ -1,5 +1,4 @@
 // xfail-boot
-// xfail-stage0
 // -*- rust -*-
 
 // Tests for if as expressions with dynamic type sizes
@@ -28,26 +27,7 @@ fn test_tup() {
   test_generic[t](tup(1, 2), tup(2, 3), eq);
 }
 
-fn test_vec() {
-  fn compare_vec(&vec[int] v1, &vec[int] v2) -> bool {
-    ret v1 == v2;
-  }
-  auto eq = bind compare_vec(_, _);
-  test_generic[vec[int]](vec(1, 2), vec(2, 3), eq);
-}
-
-fn test_box() {
-  fn compare_box(&@bool b1, &@bool b2) -> bool {
-    ret *b1 == *b2;
-  }
-  auto eq = bind compare_box(_, _);
-  test_generic[@bool](@true, @false, eq);
-}
-
 fn main() {
   test_bool();
   test_tup();
-  // FIXME: These two don't pass yet
-  test_vec();
-  test_box();
 }
\ No newline at end of file