diff --git a/src/libcore/rt.rs b/src/libcore/rt.rs index 2d2d24e6018..f9de0bc91fd 100644 --- a/src/libcore/rt.rs +++ b/src/libcore/rt.rs @@ -14,7 +14,7 @@ //! Runtime calls emitted by the compiler. use cast::transmute; -use libc::{c_char, c_void, size_t, uintptr_t}; +use libc::{c_char, c_uchar, c_void, size_t, uintptr_t}; use managed::raw::BoxRepr; use str; use sys; @@ -123,6 +123,11 @@ pub unsafe fn check_not_borrowed(a: *u8) { } } +#[lang="strdup_uniq"] +pub unsafe fn strdup_uniq(ptr: *c_uchar, len: uint) -> ~str { + str::raw::from_buf_len(ptr, len) +} + // Local Variables: // mode: rust; // fill-column: 78; diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index df7b7196a24..dcfa1755d09 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -74,16 +74,17 @@ pub enum LangItem { BorrowAsImmFnLangItem, // 30 ReturnToMutFnLangItem, // 31 CheckNotBorrowedFnLangItem, // 32 + StrDupUniqFnLangItem, // 33 } struct LanguageItems { - items: [ Option * 33 ] + items: [ Option * 34 ] } impl LanguageItems { static pub fn new() -> LanguageItems { LanguageItems { - items: [ None, ..33 ] + items: [ None, ..34 ] } } @@ -133,6 +134,7 @@ impl LanguageItems { 30 => "borrow_as_imm", 31 => "return_to_mut", 32 => "check_not_borrowed", + 33 => "strdup_uniq", _ => "???" } @@ -243,6 +245,9 @@ impl LanguageItems { pub fn check_not_borrowed_fn(&const self) -> def_id { self.items[CheckNotBorrowedFnLangItem as uint].get() } + pub fn strdup_uniq_fn(&const self) -> def_id { + self.items[StrDupUniqFnLangItem as uint].get() + } } fn LanguageItemCollector(crate: @crate, @@ -289,6 +294,7 @@ fn LanguageItemCollector(crate: @crate, item_refs.insert(~"return_to_mut", ReturnToMutFnLangItem as uint); item_refs.insert(~"check_not_borrowed", CheckNotBorrowedFnLangItem as uint); + item_refs.insert(~"strdup_uniq", StrDupUniqFnLangItem as uint); LanguageItemCollector { crate: crate, diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index eb2fd91e605..54e6d25718b 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -276,10 +276,9 @@ fn trans_lit_str(bcx: block, fn trans_uniq_or_managed_vstore(bcx: block, - heap: heap, - vstore_expr: @ast::expr, - content_expr: @ast::expr) -> DatumBlock -{ + heap: heap, + vstore_expr: @ast::expr, + content_expr: @ast::expr) -> DatumBlock { //! // // @[...] or ~[...] (also @"..." or ~"...") allocate boxes in the @@ -289,6 +288,34 @@ fn trans_uniq_or_managed_vstore(bcx: block, bcx.expr_to_str(vstore_expr), heap); let _indenter = indenter(); + // Handle ~"". + match heap { + heap_exchange => { + match content_expr.node { + ast::expr_lit(@ast::spanned { + node: ast::lit_str(s), _ + }) => { + let llptrval = C_cstr(bcx.ccx(), copy *s); + let llptrval = PointerCast(bcx, llptrval, T_ptr(T_i8())); + let llsizeval = C_uint(bcx.ccx(), s.len()); + let typ = ty::mk_estr(bcx.tcx(), ty::vstore_uniq); + let lldestval = datum::scratch_datum(bcx, typ, false); + let bcx = callee::trans_rtcall_or_lang_call( + bcx, + bcx.tcx().lang_items.strdup_uniq_fn(), + ~[ llptrval, llsizeval ], + expr::SaveIn(lldestval.to_ref_llval(bcx))); + return datum::DatumBlock { + bcx: bcx, + datum: lldestval + }; + } + _ => {} + } + } + heap_shared => {} + } + let vt = vec_types_from_expr(bcx, vstore_expr); let count = elements_required(bcx, content_expr);