Skip to content

Commit d2d42fd

Browse files
committed
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.
1 parent ed14ea1 commit d2d42fd

10 files changed

+191
-54
lines changed

src/comp/middle/trans.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5215,20 +5215,25 @@ fn init_local(@block_ctxt cx, @ast.local local) -> result {
52155215
}
52165216
}
52175217
case (_) {
5218-
if (middle.ty.type_has_dynamic_size(ty)) {
5219-
auto llsz = size_of(bcx, ty);
5220-
bcx = call_bzero(llsz.bcx, llptr, llsz.val).bcx;
5221-
5222-
} else {
5223-
auto llty = type_of(bcx.fcx.ccx, ty);
5224-
auto null = lib.llvm.llvm.LLVMConstNull(llty);
5225-
bcx.build.Store(null, llptr);
5226-
}
5218+
bcx = zero_alloca(bcx, llptr, ty).bcx;
52275219
}
52285220
}
52295221
ret res(bcx, llptr);
52305222
}
52315223

5224+
fn zero_alloca(@block_ctxt cx, ValueRef llptr, @ty.t t) -> result {
5225+
auto bcx = cx;
5226+
if (ty.type_has_dynamic_size(t)) {
5227+
auto llsz = size_of(bcx, t);
5228+
bcx = call_bzero(llsz.bcx, llptr, llsz.val).bcx;
5229+
} else {
5230+
auto llty = type_of(bcx.fcx.ccx, t);
5231+
auto null = lib.llvm.llvm.LLVMConstNull(llty);
5232+
bcx.build.Store(null, llptr);
5233+
}
5234+
ret res(bcx, llptr);
5235+
}
5236+
52325237
fn trans_stmt(@block_ctxt cx, &ast.stmt s) -> result {
52335238
auto bcx = cx;
52345239
alt (s.node) {
@@ -5407,8 +5412,7 @@ fn trans_block(@block_ctxt cx, &ast.block b) -> result {
54075412
ret r;
54085413
} else {
54095414
auto r_ty = ty.expr_ty(e);
5410-
5411-
if (ty.type_is_boxed(r_ty)) {
5415+
if (!ty.type_is_nil(r_ty)) {
54125416
// The value resulting from the block gets copied into an
54135417
// alloca created in an outer scope and its refcount
54145418
// bumped so that it can escape this block. This means
@@ -5424,9 +5428,8 @@ fn trans_block(@block_ctxt cx, &ast.block b) -> result {
54245428
// NB: Here we're building and initalizing the alloca in
54255429
// the alloca context, not this block's context.
54265430
auto res_alloca = alloc_ty(bcx, r_ty);
5427-
auto alloca_ty = type_of(bcx.fcx.ccx, r_ty);
5428-
auto builder = new_builder(bcx.fcx.llallocas);
5429-
builder.Store(C_null(alloca_ty), res_alloca.val);
5431+
auto llbcx = llallocas_block_ctxt(bcx.fcx);
5432+
zero_alloca(llbcx, res_alloca.val, r_ty);
54305433

54315434
// Now we're working in our own block context again
54325435
auto res_copy = copy_ty(bcx, INIT,
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// xfail-boot
2+
// -*- rust -*-
3+
4+
type compare[T] = fn(@T t1, @T t2) -> bool;
5+
6+
fn test_generic[T](@T expected, &compare[T] eq) {
7+
let @T actual = alt (true) {
8+
case (true) {
9+
expected
10+
}
11+
};
12+
check (eq(expected, actual));
13+
}
14+
15+
fn test_box() {
16+
fn compare_box(@bool b1, @bool b2) -> bool {
17+
ret *b1 == b2;
18+
}
19+
auto eq = bind compare_box(_, _);
20+
test_generic[bool](@true, eq);
21+
}
22+
23+
fn main() {
24+
test_box();
25+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// xfail-boot
2+
// xfail-stage0
3+
// -*- rust -*-
4+
5+
type compare[T] = fn(&T t1, &T t2) -> bool;
6+
7+
fn test_generic[T](&T expected, &compare[T] eq) {
8+
let T actual = alt (true) {
9+
case (true) {
10+
expected
11+
}
12+
};
13+
check (eq(expected, actual));
14+
}
15+
16+
fn test_vec() {
17+
fn compare_vec(vec[int] v1, vec[int] v2) -> bool {
18+
ret v1 == v2;
19+
}
20+
auto eq = bind compare_vec(_, _);
21+
test_generic[vec[int]](vec(1, 2, 3), eq);
22+
}
23+
24+
fn main() {
25+
test_vec();
26+
}

src/test/run-pass/expr-alt-generic.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// xfail-boot
2+
// -*- rust -*-
3+
4+
type compare[T] = fn(&T t1, &T t2) -> bool;
5+
6+
fn test_generic[T](&T expected, &compare[T] eq) {
7+
let T actual = alt (true) {
8+
case (true) {
9+
expected
10+
}
11+
};
12+
check (eq(expected, actual));
13+
}
14+
15+
fn test_bool() {
16+
fn compare_bool(&bool b1, &bool b2) -> bool {
17+
ret b1 == b2;
18+
}
19+
auto eq = bind compare_bool(_, _);
20+
test_generic[bool](true, eq);
21+
}
22+
23+
fn test_tup() {
24+
type t = tup(int, int);
25+
fn compare_tup(&t t1, &t t2) -> bool {
26+
ret t1 == t2;
27+
}
28+
auto eq = bind compare_tup(_, _);
29+
test_generic[t](tup(1, 2), eq);
30+
}
31+
32+
fn main() {
33+
test_bool();
34+
test_tup();
35+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// xfail-boot
2+
// -*- rust -*-
3+
4+
type compare[T] = fn(@T t1, @T t2) -> bool;
5+
6+
fn test_generic[T](@T expected, &compare[T] eq) {
7+
let @T actual = { expected };
8+
check (eq(expected, actual));
9+
}
10+
11+
fn test_box() {
12+
fn compare_box(@bool b1, @bool b2) -> bool {
13+
log *b1;
14+
log *b2;
15+
ret *b1 == *b2;
16+
}
17+
auto eq = bind compare_box(_, _);
18+
test_generic[bool](@true, eq);
19+
}
20+
21+
fn main() {
22+
test_box();
23+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// xfail-boot
2+
// xfail-stage0
3+
// -*- rust -*-
4+
5+
type compare[T] = fn(&T t1, &T t2) -> bool;
6+
7+
fn test_generic[T](&T expected, &compare[T] eq) {
8+
let T actual = { expected };
9+
check (eq(expected, actual));
10+
}
11+
12+
fn test_vec() {
13+
fn compare_vec(&vec[int] v1, &vec[int] v2) -> bool {
14+
ret v1 == v2;
15+
}
16+
auto eq = bind compare_vec(_, _);
17+
test_generic[vec[int]](vec(1, 2), eq);
18+
}
19+
20+
fn main() {
21+
test_vec();
22+
}

src/test/run-pass/expr-block-generic.rs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// xfail-boot
2-
// xfail-stage0
32
// -*- rust -*-
43

54
// Tests for standalone blocks as expressions with dynamic type sizes
@@ -29,28 +28,9 @@ fn test_tup() {
2928
test_generic[t](tup(1, 2), eq);
3029
}
3130

32-
fn test_vec() {
33-
fn compare_vec(&vec[int] v1, &vec[int] v2) -> bool {
34-
ret v1 == v2;
35-
}
36-
auto eq = bind compare_vec(_, _);
37-
test_generic[vec[int]](vec(1, 2), eq);
38-
}
39-
40-
fn test_box() {
41-
fn compare_box(&@bool b1, &@bool b2) -> bool {
42-
ret *b1 == *b2;
43-
}
44-
auto eq = bind compare_box(_, _);
45-
test_generic[@bool](@true, eq);
46-
}
47-
4831
fn main() {
4932
test_bool();
5033
test_tup();
51-
// FIXME: These two don't pass yet
52-
test_vec();
53-
test_box();
5434
}
5535

5636

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// xfail-boot
2+
// -*- rust -*-
3+
4+
type compare[T] = fn(@T t1, @T t2) -> bool;
5+
6+
fn test_generic[T](@T expected, @T not_expected, &compare[T] eq) {
7+
let @T actual = if (true) { expected } else { not_expected };
8+
check (eq(expected, actual));
9+
}
10+
11+
fn test_box() {
12+
fn compare_box(@bool b1, @bool b2) -> bool {
13+
ret *b1 == *b2;
14+
}
15+
auto eq = bind compare_box(_, _);
16+
test_generic[bool](@true, @false, eq);
17+
}
18+
19+
fn main() {
20+
test_box();
21+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// xfail-boot
2+
// xfail-stage0
3+
// -*- rust -*-
4+
5+
type compare[T] = fn(&T t1, &T t2) -> bool;
6+
7+
fn test_generic[T](&T expected, &T not_expected, &compare[T] eq) {
8+
let T actual = if (true) { expected } else { not_expected };
9+
check (eq(expected, actual));
10+
}
11+
12+
fn test_vec() {
13+
fn compare_vec(&vec[int] v1, &vec[int] v2) -> bool {
14+
ret v1 == v2;
15+
}
16+
auto eq = bind compare_vec(_, _);
17+
test_generic[vec[int]](vec(1, 2), vec(2, 3), eq);
18+
}
19+
20+
fn main() {
21+
test_vec();
22+
}

src/test/run-pass/expr-if-generic.rs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// xfail-boot
2-
// xfail-stage0
32
// -*- rust -*-
43

54
// Tests for if as expressions with dynamic type sizes
@@ -28,26 +27,7 @@ fn test_tup() {
2827
test_generic[t](tup(1, 2), tup(2, 3), eq);
2928
}
3029

31-
fn test_vec() {
32-
fn compare_vec(&vec[int] v1, &vec[int] v2) -> bool {
33-
ret v1 == v2;
34-
}
35-
auto eq = bind compare_vec(_, _);
36-
test_generic[vec[int]](vec(1, 2), vec(2, 3), eq);
37-
}
38-
39-
fn test_box() {
40-
fn compare_box(&@bool b1, &@bool b2) -> bool {
41-
ret *b1 == *b2;
42-
}
43-
auto eq = bind compare_box(_, _);
44-
test_generic[@bool](@true, @false, eq);
45-
}
46-
4730
fn main() {
4831
test_bool();
4932
test_tup();
50-
// FIXME: These two don't pass yet
51-
test_vec();
52-
test_box();
5333
}

0 commit comments

Comments
 (0)