mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 23:12:02 +00:00
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.
This commit is contained in:
parent
ed14ea1d3f
commit
d2d42fd4c7
@ -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,
|
||||
|
25
src/test/run-pass/expr-alt-generic-box1.rs
Normal file
25
src/test/run-pass/expr-alt-generic-box1.rs
Normal file
@ -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();
|
||||
}
|
26
src/test/run-pass/expr-alt-generic-box2.rs
Normal file
26
src/test/run-pass/expr-alt-generic-box2.rs
Normal file
@ -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();
|
||||
}
|
35
src/test/run-pass/expr-alt-generic.rs
Normal file
35
src/test/run-pass/expr-alt-generic.rs
Normal file
@ -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();
|
||||
}
|
23
src/test/run-pass/expr-block-generic-box1.rs
Normal file
23
src/test/run-pass/expr-block-generic-box1.rs
Normal file
@ -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();
|
||||
}
|
22
src/test/run-pass/expr-block-generic-box2.rs
Normal file
22
src/test/run-pass/expr-block-generic-box2.rs
Normal file
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
21
src/test/run-pass/expr-if-generic-box1.rs
Normal file
21
src/test/run-pass/expr-if-generic-box1.rs
Normal file
@ -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();
|
||||
}
|
22
src/test/run-pass/expr-if-generic-box2.rs
Normal file
22
src/test/run-pass/expr-if-generic-box2.rs
Normal file
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
Loading…
Reference in New Issue
Block a user