From 681bbd396b9b993d895d8826bfb45e4ed33df3ce Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 4 Dec 2014 17:18:57 -0500 Subject: [PATCH 01/39] librustc: add "str" lang item --- src/librustc/middle/lang_items.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index da1c0bd649a1..f850c5795528 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -265,6 +265,7 @@ lets_do_this! { OrdTraitLangItem, "ord", ord_trait; StrEqFnLangItem, "str_eq", str_eq_fn; + StrStructLangItem, "str", str_struct; // A number of panic-related lang items. The `panic` item corresponds to // divide-by-zero and various panic cases with `match`. The From f63b8e42412a7ee734ccfd6bb4ec16a6389846ca Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 4 Dec 2014 20:30:56 -0500 Subject: [PATCH 02/39] librustc: use "str" lang item in `mk_str`/`mk_str_slice` --- src/librustc/middle/ty.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 994f0c2090a5..1c839ac9b108 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -46,6 +46,7 @@ use metadata::csearch; use middle::const_eval; use middle::def; use middle::dependency_format; +use middle::lang_items::StrStructLangItem; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem}; use middle::lang_items::{FnOnceTraitLangItem, TyDescStructLangItem}; use middle::mem_categorization as mc; @@ -2149,15 +2150,14 @@ pub fn mk_mach_float<'tcx>(tm: ast::FloatTy) -> Ty<'tcx> { } pub fn mk_str<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> { - mk_t(cx, ty_str) + match cx.lang_items.require(StrStructLangItem) { + Ok(did) => mk_struct(cx, did, Substs::empty()), + Err(err) => cx.sess.fatal(err.as_slice()), + } } -pub fn mk_str_slice<'tcx>(cx: &ctxt<'tcx>, r: Region, m: ast::Mutability) -> Ty<'tcx> { - mk_rptr(cx, r, - mt { - ty: mk_t(cx, ty_str), - mutbl: m - }) +pub fn mk_str_slice<'tcx>(cx: &ctxt<'tcx>, r: Region) -> Ty<'tcx> { + mk_rptr(cx, r, mt { ty: mk_str(cx), mutbl: MutImmutable }) } pub fn mk_enum<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId, substs: Substs<'tcx>) -> Ty<'tcx> { From 5c73c5dcc1130f5857cfafd1cb4b11334506d9c7 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 4 Dec 2014 20:33:20 -0500 Subject: [PATCH 03/39] librustc[_trans]: fix fallout of changing `mk_str_slice` signature --- src/librustc_trans/trans/_match.rs | 2 +- src/librustc_typeck/check/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index ada46ab7db71..492720326867 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -805,7 +805,7 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>, ty::ty_uint(ast::TyU8) => { // NOTE: cast &[u8] to &str and abuse the str_eq lang item, // which calls memcmp(). - let t = ty::mk_str_slice(cx.tcx(), ty::ReStatic, ast::MutImmutable); + let t = ty::mk_str_slice(cx.tcx(), ty::ReStatic); let lhs = BitCast(cx, lhs, type_of::type_of(cx.ccx(), t).ptr_to()); let rhs = BitCast(cx, rhs, type_of::type_of(cx.ccx(), t).ptr_to()); compare_str(cx, lhs, rhs, rhs_t) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a0f3f2734d97..2977ea720c17 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2844,7 +2844,7 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let tcx = fcx.ccx.tcx; match lit.node { - ast::LitStr(..) => ty::mk_str_slice(tcx, ty::ReStatic, ast::MutImmutable), + ast::LitStr(..) => ty::mk_str_slice(tcx, ty::ReStatic), ast::LitBinary(..) => { ty::mk_slice(tcx, ty::ReStatic, ty::mt{ ty: ty::mk_u8(), mutbl: ast::MutImmutable }) } From c9779215d5fb7f20ee4ed0e1a64a87f8f8078777 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 4 Dec 2014 20:57:33 -0500 Subject: [PATCH 04/39] librustc: add `is_str` utility function --- src/librustc/middle/ty.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 1c839ac9b108..67ab72b68034 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2390,6 +2390,13 @@ impl<'tcx> ParamBounds<'tcx> { // Type utilities +pub fn is_str(cx: &ctxt, did: DefId) -> bool { + match cx.lang_items.require(StrStructLangItem) { + Ok(lang_did) => lang_did == did, + Err(err) => cx.sess.fatal(err.as_slice()), + } +} + pub fn type_is_nil(ty: Ty) -> bool { match ty.sty { ty_tup(ref tys) => tys.is_empty(), From c00d178c724674dce369c88bfb2cb12b2feb15af Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 4 Dec 2014 20:39:23 -0500 Subject: [PATCH 05/39] librustc: kill `ty_str` --- src/librustc/metadata/tyencode.rs | 2 +- src/librustc/middle/check_match.rs | 6 ++-- src/librustc/middle/effect.rs | 11 ++++--- src/librustc/middle/fast_reject.rs | 2 +- src/librustc/middle/infer/coercion.rs | 4 +-- src/librustc/middle/infer/combine.rs | 4 --- src/librustc/middle/infer/skolemize.rs | 1 - src/librustc/middle/mem_categorization.rs | 12 ++++--- src/librustc/middle/traits/coherence.rs | 5 +-- src/librustc/middle/traits/select.rs | 2 +- src/librustc/middle/ty.rs | 38 +++++++++++------------ src/librustc/middle/ty_fold.rs | 2 +- src/librustc/util/ppaux.rs | 3 +- src/librustc_typeck/check/method/probe.rs | 5 ++- src/librustc_typeck/check/regionck.rs | 6 +++- src/librustc_typeck/check/regionmanip.rs | 7 +++-- src/librustc_typeck/coherence/mod.rs | 4 +-- src/librustc_typeck/variance.rs | 6 +++- 18 files changed, 69 insertions(+), 51 deletions(-) diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index bbb2faaae069..5d1ff762b307 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -272,7 +272,7 @@ fn enc_sty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, None => mywrite!(w, "|"), } } - ty::ty_str => { + ty::ty_struct(did, _) if ty::is_str(cx.tcx, did) => { mywrite!(w, "v"); } ty::ty_closure(ref f) => { diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index ed119081f78c..b4a0ddcc4873 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -485,7 +485,9 @@ fn construct_witness(cx: &MatchCheckCtxt, ctor: &Constructor, }, _ => unreachable!() }, - ty::ty_str => ast::PatWild(ast::PatWildSingle), + ty::ty_struct(did, _) if ty::is_str(cx.tcx, did) => { + ast::PatWild(ast::PatWildSingle) + }, _ => { assert_eq!(pats_len, 1); @@ -737,7 +739,7 @@ pub fn constructor_arity(cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> uin ConstantValue(_) => 0u, _ => unreachable!() }, - ty::ty_str => 0u, + ty::ty_struct(did, _) if ty::is_str(cx.tcx, did) => 0u, _ => 1u }, ty::ty_enum(eid, _) => { diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index dbec69f42050..8a114693a265 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -71,11 +71,14 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> { debug!("effect: checking index with base type {}", ppaux::ty_to_string(self.tcx, base_type)); match base_type.sty { - ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => if ty::ty_str == ty.sty { - span_err!(self.tcx.sess, e.span, E0134, - "modification of string types is not allowed"); + ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty.sty { + ty::ty_struct(did, _) if ty::is_str(self.tcx, did) => { + span_err!(self.tcx.sess, e.span, E0134, + "modification of string types is not allowed"); + }, + _ => {}, }, - ty::ty_str => { + ty::ty_struct(did, _) if ty::is_str(self.tcx, did) => { span_err!(self.tcx.sess, e.span, E0135, "modification of string types is not allowed"); } diff --git a/src/librustc/middle/fast_reject.rs b/src/librustc/middle/fast_reject.rs index 888f01f9118f..9befdf500e33 100644 --- a/src/librustc/middle/fast_reject.rs +++ b/src/librustc/middle/fast_reject.rs @@ -54,7 +54,7 @@ pub fn simplify_type(tcx: &ty::ctxt, ty::ty_uint(uint_type) => Some(UintSimplifiedType(uint_type)), ty::ty_float(float_type) => Some(FloatSimplifiedType(float_type)), ty::ty_enum(def_id, _) => Some(EnumSimplifiedType(def_id)), - ty::ty_str => Some(StrSimplifiedType), + ty::ty_struct(did, _) if ty::is_str(tcx, did) => Some(StrSimplifiedType), ty::ty_vec(..) => Some(VecSimplifiedType), ty::ty_ptr(_) => Some(PtrSimplifiedType), ty::ty_trait(ref trait_info) => { diff --git a/src/librustc/middle/infer/coercion.rs b/src/librustc/middle/infer/coercion.rs index f04c519badc8..d77e2c6a783d 100644 --- a/src/librustc/middle/infer/coercion.rs +++ b/src/librustc/middle/infer/coercion.rs @@ -105,7 +105,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { match b.sty { ty::ty_ptr(mt_b) => { match mt_b.ty.sty { - ty::ty_str => { + ty::ty_struct(did, _) if ty::is_str(self.0.infcx.tcx, did) => { return self.unpack_actual_value(a, |sty_a| { self.coerce_unsafe_ptr(a, sty_a, b, ast::MutImmutable) }); @@ -132,7 +132,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { ty::ty_rptr(_, mt_b) => { match mt_b.ty.sty { - ty::ty_str => { + ty::ty_struct(did, _) if ty::is_str(self.0.infcx.tcx, did) => { return self.unpack_actual_value(a, |sty_a| { self.coerce_borrowed_pointer(a, sty_a, b, ast::MutImmutable) }); diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs index ab9c5b86aeb6..ea9a3191c358 100644 --- a/src/librustc/middle/infer/combine.rs +++ b/src/librustc/middle/infer/combine.rs @@ -478,10 +478,6 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C, }) } - (&ty::ty_str, &ty::ty_str) => { - Ok(ty::mk_str(tcx)) - } - (&ty::ty_tup(ref as_), &ty::ty_tup(ref bs)) => { if as_.len() == bs.len() { as_.iter().zip(bs.iter()) diff --git a/src/librustc/middle/infer/skolemize.rs b/src/librustc/middle/infer/skolemize.rs index 62bf1d0126a5..09f2cb215890 100644 --- a/src/librustc/middle/infer/skolemize.rs +++ b/src/librustc/middle/infer/skolemize.rs @@ -145,7 +145,6 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeSkolemizer<'a, 'tcx> { ty::ty_float(..) | ty::ty_enum(..) | ty::ty_uniq(..) | - ty::ty_str | ty::ty_err | ty::ty_vec(..) | ty::ty_ptr(..) | diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index cd70d8e2b487..601ac1899526 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -194,7 +194,7 @@ pub enum deref_kind { // Categorizes a derefable type. Note that we include vectors and strings as // derefable (we model an index as the combination of a deref and then a // pointer adjustment). -pub fn opt_deref_kind(t: Ty) -> Option { +pub fn opt_deref_kind(tcx: &ty::ctxt, t: Ty) -> Option { match t.sty { ty::ty_uniq(_) | ty::ty_closure(box ty::ClosureTy {store: ty::UniqTraitStore, ..}) => { @@ -217,12 +217,16 @@ pub fn opt_deref_kind(t: Ty) -> Option { Some(deref_ptr(UnsafePtr(mt.mutbl))) } + ty::ty_struct(did, _) if ty::is_str(tcx, did) => { + Some(deref_interior(InteriorElement(element_kind(t)))) + } + ty::ty_enum(..) | ty::ty_struct(..) => { // newtype Some(deref_interior(InteriorField(PositionalField(0)))) } - ty::ty_vec(_, _) | ty::ty_str => { + ty::ty_vec(_, _) => { Some(deref_interior(InteriorElement(element_kind(t)))) } @@ -232,7 +236,7 @@ pub fn opt_deref_kind(t: Ty) -> Option { pub fn deref_kind<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> deref_kind { debug!("deref_kind {}", ty_to_string(tcx, t)); - match opt_deref_kind(t) { + match opt_deref_kind(tcx, t) { Some(k) => k, None => { tcx.sess.bug( @@ -989,7 +993,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { ty::ty_fn_args(method_ty)[0] } None => { - match ty::array_element_ty(base_cmt.ty) { + match ty::array_element_ty(self.tcx(), base_cmt.ty) { Some(ty) => ty, None => { self.tcx().sess.span_bug( diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs index 1bce353cb0cf..2acc7cc2e9a5 100644 --- a/src/librustc/middle/traits/coherence.rs +++ b/src/librustc/middle/traits/coherence.rs @@ -84,11 +84,12 @@ pub fn ty_is_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool { ty::ty_char | ty::ty_int(..) | ty::ty_uint(..) | - ty::ty_float(..) | - ty::ty_str(..) => { + ty::ty_float(..) => { false } + ty::ty_struct(did, _) if ty::is_str(tcx, did) => { false } + ty::ty_unboxed_closure(..) => { // This routine is invoked on types specified by users as // part of an impl and hence an unboxed closure type diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 0e6a0c19f706..31113d2c0a2f 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -1400,7 +1400,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - ty::ty_str => { + ty::ty_struct(did, _) if ty::is_str(self.tcx(), did) => { // Equivalent to [u8] match bound { ty::BoundSync | diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 67ab72b68034..75889fefeda2 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1230,7 +1230,6 @@ pub enum sty<'tcx> { /// well.` ty_enum(DefId, Substs<'tcx>), ty_uniq(Ty<'tcx>), - ty_str, ty_vec(Ty<'tcx>, Option), // Second field is length. ty_ptr(mt<'tcx>), ty_rptr(Region, mt<'tcx>), @@ -1995,8 +1994,7 @@ impl FlagComputation { &ty_char | &ty_int(_) | &ty_float(_) | - &ty_uint(_) | - &ty_str => { + &ty_uint(_) => { } // You might think that we could just return ty_err for @@ -2302,7 +2300,7 @@ pub fn maybe_walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>| -> bool) { } match ty.sty { ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) | - ty_str | ty_infer(_) | ty_param(_) | ty_err => {} + ty_infer(_) | ty_param(_) | ty_err => {} ty_uniq(ty) | ty_vec(ty, _) | ty_open(ty) => maybe_walk_ty(ty, f), ty_ptr(ref tm) | ty_rptr(_, ref tm) => { maybe_walk_ty(tm.ty, f); @@ -2432,10 +2430,11 @@ pub fn type_is_self(ty: Ty) -> bool { } } -fn type_is_slice(ty: Ty) -> bool { +fn type_is_slice(cx: &ctxt, ty: Ty) -> bool { match ty.sty { ty_ptr(mt) | ty_rptr(_, mt) => match mt.ty.sty { - ty_vec(_, None) | ty_str => true, + ty_vec(_, None) => true, + ty_struct(did, _) if is_str(cx, did) => true, _ => false, }, _ => false @@ -2454,11 +2453,11 @@ pub fn type_is_vec(ty: Ty) -> bool { } } -pub fn type_is_structural(ty: Ty) -> bool { +pub fn type_is_structural(cx: &ctxt, ty: Ty) -> bool { match ty.sty { ty_struct(..) | ty_tup(_) | ty_enum(..) | ty_closure(_) | ty_vec(_, Some(_)) | ty_unboxed_closure(..) => true, - _ => type_is_slice(ty) | type_is_trait(ty) + _ => type_is_slice(cx, ty) | type_is_trait(ty) } } @@ -2472,7 +2471,7 @@ pub fn type_is_simd(cx: &ctxt, ty: Ty) -> bool { pub fn sequence_element_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { match ty.sty { ty_vec(ty, _) => ty, - ty_str => mk_mach_uint(ast::TyU8), + ty_struct(did, _) if is_str(cx, did) => mk_mach_uint(ast::TyU8), ty_open(ty) => sequence_element_type(cx, ty), _ => cx.sess.bug(format!("sequence_element_type called on non-sequence value: {}", ty_to_string(cx, ty)).as_slice()), @@ -2833,7 +2832,7 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents { ty_uniq(typ) => { TC::ReachesFfiUnsafe | match typ.sty { - ty_str => TC::OwnsOwned, + ty_struct(did, _) if is_str(cx, did) => TC::OwnsOwned, _ => tc_ty(cx, typ, cache).owned_pointer(), } } @@ -2848,7 +2847,7 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents { ty_rptr(r, ref mt) => { TC::ReachesFfiUnsafe | match mt.ty.sty { - ty_str => borrowed_contents(r, ast::MutImmutable), + ty_struct(did, _) if is_str(cx, did) => borrowed_contents(r, ast::MutImmutable), ty_vec(..) => tc_ty(cx, mt.ty, cache).reference(borrowed_contents(r, mt.mutbl)), _ => tc_ty(cx, mt.ty, cache).reference(borrowed_contents(r, mt.mutbl)), } @@ -2861,7 +2860,7 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents { ty_vec(ty, None) => { tc_ty(cx, ty, cache) | TC::Nonsized } - ty_str => TC::Nonsized, + ty_struct(did, _) if is_str(cx, did) => TC::Nonsized, ty_struct(did, ref substs) => { let flds = struct_fields(cx, did, substs); @@ -3131,7 +3130,6 @@ pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>) -> bool { ty_int(_) | ty_uint(_) | ty_float(_) | - ty_str | ty_bare_fn(_) | ty_closure(_) | ty_infer(_) | @@ -3140,6 +3138,7 @@ pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>) -> bool { ty_vec(_, None) => { false } + ty_struct(did, _) if ty::is_str(cx, did) => false, ty_uniq(typ) | ty_open(typ) => { type_requires(cx, seen, r_ty, typ) } @@ -3471,7 +3470,8 @@ pub fn lltype_is_sized<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> bool { // the size of an object at runtime. pub fn unsized_part_of_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { match ty.sty { - ty_str | ty_trait(..) | ty_vec(..) => ty, + ty_trait(..) | ty_vec(..) => ty, + ty_struct(did, _) if ty::is_str(cx, did) => ty, ty_struct(def_id, ref substs) => { let unsized_fields: Vec<_> = struct_fields(cx, def_id, substs).iter() .map(|f| f.mt.ty).filter(|ty| !type_is_sized(cx, *ty)).collect(); @@ -3557,10 +3557,10 @@ pub fn index<'tcx>(ty: Ty<'tcx>) -> Option> { // Returns the type of elements contained within an 'array-like' type. // This is exactly the same as the above, except it supports strings, // which can't actually be indexed. -pub fn array_element_ty<'tcx>(ty: Ty<'tcx>) -> Option> { +pub fn array_element_ty<'tcx>(cx: &ctxt, ty: Ty<'tcx>) -> Option> { match ty.sty { ty_vec(ty, _) => Some(ty), - ty_str => Some(mk_u8()), + ty_struct(did, _) if is_str(cx, did) => Some(mk_u8()), _ => None } } @@ -4208,9 +4208,10 @@ pub fn impl_or_trait_item_idx(id: ast::Name, trait_items: &[ImplOrTraitItem]) pub fn ty_sort_string<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> String { match ty.sty { ty_bool | ty_char | ty_int(_) | - ty_uint(_) | ty_float(_) | ty_str => { + ty_uint(_) | ty_float(_) => { ::util::ppaux::ty_to_string(cx, ty) } + ty_struct(did, _) if ty::is_str(cx, did) => ::util::ppaux::ty_to_string(cx, ty), ty_tup(ref tys) if tys.is_empty() => ::util::ppaux::ty_to_string(cx, ty), ty_enum(id, _) => format!("enum {}", item_path_str(cx, id)), @@ -5653,7 +5654,7 @@ pub fn hash_crate_independent(tcx: &ctxt, ty: Ty, svh: &Svh) -> u64 { byte!(6); hash!(f); } - ty_str => { + ty_struct(did, _) if is_str(tcx, did) => { byte!(7); } ty_enum(d, _) => { @@ -5995,7 +5996,6 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec, ty_uint(_) | ty_float(_) | ty_uniq(_) | - ty_str | ty_vec(_, _) | ty_ptr(_) | ty_bare_fn(_) | diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 77092025349e..721d2041a8e0 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -631,7 +631,7 @@ pub fn super_fold_sty<'tcx, T: TypeFolder<'tcx>>(this: &mut T, ty::ty_unboxed_closure(did, ref region, ref substs) => { ty::ty_unboxed_closure(did, region.fold_with(this), substs.fold_with(this)) } - ty::ty_bool | ty::ty_char | ty::ty_str | + ty::ty_bool | ty::ty_char | ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) | ty::ty_err | ty::ty_infer(_) | ty::ty_param(..) => { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 1283e89c29d0..414627b41e94 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -18,7 +18,7 @@ use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region, ReEmpty}; use middle::ty::{ReSkolemized, ReVar, BrEnv}; use middle::ty::{mt, Ty, ParamTy}; use middle::ty::{ty_bool, ty_char, ty_struct, ty_enum}; -use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn, ty_closure}; +use middle::ty::{ty_err, ty_vec, ty_float, ty_bare_fn, ty_closure}; use middle::ty::{ty_param, ty_ptr, ty_rptr, ty_tup, ty_open}; use middle::ty::{ty_unboxed_closure}; use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer}; @@ -442,7 +442,6 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String { bound_sep, bound_str) } - ty_str => "str".to_string(), ty_unboxed_closure(ref did, _, ref substs) => { let unboxed_closures = cx.unboxed_closures.borrow(); unboxed_closures.get(did).map(|cl| { diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 6ff276edbce7..7065ae645aaf 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -639,7 +639,10 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { // FIXME -- Super hack. For DST types, we will convert to // &&[T] or &&str, as part of a kind of legacy lookup scheme. match step.self_ty.sty { - ty::ty_str | ty::ty_vec(_, None) => self.pick_autorefrefd_method(step), + ty::ty_vec(_, None) => self.pick_autorefrefd_method(step), + ty::ty_struct(did, _) if ty::is_str(self.tcx(), did) => { + self.pick_autorefrefd_method(step) + } _ => None } } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 2aec4393de94..9021b00f240b 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -1224,7 +1224,11 @@ fn constrain_index<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>, let r_index_expr = ty::ReScope(CodeExtent::from_node_id(index_expr.id)); if let ty::ty_rptr(r_ptr, mt) = indexed_ty.sty { match mt.ty.sty { - ty::ty_vec(_, None) | ty::ty_str => { + ty::ty_vec(_, None) => { + rcx.fcx.mk_subr(infer::IndexSlice(index_expr.span), + r_index_expr, r_ptr); + } + ty::ty_struct(did, _) if ty::is_str(rcx.tcx(), did) => { rcx.fcx.mk_subr(infer::IndexSlice(index_expr.span), r_index_expr, r_ptr); } diff --git a/src/librustc_typeck/check/regionmanip.rs b/src/librustc_typeck/check/regionmanip.rs index 92dfd8b5f56d..5199a89599f0 100644 --- a/src/librustc_typeck/check/regionmanip.rs +++ b/src/librustc_typeck/check/regionmanip.rs @@ -62,8 +62,11 @@ impl<'a, 'tcx> Wf<'a, 'tcx> { ty::ty_uint(..) | ty::ty_float(..) | ty::ty_bare_fn(..) | - ty::ty_err | - ty::ty_str => { + ty::ty_err => { + // No borrowed content reachable here. + } + + ty::ty_struct(did, _) if ty::is_str(self.tcx, did) => { // No borrowed content reachable here. } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index b8642ddde408..a533e765585a 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -22,7 +22,7 @@ use middle::subst; use middle::ty::{ImplContainer, ImplOrTraitItemId, MethodTraitItemId}; use middle::ty::{TypeTraitItemId, lookup_item_type}; use middle::ty::{Ty, ty_bool, ty_char, ty_enum, ty_err}; -use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_open}; +use middle::ty::{ty_vec, ty_float, ty_infer, ty_int, ty_open}; use middle::ty::{ty_param, Polytype, ty_ptr}; use middle::ty::{ty_rptr, ty_struct, ty_trait, ty_tup}; use middle::ty::{ty_uint, ty_unboxed_closure, ty_uniq, ty_bare_fn}; @@ -81,7 +81,7 @@ fn get_base_type<'a, 'tcx>(inference_context: &InferCtxt<'a, 'tcx>, } ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) | - ty_str(..) | ty_vec(..) | ty_bare_fn(..) | ty_closure(..) | ty_tup(..) | + ty_vec(..) | ty_bare_fn(..) | ty_closure(..) | ty_tup(..) | ty_infer(..) | ty_param(..) | ty_err | ty_open(..) | ty_uniq(_) | ty_ptr(_) | ty_rptr(_, _) => { debug!("(getting base type) no base type; found {}", diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index ade3144ce414..2c4efc2ff1d3 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -720,7 +720,11 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { match ty.sty { ty::ty_bool | ty::ty_char | ty::ty_int(_) | ty::ty_uint(_) | - ty::ty_float(_) | ty::ty_str => { + ty::ty_float(_) => { + /* leaf type -- noop */ + } + + ty::ty_struct(did, _) if ty::is_str(self.tcx(), did) => { /* leaf type -- noop */ } From b00cc6bf9d77b382d0631f4f12e52850c177a927 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 4 Dec 2014 23:11:23 -0500 Subject: [PATCH 06/39] librustc_trans: kill `ty_str` --- src/librustc_trans/trans/_match.rs | 2 +- src/librustc_trans/trans/adt.rs | 2 +- src/librustc_trans/trans/base.rs | 2 +- src/librustc_trans/trans/consts.rs | 8 ++++++-- src/librustc_trans/trans/debuginfo.rs | 12 ++++++++---- src/librustc_trans/trans/glue.rs | 4 ++-- src/librustc_trans/trans/tvec.rs | 10 ++++++++-- src/librustc_trans/trans/type_of.rs | 17 +++++++++-------- 8 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index 492720326867..896e310c308b 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -800,7 +800,7 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>, match rhs_t.sty { ty::ty_rptr(_, mt) => match mt.ty.sty { - ty::ty_str => compare_str(cx, lhs, rhs, rhs_t), + ty::ty_struct(did, _) if ty::is_str(cx.tcx(), did) => compare_str(cx, lhs, rhs, rhs_t), ty::ty_vec(ty, _) => match ty.sty { ty::ty_uint(ast::TyU8) => { // NOTE: cast &[u8] to &str and abuse the str_eq lang item, diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index 2f0f373325a0..b3a14505bda9 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -298,7 +298,7 @@ impl<'tcx> Case<'tcx> { // &T/&mut T/Box could either be a thin or fat pointer depending on T ty::ty_rptr(_, ty::mt { ty, .. }) | ty::ty_uniq(ty) => match ty.sty { // &[T] and &str are a pointer and length pair - ty::ty_vec(_, None) | ty::ty_str => return Some(FatPointer(i)), + ty::ty_vec(_, None) => return Some(FatPointer(i)), // &Trait is a pair of pointers: the actual object and a vtable ty::ty_trait(..) => return Some(FatPointer(i)), diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 9d0e096c71d6..054096f1cb0e 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -1161,7 +1161,7 @@ pub fn memcpy_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>) { let _icx = push_ctxt("memcpy_ty"); let ccx = bcx.ccx(); - if ty::type_is_structural(t) { + if ty::type_is_structural(bcx.tcx(), t) { let llty = type_of::type_of(ccx, t); let llsz = llsize_of(ccx, llty); let llalign = type_of::align_of(ccx, t); diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 42daf7188160..6c6ecf5788ba 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -436,7 +436,11 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr) -> ValueRef { let (arr, len) = match bt.sty { ty::ty_vec(_, Some(u)) => (bv, C_uint(cx, u)), ty::ty_open(ty) => match ty.sty { - ty::ty_vec(_, None) | ty::ty_str => { + ty::ty_vec(_, None) => { + let e1 = const_get_elt(cx, bv, &[0]); + (const_deref_ptr(cx, e1), const_get_elt(cx, bv, &[1])) + }, + ty::ty_struct(did, _) if ty::is_str(cx.tcx(), did) => { let e1 = const_get_elt(cx, bv, &[0]); (const_deref_ptr(cx, e1), const_get_elt(cx, bv, &[1])) }, @@ -463,7 +467,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr) -> ValueRef { let len = llvm::LLVMConstIntGetZExtValue(len) as u64; let len = match bt.sty { ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty.sty { - ty::ty_str => { + ty::ty_struct(did, _) if ty::is_str(cx.tcx(), did) => { assert!(len > 0); len - 1 } diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 555cb0004892..c7ca5251b028 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -355,12 +355,14 @@ impl<'tcx> TypeMap<'tcx> { match type_.sty { ty::ty_bool | ty::ty_char | - ty::ty_str | ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) => { push_debuginfo_type_name(cx, type_, false, &mut unique_type_id); }, + ty::ty_struct(did, _) if ty::is_str(cx.tcx(), did) => { + push_debuginfo_type_name(cx, type_, false, &mut unique_type_id); + }, ty::ty_enum(def_id, ref substs) => { unique_type_id.push_str("enum "); from_def_id_and_substs(self, cx, def_id, substs, &mut unique_type_id); @@ -2915,7 +2917,9 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } // FIXME Can we do better than this for unsized vec/str fields? ty::ty_vec(typ, None) => fixed_vec_metadata(cx, unique_type_id, typ, 0, usage_site_span), - ty::ty_str => fixed_vec_metadata(cx, unique_type_id, ty::mk_i8(), 0, usage_site_span), + ty::ty_struct(did, _) if ty::is_str(cx.tcx(), did) => { + fixed_vec_metadata(cx, unique_type_id, ty::mk_i8(), 0, usage_site_span) + }, ty::ty_trait(..) => { MetadataCreationResult::new( trait_pointer_metadata(cx, t, None, unique_type_id), @@ -2926,7 +2930,7 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ty::ty_vec(typ, None) => { vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span) } - ty::ty_str => { + ty::ty_struct(did, _) if ty::is_str(cx.tcx(), did) => { vec_slice_metadata(cx, t, ty::mk_u8(), unique_type_id, usage_site_span) } ty::ty_trait(..) => { @@ -3692,7 +3696,7 @@ fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, match t.sty { ty::ty_bool => output.push_str("bool"), ty::ty_char => output.push_str("char"), - ty::ty_str => output.push_str("str"), + ty::ty_struct(did, _) if ty::is_str(cx.tcx(), did) => output.push_str("str"), ty::ty_int(ast::TyI) => output.push_str("int"), ty::ty_int(ast::TyI8) => output.push_str("i8"), ty::ty_int(ast::TyI16) => output.push_str("i16"), diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs index fbaf1e658106..40ba46821d55 100644 --- a/src/librustc_trans/trans/glue.rs +++ b/src/librustc_trans/trans/glue.rs @@ -364,7 +364,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>) ty::ty_vec(ty, None) => { tvec::make_drop_glue_unboxed(bcx, v0, ty, true) } - ty::ty_str => { + ty::ty_struct(did, _) if ty::is_str(bcx.tcx(), did) => { let unit_ty = ty::sequence_element_type(bcx.tcx(), content_ty); tvec::make_drop_glue_unboxed(bcx, v0, unit_ty, true) } @@ -469,7 +469,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>) _ => { assert!(ty::type_is_sized(bcx.tcx(), t)); if ty::type_needs_drop(bcx.tcx(), t) && - ty::type_is_structural(t) { + ty::type_is_structural(bcx.tcx(), t) { iter_structural_ty(bcx, v0, t, |bb, vv, tt| drop_ty(bb, vv, tt, None)) } else { bcx diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs index 00f938191f8d..18b5b189ee66 100644 --- a/src/librustc_trans/trans/tvec.rs +++ b/src/librustc_trans/trans/tvec.rs @@ -401,13 +401,19 @@ pub fn get_base_and_len(bcx: Block, match vec_ty.sty { ty::ty_vec(_, Some(n)) => get_fixed_base_and_len(bcx, llval, n), ty::ty_open(ty) => match ty.sty { - ty::ty_vec(_, None) | ty::ty_str => get_slice_base_and_len(bcx, llval), + ty::ty_vec(_, None) => get_slice_base_and_len(bcx, llval), + ty::ty_struct(did, _) if ty::is_str(bcx.tcx(), did) => { + get_slice_base_and_len(bcx, llval) + }, _ => ccx.sess().bug("unexpected type in get_base_and_len") }, // Only used for pattern matching. ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty.sty { - ty::ty_vec(_, None) | ty::ty_str => get_slice_base_and_len(bcx, llval), + ty::ty_vec(_, None) => get_slice_base_and_len(bcx, llval), + ty::ty_struct(did, _) if ty::is_str(bcx.tcx(), did) => { + get_slice_base_and_len(bcx, llval) + }, ty::ty_vec(_, Some(n)) => { let base = GEPi(bcx, Load(bcx, llval), &[0u, 0u]); (base, C_uint(ccx, n)) diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs index 005f6ca4c708..73a809a7aa59 100644 --- a/src/librustc_trans/trans/type_of.rs +++ b/src/librustc_trans/trans/type_of.rs @@ -243,7 +243,7 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ cx.sess().bug(format!("fictitious type {} in sizing_type_of()", ppaux::ty_to_string(cx.tcx(), t)).as_slice()) } - ty::ty_vec(_, None) | ty::ty_trait(..) | ty::ty_str => panic!("unreachable") + ty::ty_vec(_, None) | ty::ty_trait(..) => panic!("unreachable") }; cx.llsizingtypes().borrow_mut().insert(t, llsizingty); @@ -270,7 +270,8 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type { } match ty::unsized_part_of_type(cx.tcx(), t).sty { - ty::ty_str | ty::ty_vec(..) => Type::uint_from_ty(cx, ast::TyU), + ty::ty_vec(..) => Type::uint_from_ty(cx, ast::TyU), + ty::ty_struct(did, _) if ty::is_str(cx.tcx(), did) => Type::uint_from_ty(cx, ast::TyU), ty::ty_trait(_) => Type::vtable_ptr(cx), _ => panic!("Unexpected type returned from unsized_part_of_type : {}", t.repr(cx.tcx())) @@ -334,7 +335,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type { ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) | ty::ty_ptr(ty::mt{ty, ..}) => { match ty.sty { - ty::ty_str => { + ty::ty_struct(did, _) if ty::is_str(cx.tcx(), did) => { // This means we get a nicer name in the output (str is always // unsized). cx.tn().find_type("str_slice").unwrap() @@ -362,7 +363,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type { Type::opaque_trait_data(cx) } - ty::ty_str => Type::i8(cx), + ty::ty_struct(did, _) if ty::is_str(cx.tcx(), did) => Type::i8(cx), ty::ty_bare_fn(_) => { type_of_fn_from_ty(cx, t).ptr_to() @@ -394,6 +395,10 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type { } ty::ty_open(t) => match t.sty { + ty::ty_struct(did, _) if ty::is_str(cx.tcx(), did) => { + let p_ty = Type::i8p(cx); + Type::struct_(cx, &[p_ty, type_of_unsize_info(cx, t)], false) + } ty::ty_struct(..) => { let p_ty = type_of(cx, t).ptr_to(); Type::struct_(cx, &[p_ty, type_of_unsize_info(cx, t)], false) @@ -402,10 +407,6 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type { let p_ty = type_of(cx, ty).ptr_to(); Type::struct_(cx, &[p_ty, type_of_unsize_info(cx, t)], false) } - ty::ty_str => { - let p_ty = Type::i8p(cx); - Type::struct_(cx, &[p_ty, type_of_unsize_info(cx, t)], false) - } ty::ty_trait(..) => Type::opaque_trait(cx), _ => cx.sess().bug(format!("ty_open with sized type: {}", ppaux::ty_to_string(cx.tcx(), t)).as_slice()) From b4b2551180b90af6c2042808dc0d035f601a17d3 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 00:03:33 -0500 Subject: [PATCH 07/39] libsyntax: kill `TyStr` --- src/libsyntax/ast.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 7e421df505d6..bde6ecc3606d 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1090,7 +1090,6 @@ pub enum PrimTy { TyInt(IntTy), TyUint(UintTy), TyFloat(FloatTy), - TyStr, TyBool, TyChar } From 10b2f554c4abe95a627833ac268f1982fa0808ae Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 00:04:11 -0500 Subject: [PATCH 08/39] librustc: kill `TyStr` --- src/librustc/middle/astconv_util.rs | 3 --- src/librustc/middle/resolve.rs | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/librustc/middle/astconv_util.rs b/src/librustc/middle/astconv_util.rs index 6b90bcd60e75..16755b52d541 100644 --- a/src/librustc/middle/astconv_util.rs +++ b/src/librustc/middle/astconv_util.rs @@ -75,9 +75,6 @@ pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty) check_path_args(tcx, path, NO_TPS | NO_REGIONS); Some(ty::mk_mach_float(ft)) } - ast::TyStr => { - Some(ty::mk_str(tcx)) - } } } _ => None diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index b958bdce0a7e..aef7ffbe6ed5 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -65,7 +65,7 @@ use syntax::ast::{StructVariantKind, TraitRef, TraitTyParamBound}; use syntax::ast::{TupleVariantKind, Ty, TyBool, TyChar, TyClosure, TyF32}; use syntax::ast::{TyF64, TyFloat, TyI, TyI8, TyI16, TyI32, TyI64, TyInt, TyObjectSum}; use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyPolyTraitRef, TyProc, TyQPath}; -use syntax::ast::{TyRptr, TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint}; +use syntax::ast::{TyRptr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint}; use syntax::ast::{TypeImplItem, UnnamedField}; use syntax::ast::{Variant, ViewItem, ViewItemExternCrate}; use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple}; @@ -869,7 +869,6 @@ impl PrimitiveTypeTable { table.intern("i16", TyInt(TyI16)); table.intern("i32", TyInt(TyI32)); table.intern("i64", TyInt(TyI64)); - table.intern("str", TyStr); table.intern("uint", TyUint(TyU)); table.intern("u8", TyUint(TyU8)); table.intern("u16", TyUint(TyU16)); From a55ae0e1419a96d17ea5785b8bd9c956e235a79b Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 01:53:00 -0500 Subject: [PATCH 09/39] libsyntax: use the full path of `str` in `format_args!` --- src/libsyntax/ext/format.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index d7d6c636849a..223823d64cfb 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -512,9 +512,14 @@ impl<'a, 'b> Context<'a, 'b> { // format "string" let static_str_name = self.ecx.ident_of("__STATIC_FMTSTR"); let static_lifetime = self.ecx.lifetime(self.fmtsp, self.ecx.ident_of("'static").name); + let str_path = self.ecx.path_global(self.fmtsp, vec![ + self.ecx.ident_of("std"), + self.ecx.ident_of("str"), + self.ecx.ident_of("str"), + ]); let piece_ty = self.ecx.ty_rptr( self.fmtsp, - self.ecx.ty_ident(self.fmtsp, self.ecx.ident_of("str")), + self.ecx.ty_path(str_path), Some(static_lifetime), ast::MutImmutable); lets.push(Context::item_static_array(self.ecx, From 2727aa11cef354cdb583d7534f6c21d9edc896f3 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 02:20:12 -0500 Subject: [PATCH 10/39] libcore: use full path of `str` in `panic!` macro --- src/libcore/macros.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 9016f40b1b83..553edef67530 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -10,6 +10,8 @@ #![macro_escape] +// NOTE(stage0): Remove macro after a snapshot +#[cfg(stage0)] /// Entry point of task panic, for details, see std::macros #[macro_export] macro_rules! panic( @@ -46,6 +48,44 @@ macro_rules! panic( }); ) +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +/// Entry point of task panic, for details, see std::macros +#[macro_export] +macro_rules! panic( + () => ( + panic!("{}", "explicit panic") + ); + ($msg:expr) => ({ + static _MSG_FILE_LINE: (&'static ::std::str::str, &'static ::std::str::str, uint) = + ($msg, file!(), line!()); + ::core::panicking::panic(&_MSG_FILE_LINE) + }); + ($fmt:expr, $($arg:tt)*) => ({ + // a closure can't have return type !, so we need a full + // function to pass to format_args!, *and* we need the + // file and line numbers right here; so an inner bare fn + // is our only choice. + // + // LLVM doesn't tend to inline this, presumably because begin_unwind_fmt + // is #[cold] and #[inline(never)] and because this is flagged as cold + // as returning !. We really do want this to be inlined, however, + // because it's just a tiny wrapper. Small wins (156K to 149K in size) + // were seen when forcing this to be inlined, and that number just goes + // up with the number of calls to panic!() + // + // The leading _'s are to avoid dead code warnings if this is + // used inside a dead function. Just `#[allow(dead_code)]` is + // insufficient, since the user may have + // `#[forbid(dead_code)]` and which cannot be overridden. + #[inline(always)] + fn _run_fmt(fmt: &::std::fmt::Arguments) -> ! { + static _FILE_LINE: (&'static ::std::str::str, uint) = (file!(), line!()); + ::core::panicking::panic_fmt(fmt, &_FILE_LINE) + } + format_args!(_run_fmt, $fmt, $($arg)*) + }); +) + /// Runtime assertion, for details see std::macros #[macro_export] macro_rules! assert( From 52cae4c8478e7c6347271b4c9b4c1b678aacce1f Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 00:24:05 -0500 Subject: [PATCH 11/39] libcore: make `str` a library type --- src/libcore/fmt/float.rs | 1 + src/libcore/fmt/mod.rs | 3 + src/libcore/fmt/num.rs | 2 + src/libcore/intrinsics.rs | 3 + src/libcore/lib.rs | 1 + src/libcore/num/f32.rs | 2 + src/libcore/num/f64.rs | 2 + src/libcore/num/mod.rs | 10 +- src/libcore/option.rs | 2 + src/libcore/panicking.rs | 2 + src/libcore/prelude.rs | 4 +- src/libcore/raw.rs | 2 + src/libcore/str.rs | 952 +++++++++++++++++++++++++++++++++++++- 13 files changed, 980 insertions(+), 6 deletions(-) diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index 1e31df837794..8e9621be6cff 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -22,6 +22,7 @@ use num::{Float, FPNaN, FPInfinite, ToPrimitive}; use num::cast; use result::Ok; use slice::{mod, SlicePrelude}; +#[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot use str::StrPrelude; /// A flag that specifies whether to use exponential (scientific) notation. diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 7b9dd70c58f0..f0ebeb874f24 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -23,7 +23,10 @@ use result::{Ok, Err}; use result; use slice::SlicePrelude; use slice; +#[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot use str::StrPrelude; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use str::str; pub use self::num::radix; pub use self::num::Radix; diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index a441ced03b26..5e9adcf9ca96 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -18,6 +18,8 @@ use fmt; use iter::DoubleEndedIteratorExt; use num::{Int, cast}; use slice::SlicePrelude; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use str::str; /// A type that represents a specific radix #[doc(hidden)] diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index ece2ac6975ed..6cb66be52281 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -42,6 +42,9 @@ #![experimental] #![allow(missing_docs)] +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use str::str; + pub type GlueFn = extern "Rust" fn(*const i8); #[lang="ty_desc"] diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 5ad9462daf27..3056173d931f 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -142,4 +142,5 @@ mod std { pub use kinds; pub use option; pub use fmt; + pub use str; } diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index add42a2ddce8..c590e7800d7d 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -21,6 +21,8 @@ use mem; use num::{Float, FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN}; use num::from_str_radix; use option::Option; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use str::str; #[stable] pub const RADIX: uint = 2u; diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 12c0771d0b93..95dfb4eb9b53 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -21,6 +21,8 @@ use mem; use num::{Float, FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN}; use num::from_str_radix; use option::Option; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use str::str; // FIXME(#5527): These constants should be deprecated once associated // constants are implemented in favour of referencing the respective diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 748e8942a3fe..9b27927e14e0 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -31,7 +31,11 @@ use mem::size_of; use ops::{Add, Sub, Mul, Div, Rem, Neg}; use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr}; use option::{Option, Some, None}; -use str::{FromStr, from_str, StrPrelude}; +use str::{FromStr, from_str}; +#[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot +use str::StrPrelude; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use str::str; /// Simultaneous division and remainder #[inline] @@ -1437,8 +1441,8 @@ pub trait FromStrRadix { /// A utility function that just calls FromStrRadix::from_str_radix. #[experimental = "might need to return Result"] -pub fn from_str_radix(str: &str, radix: uint) -> Option { - FromStrRadix::from_str_radix(str, radix) +pub fn from_str_radix(s: &str, radix: uint) -> Option { + FromStrRadix::from_str_radix(s, radix) } macro_rules! from_str_radix_float_impl { diff --git a/src/libcore/option.rs b/src/libcore/option.rs index ef895a1d7fbc..0cb574bf11cb 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -154,6 +154,8 @@ use slice; use slice::AsSlice; use clone::Clone; use ops::Deref; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use str::str; // Note that this is not a lang item per se, but it has a hidden dependency on // `Iterator`, which is one. The compiler assumes that the `next` method of diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs index fd0526db411c..f6feb9152b3e 100644 --- a/src/libcore/panicking.rs +++ b/src/libcore/panicking.rs @@ -32,6 +32,8 @@ use fmt; use intrinsics; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use str::str; #[cold] #[inline(never)] // this is the slow path, always #[lang="panic"] diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index 6678a20087b7..8f41dd6134f2 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -60,7 +60,9 @@ pub use option::Option::{Some, None}; pub use ptr::RawPtr; pub use result::Result; pub use result::Result::{Ok, Err}; -pub use str::{Str, StrPrelude}; +pub use str::Str; +#[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot +pub use str::StrPrelude; pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4}; pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8}; pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12}; diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs index d156f71462dd..a6b0470f2d8a 100644 --- a/src/libcore/raw.rs +++ b/src/libcore/raw.rs @@ -20,6 +20,8 @@ use mem; use kinds::Sized; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use str::str; /// The representation of a Rust slice #[repr(C)] diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 4be628f0ac3b..0ec3f8daa4a2 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -1149,7 +1149,11 @@ pub mod raw { use ptr::RawPtr; use raw::Slice; use slice::SlicePrelude; - use str::{is_utf8, StrPrelude}; + use str::is_utf8; + #[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot + use str::StrPrelude; + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + use str::str; /// Converts a slice of bytes to a string slice without checking /// that the string contains valid UTF-8. @@ -1213,7 +1217,11 @@ pub mod traits { use iter::IteratorExt; use option::{Option, Some}; use ops; - use str::{Str, StrPrelude, eq_slice}; + use str::{Str, eq_slice}; + #[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot + use str::StrPrelude; + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + use str::str; impl Ord for str { #[inline] @@ -1294,6 +1302,8 @@ impl<'a, Sized? S> Str for &'a S where S: Str { fn as_slice(&self) -> &str { Str::as_slice(*self) } } +// NOTE(stage0): Remove trait after a snapshot +#[cfg(stage0)] /// Methods for string slices pub trait StrPrelude for Sized? { /// Returns true if one string contains another @@ -1953,6 +1963,8 @@ fn slice_error_fail(s: &str, begin: uint, end: uint) -> ! { begin, end, s); } +// NOTE(stage0): Remove impl after a snapshot +#[cfg(stage0)] impl StrPrelude for str { #[inline] fn contains(&self, needle: &str) -> bool { @@ -2309,6 +2321,942 @@ impl StrPrelude for str { fn len(&self) -> uint { self.repr().len } } +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +#[allow(non_camel_case_types)] +#[lang = "str"] +/// Core string type +pub struct str([u8]); + +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +impl str { + /// Returns true if one string contains another + /// + /// # Arguments + /// + /// - needle - The string to look for + /// + /// # Example + /// + /// ```rust + /// assert!("bananas".contains("nana")); + /// ``` + #[inline] + pub fn contains(&self, needle: &str) -> bool { + self.find_str(needle).is_some() + } + + /// Returns true if a string contains a char. + /// + /// # Arguments + /// + /// - needle - The char to look for + /// + /// # Example + /// + /// ```rust + /// assert!("hello".contains_char('e')); + /// ``` + #[inline] + pub fn contains_char(&self, needle: char) -> bool { + self.find(needle).is_some() + } + + /// An iterator over the characters of `self`. Note, this iterates + /// over Unicode code-points, not Unicode graphemes. + /// + /// # Example + /// + /// ```rust + /// let v: Vec = "abc åäö".chars().collect(); + /// assert_eq!(v, vec!['a', 'b', 'c', ' ', 'å', 'ä', 'ö']); + /// ``` + #[inline] + pub fn chars(&self) -> Chars { + Chars{iter: self.as_bytes().iter()} + } + + /// An iterator over the bytes of `self` + /// + /// # Example + /// + /// ```rust + /// let v: Vec = "bors".bytes().collect(); + /// assert_eq!(v, b"bors".to_vec()); + /// ``` + #[inline] + pub fn bytes(&self) -> Bytes { + self.as_bytes().iter().map(|&b| b) + } + + /// An iterator over the characters of `self` and their byte offsets. + #[inline] + pub fn char_indices(&self) -> CharOffsets { + CharOffsets{front_offset: 0, iter: self.chars()} + } + + /// An iterator over substrings of `self`, separated by characters + /// matched by `sep`. + /// + /// # Example + /// + /// ```rust + /// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect(); + /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]); + /// + /// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect(); + /// assert_eq!(v, vec!["abc", "def", "ghi"]); + /// + /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect(); + /// assert_eq!(v, vec!["lion", "", "tiger", "leopard"]); + /// + /// let v: Vec<&str> = "".split('X').collect(); + /// assert_eq!(v, vec![""]); + /// ``` + #[inline] + pub fn split(&self, sep: Sep) -> CharSplits { + CharSplits { + string: self, + only_ascii: sep.only_ascii(), + sep: sep, + allow_trailing_empty: true, + finished: false, + } + } + + /// An iterator over substrings of `self`, separated by characters + /// matched by `sep`, restricted to splitting at most `count` + /// times. + /// + /// # Example + /// + /// ```rust + /// let v: Vec<&str> = "Mary had a little lambda".splitn(2, ' ').collect(); + /// assert_eq!(v, vec!["Mary", "had", "a little lambda"]); + /// + /// let v: Vec<&str> = "abc1def2ghi".splitn(1, |c: char| c.is_numeric()).collect(); + /// assert_eq!(v, vec!["abc", "def2ghi"]); + /// + /// let v: Vec<&str> = "lionXXtigerXleopard".splitn(2, 'X').collect(); + /// assert_eq!(v, vec!["lion", "", "tigerXleopard"]); + /// + /// let v: Vec<&str> = "abcXdef".splitn(0, 'X').collect(); + /// assert_eq!(v, vec!["abcXdef"]); + /// + /// let v: Vec<&str> = "".splitn(1, 'X').collect(); + /// assert_eq!(v, vec![""]); + /// ``` + #[inline] + pub fn splitn(&self, count: uint, sep: Sep) + -> CharSplitsN { + CharSplitsN { + iter: self.split(sep), + count: count, + invert: false, + } + } + + /// An iterator over substrings of `self`, separated by characters + /// matched by `sep`. + /// + /// Equivalent to `split`, except that the trailing substring + /// is skipped if empty (terminator semantics). + /// + /// # Example + /// + /// ```rust + /// let v: Vec<&str> = "A.B.".split_terminator('.').collect(); + /// assert_eq!(v, vec!["A", "B"]); + /// + /// let v: Vec<&str> = "A..B..".split_terminator('.').collect(); + /// assert_eq!(v, vec!["A", "", "B", ""]); + /// + /// let v: Vec<&str> = "Mary had a little lamb".split(' ').rev().collect(); + /// assert_eq!(v, vec!["lamb", "little", "a", "had", "Mary"]); + /// + /// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).rev().collect(); + /// assert_eq!(v, vec!["ghi", "def", "abc"]); + /// + /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').rev().collect(); + /// assert_eq!(v, vec!["leopard", "tiger", "", "lion"]); + /// ``` + #[inline] + pub fn split_terminator(&self, sep: Sep) + -> CharSplits { + CharSplits { + allow_trailing_empty: false, + ..self.split(sep) + } + } + + /// An iterator over substrings of `self`, separated by characters + /// matched by `sep`, starting from the end of the string. + /// Restricted to splitting at most `count` times. + /// + /// # Example + /// + /// ```rust + /// let v: Vec<&str> = "Mary had a little lamb".rsplitn(2, ' ').collect(); + /// assert_eq!(v, vec!["lamb", "little", "Mary had a"]); + /// + /// let v: Vec<&str> = "abc1def2ghi".rsplitn(1, |c: char| c.is_numeric()).collect(); + /// assert_eq!(v, vec!["ghi", "abc1def"]); + /// + /// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(2, 'X').collect(); + /// assert_eq!(v, vec!["leopard", "tiger", "lionX"]); + /// ``` + #[inline] + pub fn rsplitn(&self, count: uint, sep: Sep) + -> CharSplitsN { + CharSplitsN { + iter: self.split(sep), + count: count, + invert: true, + } + } + + /// An iterator over the start and end indices of the disjoint + /// matches of `sep` within `self`. + /// + /// That is, each returned value `(start, end)` satisfies + /// `self.slice(start, end) == sep`. For matches of `sep` within + /// `self` that overlap, only the indices corresponding to the + /// first match are returned. + /// + /// # Example + /// + /// ```rust + /// let v: Vec<(uint, uint)> = "abcXXXabcYYYabc".match_indices("abc").collect(); + /// assert_eq!(v, vec![(0,3), (6,9), (12,15)]); + /// + /// let v: Vec<(uint, uint)> = "1abcabc2".match_indices("abc").collect(); + /// assert_eq!(v, vec![(1,4), (4,7)]); + /// + /// let v: Vec<(uint, uint)> = "ababa".match_indices("aba").collect(); + /// assert_eq!(v, vec![(0, 3)]); // only the first `aba` + /// ``` + #[inline] + pub fn match_indices<'a>(&'a self, sep: &'a str) -> MatchIndices<'a> { + assert!(!sep.is_empty()) + MatchIndices { + haystack: self, + needle: sep, + searcher: Searcher::new(self.as_bytes(), sep.as_bytes()) + } + } + + /// An iterator over the substrings of `self` separated by `sep`. + /// + /// # Example + /// + /// ```rust + /// let v: Vec<&str> = "abcXXXabcYYYabc".split_str("abc").collect(); + /// assert_eq!(v, vec!["", "XXX", "YYY", ""]); + /// + /// let v: Vec<&str> = "1abcabc2".split_str("abc").collect(); + /// assert_eq!(v, vec!["1", "", "2"]); + /// ``` + #[inline] + pub fn split_str<'a>(&'a self, sep: &'a str) -> StrSplits<'a> { + StrSplits { + it: self.match_indices(sep), + last_end: 0, + finished: false + } + } + + /// An iterator over the lines of a string (subsequences separated + /// by `\n`). This does not include the empty string after a + /// trailing `\n`. + /// + /// # Example + /// + /// ```rust + /// let four_lines = "foo\nbar\n\nbaz\n"; + /// let v: Vec<&str> = four_lines.lines().collect(); + /// assert_eq!(v, vec!["foo", "bar", "", "baz"]); + /// ``` + #[inline] + pub fn lines(&self) -> CharSplits { + self.split_terminator('\n') + } + + /// An iterator over the lines of a string, separated by either + /// `\n` or `\r\n`. As with `.lines()`, this does not include an + /// empty trailing line. + /// + /// # Example + /// + /// ```rust + /// let four_lines = "foo\r\nbar\n\r\nbaz\n"; + /// let v: Vec<&str> = four_lines.lines_any().collect(); + /// assert_eq!(v, vec!["foo", "bar", "", "baz"]); + /// ``` + pub fn lines_any(&self) -> AnyLines { + self.lines().map(|line| { + let l = line.len(); + if l > 0 && line.as_bytes()[l - 1] == b'\r' { line.slice(0, l - 1) } + else { line } + }) + } + + /// Returns the number of Unicode code points (`char`) that a + /// string holds. + /// + /// This does not perform any normalization, and is `O(n)`, since + /// UTF-8 is a variable width encoding of code points. + /// + /// *Warning*: The number of code points in a string does not directly + /// correspond to the number of visible characters or width of the + /// visible text due to composing characters, and double- and + /// zero-width ones. + /// + /// See also `.len()` for the byte length. + /// + /// # Example + /// + /// ```rust + /// // composed forms of `ö` and `é` + /// let c = "Löwe 老虎 Léopard"; // German, Simplified Chinese, French + /// // decomposed forms of `ö` and `é` + /// let d = "Lo\u0308we 老虎 Le\u0301opard"; + /// + /// assert_eq!(c.char_len(), 15); + /// assert_eq!(d.char_len(), 17); + /// + /// assert_eq!(c.len(), 21); + /// assert_eq!(d.len(), 23); + /// + /// // the two strings *look* the same + /// println!("{}", c); + /// println!("{}", d); + /// ``` + #[inline] + pub fn char_len(&self) -> uint { self.chars().count() } + + /// Returns a slice of the given string from the byte range + /// [`begin`..`end`). + /// + /// This operation is `O(1)`. + /// + /// Panics when `begin` and `end` do not point to valid characters + /// or point beyond the last character of the string. + /// + /// See also `slice_to` and `slice_from` for slicing prefixes and + /// suffixes of strings, and `slice_chars` for slicing based on + /// code point counts. + /// + /// # Example + /// + /// ```rust + /// let s = "Löwe 老虎 Léopard"; + /// assert_eq!(s.slice(0, 1), "L"); + /// + /// assert_eq!(s.slice(1, 9), "öwe 老"); + /// + /// // these will panic: + /// // byte 2 lies within `ö`: + /// // s.slice(2, 3); + /// + /// // byte 8 lies within `老` + /// // s.slice(1, 8); + /// + /// // byte 100 is outside the string + /// // s.slice(3, 100); + /// ``` + #[inline] + pub fn slice(&self, begin: uint, end: uint) -> &str { + // is_char_boundary checks that the index is in [0, .len()] + if begin <= end && + self.is_char_boundary(begin) && + self.is_char_boundary(end) { + unsafe { self.slice_unchecked(begin, end) } + } else { + slice_error_fail(self, begin, end) + } + } + + /// Returns a slice of the string from `begin` to its end. + /// + /// Equivalent to `self.slice(begin, self.len())`. + /// + /// Panics when `begin` does not point to a valid character, or is + /// out of bounds. + /// + /// See also `slice`, `slice_to` and `slice_chars`. + #[inline] + pub fn slice_from(&self, begin: uint) -> &str { + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(begin) { + unsafe { self.slice_unchecked(begin, self.len()) } + } else { + slice_error_fail(self, begin, self.len()) + } + } + + /// Returns a slice of the string from the beginning to byte + /// `end`. + /// + /// Equivalent to `self.slice(0, end)`. + /// + /// Panics when `end` does not point to a valid character, or is + /// out of bounds. + /// + /// See also `slice`, `slice_from` and `slice_chars`. + #[inline] + pub fn slice_to(&self, end: uint) -> &str { + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(end) { + unsafe { self.slice_unchecked(0, end) } + } else { + slice_error_fail(self, 0, end) + } + } + + /// Returns a slice of the string from the character range + /// [`begin`..`end`). + /// + /// That is, start at the `begin`-th code point of the string and + /// continue to the `end`-th code point. This does not detect or + /// handle edge cases such as leaving a combining character as the + /// first code point of the string. + /// + /// Due to the design of UTF-8, this operation is `O(end)`. + /// See `slice`, `slice_to` and `slice_from` for `O(1)` + /// variants that use byte indices rather than code point + /// indices. + /// + /// Panics if `begin` > `end` or the either `begin` or `end` are + /// beyond the last character of the string. + /// + /// # Example + /// + /// ```rust + /// let s = "Löwe 老虎 Léopard"; + /// assert_eq!(s.slice_chars(0, 4), "Löwe"); + /// assert_eq!(s.slice_chars(5, 7), "老虎"); + /// ``` + pub fn slice_chars(&self, begin: uint, end: uint) -> &str { + assert!(begin <= end); + let mut count = 0; + let mut begin_byte = None; + let mut end_byte = None; + + // This could be even more efficient by not decoding, + // only finding the char boundaries + for (idx, _) in self.char_indices() { + if count == begin { begin_byte = Some(idx); } + if count == end { end_byte = Some(idx); break; } + count += 1; + } + if begin_byte.is_none() && count == begin { begin_byte = Some(self.len()) } + if end_byte.is_none() && count == end { end_byte = Some(self.len()) } + + match (begin_byte, end_byte) { + (None, _) => panic!("slice_chars: `begin` is beyond end of string"), + (_, None) => panic!("slice_chars: `end` is beyond end of string"), + (Some(a), Some(b)) => unsafe { self.slice_unchecked(a, b) } + } + } + + /// Takes a bytewise (not UTF-8) slice from a string. + /// + /// Returns the substring from [`begin`..`end`). + /// + /// Caller must check both UTF-8 character boundaries and the boundaries of + /// the entire slice as well. + #[inline] + pub unsafe fn slice_unchecked(&self, begin: uint, end: uint) -> &str { + mem::transmute(Slice { + data: self.as_ptr().offset(begin as int), + len: end - begin, + }) + } + + /// Returns true if `needle` is a prefix of the string. + /// + /// # Example + /// + /// ```rust + /// assert!("banana".starts_with("ba")); + /// ``` + #[inline] + pub fn starts_with(&self, needle: &str) -> bool { + let n = needle.len(); + self.len() >= n && needle.as_bytes() == self.as_bytes()[..n] + } + + /// Returns true if `needle` is a suffix of the string. + /// + /// # Example + /// + /// ```rust + /// assert!("banana".ends_with("nana")); + /// ``` + #[inline] + pub fn ends_with(&self, needle: &str) -> bool { + let (m, n) = (self.len(), needle.len()); + m >= n && needle.as_bytes() == self.as_bytes()[m-n..] + } + + /// Returns a string with characters that match `to_trim` removed from the left and the right. + /// + /// # Arguments + /// + /// * to_trim - a character matcher + /// + /// # Example + /// + /// ```rust + /// assert_eq!("11foo1bar11".trim_chars('1'), "foo1bar") + /// let x: &[_] = &['1', '2']; + /// assert_eq!("12foo1bar12".trim_chars(x), "foo1bar") + /// assert_eq!("123foo1bar123".trim_chars(|c: char| c.is_numeric()), "foo1bar") + /// ``` + #[inline] + pub fn trim_chars(&self, mut to_trim: C) -> &str { + let cur = match self.find(|c: char| !to_trim.matches(c)) { + None => "", + Some(i) => unsafe { self.slice_unchecked(i, self.len()) } + }; + match cur.rfind(|c: char| !to_trim.matches(c)) { + None => "", + Some(i) => { + let right = cur.char_range_at(i).next; + unsafe { cur.slice_unchecked(0, right) } + } + } + } + + /// Returns a string with leading `chars_to_trim` removed. + /// + /// # Arguments + /// + /// * to_trim - a character matcher + /// + /// # Example + /// + /// ```rust + /// assert_eq!("11foo1bar11".trim_left_chars('1'), "foo1bar11") + /// let x: &[_] = &['1', '2']; + /// assert_eq!("12foo1bar12".trim_left_chars(x), "foo1bar12") + /// assert_eq!("123foo1bar123".trim_left_chars(|c: char| c.is_numeric()), "foo1bar123") + /// ``` + #[inline] + pub fn trim_left_chars(&self, mut to_trim: C) -> &str { + match self.find(|c: char| !to_trim.matches(c)) { + None => "", + Some(first) => unsafe { self.slice_unchecked(first, self.len()) } + } + } + + /// Returns a string with trailing `chars_to_trim` removed. + /// + /// # Arguments + /// + /// * to_trim - a character matcher + /// + /// # Example + /// + /// ```rust + /// assert_eq!("11foo1bar11".trim_right_chars('1'), "11foo1bar") + /// let x: &[_] = &['1', '2']; + /// assert_eq!("12foo1bar12".trim_right_chars(x), "12foo1bar") + /// assert_eq!("123foo1bar123".trim_right_chars(|c: char| c.is_numeric()), "123foo1bar") + /// ``` + #[inline] + pub fn trim_right_chars(&self, mut to_trim: C) -> &str { + match self.rfind(|c: char| !to_trim.matches(c)) { + None => "", + Some(last) => { + let next = self.char_range_at(last).next; + unsafe { self.slice_unchecked(0u, next) } + } + } + } + + /// Check that `index`-th byte lies at the start and/or end of a + /// UTF-8 code point sequence. + /// + /// The start and end of the string (when `index == self.len()`) + /// are considered to be boundaries. + /// + /// Panics if `index` is greater than `self.len()`. + /// + /// # Example + /// + /// ```rust + /// let s = "Löwe 老虎 Léopard"; + /// assert!(s.is_char_boundary(0)); + /// // start of `老` + /// assert!(s.is_char_boundary(6)); + /// assert!(s.is_char_boundary(s.len())); + /// + /// // second byte of `ö` + /// assert!(!s.is_char_boundary(2)); + /// + /// // third byte of `老` + /// assert!(!s.is_char_boundary(8)); + /// ``` + #[inline] + pub fn is_char_boundary(&self, index: uint) -> bool { + if index == self.len() { return true; } + match self.as_bytes().get(index) { + None => false, + Some(&b) => b < 128u8 || b >= 192u8, + } + } + + /// Pluck a character out of a string and return the index of the next + /// character. + /// + /// This function can be used to iterate over the Unicode characters of a + /// string. + /// + /// # Example + /// + /// This example manually iterates through the characters of a + /// string; this should normally be done by `.chars()` or + /// `.char_indices`. + /// + /// ```rust + /// use std::str::CharRange; + /// + /// let s = "中华Việt Nam"; + /// let mut i = 0u; + /// while i < s.len() { + /// let CharRange {ch, next} = s.char_range_at(i); + /// println!("{}: {}", i, ch); + /// i = next; + /// } + /// ``` + /// + /// ## Output + /// + /// ```ignore + /// 0: 中 + /// 3: 华 + /// 6: V + /// 7: i + /// 8: ệ + /// 11: t + /// 12: + /// 13: N + /// 14: a + /// 15: m + /// ``` + /// + /// # Arguments + /// + /// * s - The string + /// * i - The byte offset of the char to extract + /// + /// # Return value + /// + /// A record {ch: char, next: uint} containing the char value and the byte + /// index of the next Unicode character. + /// + /// # Panics + /// + /// If `i` is greater than or equal to the length of the string. + /// If `i` is not the index of the beginning of a valid UTF-8 character. + #[inline] + pub fn char_range_at(&self, i: uint) -> CharRange { + if self.as_bytes()[i] < 128u8 { + return CharRange {ch: self.as_bytes()[i] as char, next: i + 1 }; + } + + // Multibyte case is a fn to allow char_range_at to inline cleanly + fn multibyte_char_range_at(s: &str, i: uint) -> CharRange { + let mut val = s.as_bytes()[i] as u32; + let w = UTF8_CHAR_WIDTH[val as uint] as uint; + assert!((w != 0)); + + val = utf8_first_byte!(val, w); + val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 1]); + if w > 2 { val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 2]); } + if w > 3 { val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 3]); } + + return CharRange {ch: unsafe { mem::transmute(val) }, next: i + w}; + } + + return multibyte_char_range_at(self, i); + } + + /// Given a byte position and a str, return the previous char and its position. + /// + /// This function can be used to iterate over a Unicode string in reverse. + /// + /// Returns 0 for next index if called on start index 0. + /// + /// # Panics + /// + /// If `i` is greater than the length of the string. + /// If `i` is not an index following a valid UTF-8 character. + #[inline] + pub fn char_range_at_reverse(&self, start: uint) -> CharRange { + let mut prev = start; + + prev = prev.saturating_sub(1); + if self.as_bytes()[prev] < 128 { + return CharRange{ch: self.as_bytes()[prev] as char, next: prev} + } + + // Multibyte case is a fn to allow char_range_at_reverse to inline cleanly + fn multibyte_char_range_at_reverse(s: &str, mut i: uint) -> CharRange { + // while there is a previous byte == 10...... + while i > 0 && s.as_bytes()[i] & !CONT_MASK == TAG_CONT_U8 { + i -= 1u; + } + + let mut val = s.as_bytes()[i] as u32; + let w = UTF8_CHAR_WIDTH[val as uint] as uint; + assert!((w != 0)); + + val = utf8_first_byte!(val, w); + val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 1]); + if w > 2 { val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 2]); } + if w > 3 { val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 3]); } + + return CharRange {ch: unsafe { mem::transmute(val) }, next: i}; + } + + return multibyte_char_range_at_reverse(self, prev); + } + + /// Plucks the character starting at the `i`th byte of a string. + /// + /// # Example + /// + /// ```rust + /// let s = "abπc"; + /// assert_eq!(s.char_at(1), 'b'); + /// assert_eq!(s.char_at(2), 'π'); + /// assert_eq!(s.char_at(4), 'c'); + /// ``` + /// + /// # Panics + /// + /// If `i` is greater than or equal to the length of the string. + /// If `i` is not the index of the beginning of a valid UTF-8 character. + #[inline] + pub fn char_at(&self, i: uint) -> char { + self.char_range_at(i).ch + } + + /// Plucks the character ending at the `i`th byte of a string. + /// + /// # Panics + /// + /// If `i` is greater than the length of the string. + /// If `i` is not an index following a valid UTF-8 character. + #[inline] + pub fn char_at_reverse(&self, i: uint) -> char { + self.char_range_at_reverse(i).ch + } + + /// Work with the byte buffer of a string as a byte slice. + /// + /// # Example + /// + /// ```rust + /// assert_eq!("bors".as_bytes(), b"bors"); + /// ``` + #[inline] + pub fn as_bytes(&self) -> &[u8] { + unsafe { mem::transmute(self) } + } + + /// Returns the byte index of the first character of `self` that + /// matches `search`. + /// + /// # Return value + /// + /// `Some` containing the byte index of the last matching character + /// or `None` if there is no match + /// + /// # Example + /// + /// ```rust + /// let s = "Löwe 老虎 Léopard"; + /// + /// assert_eq!(s.find('L'), Some(0)); + /// assert_eq!(s.find('é'), Some(14)); + /// + /// // the first space + /// assert_eq!(s.find(|c: char| c.is_whitespace()), Some(5)); + /// + /// // neither are found + /// let x: &[_] = &['1', '2']; + /// assert_eq!(s.find(x), None); + /// ``` + pub fn find(&self, mut search: C) -> Option { + if search.only_ascii() { + self.bytes().position(|b| search.matches(b as char)) + } else { + for (index, c) in self.char_indices() { + if search.matches(c) { return Some(index); } + } + None + } + } + + /// Returns the byte index of the last character of `self` that + /// matches `search`. + /// + /// # Return value + /// + /// `Some` containing the byte index of the last matching character + /// or `None` if there is no match. + /// + /// # Example + /// + /// ```rust + /// let s = "Löwe 老虎 Léopard"; + /// + /// assert_eq!(s.rfind('L'), Some(13)); + /// assert_eq!(s.rfind('é'), Some(14)); + /// + /// // the second space + /// assert_eq!(s.rfind(|c: char| c.is_whitespace()), Some(12)); + /// + /// // searches for an occurrence of either `1` or `2`, but neither are found + /// let x: &[_] = &['1', '2']; + /// assert_eq!(s.rfind(x), None); + /// ``` + pub fn rfind(&self, mut search: C) -> Option { + if search.only_ascii() { + self.bytes().rposition(|b| search.matches(b as char)) + } else { + for (index, c) in self.char_indices().rev() { + if search.matches(c) { return Some(index); } + } + None + } + } + + /// Returns the byte index of the first matching substring + /// + /// # Arguments + /// + /// * `needle` - The string to search for + /// + /// # Return value + /// + /// `Some` containing the byte index of the first matching substring + /// or `None` if there is no match. + /// + /// # Example + /// + /// ```rust + /// let s = "Löwe 老虎 Léopard"; + /// + /// assert_eq!(s.find_str("老虎 L"), Some(6)); + /// assert_eq!(s.find_str("muffin man"), None); + /// ``` + pub fn find_str(&self, needle: &str) -> Option { + if needle.is_empty() { + Some(0) + } else { + self.match_indices(needle) + .next() + .map(|(start, _end)| start) + } + } + + /// Retrieves the first character from a string slice and returns + /// it. This does not allocate a new string; instead, it returns a + /// slice that point one character beyond the character that was + /// shifted. If the string does not contain any characters, + /// None is returned instead. + /// + /// # Example + /// + /// ```rust + /// let s = "Löwe 老虎 Léopard"; + /// let (c, s1) = s.slice_shift_char().unwrap(); + /// assert_eq!(c, 'L'); + /// assert_eq!(s1, "öwe 老虎 Léopard"); + /// + /// let (c, s2) = s1.slice_shift_char().unwrap(); + /// assert_eq!(c, 'ö'); + /// assert_eq!(s2, "we 老虎 Léopard"); + /// ``` + #[inline] + pub fn slice_shift_char(&self) -> Option<(char, &str)> { + if self.is_empty() { + None + } else { + let CharRange {ch, next} = self.char_range_at(0u); + let next_s = unsafe { self.slice_unchecked(next, self.len()) }; + Some((ch, next_s)) + } + } + + /// Returns the byte offset of an inner slice relative to an enclosing outer slice. + /// + /// Panics if `inner` is not a direct slice contained within self. + /// + /// # Example + /// + /// ```rust + /// let string = "a\nb\nc"; + /// let lines: Vec<&str> = string.lines().collect(); + /// + /// assert!(string.subslice_offset(lines[0]) == 0); // &"a" + /// assert!(string.subslice_offset(lines[1]) == 2); // &"b" + /// assert!(string.subslice_offset(lines[2]) == 4); // &"c" + /// ``` + pub fn subslice_offset(&self, inner: &str) -> uint { + let a_start = self.as_ptr() as uint; + let a_end = a_start + self.len(); + let b_start = inner.as_ptr() as uint; + let b_end = b_start + inner.len(); + + assert!(a_start <= b_start); + assert!(b_end <= a_end); + b_start - a_start + } + + /// Return an unsafe pointer to the strings buffer. + /// + /// The caller must ensure that the string outlives this pointer, + /// and that it is not reallocated (e.g. by pushing to the + /// string). + #[inline] + pub fn as_ptr(&self) -> *const u8 { + self.repr().data + } + + /// Return an iterator of `u16` over the string encoded as UTF-16. + #[inline] + pub fn utf16_units(&self) -> Utf16CodeUnits { + Utf16CodeUnits { encoder: Utf16Encoder::new(self.chars()) } + } + + /// Return the number of bytes in this string + /// + /// # Example + /// + /// ``` + /// assert_eq!("foo".len(), 3); + /// assert_eq!("ƒoo".len(), 4); + /// ``` + #[experimental = "not triaged yet"] + #[inline] + pub fn len(&self) -> uint { self.repr().len } + + /// Returns true if this slice contains no bytes + /// + /// # Example + /// + /// ``` + /// assert!("".is_empty()); + /// ``` + #[experimental = "not triaged yet"] + #[inline] + pub fn is_empty(&self) -> bool { self.len() == 0 } +} + impl<'a> Default for &'a str { fn default() -> &'a str { "" } } From 6e5f5d97af10c47d6d1e52ca0ff700cfedace338 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 11:37:11 -0500 Subject: [PATCH 12/39] libunicode: fix fallout --- src/libunicode/tables.rs | 3 +++ src/libunicode/u_str.rs | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libunicode/tables.rs b/src/libunicode/tables.rs index 7cece6701dc8..778e5d4d0843 100644 --- a/src/libunicode/tables.rs +++ b/src/libunicode/tables.rs @@ -3641,6 +3641,9 @@ pub mod property { } pub mod regex { + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + use core::str::str; + pub static UNICODE_CLASSES: &'static [(&'static str, &'static &'static [(char, char)])] = &[ ("Alphabetic", &super::derived_property::Alphabetic_table), ("Arabic", &super::script::Arabic_table), ("Armenian", &super::script::Armenian_table), ("Avestan", diff --git a/src/libunicode/u_str.rs b/src/libunicode/u_str.rs index a5f761425759..8d7bc1a66b86 100644 --- a/src/libunicode/u_str.rs +++ b/src/libunicode/u_str.rs @@ -22,7 +22,11 @@ use core::iter::{Filter, AdditiveIterator, Iterator, IteratorExt}; use core::iter::{DoubleEndedIterator, DoubleEndedIteratorExt}; use core::kinds::Sized; use core::option::{Option, None, Some}; -use core::str::{CharSplits, StrPrelude}; +use core::str::CharSplits; +#[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot +use core::str::StrPrelude; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use u_char::UnicodeChar; use tables::grapheme::GraphemeCat; From 8608ac75ff9383be70d6a60b2b8d505f3123cc93 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 11:38:42 -0500 Subject: [PATCH 13/39] librand: fix fallout --- src/librand/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librand/lib.rs b/src/librand/lib.rs index de40ee4893d5..f1714795779e 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -488,6 +488,8 @@ pub struct Closed01(pub F); #[cfg(not(test))] mod std { pub use core::{option, fmt}; // panic!() + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + pub use core::str; } #[cfg(test)] From 8ad92389770bb16c8bf31670a1ff032eed23030d Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 12:11:32 -0500 Subject: [PATCH 14/39] libcollections: fix fallout --- src/libcollections/hash/mod.rs | 2 ++ src/libcollections/lib.rs | 2 ++ src/libcollections/str.rs | 7 ++++++- src/libcollections/string.rs | 23 ++++++++++++++--------- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/libcollections/hash/mod.rs b/src/libcollections/hash/mod.rs index 1dc2539c592e..c481bdb8663d 100644 --- a/src/libcollections/hash/mod.rs +++ b/src/libcollections/hash/mod.rs @@ -69,6 +69,8 @@ use core::borrow::{Cow, ToOwned}; use core::intrinsics::TypeId; use core::mem; use core::num::Int; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use vec::Vec; diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 1e104b314478..07dce307b653 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -115,4 +115,6 @@ mod std { pub use core::clone; // deriving(Clone) pub use core::cmp; // deriving(Eq, Ord, etc.) pub use hash; // deriving(Hash) + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + pub use core::str; } diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index ad0a5e761764..ee7e53682e4f 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -79,7 +79,12 @@ pub use core::str::{eq_slice, is_utf8, is_utf16, Utf16Items}; pub use core::str::{Utf16Item, ScalarValue, LoneSurrogate, utf16_items}; pub use core::str::{truncate_utf16_at_nul, utf8_char_width, CharRange}; pub use core::str::{FromStr, from_str}; -pub use core::str::{Str, StrPrelude}; +pub use core::str::Str; +// NOTE(stage0): Remove import after a snapshot +#[cfg(stage0)] +pub use core::str::StrPrelude; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +pub use core::str::str; pub use core::str::{from_utf8_unchecked, from_c_str}; pub use unicode::str::{UnicodeStrPrelude, Words, Graphemes, GraphemeIndices}; diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index fbb0bb5c4ce8..431a33b008e7 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -14,6 +14,9 @@ use core::prelude::*; +#[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot +use core::str::StrPrelude; + use core::borrow::{Cow, IntoCow}; use core::default::Default; use core::fmt; @@ -22,11 +25,13 @@ use core::ptr; use core::ops; // FIXME: ICE's abound if you import the `Slice` type while importing `Slice` trait use core::raw::Slice as RawSlice; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use hash; use slice::CloneSliceAllocPrelude; -use str; use str::{CharRange, CowString, FromStr, StrAllocating, Owned}; +use str as str_; use vec::{DerefVec, Vec, as_vec}; /// A growable string stored as a UTF-8 encoded buffer. @@ -103,7 +108,7 @@ impl String { #[inline] #[unstable = "error type may change"] pub fn from_utf8(vec: Vec) -> Result> { - if str::is_utf8(vec.as_slice()) { + if str_::is_utf8(vec.as_slice()) { Ok(String { vec: vec }) } else { Err(vec) @@ -122,7 +127,7 @@ impl String { /// ``` #[unstable = "return type may change"] pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> CowString<'a> { - if str::is_utf8(v) { + if str_::is_utf8(v) { return Cow::Borrowed(unsafe { mem::transmute(v) }) } @@ -172,7 +177,7 @@ impl String { if byte < 128u8 { // subseqidx handles this } else { - let w = str::utf8_char_width(byte); + let w = str_::utf8_char_width(byte); match w { 2 => { @@ -255,10 +260,10 @@ impl String { #[unstable = "error value in return may change"] pub fn from_utf16(v: &[u16]) -> Option { let mut s = String::with_capacity(v.len()); - for c in str::utf16_items(v) { + for c in str_::utf16_items(v) { match c { - str::ScalarValue(c) => s.push(c), - str::LoneSurrogate(_) => return None + str_::ScalarValue(c) => s.push(c), + str_::LoneSurrogate(_) => return None } } Some(s) @@ -279,7 +284,7 @@ impl String { /// ``` #[stable] pub fn from_utf16_lossy(v: &[u16]) -> String { - str::utf16_items(v).map(|c| c.to_char_lossy()).collect() + str_::utf16_items(v).map(|c| c.to_char_lossy()).collect() } /// Convert a vector of `char`s to a `String`. @@ -317,7 +322,7 @@ impl String { /// slice is not checked to see whether it contains valid UTF-8 #[unstable = "just renamed from `mod raw`"] pub unsafe fn from_raw_buf(buf: *const u8) -> String { - String::from_str(str::from_c_str(buf as *const i8)) + String::from_str(str_::from_c_str(buf as *const i8)) } /// Creates a `String` from a `*const u8` buffer of the given length. From be8c54c8c17920ef1d3d0d3334a86dc596b6c003 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 13:36:31 -0500 Subject: [PATCH 15/39] librustrt: fix fallout --- src/librustrt/c_str.rs | 10 +++++++--- src/librustrt/lib.rs | 2 ++ src/librustrt/unwind.rs | 2 ++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/librustrt/c_str.rs b/src/librustrt/c_str.rs index 261bd1b9f8cb..6c981ef209fd 100644 --- a/src/librustrt/c_str.rs +++ b/src/librustrt/c_str.rs @@ -74,11 +74,15 @@ use core::kinds::{Sized, marker}; use core::mem; use core::prelude::{Clone, Drop, Eq, Iterator}; use core::prelude::{SlicePrelude, None, Option, Ordering, PartialEq}; -use core::prelude::{PartialOrd, RawPtr, Some, StrPrelude, range}; +use core::prelude::{PartialOrd, RawPtr, Some, range}; +#[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot +use core::prelude::{StrPrelude}; use core::ptr; use core::raw::Slice; use core::slice; -use core::str; +use core::str as str_; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use libc; /// The representation of a C String. @@ -228,7 +232,7 @@ impl CString { #[inline] pub fn as_str<'a>(&'a self) -> Option<&'a str> { let buf = self.as_bytes_no_nul(); - str::from_utf8(buf) + str_::from_utf8(buf) } /// Return a CString iterator. diff --git a/src/librustrt/lib.rs b/src/librustrt/lib.rs index 066e8c51aef0..498a330fcffe 100644 --- a/src/librustrt/lib.rs +++ b/src/librustrt/lib.rs @@ -127,4 +127,6 @@ pub mod shouldnt_be_public { #[cfg(not(test))] mod std { pub use core::{fmt, option, cmp}; + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + pub use core::str; } diff --git a/src/librustrt/unwind.rs b/src/librustrt/unwind.rs index 697ee95df4c0..9b62a2b48fbf 100644 --- a/src/librustrt/unwind.rs +++ b/src/librustrt/unwind.rs @@ -70,6 +70,8 @@ use core::fmt; use core::intrinsics; use core::mem; use core::raw::Closure; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use libc::c_void; use local::Local; From 31a3b28aafbdb1f54e9219d011c972afe2fe4bb4 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 14:42:18 -0500 Subject: [PATCH 16/39] libstd: use full path of `str` in `panic!` macro --- src/libstd/macros.rs | 57 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 76419bee41c2..dabb8245e10e 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -36,6 +36,7 @@ /// panic!(4i); // panic with the value of 4 to be collected elsewhere /// panic!("this is a {} {message}", "fancy", message = "message"); /// ``` +#[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot #[macro_export] macro_rules! panic( () => ({ @@ -72,6 +73,62 @@ macro_rules! panic( }); ) +/// The entry point for panic of Rust tasks. +/// +/// This macro is used to inject panic into a Rust task, causing the task to +/// unwind and panic entirely. Each task's panic can be reaped as the +/// `Box` type, and the single-argument form of the `panic!` macro will be +/// the value which is transmitted. +/// +/// The multi-argument form of this macro panics with a string and has the +/// `format!` syntax for building a string. +/// +/// # Example +/// +/// ```should_fail +/// # #![allow(unreachable_code)] +/// panic!(); +/// panic!("this is a terrible mistake!"); +/// panic!(4i); // panic with the value of 4 to be collected elsewhere +/// panic!("this is a {} {message}", "fancy", message = "message"); +/// ``` +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +#[macro_export] +macro_rules! panic( + () => ({ + panic!("explicit panic") + }); + ($msg:expr) => ({ + // static requires less code at runtime, more constant data + static _FILE_LINE: (&'static ::std::str::str, uint) = (file!(), line!()); + ::std::rt::begin_unwind($msg, &_FILE_LINE) + }); + ($fmt:expr, $($arg:tt)*) => ({ + // a closure can't have return type !, so we need a full + // function to pass to format_args!, *and* we need the + // file and line numbers right here; so an inner bare fn + // is our only choice. + // + // LLVM doesn't tend to inline this, presumably because begin_unwind_fmt + // is #[cold] and #[inline(never)] and because this is flagged as cold + // as returning !. We really do want this to be inlined, however, + // because it's just a tiny wrapper. Small wins (156K to 149K in size) + // were seen when forcing this to be inlined, and that number just goes + // up with the number of calls to panic!() + // + // The leading _'s are to avoid dead code warnings if this is + // used inside a dead function. Just `#[allow(dead_code)]` is + // insufficient, since the user may have + // `#[forbid(dead_code)]` and which cannot be overridden. + #[inline(always)] + fn _run_fmt(fmt: &::std::fmt::Arguments) -> ! { + static _FILE_LINE: (&'static ::std::str::str, uint) = (file!(), line!()); + ::std::rt::begin_unwind_fmt(fmt, &_FILE_LINE) + } + format_args!(_run_fmt, $fmt, $($arg)*) + }); +) + /// Ensure that a boolean expression is `true` at runtime. /// /// This will invoke the `panic!` macro if the provided expression cannot be From e3739771eb112d714931446bb7fe920553265052 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 14:02:35 -0500 Subject: [PATCH 17/39] libstd: fix fallout --- src/libstd/ascii.rs | 6 ++++- src/libstd/dynamic_lib.rs | 9 ++++--- src/libstd/error.rs | 2 ++ src/libstd/failure.rs | 2 ++ src/libstd/io/fs.rs | 2 ++ src/libstd/io/mod.rs | 12 ++++++--- src/libstd/io/net/addrinfo.rs | 2 ++ src/libstd/io/net/ip.rs | 6 ++++- src/libstd/io/stdio.rs | 3 +++ src/libstd/io/tempfile.rs | 2 ++ src/libstd/lib.rs | 2 ++ src/libstd/num/strconv.rs | 1 + src/libstd/os.rs | 46 ++++++++++++++++++++++++++++++++--- src/libstd/path/mod.rs | 24 ++++++++++-------- src/libstd/path/posix.rs | 6 +++-- src/libstd/path/windows.rs | 6 ++++- src/libstd/prelude.rs | 6 ++++- src/libstd/rt/backtrace.rs | 6 ++++- src/libstd/task.rs | 2 ++ 19 files changed, 118 insertions(+), 27 deletions(-) diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 403ca9d14321..0e98cebb9ecd 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -16,12 +16,16 @@ #![allow(deprecated)] use core::kinds::Sized; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use fmt; use iter::IteratorExt; use mem; use option::{Option, Some, None}; use slice::{SlicePrelude, AsSlice}; -use str::{Str, StrPrelude}; +use str::Str; +#[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot +use str::StrPrelude; use string::{String, IntoString}; use vec::Vec; diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs index 160365dac361..c67ebc9c33cc 100644 --- a/src/libstd/dynamic_lib.rs +++ b/src/libstd/dynamic_lib.rs @@ -16,6 +16,8 @@ #![allow(missing_docs)] use clone::Clone; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use c_str::ToCStr; use iter::IteratorExt; use mem; @@ -25,7 +27,7 @@ use os; use path::{Path,GenericPath}; use result::*; use slice::{AsSlice,SlicePrelude}; -use str; +use str as str_; use string::String; use vec::Vec; @@ -39,7 +41,7 @@ impl Drop for DynamicLibrary { } }) { Ok(()) => {}, - Err(str) => panic!("{}", str) + Err(s) => panic!("{}", s) } } } @@ -82,7 +84,7 @@ impl DynamicLibrary { search_path.insert(0, path.clone()); let newval = DynamicLibrary::create_path(search_path.as_slice()); os::setenv(DynamicLibrary::envvar(), - str::from_utf8(newval.as_slice()).unwrap()); + str_::from_utf8(newval.as_slice()).unwrap()); } /// From a slice of paths, create a new vector which is suitable to be an @@ -282,6 +284,7 @@ pub mod dl { use ptr; use result::{Ok, Err, Result}; use slice::SlicePrelude; + #[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot use str::StrPrelude; use str; use string::String; diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 82ad893f88a1..6a7f2ab84199 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -78,6 +78,8 @@ //! } //! ``` +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use option::{Option, None}; use kinds::Send; use string::String; diff --git a/src/libstd/failure.rs b/src/libstd/failure.rs index d839c1484e56..d5b1fe6ed781 100644 --- a/src/libstd/failure.rs +++ b/src/libstd/failure.rs @@ -13,6 +13,8 @@ use alloc::boxed::Box; use any::{Any, AnyRefExt}; use cell::RefCell; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use fmt; use io::{Writer, IoResult}; use kinds::Send; diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs index e52c00f8247a..f2e71a44b70c 100644 --- a/src/libstd/io/fs.rs +++ b/src/libstd/io/fs.rs @@ -50,6 +50,8 @@ //! fs::unlink(&path); //! ``` +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use clone::Clone; use io::standard_error; use io::{FilePermission, Write, Open, FileAccess, FileMode, FileType}; diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index b2e4fc75cf23..ea0f96e74ee4 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -226,6 +226,8 @@ pub use self::IoErrorKind::*; use char::Char; use clone::Clone; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use default::Default; use error::{FromError, Error}; use fmt; @@ -239,8 +241,10 @@ use boxed::Box; use result::{Ok, Err, Result}; use sys; use slice::{AsSlice, SlicePrelude}; -use str::{Str, StrPrelude}; -use str; +use str::Str; +#[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot +use str::StrPrelude; +use str as str_; use string::String; use uint; use unicode::char::UnicodeChar; @@ -1496,7 +1500,7 @@ pub trait Buffer: Reader { /// valid utf-8 encoded codepoint as the next few bytes in the stream. fn read_char(&mut self) -> IoResult { let first_byte = try!(self.read_byte()); - let width = str::utf8_char_width(first_byte); + let width = str_::utf8_char_width(first_byte); if width == 1 { return Ok(first_byte as char) } if width == 0 { return Err(standard_error(InvalidInput)) } // not utf8 let mut buf = [first_byte, 0, 0, 0]; @@ -1510,7 +1514,7 @@ pub trait Buffer: Reader { } } } - match str::from_utf8(buf[..width]) { + match str_::from_utf8(buf[..width]) { Some(s) => Ok(s.char_at(0)), None => Err(standard_error(InvalidInput)) } diff --git a/src/libstd/io/net/addrinfo.rs b/src/libstd/io/net/addrinfo.rs index 7de786921309..83ebde914633 100644 --- a/src/libstd/io/net/addrinfo.rs +++ b/src/libstd/io/net/addrinfo.rs @@ -19,6 +19,8 @@ pub use self::SocketType::*; pub use self::Flag::*; pub use self::Protocol::*; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use iter::IteratorExt; use io::{IoResult}; use io::net::ip::{SocketAddr, IpAddr}; diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs index 4812e911cc48..d8a9fbc671e1 100644 --- a/src/libstd/io/net/ip.rs +++ b/src/libstd/io/net/ip.rs @@ -17,13 +17,17 @@ pub use self::IpAddr::*; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use fmt; use io::{mod, IoResult, IoError}; use io::net; use iter::{Iterator, IteratorExt}; use option::{Option, None, Some}; use result::{Ok, Err}; -use str::{FromStr, StrPrelude}; +use str::FromStr; +#[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot +use str::StrPrelude; use slice::{CloneSlicePrelude, SlicePrelude}; use vec::Vec; diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index ad5dcf71df73..3c4629725e10 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -30,6 +30,8 @@ use self::StdSource::*; use boxed::Box; use cell::RefCell; use clone::Clone; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use failure::LOCAL_STDERR; use fmt; use io::{Reader, Writer, IoResult, IoError, OtherIoError, Buffer, @@ -44,6 +46,7 @@ use rustrt; use rustrt::local::Local; use rustrt::task::Task; use slice::SlicePrelude; +#[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot use str::StrPrelude; use string::String; use sys::{fs, tty}; diff --git a/src/libstd/io/tempfile.rs b/src/libstd/io/tempfile.rs index 4788ba79b7fa..c10bd5095ab3 100644 --- a/src/libstd/io/tempfile.rs +++ b/src/libstd/io/tempfile.rs @@ -10,6 +10,8 @@ //! Temporary files and directories +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use io::{fs, IoResult}; use io; use libc; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index d4274d7e4017..7a14c247cd0a 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -273,4 +273,6 @@ mod std { pub use boxed; // used for vec![] + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + pub use core::str; } diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index b42286c0308c..656bd8c5ef73 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -21,6 +21,7 @@ use char::Char; use num; use num::{Int, Float, FPNaN, FPInfinite, ToPrimitive}; use slice::{SlicePrelude, CloneSliceAllocPrelude}; +#[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot use str::StrPrelude; use string::String; use vec::Vec; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index a8adfec34ed6..32b34d4ae551 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -32,6 +32,8 @@ pub use self::MapOption::*; pub use self::MapError::*; use clone::Clone; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use error::{FromError, Error}; use fmt; use io::{IoResult, IoError}; @@ -50,7 +52,9 @@ use ptr; use result::{Err, Ok, Result}; use slice::{AsSlice, SlicePrelude, PartialEqSlicePrelude}; use slice::CloneSliceAllocPrelude; -use str::{Str, StrPrelude, StrAllocating}; +use str::{Str, StrAllocating}; +#[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot +use str::StrPrelude; use string::{String, ToString}; use sync::atomic::{AtomicInt, INIT_ATOMIC_INT, SeqCst}; use vec::Vec; @@ -1263,7 +1267,7 @@ pub enum MapError { impl fmt::Show for MapError { fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result { - let str = match *self { + let s = match *self { ErrFdNotAvail => "fd not available for reading or writing", ErrInvalidFd => "Invalid fd", ErrUnaligned => { @@ -1289,7 +1293,7 @@ impl fmt::Show for MapError { return write!(out, "MapViewOfFile failure = {}", code) } }; - write!(out, "{}", str) + write!(out, "{}", s) } } @@ -1536,6 +1540,9 @@ impl MemoryMap { #[cfg(target_os = "linux")] pub mod consts { + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + use core::str::str; + pub use os::arch_consts::ARCH; pub const FAMILY: &'static str = "unix"; @@ -1567,6 +1574,9 @@ pub mod consts { #[cfg(target_os = "macos")] pub mod consts { + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + use core::str::str; + pub use os::arch_consts::ARCH; pub const FAMILY: &'static str = "unix"; @@ -1598,6 +1608,9 @@ pub mod consts { #[cfg(target_os = "ios")] pub mod consts { + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + use core::str::str; + pub use os::arch_consts::ARCH; pub const FAMILY: &'static str = "unix"; @@ -1617,6 +1630,9 @@ pub mod consts { #[cfg(target_os = "freebsd")] pub mod consts { + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + use core::str::str; + pub use os::arch_consts::ARCH; pub const FAMILY: &'static str = "unix"; @@ -1648,6 +1664,9 @@ pub mod consts { #[cfg(target_os = "dragonfly")] pub mod consts { + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + use core::str::str; + pub use os::arch_consts::ARCH; pub const FAMILY: &'static str = "unix"; @@ -1679,6 +1698,9 @@ pub mod consts { #[cfg(target_os = "android")] pub mod consts { + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + use core::str::str; + pub use os::arch_consts::ARCH; pub const FAMILY: &'static str = "unix"; @@ -1710,6 +1732,9 @@ pub mod consts { #[cfg(target_os = "windows")] pub mod consts { + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + use core::str::str; + pub use os::arch_consts::ARCH; pub const FAMILY: &'static str = "windows"; @@ -1741,26 +1766,41 @@ pub mod consts { #[cfg(target_arch = "x86")] mod arch_consts { + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + use core::str::str; + pub const ARCH: &'static str = "x86"; } #[cfg(target_arch = "x86_64")] mod arch_consts { + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + use core::str::str; + pub const ARCH: &'static str = "x86_64"; } #[cfg(target_arch = "arm")] mod arch_consts { + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + use core::str::str; + pub const ARCH: &'static str = "arm"; } #[cfg(target_arch = "mips")] mod arch_consts { + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + use core::str::str; + pub const ARCH: &'static str = "mips"; } #[cfg(target_arch = "mipsel")] mod arch_consts { + #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot + use core::str::str; + pub const ARCH: &'static str = "mipsel"; } diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index b17106e811f6..5195fe91b3da 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -62,13 +62,17 @@ #![experimental] use core::kinds::Sized; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use c_str::CString; use clone::Clone; use fmt; use iter::IteratorExt; use option::{Option, None, Some}; -use str; -use str::{CowString, MaybeOwned, Str, StrPrelude}; +use str as str_; +use str::{CowString, MaybeOwned, Str}; +#[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot +use str::StrPrelude; use string::String; use slice::{AsSlice, CloneSliceAllocPrelude}; use slice::{PartialEqSlicePrelude, SlicePrelude}; @@ -196,7 +200,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// ``` #[inline] fn as_str<'a>(&'a self) -> Option<&'a str> { - str::from_utf8(self.as_vec()) + str_::from_utf8(self.as_vec()) } /// Returns the path as a byte vector @@ -292,7 +296,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// ``` #[inline] fn dirname_str<'a>(&'a self) -> Option<&'a str> { - str::from_utf8(self.dirname()) + str_::from_utf8(self.dirname()) } /// Returns the file component of `self`, as a byte vector. @@ -326,7 +330,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// ``` #[inline] fn filename_str<'a>(&'a self) -> Option<&'a str> { - self.filename().and_then(str::from_utf8) + self.filename().and_then(str_::from_utf8) } /// Returns the stem of the filename of `self`, as a byte vector. @@ -372,7 +376,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// ``` #[inline] fn filestem_str<'a>(&'a self) -> Option<&'a str> { - self.filestem().and_then(str::from_utf8) + self.filestem().and_then(str_::from_utf8) } /// Returns the extension of the filename of `self`, as an optional byte vector. @@ -419,7 +423,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// ``` #[inline] fn extension_str<'a>(&'a self) -> Option<&'a str> { - self.extension().and_then(str::from_utf8) + self.extension().and_then(str_::from_utf8) } /// Replaces the filename portion of the path with the given byte vector or string. @@ -792,7 +796,7 @@ pub trait BytesContainer for Sized? { /// Returns the receiver interpreted as a utf-8 string, if possible #[inline] fn container_as_str<'a>(&'a self) -> Option<&'a str> { - str::from_utf8(self.container_as_bytes()) + str_::from_utf8(self.container_as_bytes()) } /// Returns whether .container_as_str() is guaranteed to not fail // FIXME (#8888): Remove unused arg once :: works @@ -896,7 +900,7 @@ impl BytesContainer for CString { } } -impl<'a> BytesContainer for str::MaybeOwned<'a> { +impl<'a> BytesContainer for str_::MaybeOwned<'a> { #[inline] fn container_as_bytes<'b>(&'b self) -> &'b [u8] { self.as_slice().as_bytes() @@ -906,7 +910,7 @@ impl<'a> BytesContainer for str::MaybeOwned<'a> { Some(self.as_slice()) } #[inline] - fn is_str(_: Option<&str::MaybeOwned>) -> bool { true } + fn is_str(_: Option<&str_::MaybeOwned>) -> bool { true } } impl<'a, Sized? T: BytesContainer> BytesContainer for &'a T { diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index f6778588addb..d2462b1b3c2e 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -12,6 +12,8 @@ use c_str::{CString, ToCStr}; use clone::Clone; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; use hash; use io::Writer; @@ -20,7 +22,7 @@ use iter::{Iterator, IteratorExt, Map}; use option::{Option, None, Some}; use kinds::Sized; use str::{FromStr, Str}; -use str; +use str as str_; use slice::{CloneSliceAllocPrelude, Splits, AsSlice, VectorVector, PartialEqSlicePrelude, SlicePrelude}; use vec::Vec; @@ -400,7 +402,7 @@ impl Path { /// Returns an iterator that yields each component of the path as Option<&str>. /// See components() for details. pub fn str_components<'a>(&'a self) -> StrComponents<'a> { - self.components().map(str::from_utf8) + self.components().map(str_::from_utf8) } } diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 13891a633301..050ddfb0ce47 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -18,6 +18,8 @@ use ascii::AsciiCast; use c_str::{CString, ToCStr}; use clone::Clone; use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use hash; use io::Writer; use iter::{AdditiveIterator, DoubleEndedIteratorExt, Extend}; @@ -25,7 +27,9 @@ use iter::{Iterator, IteratorExt, Map}; use mem; use option::{Option, Some, None}; use slice::{AsSlice, SlicePrelude}; -use str::{CharSplits, FromStr, Str, StrAllocating, StrVector, StrPrelude}; +use str::{CharSplits, FromStr, Str, StrAllocating, StrVector}; +#[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot +use str::StrPrelude; use string::String; use unicode::char::UnicodeChar; use vec::Vec; diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index ec1cff73e96c..3b5679f4b6d0 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -79,8 +79,12 @@ #[doc(no_inline)] pub use result::Result; #[doc(no_inline)] pub use result::Result::{Ok, Err}; #[doc(no_inline)] pub use io::{Buffer, Writer, Reader, Seek, BufferPrelude}; -#[doc(no_inline)] pub use str::{Str, StrVector, StrPrelude}; +#[doc(no_inline)] pub use str::{Str, StrVector}; +#[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot +#[doc(no_inline)] pub use str::StrPrelude; #[doc(no_inline)] pub use str::{StrAllocating, UnicodeStrPrelude}; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +#[doc(no_inline)] pub use core::str::str; #[doc(no_inline)] pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4}; #[doc(no_inline)] pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8}; #[doc(no_inline)] pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12}; diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs index 159fc3080e83..04215f834390 100644 --- a/src/libstd/rt/backtrace.rs +++ b/src/libstd/rt/backtrace.rs @@ -12,12 +12,16 @@ #![allow(non_camel_case_types)] +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use io::{IoResult, Writer}; use iter::{Iterator, IteratorExt}; use option::{Some, None}; use os; use result::{Ok, Err}; -use str::{StrPrelude, from_str}; +use str::from_str; +#[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot +use str::StrPrelude; use sync::atomic; use unicode::char::UnicodeChar; diff --git a/src/libstd/task.rs b/src/libstd/task.rs index a0ee08570d90..ca07dc03f422 100644 --- a/src/libstd/task.rs +++ b/src/libstd/task.rs @@ -47,6 +47,8 @@ use any::Any; use borrow::IntoCow; use boxed::Box; use comm::channel; +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use io::{Writer, stdio}; use kinds::{Send, marker}; use option::{None, Some, Option}; From 005cdb76882189d326989211b16b0bd41aaf05e2 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 18:24:48 -0500 Subject: [PATCH 18/39] libfmt_macros: fix fallout --- src/libfmt_macros/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 03b65b3f71c8..0a3d1fa3f2d3 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -30,7 +30,7 @@ pub use self::Alignment::*; pub use self::Flag::*; pub use self::Count::*; -use std::str; +use std::str as str_; use std::string; /// A piece is a portion of the format string which represents the next part @@ -136,7 +136,7 @@ pub enum Count<'a> { /// necessary there's probably lots of room for improvement performance-wise. pub struct Parser<'a> { input: &'a str, - cur: str::CharOffsets<'a>, + cur: str_::CharOffsets<'a>, /// Error messages accumulated during parsing pub errors: Vec, } From 54c55cfb938d8e1deb00fe9e926d8008795c1eb0 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 18:35:20 -0500 Subject: [PATCH 19/39] libserialize: fix fallout --- src/libserialize/json.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index fa82eb93faee..30c7d0a09035 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -199,7 +199,8 @@ use self::InternalStackElement::*; use std; use std::collections::{HashMap, TreeMap}; -use std::{char, f64, fmt, io, num, str}; +use std::{char, f64, fmt, io, num}; +use std::str as str_; use std::mem::{swap, transmute}; use std::num::{Float, FPNaN, FPInfinite, Int}; use std::str::{FromStr, ScalarValue}; @@ -577,7 +578,7 @@ impl<'a> ::Encoder for Encoder<'a> { let mut check_encoder = Encoder::new(&mut buf); try!(f(transmute(&mut check_encoder))); } - let out = str::from_utf8(buf[]).unwrap(); + let out = str_::from_utf8(buf[]).unwrap(); let needs_wrapping = out.char_at(0) != '"' && out.char_at_reverse(out.len()) != '"'; if needs_wrapping { try!(write!(self.writer, "\"")); } try!(f(self)); @@ -838,7 +839,7 @@ impl<'a> ::Encoder for PrettyEncoder<'a> { let mut check_encoder = PrettyEncoder::new(&mut buf); try!(f(transmute(&mut check_encoder))); } - let out = str::from_utf8(buf[]).unwrap(); + let out = str_::from_utf8(buf[]).unwrap(); let needs_wrapping = out.char_at(0) != '"' && out.char_at_reverse(out.len()) != '"'; if needs_wrapping { try!(write!(self.writer, "\"")); } try!(f(self)); @@ -1162,7 +1163,7 @@ impl Stack { match self.stack[idx] { InternalIndex(i) => Index(i), InternalKey(start, size) => { - Key(str::from_utf8( + Key(str_::from_utf8( self.str_buffer[start as uint .. start as uint + size as uint]).unwrap()) } } @@ -1204,7 +1205,7 @@ impl Stack { None => None, Some(&InternalIndex(i)) => Some(Index(i)), Some(&InternalKey(start, size)) => { - Some(Key(str::from_utf8( + Some(Key(str_::from_utf8( self.str_buffer[start as uint .. (start+size) as uint] ).unwrap())) } @@ -1557,7 +1558,7 @@ impl> Parser { } let buf = [n1, try!(self.decode_hex_escape())]; - match str::utf16_items(buf.as_slice()).next() { + match str_::utf16_items(buf.as_slice()).next() { Some(ScalarValue(c)) => res.push(c), _ => return self.error(LoneLeadingSurrogateInHexEscape), } @@ -1906,7 +1907,7 @@ pub fn from_reader(rdr: &mut io::Reader) -> Result { Ok(c) => c, Err(e) => return Err(io_error_to_error(e)) }; - let s = match str::from_utf8(contents.as_slice()) { + let s = match str_::from_utf8(contents.as_slice()) { Some(s) => s, _ => return Err(SyntaxError(NotUtf8, 0, 0)) }; @@ -2098,7 +2099,7 @@ impl ::Decoder for Decoder { } }; let idx = match names.iter() - .position(|n| str::eq_slice(*n, name.as_slice())) { + .position(|n| str_::eq_slice(*n, name.as_slice())) { Some(idx) => idx, None => return Err(UnknownVariantError(name)) }; From 7f6b844d669e995b1448c113e8f6bbb28658fc06 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 18:49:11 -0500 Subject: [PATCH 20/39] librbml: fix fallout --- src/librbml/lib.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index 6f3fbe125100..8b03e33af112 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -35,7 +35,7 @@ extern crate serialize; pub use self::EbmlEncoderTag::*; pub use self::Error::*; -use std::str; +use std::str as str_; pub mod io; @@ -57,7 +57,7 @@ impl<'doc> Doc<'doc> { } pub fn as_str_slice<'a>(&'a self) -> &'a str { - str::from_utf8(self.data[self.start..self.end]).unwrap() + str_::from_utf8(self.data[self.start..self.end]).unwrap() } pub fn as_str(&self) -> String { @@ -333,10 +333,10 @@ pub mod reader { if r_tag == (EsLabel as uint) { self.pos = r_doc.end; - let str = r_doc.as_str_slice(); - if lbl != str { + let s = r_doc.as_str_slice(); + if lbl != s { return Err(Expected(format!("Expected label {} but \ - found {}", lbl, str))); + found {}", lbl, s))); } } } From adab4be5ca1a6e131b08a89c4c82d8c19491a076 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 18:49:51 -0500 Subject: [PATCH 21/39] libsyntax: fix fallout --- src/libsyntax/ext/quote.rs | 6 +++--- src/libsyntax/ext/tt/macro_parser.rs | 8 ++++---- src/libsyntax/parse/lexer/comments.rs | 4 ++-- src/libsyntax/parse/lexer/mod.rs | 10 +++++----- src/libsyntax/parse/mod.rs | 6 +++--- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 45752499ad59..efddcace141c 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -475,11 +475,11 @@ pub fn expand_quote_stmt(cx: &mut ExtCtxt, } fn ids_ext(strs: Vec ) -> Vec { - strs.iter().map(|str| str_to_ident((*str).as_slice())).collect() + strs.iter().map(|s| str_to_ident((*s).as_slice())).collect() } -fn id_ext(str: &str) -> ast::Ident { - str_to_ident(str) +fn id_ext(s: &str) -> ast::Ident { + str_to_ident(s) } // Lift an ident to the expr that evaluates to that ident. diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 4785fe37293c..4a10b2746496 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -256,11 +256,11 @@ pub fn parse_or_else(sess: &ParseSess, -> HashMap> { match parse(sess, cfg, rdr, ms.as_slice()) { Success(m) => m, - Failure(sp, str) => { - sess.span_diagnostic.span_fatal(sp, str.as_slice()) + Failure(sp, s) => { + sess.span_diagnostic.span_fatal(sp, s.as_slice()) } - Error(sp, str) => { - sess.span_diagnostic.span_fatal(sp, str.as_slice()) + Error(sp, s) => { + sess.span_diagnostic.span_fatal(sp, s.as_slice()) } } } diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs index b62d2d744c9e..310d37490b08 100644 --- a/src/libsyntax/parse/lexer/comments.rs +++ b/src/libsyntax/parse/lexer/comments.rs @@ -20,7 +20,7 @@ use parse::lexer; use print::pprust; use std::io; -use std::str; +use std::str as str_; use std::string::String; use std::uint; @@ -212,7 +212,7 @@ fn all_whitespace(s: &str, col: CharPos) -> Option { let mut col = col.to_uint(); let mut cursor: uint = 0; while col > 0 && cursor < len { - let r: str::CharRange = s.char_range_at(cursor); + let r: str_::CharRange = s.char_range_at(cursor); if !r.ch.is_whitespace() { return None; } diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 27b65e0f5279..90cbe0f3a8f7 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -21,7 +21,7 @@ use std::fmt; use std::mem::replace; use std::num; use std::rc::Rc; -use std::str; +use std::str as str_; pub use ext::tt::transcribe::{TtReader, new_tt_reader}; @@ -272,10 +272,10 @@ impl<'a> StringReader<'a> { /// Converts CRLF to LF in the given string, raising an error on bare CR. fn translate_crlf<'a>(&self, start: BytePos, - s: &'a str, errmsg: &'a str) -> str::CowString<'a> { + s: &'a str, errmsg: &'a str) -> str_::CowString<'a> { let mut i = 0u; while i < s.len() { - let str::CharRange { ch, next } = s.char_range_at(i); + let str_::CharRange { ch, next } = s.char_range_at(i); if ch == '\r' { if next < s.len() && s.char_at(next) == '\n' { return translate_crlf_(self, start, s, errmsg, i).into_cow(); @@ -293,7 +293,7 @@ impl<'a> StringReader<'a> { let mut buf = String::with_capacity(s.len()); let mut j = 0; while i < s.len() { - let str::CharRange { ch, next } = s.char_range_at(i); + let str_::CharRange { ch, next } = s.char_range_at(i); if ch == '\r' { if j < i { buf.push_str(s.slice(j, i)); } j = next; @@ -357,7 +357,7 @@ impl<'a> StringReader<'a> { let offset = self.byte_offset(self.pos).to_uint(); let s = self.filemap.deref().src.as_slice(); if offset >= s.len() { return None } - let str::CharRange { next, .. } = s.char_range_at(offset); + let str_::CharRange { next, .. } = s.char_range_at(offset); if next < s.len() { Some(s.char_at(next)) } else { diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 8d0c2de048a5..2a5d4c1982a6 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -21,7 +21,7 @@ use std::cell::{Cell, RefCell}; use std::io::File; use std::rc::Rc; use std::num::Int; -use std::str; +use std::str as str_; use std::iter; pub mod lexer; @@ -255,7 +255,7 @@ pub fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option) unreachable!() } }; - match str::from_utf8(bytes.as_slice()) { + match str_::from_utf8(bytes.as_slice()) { Some(s) => { return string_to_filemap(sess, s.to_string(), path.as_str().unwrap().to_string()) @@ -429,7 +429,7 @@ pub fn str_lit(lit: &str) -> String { let error = |i| format!("lexer should have rejected {} at {}", lit, i); /// Eat everything up to a non-whitespace - fn eat<'a>(it: &mut iter::Peekable<(uint, char), str::CharOffsets<'a>>) { + fn eat<'a>(it: &mut iter::Peekable<(uint, char), str_::CharOffsets<'a>>) { loop { match it.peek().map(|x| x.val1()) { Some(' ') | Some('\n') | Some('\r') | Some('\t') => { From bd7ccae661262b9e23f670635509db2247ebf3ae Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 19:58:25 -0500 Subject: [PATCH 22/39] librustc_back: fix fallout --- src/librustc_back/archive.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs index a88bcafaa64b..1d0ac3478e0f 100644 --- a/src/librustc_back/archive.rs +++ b/src/librustc_back/archive.rs @@ -15,7 +15,7 @@ use std::io::process::{Command, ProcessOutput}; use std::io::{fs, TempDir}; use std::io; use std::os; -use std::str; +use std::str as str_; use syntax::diagnostic::Handler as ErrorHandler; pub static METADATA_FILENAME: &'static str = "rust.metadata.bin"; @@ -77,11 +77,11 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option, cmd, o.status).as_slice()); handler.note(format!("stdout ---\n{}", - str::from_utf8(o.output + str_::from_utf8(o.output .as_slice()).unwrap()) .as_slice()); handler.note(format!("stderr ---\n{}", - str::from_utf8(o.error + str_::from_utf8(o.error .as_slice()).unwrap()) .as_slice()); handler.abort_if_errors(); @@ -147,7 +147,7 @@ impl<'a> Archive<'a> { /// Lists all files in an archive pub fn files(&self) -> Vec { let output = run_ar(self.handler, &self.maybe_ar_prog, "t", None, &[&self.dst]); - let output = str::from_utf8(output.output.as_slice()).unwrap(); + let output = str_::from_utf8(output.output.as_slice()).unwrap(); // use lines_any because windows delimits output with `\r\n` instead of // just `\n` output.lines_any().map(|s| s.to_string()).collect() From 1174f1c8cd62eac632fc43281d7cac4b982d1b2b Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 20:09:25 -0500 Subject: [PATCH 23/39] librustc: fix fallout --- src/librustc/lint/builtin.rs | 4 ++-- src/librustc/middle/astencode.rs | 6 +++--- src/librustc/util/ppaux.rs | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index b0ac98c94e74..fa3b76be54c8 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -895,9 +895,9 @@ impl NonSnakeCase { }) } - fn to_snake_case(str: &str) -> String { + fn to_snake_case(s: &str) -> String { let mut words = vec![]; - for s in str.split('_') { + for s in s.split('_') { let mut last_upper = false; let mut buf = String::new(); if s.is_empty() { continue; } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 113d127503f0..4aae0f48d467 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -1498,11 +1498,11 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { }).unwrap(); fn type_string(doc: rbml::Doc) -> String { - let mut str = String::new(); + let mut s = String::new(); for i in range(doc.start, doc.end) { - str.push(doc.data[i] as char); + s.push(doc.data[i] as char); } - str + s } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 414627b41e94..f38bda2c2f20 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -49,15 +49,15 @@ pub fn note_and_explain_region(cx: &ctxt, region: ty::Region, suffix: &str) -> Option { match explain_region_and_span(cx, region) { - (ref str, Some(span)) => { + (ref s, Some(span)) => { cx.sess.span_note( span, - format!("{}{}{}", prefix, *str, suffix).as_slice()); + format!("{}{}{}", prefix, *s, suffix).as_slice()); Some(span) } - (ref str, None) => { + (ref s, None) => { cx.sess.note( - format!("{}{}{}", prefix, *str, suffix).as_slice()); + format!("{}{}{}", prefix, *s, suffix).as_slice()); None } } From d3d537433994d0950b59c5bd79ef39b9b9b2c717 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 20:22:27 -0500 Subject: [PATCH 24/39] librustc_trans: fix fallout --- src/librustc_trans/back/link.rs | 4 ++-- src/librustc_trans/back/write.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 6057f9d90819..c2dcda084e3f 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -29,7 +29,7 @@ use std::io::fs::PathExtensions; use std::io::{fs, TempDir, Command}; use std::io; use std::mem; -use std::str; +use std::str as str_; use std::string::String; use flate; use serialize::hex::ToHex; @@ -794,7 +794,7 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool, sess.note(format!("{}", &cmd).as_slice()); let mut output = prog.error.clone(); output.push_all(prog.output.as_slice()); - sess.note(str::from_utf8(output.as_slice()).unwrap()); + sess.note(str_::from_utf8(output.as_slice()).unwrap()); sess.abort_if_errors(); } debug!("linker stderr:\n{}", String::from_utf8(prog.error).unwrap()); diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index e5ffe2675d6f..8dfc23440cb8 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -27,7 +27,7 @@ use std::io::Command; use std::io::fs; use std::iter::Unfold; use std::ptr; -use std::str; +use std::str as str_; use std::mem; use std::sync::{Arc, Mutex}; use std::task::TaskBuilder; @@ -930,7 +930,7 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) { sess.note(format!("{}", &cmd).as_slice()); let mut note = prog.error.clone(); note.push_all(prog.output.as_slice()); - sess.note(str::from_utf8(note.as_slice()).unwrap()); + sess.note(str_::from_utf8(note.as_slice()).unwrap()); sess.abort_if_errors(); } }, From 99fb6c1a3ff7f6cde562d2014e3b16620bada513 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 21:30:46 -0500 Subject: [PATCH 25/39] librustdoc: kill `ty_str` and `TyStr` --- src/librustdoc/clean/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7e02891160ad..e41a47255706 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1322,7 +1322,6 @@ impl<'tcx> Clean for ty::Ty<'tcx> { ty::ty_uint(ast::TyU64) => Primitive(U64), ty::ty_float(ast::TyF32) => Primitive(F32), ty::ty_float(ast::TyF64) => Primitive(F64), - ty::ty_str => Primitive(Str), ty::ty_uniq(t) => { let box_did = cx.tcx_opt().and_then(|tcx| { tcx.lang_items.owned_box() @@ -2161,7 +2160,6 @@ fn resolve_type(cx: &DocContext, match def { def::DefSelfTy(i) => return Self(ast_util::local_def(i)), def::DefPrimTy(p) => match p { - ast::TyStr => return Primitive(Str), ast::TyBool => return Primitive(Bool), ast::TyChar => return Primitive(Char), ast::TyInt(ast::TyI) => return Primitive(Int), From d11d28da99fe49f1659e351d3e55cc7be5d66eb7 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 21:43:44 -0500 Subject: [PATCH 26/39] librustdoc: fix fallout --- src/librustdoc/html/markdown.rs | 12 ++++++------ src/librustdoc/html/render.rs | 4 ++-- src/librustdoc/test.rs | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index df25daa3ca1a..c06325a44587 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -32,7 +32,7 @@ use std::ascii::AsciiExt; use std::cell::{RefCell, Cell}; use std::fmt; use std::slice; -use std::str; +use std::str as str_; use std::collections::HashMap; use html::toc::TocBuilder; @@ -166,14 +166,14 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { let my_opaque: &MyOpaque = &*((*opaque).opaque as *const MyOpaque); let text = slice::from_raw_buf(&(*orig_text).data, (*orig_text).size as uint); - let origtext = str::from_utf8(text).unwrap(); + let origtext = str_::from_utf8(text).unwrap(); debug!("docblock: ==============\n{}\n=======", text); let rendered = if lang.is_null() { false } else { let rlang = slice::from_raw_buf(&(*lang).data, (*lang).size as uint); - let rlang = str::from_utf8(rlang).unwrap(); + let rlang = str_::from_utf8(rlang).unwrap(); if LangString::parse(rlang).notrust { (my_opaque.dfltblk)(ob, orig_text, lang, opaque as *mut libc::c_void); @@ -317,14 +317,14 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) { } else { let lang = slice::from_raw_buf(&(*lang).data, (*lang).size as uint); - let s = str::from_utf8(lang).unwrap(); + let s = str_::from_utf8(lang).unwrap(); LangString::parse(s) }; if block_info.notrust { return } let text = slice::from_raw_buf(&(*text).data, (*text).size as uint); let opaque = opaque as *mut hoedown_html_renderer_state; let tests = &mut *((*opaque).opaque as *mut ::test::Collector); - let text = str::from_utf8(text).unwrap(); + let text = str_::from_utf8(text).unwrap(); let lines = text.lines().map(|l| { stripped_filtered_line(l).unwrap_or(l) }); @@ -345,7 +345,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) { tests.register_header("", level as u32); } else { let text = slice::from_raw_buf(&(*text).data, (*text).size as uint); - let text = str::from_utf8(text).unwrap(); + let text = str_::from_utf8(text).unwrap(); tests.register_header(text, level as u32); } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 9eee8e04f0c2..3ea98ba6c2d6 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -42,7 +42,7 @@ use std::fmt; use std::io::fs::PathExtensions; use std::io::{fs, File, BufferedWriter, BufferedReader}; use std::io; -use std::str; +use std::str as str_; use std::string::String; use std::sync::Arc; @@ -739,7 +739,7 @@ impl<'a> SourceCollector<'a> { filename.ends_with("macros>") => return Ok(()), Err(e) => return Err(e) }; - let contents = str::from_utf8(contents.as_slice()).unwrap(); + let contents = str_::from_utf8(contents.as_slice()).unwrap(); // Remove the utf-8 BOM if any let contents = if contents.starts_with("\ufeff") { diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 7ca7ae4b2114..3ec8e00b44b4 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -13,7 +13,7 @@ use std::dynamic_lib::DynamicLibrary; use std::io::{Command, TempDir}; use std::io; use std::os; -use std::str; +use std::str as str_; use std::string::String; use std::collections::{HashSet, HashMap}; @@ -198,7 +198,7 @@ fn runtest(test: &str, cratename: &str, libs: Vec, externs: core::Externs, panic!("test executable succeeded when it should have failed"); } else if !should_fail && !out.status.success() { panic!("test executable failed:\n{}", - str::from_utf8(out.error.as_slice())); + str_::from_utf8(out.error.as_slice())); } } } From ca8649f1e35831b8b1a520d84916faa175248909 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 5 Dec 2014 22:35:11 -0500 Subject: [PATCH 27/39] compiletest: fix fallout --- src/compiletest/runtest.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 5c3e5e12adbc..7a6193a0eb8f 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -30,7 +30,7 @@ use std::io::process; use std::io::timer; use std::io; use std::os; -use std::str; +use std::str as str_; use std::string::String; use std::task; use std::time::Duration; @@ -426,7 +426,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { gdbserver :5039 {}/{}", config.adb_test_dir.clone(), config.adb_test_dir.clone(), - str::from_utf8( + str_::from_utf8( exe_file.filename() .unwrap()).unwrap()); @@ -1731,7 +1731,7 @@ fn disassemble_extract(config: &Config, _props: &TestProps, fn count_extracted_lines(p: &Path) -> uint { let x = File::open(&p.with_extension("ll")).read_to_end().unwrap(); - let x = str::from_utf8(x.as_slice()).unwrap(); + let x = str_::from_utf8(x.as_slice()).unwrap(); x.lines().count() } From c73df951233b349e9dce04280a0d76da528cd160 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 6 Dec 2014 08:34:33 -0500 Subject: [PATCH 28/39] Fix run-pass tests --- src/test/auxiliary/lang-item-public.rs | 3 +++ src/test/auxiliary/weak-lang-items.rs | 2 +- src/test/run-pass/backtrace.rs | 10 +++++----- src/test/run-pass/core-run-destroy.rs | 2 -- src/test/run-pass/foreign-fn-linkname.rs | 4 ++-- src/test/run-pass/issue-18353.rs | 4 ++-- src/test/run-pass/move-out-of-field.rs | 4 ++-- 7 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/test/auxiliary/lang-item-public.rs b/src/test/auxiliary/lang-item-public.rs index ea2461ccfa8e..67b5d10bae28 100644 --- a/src/test/auxiliary/lang-item-public.rs +++ b/src/test/auxiliary/lang-item-public.rs @@ -14,6 +14,9 @@ #[lang="sized"] pub trait Sized for Sized? {} +#[lang="str"] +struct str([u8]); + #[lang="panic"] fn panic(_: &(&'static str, &'static str, uint)) -> ! { loop {} } diff --git a/src/test/auxiliary/weak-lang-items.rs b/src/test/auxiliary/weak-lang-items.rs index 6a1f8588b60d..59e9813b9676 100644 --- a/src/test/auxiliary/weak-lang-items.rs +++ b/src/test/auxiliary/weak-lang-items.rs @@ -32,6 +32,6 @@ pub fn foo() { } mod std { - pub use core::{option, fmt}; + pub use core::{option, fmt, str}; } diff --git a/src/test/run-pass/backtrace.rs b/src/test/run-pass/backtrace.rs index a267b8dcc86d..718296c8c405 100644 --- a/src/test/run-pass/backtrace.rs +++ b/src/test/run-pass/backtrace.rs @@ -13,7 +13,7 @@ use std::os; use std::io::process::Command; use std::finally::Finally; -use std::str; +use std::str as str_; #[inline(never)] fn foo() { @@ -40,7 +40,7 @@ fn runtest(me: &str) { let p = template.clone().arg("fail").env("RUST_BACKTRACE", "1").spawn().unwrap(); let out = p.wait_with_output().unwrap(); assert!(!out.status.success()); - let s = str::from_utf8(out.error.as_slice()).unwrap(); + let s = str_::from_utf8(out.error.as_slice()).unwrap(); assert!(s.contains("stack backtrace") && s.contains("foo::h"), "bad output: {}", s); @@ -48,7 +48,7 @@ fn runtest(me: &str) { let p = template.clone().arg("fail").spawn().unwrap(); let out = p.wait_with_output().unwrap(); assert!(!out.status.success()); - let s = str::from_utf8(out.error.as_slice()).unwrap(); + let s = str_::from_utf8(out.error.as_slice()).unwrap(); assert!(!s.contains("stack backtrace") && !s.contains("foo::h"), "bad output2: {}", s); @@ -56,7 +56,7 @@ fn runtest(me: &str) { let p = template.clone().arg("double-fail").spawn().unwrap(); let out = p.wait_with_output().unwrap(); assert!(!out.status.success()); - let s = str::from_utf8(out.error.as_slice()).unwrap(); + let s = str_::from_utf8(out.error.as_slice()).unwrap(); // loosened the following from double::h to double:: due to // spurious failures on mac, 32bit, optimized assert!(s.contains("stack backtrace") && s.contains("double::"), @@ -67,7 +67,7 @@ fn runtest(me: &str) { .env("RUST_BACKTRACE", "1").spawn().unwrap(); let out = p.wait_with_output().unwrap(); assert!(!out.status.success()); - let s = str::from_utf8(out.error.as_slice()).unwrap(); + let s = str_::from_utf8(out.error.as_slice()).unwrap(); let mut i = 0; for _ in range(0i, 2) { i += s.slice_from(i + 10).find_str("stack backtrace").unwrap() + 10; diff --git a/src/test/run-pass/core-run-destroy.rs b/src/test/run-pass/core-run-destroy.rs index d8dfb433e6d4..011352012e82 100644 --- a/src/test/run-pass/core-run-destroy.rs +++ b/src/test/run-pass/core-run-destroy.rs @@ -22,7 +22,6 @@ extern crate libc; use std::io::{Process, Command, timer}; use std::time::Duration; -use std::str; macro_rules! succeed( ($e:expr) => ( match $e { Ok(..) => {}, Err(e) => panic!("panic: {}", e) } @@ -58,7 +57,6 @@ pub fn test_destroy_actually_kills(force: bool) { use std::io::process::{Command, ProcessOutput, ExitStatus, ExitSignal}; use std::io::timer; use libc; - use std::str; #[cfg(all(unix,not(target_os="android")))] static BLOCK_COMMAND: &'static str = "cat"; diff --git a/src/test/run-pass/foreign-fn-linkname.rs b/src/test/run-pass/foreign-fn-linkname.rs index 750c0c8ed682..e6168da84dfb 100644 --- a/src/test/run-pass/foreign-fn-linkname.rs +++ b/src/test/run-pass/foreign-fn-linkname.rs @@ -22,9 +22,9 @@ mod mlibc { } } -fn strlen(str: String) -> uint { +fn strlen(s: String) -> uint { // C string is terminated with a zero - str.as_slice().with_c_str(|buf| { + s.as_slice().with_c_str(|buf| { unsafe { mlibc::my_strlen(buf) as uint } diff --git a/src/test/run-pass/issue-18353.rs b/src/test/run-pass/issue-18353.rs index c734c1a32224..7d516ed2043e 100644 --- a/src/test/run-pass/issue-18353.rs +++ b/src/test/run-pass/issue-18353.rs @@ -16,6 +16,6 @@ struct Str { } fn main() { - let str: Option<&Str> = None; - str.is_some(); + let s: Option<&Str> = None; + s.is_some(); } diff --git a/src/test/run-pass/move-out-of-field.rs b/src/test/run-pass/move-out-of-field.rs index 92c5e025b9b2..5658eda4792f 100644 --- a/src/test/run-pass/move-out-of-field.rs +++ b/src/test/run-pass/move-out-of-field.rs @@ -30,6 +30,6 @@ pub fn main() { }; sb.append("Hello, "); sb.append("World!"); - let str = to_string(sb); - assert_eq!(str.as_slice(), "Hello, World!"); + let s = to_string(sb); + assert_eq!(s.as_slice(), "Hello, World!"); } From fd0a965d052f82e4615d6b77a245dc6c8f882c17 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 6 Dec 2014 10:20:05 -0500 Subject: [PATCH 29/39] FIXME I broke run-pass/unsized3 --- src/test/run-pass/unsized3.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/run-pass/unsized3.rs b/src/test/run-pass/unsized3.rs index e5e6ce6e76bb..df91a4a79afb 100644 --- a/src/test/run-pass/unsized3.rs +++ b/src/test/run-pass/unsized3.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-test // Test structs with always-unsized fields. use std::mem; From c373b72930e4d597d029cf24542f72b36ba99570 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 6 Dec 2014 10:47:13 -0500 Subject: [PATCH 30/39] Fix compile-fail tests --- src/test/compile-fail/bad-mid-path-type-params.rs | 3 +++ src/test/compile-fail/const-cast-different-types.rs | 4 ++-- src/test/compile-fail/dst-object-from-unsized-type.rs | 4 ++-- src/test/compile-fail/issue-14366.rs | 4 ++-- src/test/compile-fail/issue-14721.rs | 2 +- src/test/compile-fail/issue-15783.rs | 2 +- src/test/compile-fail/issue-16338.rs | 2 +- src/test/compile-fail/issue-2149.rs | 2 +- src/test/compile-fail/privacy1.rs | 3 +++ .../regions-bounded-method-type-parameters-trait-bound.rs | 3 +++ src/test/compile-fail/regions-struct-not-wf.rs | 4 ++++ src/test/compile-fail/repeat_count.rs | 2 +- src/test/compile-fail/stage0-clone-contravariant-lifetime.rs | 3 +++ src/test/compile-fail/str-idx.rs | 2 +- 14 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/test/compile-fail/bad-mid-path-type-params.rs b/src/test/compile-fail/bad-mid-path-type-params.rs index 3a2a75586576..4a6254b6f24c 100644 --- a/src/test/compile-fail/bad-mid-path-type-params.rs +++ b/src/test/compile-fail/bad-mid-path-type-params.rs @@ -16,6 +16,9 @@ #[lang="sized"] pub trait Sized {} +#[lang = "str"] +struct str([u8]); + struct S { contents: T, } diff --git a/src/test/compile-fail/const-cast-different-types.rs b/src/test/compile-fail/const-cast-different-types.rs index 6b8e126db779..34ec09830ed3 100644 --- a/src/test/compile-fail/const-cast-different-types.rs +++ b/src/test/compile-fail/const-cast-different-types.rs @@ -10,9 +10,9 @@ static a: &'static str = "foo"; static b: *const u8 = a as *const u8; -//~^ ERROR mismatched types: expected `*const u8`, found `&'static str` +//~^ ERROR mismatched types: expected `*const u8`, found `&'static core::str::str` static c: *const u8 = &a as *const u8; -//~^ ERROR mismatched types: expected `*const u8`, found `&&'static str` +//~^ ERROR mismatched types: expected `*const u8`, found `&&'static core::str::str` fn main() { } diff --git a/src/test/compile-fail/dst-object-from-unsized-type.rs b/src/test/compile-fail/dst-object-from-unsized-type.rs index 99c63c3c6e95..51e4f1060867 100644 --- a/src/test/compile-fail/dst-object-from-unsized-type.rs +++ b/src/test/compile-fail/dst-object-from-unsized-type.rs @@ -25,12 +25,12 @@ fn test2(t: &T) { fn test3() { let _: &[&Foo] = &["hi"]; - //~^ ERROR `core::kinds::Sized` is not implemented for the type `str` + //~^ ERROR `core::kinds::Sized` is not implemented for the type `core::str::str` } fn test4() { let _: &Foo = "hi" as &Foo; - //~^ ERROR `core::kinds::Sized` is not implemented for the type `str` + //~^ ERROR `core::kinds::Sized` is not implemented for the type `core::str::str` } fn main() { } diff --git a/src/test/compile-fail/issue-14366.rs b/src/test/compile-fail/issue-14366.rs index 01a15023fbaa..a9025cc1bb90 100644 --- a/src/test/compile-fail/issue-14366.rs +++ b/src/test/compile-fail/issue-14366.rs @@ -10,6 +10,6 @@ fn main() { let _x = "test" as &::std::any::Any; -//~^ ERROR the trait `core::kinds::Sized` is not implemented for the type `str` -//~^^ ERROR the trait `core::kinds::Sized` is not implemented for the type `str` +//~^ ERROR the trait `core::kinds::Sized` is not implemented for the type `core::str::str` +//~^^ ERROR the trait `core::kinds::Sized` is not implemented for the type `core::str::str` } diff --git a/src/test/compile-fail/issue-14721.rs b/src/test/compile-fail/issue-14721.rs index 92add18f9413..8fc3e89bd980 100644 --- a/src/test/compile-fail/issue-14721.rs +++ b/src/test/compile-fail/issue-14721.rs @@ -10,6 +10,6 @@ fn main() { let foo = "str"; - println!("{}", foo.desc); //~ ERROR attempted access of field `desc` on type `&str`, + println!("{}", foo.desc); //~ ERROR attempted access of field `desc` on type `&core::str::str`, // but no field with that name was found } diff --git a/src/test/compile-fail/issue-15783.rs b/src/test/compile-fail/issue-15783.rs index 32a920baa31b..d838d0dbe751 100644 --- a/src/test/compile-fail/issue-15783.rs +++ b/src/test/compile-fail/issue-15783.rs @@ -15,6 +15,6 @@ pub fn foo(params: Option<&[&str]>) -> uint { fn main() { let name = "Foo"; let msg = foo(Some(&[name.as_slice()])); -//~^ ERROR mismatched types: expected `core::option::Option<&[&str]>` +//~^ ERROR mismatched types: expected `core::option::Option<&[&core::str::str]>` assert_eq!(msg, 3); } diff --git a/src/test/compile-fail/issue-16338.rs b/src/test/compile-fail/issue-16338.rs index f62bccb22f35..391540df2aa3 100644 --- a/src/test/compile-fail/issue-16338.rs +++ b/src/test/compile-fail/issue-16338.rs @@ -12,7 +12,7 @@ use std::raw::Slice; fn main() { let Slice { data: data, len: len } = "foo"; - //~^ ERROR mismatched types: expected `&str`, found `core::raw::Slice<_>` + //~^ ERROR mismatched types: expected `&core::str::str`, found `core::raw::Slice<_>` // (expected &-ptr, found struct core::raw::Slice) } diff --git a/src/test/compile-fail/issue-2149.rs b/src/test/compile-fail/issue-2149.rs index 1150f40db762..a93fc1132226 100644 --- a/src/test/compile-fail/issue-2149.rs +++ b/src/test/compile-fail/issue-2149.rs @@ -22,5 +22,5 @@ impl vec_monad for Vec { } fn main() { ["hi"].bind(|x| [x] ); - //~^ ERROR type `[&str, ..1]` does not implement any method in scope named `bind` + //~^ ERROR type `[&core::str::str, ..1]` does not implement any method in scope named `bind` } diff --git a/src/test/compile-fail/privacy1.rs b/src/test/compile-fail/privacy1.rs index 50261839b16c..1e0132e16e64 100644 --- a/src/test/compile-fail/privacy1.rs +++ b/src/test/compile-fail/privacy1.rs @@ -14,6 +14,9 @@ #[lang="sized"] pub trait Sized {} +#[lang = "str"] +struct str([u8]); + mod bar { // shouldn't bring in too much pub use self::glob::*; diff --git a/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs b/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs index e628eb3285ae..67b730a98692 100644 --- a/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs +++ b/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs @@ -18,6 +18,9 @@ #[lang="sized"] trait Sized { } +#[lang = "str"] +struct str([u8]); + struct Inv<'a> { // invariant w/r/t 'a x: &'a mut &'a int } diff --git a/src/test/compile-fail/regions-struct-not-wf.rs b/src/test/compile-fail/regions-struct-not-wf.rs index 3de137a9efbd..d5c835d43dd4 100644 --- a/src/test/compile-fail/regions-struct-not-wf.rs +++ b/src/test/compile-fail/regions-struct-not-wf.rs @@ -12,6 +12,10 @@ #![no_std] #![allow(dead_code)] +#![feature(lang_items)] + +#[lang = "str"] +struct str([u8]); struct Ref<'a, T> { //~ ERROR the parameter type `T` may not live long enough field: &'a T diff --git a/src/test/compile-fail/repeat_count.rs b/src/test/compile-fail/repeat_count.rs index 38fbb426fb19..aceb63bec490 100644 --- a/src/test/compile-fail/repeat_count.rs +++ b/src/test/compile-fail/repeat_count.rs @@ -21,7 +21,7 @@ fn main() { let d = [0, ..0.5]; //~ ERROR expected positive integer for repeat count, found float //~^ ERROR: expected `uint`, found `_` let e = [0, .."foo"]; //~ ERROR expected positive integer for repeat count, found string - //~^ ERROR: expected `uint`, found `&'static str` + //~^ ERROR: expected `uint`, found `&'static core::str::str` let f = [0, ..-4]; //~^ ERROR expected positive integer for repeat count, found negative integer let f = [0u, ..-1]; diff --git a/src/test/compile-fail/stage0-clone-contravariant-lifetime.rs b/src/test/compile-fail/stage0-clone-contravariant-lifetime.rs index 1d1b244ab5ae..4c9b7967f4ee 100644 --- a/src/test/compile-fail/stage0-clone-contravariant-lifetime.rs +++ b/src/test/compile-fail/stage0-clone-contravariant-lifetime.rs @@ -23,6 +23,9 @@ pub trait Sized for Sized? { // Empty. } +#[lang = "str"] +struct str([u8]); + pub mod std { pub mod clone { pub trait Clone { diff --git a/src/test/compile-fail/str-idx.rs b/src/test/compile-fail/str-idx.rs index 424ffed989b3..688e4f2fed6d 100644 --- a/src/test/compile-fail/str-idx.rs +++ b/src/test/compile-fail/str-idx.rs @@ -10,5 +10,5 @@ pub fn main() { let s: &str = "hello"; - let c: u8 = s[4]; //~ ERROR cannot index a value of type `&str` + let c: u8 = s[4]; //~ ERROR cannot index a value of type `&core::str::str` } From ce37ad918fc7ae5635526678f4078797026e0fa6 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 6 Dec 2014 10:51:30 -0500 Subject: [PATCH 31/39] libstd: fix unit tests --- src/libstd/ascii.rs | 1 + src/libstd/io/buffered.rs | 1 + src/libstd/io/fs.rs | 20 ++++++++++---------- src/libstd/io/mem.rs | 1 + src/libstd/path/posix.rs | 5 +++-- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 0e98cebb9ecd..875f5c207a3a 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -633,6 +633,7 @@ mod tests { use prelude::*; use super::*; use char::from_u32; + #[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot use str::StrPrelude; macro_rules! v2ascii ( diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index fba9e4f2e25e..7c39ca2c5349 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -408,6 +408,7 @@ mod test { use super::super::{IoResult, EndOfFile}; use super::super::mem::MemReader; use self::test::Bencher; + #[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot use str::StrPrelude; /// A type, free to create, primarily intended for benchmarking creation of diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs index f2e71a44b70c..9037f44e8235 100644 --- a/src/libstd/io/fs.rs +++ b/src/libstd/io/fs.rs @@ -822,11 +822,12 @@ mod test { use prelude::*; use io::{SeekSet, SeekCur, SeekEnd, Read, Open, ReadWrite, FileType}; use io; - use str; + use str as str_; use io::fs::*; use path::Path; use io; use ops::Drop; + #[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot use str::StrPrelude; macro_rules! check( ($e:expr) => ( @@ -889,7 +890,7 @@ mod test { let mut read_buf = [0, .. 1028]; let read_str = match check!(read_stream.read(&mut read_buf)) { -1|0 => panic!("shouldn't happen"), - n => str::from_utf8(read_buf[..n]).unwrap().to_string() + n => str_::from_utf8(read_buf[..n]).unwrap().to_string() }; assert_eq!(read_str.as_slice(), message); } @@ -945,7 +946,7 @@ mod test { } } check!(unlink(filename)); - let read_str = str::from_utf8(&read_mem).unwrap(); + let read_str = str_::from_utf8(&read_mem).unwrap(); assert_eq!(read_str, message); } @@ -970,7 +971,7 @@ mod test { tell_pos_post_read = check!(read_stream.tell()); } check!(unlink(filename)); - let read_str = str::from_utf8(&read_mem).unwrap(); + let read_str = str_::from_utf8(&read_mem).unwrap(); assert_eq!(read_str, message.slice(4, 8)); assert_eq!(tell_pos_pre_read, set_cursor); assert_eq!(tell_pos_post_read, message.len() as u64); @@ -996,13 +997,12 @@ mod test { check!(read_stream.read(&mut read_mem)); } check!(unlink(filename)); - let read_str = str::from_utf8(&read_mem).unwrap(); + let read_str = str_::from_utf8(&read_mem).unwrap(); assert!(read_str.as_slice() == final_msg.as_slice()); } #[test] fn file_test_io_seek_shakedown() { - use str; // 01234567890123 let initial_msg = "qwer-asdf-zxcv"; let chunk_one: &str = "qwer"; let chunk_two: &str = "asdf"; @@ -1019,15 +1019,15 @@ mod test { check!(read_stream.seek(-4, SeekEnd)); check!(read_stream.read(&mut read_mem)); - assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_three); + assert_eq!(str_::from_utf8(&read_mem).unwrap(), chunk_three); check!(read_stream.seek(-9, SeekCur)); check!(read_stream.read(&mut read_mem)); - assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_two); + assert_eq!(str_::from_utf8(&read_mem).unwrap(), chunk_two); check!(read_stream.seek(0, SeekSet)); check!(read_stream.read(&mut read_mem)); - assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_one); + assert_eq!(str_::from_utf8(&read_mem).unwrap(), chunk_one); } check!(unlink(filename)); } @@ -1114,7 +1114,7 @@ mod test { { let n = f.filestem_str(); check!(File::open(f).read(&mut mem)); - let read_str = str::from_utf8(&mem).unwrap(); + let read_str = str_::from_utf8(&mem).unwrap(); let expected = match n { None|Some("") => panic!("really shouldn't happen.."), Some(n) => format!("{}{}", prefix, n), diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs index c5cd95f8501f..5edb286771f3 100644 --- a/src/libstd/io/mem.rs +++ b/src/libstd/io/mem.rs @@ -404,6 +404,7 @@ mod test { use io::*; use io; use self::test::Bencher; + #[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot use str::StrPrelude; #[test] diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index d2462b1b3c2e..4b848c77d34b 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -445,7 +445,8 @@ static dot_dot_static: &'static [u8] = b".."; mod tests { use prelude::*; use super::*; - use str; + use str as str_; + #[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot use str::StrPrelude; macro_rules! t( @@ -609,7 +610,7 @@ mod tests { (s: $path:expr, $op:ident, $exp:expr, opt) => ( { let path = Path::new($path); - let left = path.$op().map(|x| str::from_utf8(x).unwrap()); + let left = path.$op().map(|x| str_::from_utf8(x).unwrap()); assert!(left == $exp); } ); From 47fb373d9bcb32b516bba07df9d4a83fdd6adf41 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 6 Dec 2014 11:20:56 -0500 Subject: [PATCH 32/39] libcollections: fix unit tests --- src/libcollections/bit.rs | 4 ++-- src/libcollections/hash/mod.rs | 1 + src/libcollections/str.rs | 1 + src/libcollections/string.rs | 12 +++++++----- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index 903a9bd98232..0f65232d036e 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -2028,8 +2028,8 @@ mod tests { #[test] fn test_from_bytes() { let bitv = from_bytes(&[0b10110110, 0b00000000, 0b11111111]); - let str = format!("{}{}{}", "10110110", "00000000", "11111111"); - assert_eq!(bitv.to_string().as_slice(), str.as_slice()); + let s = format!("{}{}{}", "10110110", "00000000", "11111111"); + assert_eq!(bitv.to_string().as_slice(), s.as_slice()); } #[test] diff --git a/src/libcollections/hash/mod.rs b/src/libcollections/hash/mod.rs index c481bdb8663d..283cd76c1e44 100644 --- a/src/libcollections/hash/mod.rs +++ b/src/libcollections/hash/mod.rs @@ -328,6 +328,7 @@ mod tests { #[test] fn test_writer_hasher() { use alloc::boxed::Box; + use core::str::str; let hasher = MyWriterHasher; diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index ee7e53682e4f..10e129d195a7 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -2336,6 +2336,7 @@ mod bench { use test::black_box; use super::*; use std::iter::{IteratorExt, DoubleEndedIteratorExt}; + #[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot use std::str::StrPrelude; use std::slice::SlicePrelude; diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 431a33b008e7..302d138d4cef 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -983,8 +983,10 @@ mod tests { use test::Bencher; use slice::CloneSliceAllocPrelude; - use str::{Str, StrPrelude}; - use str; + use str::Str; + #[cfg(stage0)] // NOTE(stage0): Remove import after a snapshot + use str::StrPrelude; + use str as str_; use super::{as_string, String, ToString}; use vec::Vec; @@ -1016,11 +1018,11 @@ mod tests { #[test] fn test_from_utf8_lossy() { let xs = b"hello"; - let ys: str::CowString = "hello".into_cow(); + let ys: str_::CowString = "hello".into_cow(); assert_eq!(String::from_utf8_lossy(xs), ys); let xs = "ศไทย中华Việt Nam".as_bytes(); - let ys: str::CowString = "ศไทย中华Việt Nam".into_cow(); + let ys: str_::CowString = "ศไทย中华Việt Nam".into_cow(); assert_eq!(String::from_utf8_lossy(xs), ys); let xs = b"Hello\xC2 There\xFF Goodbye"; @@ -1100,7 +1102,7 @@ mod tests { let s_as_utf16 = s.as_slice().utf16_units().collect::>(); let u_as_string = String::from_utf16(u.as_slice()).unwrap(); - assert!(str::is_utf16(u.as_slice())); + assert!(str_::is_utf16(u.as_slice())); assert_eq!(s_as_utf16, u); assert_eq!(u_as_string, s); From d49859fc739232dbfceffe6faa96e1787f50c0a9 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 6 Dec 2014 11:24:21 -0500 Subject: [PATCH 33/39] libgraphviz: fix unit tests --- src/libgraphviz/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 0a5081d07be0..13bf9058cd95 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -548,7 +548,6 @@ mod tests { use super::{Id, LabelText, LabelStr, EscStr, Labeller}; use super::{Nodes, Edges, GraphWalk, render}; use std::io::IoResult; - use std::str; /// each node is an index in a vector in the graph. type Node = uint; From 702031ce9cb60f5881872ffc325863ce0dbe1a8c Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 6 Dec 2014 11:39:35 -0500 Subject: [PATCH 34/39] libsyntax: fix unit tests --- src/libsyntax/ext/expand.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index a697d332d16a..6851b0d9e826 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1611,7 +1611,7 @@ mod test { fn run_renaming_test(t: &RenamingTest, test_idx: uint) { let invalid_name = token::special_idents::invalid.name; let (teststr, bound_connections, bound_ident_check) = match *t { - (ref str,ref conns, bic) => (str.to_string(), conns.clone(), bic) + (ref s,ref conns, bic) => (s.to_string(), conns.clone(), bic) }; let cr = expand_crate_str(teststr.to_string()); let bindings = crate_bindings(&cr); From de8d4a43a8f5c6ac21bd7cf19093a1efe9950088 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 6 Dec 2014 13:56:51 -0500 Subject: [PATCH 35/39] libserialize: fix doc tests --- src/libserialize/base64.rs | 4 ++-- src/libserialize/hex.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libserialize/base64.rs b/src/libserialize/base64.rs index b7d8885a5f99..e693a7700cd6 100644 --- a/src/libserialize/base64.rs +++ b/src/libserialize/base64.rs @@ -73,8 +73,8 @@ impl ToBase64 for [u8] { /// use serialize::base64::{ToBase64, STANDARD}; /// /// fn main () { - /// let str = [52,32].to_base64(STANDARD); - /// println!("base 64 output: {}", str); + /// let s = [52,32].to_base64(STANDARD); + /// println!("base 64 output: {}", s); /// } /// ``` fn to_base64(&self, config: Config) -> String { diff --git a/src/libserialize/hex.rs b/src/libserialize/hex.rs index 2a3c410ba7c5..09b74400a7fc 100644 --- a/src/libserialize/hex.rs +++ b/src/libserialize/hex.rs @@ -36,8 +36,8 @@ impl ToHex for [u8] { /// use serialize::hex::ToHex; /// /// fn main () { - /// let str = [52,32].to_hex(); - /// println!("{}", str); + /// let s = [52,32].to_hex(); + /// println!("{}", s); /// } /// ``` fn to_hex(&self) -> String { From f53120df3e526f324ef7a85c9a12807ac642b022 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 6 Dec 2014 14:47:46 -0500 Subject: [PATCH 36/39] Fix bench --- src/test/bench/shootout-chameneos-redux.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index 3059a014528a..386c47886197 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -56,12 +56,12 @@ fn print_complements() { enum Color { Red, Yellow, Blue } impl fmt::Show for Color { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let str = match *self { + let s = match *self { Red => "red", Yellow => "yellow", Blue => "blue", }; - write!(f, "{}", str) + write!(f, "{}", s) } } From 7620208b0cccda5c4201a27ef59749f0607bfa8f Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 6 Dec 2014 15:57:47 -0500 Subject: [PATCH 37/39] Fix guides --- src/doc/guide-strings.md | 4 ++-- src/doc/guide-unsafe.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/guide-strings.md b/src/doc/guide-strings.md index 071c9ff013c5..ad29fdac65f1 100644 --- a/src/doc/guide-strings.md +++ b/src/doc/guide-strings.md @@ -65,10 +65,10 @@ fn main() { You can also get a `&str` from a stack-allocated array of bytes: ```{rust} -use std::str; +use std::str as str_; let x: &[u8] = &[b'a', b'b']; -let stack_str: &str = str::from_utf8(x).unwrap(); +let stack_str: &str = str_::from_utf8(x).unwrap(); ``` # Best Practices diff --git a/src/doc/guide-unsafe.md b/src/doc/guide-unsafe.md index 5b248126c80f..c955d1518b7c 100644 --- a/src/doc/guide-unsafe.md +++ b/src/doc/guide-unsafe.md @@ -567,7 +567,7 @@ pub extern fn dot_product(a: *const u32, a_len: u32, #[lang = "panic_fmt"] extern fn panic_fmt(args: &core::fmt::Arguments, - file: &str, + file: &core::str::str, line: uint) -> ! { loop {} } From 80ca6e5c0464bdf1e9e018ba3a1703d0b718715b Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 6 Dec 2014 18:04:56 -0500 Subject: [PATCH 38/39] Fix pretty test --- src/test/pretty/issue-4264.pp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp index 94a168a74ebb..dc61777028e3 100644 --- a/src/test/pretty/issue-4264.pp +++ b/src/test/pretty/issue-4264.pp @@ -38,21 +38,22 @@ () => { #[inline] #[allow(dead_code)] - static __STATIC_FMTSTR: &'static [&'static str] = - (&([("test" as &'static str)] as [&'static str, ..1]) as - &'static [&'static str, ..1]); + static __STATIC_FMTSTR: &'static [&'static ::std::str::str] = + (&([("test" as &'static core::str::str)] as + [&'static core::str::str, ..1]) as + &'static [&'static core::str::str, ..1]); let __args_vec = (&([] as [core::fmt::Argument<'_>, ..0]) as &[core::fmt::Argument<'_>, ..0]); let __args = (unsafe { ((::std::fmt::Arguments::new as - unsafe fn(&'static [&'static str], &'a [core::fmt::Argument<'a>]) -> core::fmt::Arguments<'a>)((__STATIC_FMTSTR - as - &'static [&'static str]), - (__args_vec - as - &[core::fmt::Argument<'_>, ..0])) + unsafe fn(&'static [&'static core::str::str], &'a [core::fmt::Argument<'a>]) -> core::fmt::Arguments<'a>)((__STATIC_FMTSTR + as + &'static [&'static core::str::str]), + (__args_vec + as + &[core::fmt::Argument<'_>, ..0])) as core::fmt::Arguments<'_>) } as core::fmt::Arguments<'_>); From cebddbb9ff339d761ef8e7176f7b1ee9ccd426f6 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 6 Dec 2014 18:55:52 -0500 Subject: [PATCH 39/39] libstd: fix fallout --- src/libstd/sync/poison.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libstd/sync/poison.rs b/src/libstd/sync/poison.rs index eb46fd771477..4bc04a4ca722 100644 --- a/src/libstd/sync/poison.rs +++ b/src/libstd/sync/poison.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot +use core::str::str; use option::None; use rustrt::task::Task; use rustrt::local::Local;