about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2012-04-10 18:34:21 -0700
committerGraydon Hoare <graydon@mozilla.com>2012-04-11 12:07:19 -0700
commitf34eae8802b327c23984bfef02312ce1c64a6581 (patch)
tree2c65dc6fc6d32c00a1f18f8de2b6d2b94a6dad25
parentc720ffdbc428336546448daf2f806428cc22db06 (diff)
Translate slice-strings and make fixed-strings carry their null.
-rw-r--r--src/rustc/middle/trans/base.rs11
-rw-r--r--src/rustc/middle/trans/tvec.rs32
-rw-r--r--src/rustc/middle/trans/type_of.rs2
-rw-r--r--src/rustc/middle/ty.rs16
-rw-r--r--src/test/run-pass/estr-slice.rs9
5 files changed, 39 insertions, 31 deletions
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index dbf3ca841ba..6c3e81b4999 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -1236,7 +1236,7 @@ fn copy_val_no_check(bcx: block, action: copy_action, dst: ValueRef,
     let _icx = bcx.insn_ctxt("copy_val_no_check");
     let ccx = bcx.ccx();
     let mut bcx = bcx;
-    if ty::type_is_scalar(t) {
+    if ty::type_is_scalar(t) || ty::type_is_slice(t) {
         Store(bcx, src, dst);
         ret bcx;
     }
@@ -1268,7 +1268,7 @@ fn move_val(cx: block, action: copy_action, dst: ValueRef,
     let mut src_val = src.val;
     let tcx = cx.tcx();
     let mut cx = cx;
-    if ty::type_is_scalar(t) {
+    if ty::type_is_scalar(t) || ty::type_is_slice(t) {
         if src.kind == owned { src_val = Load(cx, src_val); }
         Store(cx, src_val, dst);
         ret cx;
@@ -2294,6 +2294,13 @@ fn trans_index(cx: block, ex: @ast::expr, base: @ast::expr,
         let body = GEPi(bcx, v, [0, 0]);
         (lim, body)
       }
+      ty::ty_estr(ty::vstore_slice(_)) |
+      ty::ty_evec(_, ty::vstore_slice(_)) {
+        let body = Load(bcx, GEPi(bcx, v, [0, 0]));
+        let lim = Load(bcx, GEPi(bcx, v, [0, 1]));
+        (lim, body)
+      }
+
       ty::ty_estr(_) | ty::ty_evec(_, _) {
         bcx.sess().unimpl(#fmt("unsupported evec/estr type trans_index"));
       }
diff --git a/src/rustc/middle/trans/tvec.rs b/src/rustc/middle/trans/tvec.rs
index bce423e37e4..1008d9ed8c6 100644
--- a/src/rustc/middle/trans/tvec.rs
+++ b/src/rustc/middle/trans/tvec.rs
@@ -148,28 +148,30 @@ fn trans_vstore(bcx: block, e: @ast::expr,
 fn trans_estr(bcx: block, s: str, vstore: ast::vstore,
               sp: span, dest: dest) -> block {
     let _icx = bcx.insn_ctxt("tvec::trans_estr");
-    alt vstore {
+    let ccx = bcx.ccx();
+
+    let c = alt vstore {
       ast::vstore_fixed(_)
       {
-        let c = str::as_bytes(s) {|bytes|
-            // NB: The byte vector we have here includes the trailing \0,
-            // but we are doing a fixed-size str, meaning we _exclude_
-            // the trailing \0. And we don't let LLVM null-terminate
-            // either.
-            unsafe {
-                lib::llvm::llvm::LLVMConstString(
-                    unsafe::reinterpret_cast(vec::unsafe::to_ptr(bytes)),
-                    (bytes.len() - 1u) as libc::c_uint, lib::llvm::True)
-            }
-        };
+        // "hello"/_  =>  [i8 x 6] in llvm
+        #debug("trans_estr: fixed: %s", s);
+        C_postr(s)
+      }
 
-        #debug("trans_estr: src %s",val_str(bcx.ccx().tn, c));
-        ret base::store_in_dest(bcx, c, dest);
+      ast::vstore_slice(_) {
+        // "hello"  =>  (*i8,uint) in llvm
+        #debug("trans_estr: slice '%s'", s);
+        let cs = PointerCast(bcx, C_cstr(ccx, s), T_ptr(T_i8()));
+        C_struct([cs, C_uint(ccx, str::len(s))])
       }
+
       _ {
         bcx.ccx().sess.span_unimpl(sp, "unhandled tvec::trans_estr");
       }
-    }
+    };
+
+    #debug("trans_estr: type: %s", val_str(ccx.tn, c));
+    base::store_in_dest(bcx, c, dest)
 }
 
 fn trans_str(bcx: block, s: str, dest: dest) -> block {
diff --git a/src/rustc/middle/trans/type_of.rs b/src/rustc/middle/trans/type_of.rs
index 6e24b4c72a1..eef0f0b5101 100644
--- a/src/rustc/middle/trans/type_of.rs
+++ b/src/rustc/middle/trans/type_of.rs
@@ -72,7 +72,7 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
       }
 
       ty::ty_estr(ty::vstore_fixed(n)) {
-        T_array(T_i8(), n)
+        T_array(T_i8(), n + 1u /* +1 for trailing null */)
       }
 
       ty::ty_evec(mt, ty::vstore_fixed(n)) {
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index 4994fe24ed3..0852edcbea6 100644
--- a/src/rustc/middle/ty.rs
+++ b/src/rustc/middle/ty.rs
@@ -118,7 +118,7 @@ export type_is_sequence;
 export type_is_signed;
 export type_is_structural;
 export type_is_copyable;
-export type_is_tup_like;
+export type_is_slice;
 export type_is_unique;
 export type_is_c_like_enum;
 export type_structurally_contains;
@@ -858,13 +858,6 @@ fn sequence_element_type(cx: ctxt, ty: t) -> t {
     }
 }
 
-pure fn type_is_tup_like(ty: t) -> bool {
-    alt get(ty).struct {
-      ty_rec(_) | ty_tup(_) { true }
-      _ { false }
-    }
-}
-
 fn get_element_type(ty: t, i: uint) -> t {
     alt get(ty).struct {
       ty_rec(flds) { ret flds[i].mt.ty; }
@@ -887,6 +880,13 @@ pure fn type_is_boxed(ty: t) -> bool {
     }
 }
 
+pure fn type_is_slice(ty: t) -> bool {
+    alt get(ty).struct {
+      ty_evec(_, vstore_slice(_)) | ty_estr(vstore_slice(_)) { true }
+      _ { ret false; }
+    }
+}
+
 pure fn type_is_unique_box(ty: t) -> bool {
     alt get(ty).struct {
       ty_uniq(_) { ret true; }
diff --git a/src/test/run-pass/estr-slice.rs b/src/test/run-pass/estr-slice.rs
index bf727908e9e..f91474cba8b 100644
--- a/src/test/run-pass/estr-slice.rs
+++ b/src/test/run-pass/estr-slice.rs
@@ -1,8 +1,7 @@
-// xfail-test
 fn main() {
-    let x : str/& = "hello";
-    let mut y = "there";
+    let x = "hello"/&;
+    let mut y = "there"/&;
     y = x;
-    assert y[1] == 'h' as u8;
-    assert y[4] == 'e' as u8;
+    assert y[0] == 'h' as u8;
+    assert y[4] == 'o' as u8;
 }
\ No newline at end of file