about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-08-22 17:35:38 -0700
committerBrian Anderson <banderson@mozilla.com>2011-08-22 17:40:06 -0700
commitd6e4fa6b449e7226438d4645fb4c21fa1dc46479 (patch)
tree34012252f050a7f759b8f2b9d8f15e80c81485dd
parent3ab86fb79edd0c60e4685c0d865531011e6abdb9 (diff)
downloadrust-d6e4fa6b449e7226438d4645fb4c21fa1dc46479.tar.gz
rust-d6e4fa6b449e7226438d4645fb4c21fa1dc46479.zip
Teach rustc to append istrs. Issue #855
-rw-r--r--src/comp/middle/trans_ivec.rs30
-rw-r--r--src/test/run-pass/istr.rs19
2 files changed, 42 insertions, 7 deletions
diff --git a/src/comp/middle/trans_ivec.rs b/src/comp/middle/trans_ivec.rs
index d5b82c66436..b2189a92637 100644
--- a/src/comp/middle/trans_ivec.rs
+++ b/src/comp/middle/trans_ivec.rs
@@ -354,11 +354,6 @@ fn trans_append(cx: &@block_ctxt, t: ty::t, orig_lhs: ValueRef,
 
     let unit_ty = ty::sequence_element_type(bcx_tcx(cx), t);
     let llunitty = type_of_or_i8(cx, unit_ty);
-    alt ty::struct(bcx_tcx(cx), t) {
-      ty::ty_istr. { }
-      ty::ty_vec(_) { }
-      _ { bcx_tcx(cx).sess.bug("non-istr/ivec in trans_append"); }
-    }
 
     let rs = size_of(cx, unit_ty);
     let bcx = rs.bcx;
@@ -381,10 +376,31 @@ fn trans_append(cx: &@block_ctxt, t: ty::t, orig_lhs: ValueRef,
     let rhs_len = rhs_len_and_data.len;
     let rhs_data = rhs_len_and_data.data;
     bcx = rhs_len_and_data.bcx;
-    rs = reserve_space(bcx, llunitty, lhs, rhs_len);
-    let lhs_data = rs.val;
+
+    let have_istrs = alt ty::struct(bcx_tcx(cx), t) {
+      ty::ty_istr. { true }
+      ty::ty_vec(_) { false }
+      _ { bcx_tcx(cx).sess.bug("non-istr/ivec in trans_append"); }
+    };
+
+    let extra_len = if have_istrs {
+        // Only need one of the nulls
+        bcx.build.Sub(rhs_len, C_uint(1u))
+    } else { rhs_len };
+
+    rs = reserve_space(bcx, llunitty, lhs, extra_len);
     bcx = rs.bcx;
 
+    let lhs_data = if have_istrs {
+        let lhs_data = rs.val;
+        let lhs_data_without_null_ptr = alloca(bcx, T_ptr(llunitty));
+        incr_ptr(bcx, lhs_data, C_int(-1),
+                 lhs_data_without_null_ptr);
+        bcx.build.Load(lhs_data_without_null_ptr)
+    } else {
+        rs.val
+    };
+
     // If rhs is lhs then our rhs pointer may have changed
     rhs_len_and_data = get_len_and_data(bcx, rhs, unit_ty);
     rhs_data = rhs_len_and_data.data;
diff --git a/src/test/run-pass/istr.rs b/src/test/run-pass/istr.rs
index 6930808f647..8b0eb0ddc05 100644
--- a/src/test/run-pass/istr.rs
+++ b/src/test/run-pass/istr.rs
@@ -39,6 +39,24 @@ fn test_heap_add() {
     assert ~"this should" + ~" totally work" == ~"this should totally work";
 }
 
+fn test_append() {
+    let s = ~"";
+    s += ~"a";
+    assert s == ~"a";
+
+    let s = ~"a";
+    s += ~"b";
+    log s;
+    assert s == ~"ab";
+
+    let s = ~"c";
+    s += ~"offee";
+    assert s == ~"coffee";
+
+    s += ~"&tea";
+    assert s == ~"coffee&tea";
+}
+
 fn main() {
     test_stack_assign();
     test_heap_lit();
@@ -47,4 +65,5 @@ fn main() {
     test_stack_add();
     test_stack_heap_add();
     test_heap_add();
+    test_append();
 }
\ No newline at end of file