File tree 3 files changed +65
-7
lines changed
3 files changed +65
-7
lines changed Original file line number Diff line number Diff line change @@ -1506,16 +1506,19 @@ pub fn trans_closure<'a>(ccx: @CrateContext,
1506
1506
// emitting should be enabled.
1507
1507
debuginfo:: start_emitting_source_locations( & fcx) ;
1508
1508
1509
+ let dest = match fcx. llretptr. get( ) {
1510
+ Some ( e) => { expr:: SaveIn ( e) }
1511
+ None => {
1512
+ assert!( type_is_zero_size( bcx. ccx( ) , block_ty) )
1513
+ expr:: Ignore
1514
+ }
1515
+ } ;
1516
+
1509
1517
// This call to trans_block is the place where we bridge between
1510
1518
// translation calls that don't have a return value (trans_crate,
1511
1519
// trans_mod, trans_item, et cetera) and those that do
1512
1520
// (trans_block, trans_expr, et cetera).
1513
- if body. expr. is_none( ) || type_is_zero_size( bcx. ccx( ) , block_ty) {
1514
- bcx = controlflow:: trans_block( bcx, body, expr:: Ignore ) ;
1515
- } else {
1516
- let dest = expr:: SaveIn ( fcx. llretptr. get( ) . unwrap( ) ) ;
1517
- bcx = controlflow:: trans_block ( bcx , body , dest ) ;
1518
- }
1521
+ bcx = controlflow:: trans_block( bcx, body, dest) ;
1519
1522
1520
1523
match fcx. llreturn. get( ) {
1521
1524
Some ( _) => {
Original file line number Diff line number Diff line change @@ -74,7 +74,7 @@ pub fn trans_stmt<'a>(cx: &'a Block<'a>,
74
74
75
75
pub fn trans_block < ' a > ( bcx : & ' a Block < ' a > ,
76
76
b : & ast:: Block ,
77
- dest : expr:: Dest )
77
+ mut dest : expr:: Dest )
78
78
-> & ' a Block < ' a > {
79
79
let _icx = push_ctxt ( "trans_block" ) ;
80
80
let fcx = bcx. fcx ;
@@ -85,6 +85,14 @@ pub fn trans_block<'a>(bcx: &'a Block<'a>,
85
85
for s in b. stmts . iter ( ) {
86
86
bcx = trans_stmt ( bcx, * s) ;
87
87
}
88
+
89
+ if dest != expr:: Ignore {
90
+ let block_ty = node_id_type ( bcx, b. id ) ;
91
+ if b. expr . is_none ( ) || type_is_zero_size ( bcx. ccx ( ) , block_ty) {
92
+ dest = expr:: Ignore ;
93
+ }
94
+ }
95
+
88
96
match b. expr {
89
97
Some ( e) => {
90
98
bcx = expr:: trans_into ( bcx, e, dest) ;
Original file line number Diff line number Diff line change
1
+ // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2
+ // file at the top-level directory of this distribution and at
3
+ // http://rust-lang.org/COPYRIGHT.
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6
+ // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7
+ // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8
+ // option. This file may not be copied, modified, or distributed
9
+ // except according to those terms.
10
+
11
+ // xfail-pretty
12
+
13
+ // Don't fail on blocks without results
14
+ // There are several tests in this run-pass that raised
15
+ // when this bug was oppened. The cases where the compiler
16
+ // failed before the fix have a comment.
17
+
18
+ struct S { x : ( ) }
19
+
20
+
21
+ fn test ( slot : & mut Option < proc ( ) -> proc ( ) > , _: proc ( ) ) -> ( ) {
22
+ let a = slot. take ( ) ;
23
+ let _a = match a {
24
+ // `{let .. a(); }` would break
25
+ Some ( a) => { let _a = a ( ) ; } ,
26
+ None => ( ) ,
27
+ } ;
28
+ }
29
+
30
+ fn not ( b : bool ) -> bool {
31
+ if b {
32
+ !b
33
+ } else {
34
+ // `fail!(...)` would break
35
+ fail ! ( "Break the compiler" ) ;
36
+ }
37
+ }
38
+
39
+ pub fn main ( ) {
40
+ // {} would break
41
+ let _r = { } ;
42
+ let mut slot = None ;
43
+ // `{ test(...); }` would break
44
+ let _s : S = S { x : { test ( & mut slot, proc ( ) { } ) ; } } ;
45
+
46
+ let _b = not ( true ) ;
47
+ }
You can’t perform that action at this time.
0 commit comments