Skip to content

Commit 2c2799d

Browse files
thestingeralexcrichton
authored andcommitted
---
yaml --- r: 110431 b: refs/heads/try c: 898669c h: refs/heads/master i: 110429: c290a96 110427: d2677a5 110423: 79eba95 110415: 412977f 110399: 984e830 v: v3
1 parent a7973a7 commit 2c2799d

File tree

4 files changed

+45
-10
lines changed

4 files changed

+45
-10
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: e415c25bcd81dc1f9a5a3d25d9b48ed2d545336b
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: c7fac4471201977fdb1c0c0a26c87287e12dc644
5-
refs/heads/try: 1ac8b34ccd02965886d3ca0bd83115c7f7b73729
5+
refs/heads/try: 898669c4e203ae91e2048fb6c0f8591c867bccc6
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/src/librustc/middle/trans/expr.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ use middle::typeck::MethodCall;
6767
use util::common::indenter;
6868
use util::ppaux::Repr;
6969
use util::nodemap::NodeMap;
70-
use middle::trans::machine::llsize_of;
70+
use middle::trans::machine::{llsize_of, llsize_of_alloc};
7171
use middle::trans::type_::Type;
7272

7373
use std::slice;
@@ -1200,12 +1200,19 @@ fn trans_boxed_expr<'a>(bcx: &'a Block<'a>,
12001200
let size = llsize_of(bcx.ccx(), llty);
12011201
let Result { bcx: bcx, val: val } = malloc_raw_dyn(bcx, contents_ty,
12021202
heap_exchange, size);
1203-
let custom_cleanup_scope = fcx.push_custom_cleanup_scope();
1204-
fcx.schedule_free_value(cleanup::CustomScope(custom_cleanup_scope),
1205-
val, heap_exchange);
1206-
let bcx = trans_into(bcx, contents, SaveIn(val));
1207-
fcx.pop_custom_cleanup_scope(custom_cleanup_scope);
1208-
immediate_rvalue_bcx(bcx, val, box_ty).to_expr_datumblock()
1203+
// Unique boxes do not allocate for zero-size types. The standard library may assume
1204+
// that `free` is never called on the pointer returned for `~ZeroSizeType`.
1205+
if llsize_of_alloc(bcx.ccx(), llty) == 0 {
1206+
let bcx = trans_into(bcx, contents, SaveIn(val));
1207+
immediate_rvalue_bcx(bcx, val, box_ty).to_expr_datumblock()
1208+
} else {
1209+
let custom_cleanup_scope = fcx.push_custom_cleanup_scope();
1210+
fcx.schedule_free_value(cleanup::CustomScope(custom_cleanup_scope),
1211+
val, heap_exchange);
1212+
let bcx = trans_into(bcx, contents, SaveIn(val));
1213+
fcx.pop_custom_cleanup_scope(custom_cleanup_scope);
1214+
immediate_rvalue_bcx(bcx, val, box_ty).to_expr_datumblock()
1215+
}
12091216
} else {
12101217
let base::MallocResult { bcx, smart_ptr: bx, body } =
12111218
base::malloc_general(bcx, contents_ty, heap);

branches/try/src/libstd/rt/global_heap.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,21 @@ pub unsafe fn realloc_raw(ptr: *mut u8, size: uint) -> *mut u8 {
6464
}
6565
}
6666

67+
// The compiler never calls `exchange_free` on ~ZeroSizeType, so zero-size
68+
// allocations can point to this `static`. It would be incorrect to use a null
69+
// pointer, due to enums assuming types like unique pointers are never null.
70+
static EMPTY: () = ();
71+
6772
/// The allocator for unique pointers without contained managed pointers.
6873
#[cfg(not(test))]
6974
#[lang="exchange_malloc"]
7075
#[inline]
71-
pub unsafe fn exchange_malloc(size: uint) -> *u8 {
72-
malloc_raw(size) as *u8
76+
pub unsafe fn exchange_malloc(size: uint) -> *mut u8 {
77+
if size == 0 {
78+
&EMPTY as *() as *mut u8
79+
} else {
80+
malloc_raw(size)
81+
}
7382
}
7483

7584
// FIXME: #7496
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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+
pub fn main() {
12+
assert!(Some(~()).is_some());
13+
14+
struct Foo;
15+
assert!(Some(~Foo).is_some());
16+
17+
let xs: ~[()] = ~[];
18+
assert!(Some(xs).is_some());
19+
}

0 commit comments

Comments
 (0)