From f34eae8802b327c23984bfef02312ce1c64a6581 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Tue, 10 Apr 2012 18:34:21 -0700 Subject: [PATCH] Translate slice-strings and make fixed-strings carry their null. --- src/rustc/middle/trans/base.rs | 11 +++++++++-- src/rustc/middle/trans/tvec.rs | 32 ++++++++++++++++--------------- src/rustc/middle/trans/type_of.rs | 2 +- src/rustc/middle/ty.rs | 16 ++++++++-------- src/test/run-pass/estr-slice.rs | 9 ++++----- 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_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 @@ fn get_element_type(ty: t, i: uint) -> t { } } +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 -- GitLab