From d21336ee0a3982bdc35f17cdc32b41f6de5603d4 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 19 Jun 2014 18:22:33 -0700 Subject: [PATCH] rustc: Remove `&str` indexing from the language. Being able to index into the bytes of a string encourages poor UTF-8 hygiene. To get a view of `&[u8]` from either a `String` or `&str` slice, use the `as_bytes()` method. Closes #12710. [breaking-change] --- src/libcollections/str.rs | 4 +- src/libcollections/string.rs | 2 +- src/libcore/str.rs | 30 ++++++------ src/libgetopts/lib.rs | 4 +- src/librustc/back/link.rs | 10 ++-- src/librustc/metadata/decoder.rs | 6 +-- src/librustc/middle/dead.rs | 2 +- src/librustc/middle/liveness.rs | 2 +- src/librustc/middle/mem_categorization.rs | 7 +-- src/librustc/middle/ty.rs | 15 ++++++ src/libstd/io/fs.rs | 4 +- src/libstd/path/windows.rs | 46 ++++++++++--------- src/libsyntax/diagnostic.rs | 2 +- src/libsyntax/parse/lexer/mod.rs | 4 +- src/libtime/lib.rs | 2 +- src/libuuid/lib.rs | 4 +- src/test/bench/shootout-k-nucleotide-pipes.rs | 2 +- src/test/compile-fail/integral-indexing.rs | 12 ++--- .../{run-pass => compile-fail}/str-idx.rs | 6 +-- src/test/run-fail/str-overrun.rs | 2 +- src/test/run-pass/estr-slice.rs | 4 +- src/test/run-pass/estr-uniq.rs | 4 +- src/test/run-pass/str-concat.rs | 2 +- src/test/run-pass/task-comm-16.rs | 8 ++-- src/test/run-pass/trait-bounds-in-arc.rs | 2 +- src/test/run-pass/utf8.rs | 2 +- 26 files changed, 101 insertions(+), 87 deletions(-) rename src/test/{run-pass => compile-fail}/str-idx.rs (80%) diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index aa2b38cfa9d..fd8ce11d0b5 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -1569,8 +1569,8 @@ fn vec_str_conversions() { let n2: uint = v.len(); assert_eq!(n1, n2); while i < n1 { - let a: u8 = s1.as_slice()[i]; - let b: u8 = s2.as_slice()[i]; + let a: u8 = s1.as_bytes()[i]; + let b: u8 = s2.as_bytes()[i]; debug!("{}", a); debug!("{}", b); assert_eq!(a, b); diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 6d1fc43a4f1..936e60388a6 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -222,7 +222,7 @@ pub unsafe fn pop_byte(&mut self) -> Option { return None } - let byte = self.as_slice()[len - 1]; + let byte = self.as_bytes()[len - 1]; self.vec.set_len(len - 1); Some(byte) } diff --git a/src/libcore/str.rs b/src/libcore/str.rs index b336c57efa0..94df7a5a6c2 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -1743,7 +1743,7 @@ fn lines(&self) -> CharSplits<'a, char> { fn lines_any(&self) -> AnyLines<'a> { self.lines().map(|line| { let l = line.len(); - if l > 0 && line[l - 1] == '\r' as u8 { line.slice(0, l - 1) } + if l > 0 && line.as_bytes()[l - 1] == '\r' as u8 { line.slice(0, l - 1) } else { line } }) } @@ -1867,26 +1867,26 @@ fn trim_right_chars(&self, mut to_trim: C) -> &'a str { fn is_char_boundary(&self, index: uint) -> bool { if index == self.len() { return true; } if index > self.len() { return false; } - let b = self[index]; + let b = self.as_bytes()[index]; return b < 128u8 || b >= 192u8; } #[inline] fn char_range_at(&self, i: uint) -> CharRange { - if self[i] < 128u8 { - return CharRange {ch: self[i] as char, next: i + 1 }; + 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[i] as u32; + 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[i + 1]); - if w > 2 { val = utf8_acc_cont_byte!(val, s[i + 2]); } - if w > 3 { val = utf8_acc_cont_byte!(val, s[i + 3]); } + 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}; } @@ -1899,23 +1899,25 @@ fn char_range_at_reverse(&self, start: uint) -> CharRange { let mut prev = start; prev = prev.saturating_sub(1); - if self[prev] < 128 { return CharRange{ch: self[prev] as char, next: prev} } + 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[i] & 192u8 == TAG_CONT_U8 { + while i > 0 && s.as_bytes()[i] & 192u8 == TAG_CONT_U8 { i -= 1u; } - let mut val = s[i] as u32; + 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[i + 1]); - if w > 2 { val = utf8_acc_cont_byte!(val, s[i + 2]); } - if w > 3 { val = utf8_acc_cont_byte!(val, s[i + 3]); } + 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}; } diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index 240f5c007fa..0e525bc46e7 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -370,7 +370,7 @@ pub fn opt_default(&self, nm: &str, def: &str) -> Option { } fn is_arg(arg: &str) -> bool { - arg.len() > 1 && arg[0] == '-' as u8 + arg.len() > 1 && arg.as_bytes()[0] == '-' as u8 } fn find_opt(opts: &[Opt], nm: Name) -> Option { @@ -553,7 +553,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result { } else { let mut names; let mut i_arg = None; - if cur.as_slice()[1] == '-' as u8 { + if cur.as_bytes()[1] == '-' as u8 { let tail = cur.as_slice().slice(2, curlen); let tail_eq: Vec<&str> = tail.split('=').collect(); if tail_eq.len() <= 1 { diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index b4af291b7ea..17f29639601 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -657,8 +657,8 @@ pub fn sanitize(s: &str) -> String { // Underscore-qualify anything that didn't start as an ident. if result.len() > 0u && - result.as_slice()[0] != '_' as u8 && - ! char::is_XID_start(result.as_slice()[0] as char) { + result.as_bytes()[0] != '_' as u8 && + ! char::is_XID_start(result.as_bytes()[0] as char) { return format!("_{}", result.as_slice()); } @@ -737,9 +737,9 @@ pub fn mangle_exported_name(ccx: &CrateContext, path: PathElems, let extra2 = id % EXTRA_CHARS.len(); let id = id / EXTRA_CHARS.len(); let extra3 = id % EXTRA_CHARS.len(); - hash.push_char(EXTRA_CHARS[extra1] as char); - hash.push_char(EXTRA_CHARS[extra2] as char); - hash.push_char(EXTRA_CHARS[extra3] as char); + hash.push_char(EXTRA_CHARS.as_bytes()[extra1] as char); + hash.push_char(EXTRA_CHARS.as_bytes()[extra2] as char); + hash.push_char(EXTRA_CHARS.as_bytes()[extra3] as char); exported_name(path, hash.as_slice(), diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index f5ce8cda8c4..78a29b52bdf 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -181,7 +181,7 @@ fn item_sized(item: ebml::Doc) -> ast::Sized { fn item_method_sort(item: ebml::Doc) -> char { let mut ret = 'r'; reader::tagged_docs(item, tag_item_trait_method_sort, |doc| { - ret = doc.as_str_slice()[0] as char; + ret = doc.as_str_slice().as_bytes()[0] as char; false }); ret @@ -757,13 +757,13 @@ fn get_mutability(ch: u8) -> ast::Mutability { let explicit_self_doc = reader::get_doc(item, tag_item_trait_method_explicit_self); let string = explicit_self_doc.as_str_slice(); - let explicit_self_kind = string[0]; + let explicit_self_kind = string.as_bytes()[0]; match explicit_self_kind as char { 's' => ast::SelfStatic, 'v' => ast::SelfValue, '~' => ast::SelfUniq, // FIXME(#4846) expl. region - '&' => ast::SelfRegion(None, get_mutability(string[1])), + '&' => ast::SelfRegion(None, get_mutability(string.as_bytes()[1])), _ => fail!("unknown self type code: `{}`", explicit_self_kind as char) } } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 156b8840067..e7457f370d9 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -399,7 +399,7 @@ struct DeadVisitor<'a> { impl<'a> DeadVisitor<'a> { fn should_warn_about_field(&mut self, node: &ast::StructField_) -> bool { let (is_named, has_leading_underscore) = match node.ident() { - Some(ref ident) => (true, token::get_ident(*ident).get()[0] == ('_' as u8)), + Some(ref ident) => (true, token::get_ident(*ident).get().as_bytes()[0] == ('_' as u8)), _ => (false, false) }; let field_type = ty::node_id_to_type(self.tcx, node.id); diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 77cb5f667fd..5c09466cd96 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1511,7 +1511,7 @@ fn check_lvalue(&mut self, expr: &Expr) { fn should_warn(&self, var: Variable) -> Option { let name = self.ir.variable_name(var); - if name.len() == 0 || name.as_slice()[0] == ('_' as u8) { + if name.len() == 0 || name.as_bytes()[0] == ('_' as u8) { None } else { Some(name) diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index d26ccc40d3a..e1a2a5741fb 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -126,7 +126,6 @@ pub enum FieldName { #[deriving(Clone, PartialEq, Eq, Hash)] pub enum ElementKind { VecElement, - StrElement, OtherElement, } @@ -794,7 +793,7 @@ pub fn cat_index(&self, //! - `derefs`: the deref number to be used for //! the implicit index deref, if any (see above) - let element_ty = match ty::index(base_cmt.ty) { + let element_ty = match ty::array_element_ty(base_cmt.ty) { Some(ref mt) => mt.ty, None => { self.tcx().sess.span_bug( @@ -1137,9 +1136,6 @@ pub fn cmt_to_str(&self, cmt: &cmt_) -> String { cat_interior(_, InteriorElement(VecElement)) => { "vec content".to_string() } - cat_interior(_, InteriorElement(StrElement)) => { - "str content".to_string() - } cat_interior(_, InteriorElement(OtherElement)) => { "indexed content".to_string() } @@ -1320,7 +1316,6 @@ fn element_kind(t: ty::t) -> ElementKind { ty::ty_rptr(_, ty::mt{ty:ty, ..}) | ty::ty_uniq(ty) => match ty::get(ty).sty { ty::ty_vec(_, None) => VecElement, - ty::ty_str => StrElement, _ => OtherElement }, ty::ty_vec(..) => VecElement, diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8d84d089c01..04aa7ac8bfd 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2551,6 +2551,21 @@ pub fn deref(t: t, explicit: bool) -> Option { // Returns the type of t[i] pub fn index(t: t) -> Option { + match get(t).sty { + ty_vec(mt, Some(_)) => Some(mt), + ty_ptr(mt{ty: t, ..}) | ty_rptr(_, mt{ty: t, ..}) | + ty_box(t) | ty_uniq(t) => match get(t).sty { + ty_vec(mt, None) => Some(mt), + _ => None, + }, + _ => None + } +} + +// 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(t: t) -> Option { match get(t).sty { ty_vec(mt, Some(_)) => Some(mt), ty_ptr(mt{ty: t, ..}) | ty_rptr(_, mt{ty: t, ..}) | diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs index bc8447dfa2e..e7f26c7bd91 100644 --- a/src/libstd/io/fs.rs +++ b/src/libstd/io/fs.rs @@ -1206,8 +1206,8 @@ pub fn tmpdir() -> TempDir { let mut cur = [0u8, .. 2]; for f in files { let stem = f.filestem_str().unwrap(); - let root = stem[0] - ('0' as u8); - let name = stem[1] - ('0' as u8); + let root = stem.as_bytes()[0] - ('0' as u8); + let name = stem.as_bytes()[1] - ('0' as u8); assert!(cur[root as uint] < name); cur[root as uint] = name; } diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index ec225a588fc..113b0410875 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -242,14 +242,18 @@ unsafe fn push_unchecked(&mut self, path: T) { fn is_vol_abs(path: &str, prefix: Option) -> bool { // assume prefix is Some(DiskPrefix) let rest = path.slice_from(prefix_len(prefix)); - !rest.is_empty() && rest[0].is_ascii() && is_sep(rest[0] as char) + !rest.is_empty() && rest.as_bytes()[0].is_ascii() && is_sep(rest.as_bytes()[0] as char) } fn shares_volume(me: &Path, path: &str) -> bool { // path is assumed to have a prefix of Some(DiskPrefix) let repr = me.repr.as_slice(); match me.prefix { - Some(DiskPrefix) => repr[0] == path[0].to_ascii().to_upper().to_byte(), - Some(VerbatimDiskPrefix) => repr[4] == path[0].to_ascii().to_upper().to_byte(), + Some(DiskPrefix) => { + repr.as_bytes()[0] == path.as_bytes()[0].to_ascii().to_upper().to_byte() + } + Some(VerbatimDiskPrefix) => { + repr.as_bytes()[4] == path.as_bytes()[0].to_ascii().to_upper().to_byte() + } _ => false } } @@ -279,7 +283,7 @@ fn append_path(me: &mut Path, path: &str) { // if me is "C:" we don't want to add a path separator match me.prefix { Some(DiskPrefix) if me.repr.len() == plen => (), - _ if !(me.repr.len() > plen && me.repr.as_slice()[me.repr.len()-1] == SEP_BYTE) => { + _ if !(me.repr.len() > plen && me.repr.as_bytes()[me.repr.len()-1] == SEP_BYTE) => { s.push_char(SEP); } _ => () @@ -302,7 +306,7 @@ fn append_path(me: &mut Path, path: &str) { // absolute path, or cwd-relative and self is not same volume replace_path(self, path, prefix); } - None if !path.is_empty() && is_sep_(self.prefix, path[0]) => { + None if !path.is_empty() && is_sep_(self.prefix, path.as_bytes()[0]) => { // volume-relative path if self.prefix.is_some() { // truncate self down to the prefix, then append @@ -478,7 +482,7 @@ fn is_absolute(&self) -> bool { match self.prefix { Some(DiskPrefix) => { let rest = self.repr.as_slice().slice_from(self.prefix_len()); - rest.len() > 0 && rest[0] == SEP_BYTE + rest.len() > 0 && rest.as_bytes()[0] == SEP_BYTE } Some(_) => true, None => false @@ -638,11 +642,11 @@ pub fn str_components<'a>(&'a self) -> StrComponents<'a> { let s = match self.prefix { Some(_) => { let plen = self.prefix_len(); - if repr.len() > plen && repr[plen] == SEP_BYTE { + if repr.len() > plen && repr.as_bytes()[plen] == SEP_BYTE { repr.slice_from(plen+1) } else { repr.slice_from(plen) } } - None if repr[0] == SEP_BYTE => repr.slice_from(1), + None if repr.as_bytes()[0] == SEP_BYTE => repr.slice_from(1), None => repr }; let ret = s.split_terminator(SEP).map(Some); @@ -665,14 +669,14 @@ fn equiv_prefix(&self, other: &Path) -> bool { match (self.prefix, other.prefix) { (Some(DiskPrefix), Some(VerbatimDiskPrefix)) => { self.is_absolute() && - s_repr[0].to_ascii().eq_ignore_case(o_repr[4].to_ascii()) + s_repr.as_bytes()[0].to_ascii().eq_ignore_case(o_repr.as_bytes()[4].to_ascii()) } (Some(VerbatimDiskPrefix), Some(DiskPrefix)) => { other.is_absolute() && - s_repr[4].to_ascii().eq_ignore_case(o_repr[0].to_ascii()) + s_repr.as_bytes()[4].to_ascii().eq_ignore_case(o_repr.as_bytes()[0].to_ascii()) } (Some(VerbatimDiskPrefix), Some(VerbatimDiskPrefix)) => { - s_repr[4].to_ascii().eq_ignore_case(o_repr[4].to_ascii()) + s_repr.as_bytes()[4].to_ascii().eq_ignore_case(o_repr.as_bytes()[4].to_ascii()) } (Some(UNCPrefix(_,_)), Some(VerbatimUNCPrefix(_,_))) => { s_repr.slice(2, self.prefix_len()) == o_repr.slice(8, other.prefix_len()) @@ -718,12 +722,12 @@ fn normalize__(s: &str, prefix: Option) -> Option { let mut comps = comps; match (comps.is_some(),prefix) { (false, Some(DiskPrefix)) => { - if s[0] >= 'a' as u8 && s[0] <= 'z' as u8 { + if s.as_bytes()[0] >= 'a' as u8 && s.as_bytes()[0] <= 'z' as u8 { comps = Some(vec![]); } } (false, Some(VerbatimDiskPrefix)) => { - if s[4] >= 'a' as u8 && s[0] <= 'z' as u8 { + if s.as_bytes()[4] >= 'a' as u8 && s.as_bytes()[0] <= 'z' as u8 { comps = Some(vec![]); } } @@ -778,12 +782,12 @@ fn normalize__(s: &str, prefix: Option) -> Option { let mut s = String::with_capacity(n); match prefix { Some(DiskPrefix) => { - s.push_char(prefix_[0].to_ascii().to_upper().to_char()); + s.push_char(prefix_.as_bytes()[0].to_ascii().to_upper().to_char()); s.push_char(':'); } Some(VerbatimDiskPrefix) => { s.push_str(prefix_.slice_to(4)); - s.push_char(prefix_[4].to_ascii().to_upper().to_char()); + s.push_char(prefix_.as_bytes()[4].to_ascii().to_upper().to_char()); s.push_str(prefix_.slice_from(5)); } Some(UNCPrefix(a,b)) => { @@ -845,7 +849,7 @@ fn sepidx_or_prefix_len(&self) -> Option<(uint,uint,uint)> { fn has_nonsemantic_trailing_slash(&self) -> bool { is_verbatim(self) && self.repr.len() > self.prefix_len()+1 && - self.repr.as_slice()[self.repr.len()-1] == SEP_BYTE + self.repr.as_bytes()[self.repr.len()-1] == SEP_BYTE } fn update_normalized(&mut self, s: S) { @@ -861,7 +865,7 @@ fn update_normalized(&mut self, s: S) { /// but absolute within that volume. #[inline] pub fn is_vol_relative(path: &Path) -> bool { - path.prefix.is_none() && is_sep_byte(&path.repr.as_slice()[0]) + path.prefix.is_none() && is_sep_byte(&path.repr.as_bytes()[0]) } /// Returns whether the path is considered "cwd-relative", which means a path @@ -991,8 +995,8 @@ fn parse_prefix<'a>(mut path: &'a str) -> Option { } else { // \\?\path let idx = path.find('\\'); - if idx == Some(2) && path[1] == ':' as u8 { - let c = path[0]; + if idx == Some(2) && path.as_bytes()[1] == ':' as u8 { + let c = path.as_bytes()[0]; if c.is_ascii() && ::char::is_alphabetic(c as char) { // \\?\C:\ path return Some(VerbatimDiskPrefix); @@ -1014,9 +1018,9 @@ fn parse_prefix<'a>(mut path: &'a str) -> Option { } _ => () } - } else if path.len() > 1 && path[1] == ':' as u8 { + } else if path.len() > 1 && path.as_bytes()[1] == ':' as u8 { // C: - let c = path[0]; + let c = path.as_bytes()[0]; if c.is_ascii() && ::char::is_alphabetic(c as char) { return Some(DiskPrefix); } diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 90569bfc132..dfaa9fb5fcb 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -415,7 +415,7 @@ fn highlight_lines(err: &mut EmitterWriter, } let orig = fm.get_line(*lines.lines.get(0) as int); for pos in range(0u, left-skip) { - let cur_char = orig.as_slice()[pos] as char; + let cur_char = orig.as_bytes()[pos] as char; // Whenever a tab occurs on the previous line, we insert one on // the error-point-squiggly-line as well (instead of a space). // That way the squiggly line will usually appear in the correct diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index ac570c88837..0f188fdf18a 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1203,8 +1203,8 @@ fn read_to_eol(&mut self) -> String { fn read_one_line_comment(&mut self) -> String { let val = self.read_to_eol(); - assert!((val.as_slice()[0] == '/' as u8 && val.as_slice()[1] == '/' as u8) - || (val.as_slice()[0] == '#' as u8 && val.as_slice()[1] == '!' as u8)); + assert!((val.as_bytes()[0] == '/' as u8 && val.as_bytes()[1] == '/' as u8) + || (val.as_bytes()[0] == '#' as u8 && val.as_bytes()[1] == '!' as u8)); return val; } diff --git a/src/libtime/lib.rs b/src/libtime/lib.rs index 3ed7fccb933..f52a032961d 100644 --- a/src/libtime/lib.rs +++ b/src/libtime/lib.rs @@ -375,7 +375,7 @@ pub fn strptime(s: &str, format: &str) -> Result { fn match_str(s: &str, pos: uint, needle: &str) -> bool { let mut i = pos; for ch in needle.bytes() { - if s[i] != ch { + if s.as_bytes()[i] != ch { return false; } i += 1u; diff --git a/src/libuuid/lib.rs b/src/libuuid/lib.rs index 19627e2c2ce..0e73256893e 100644 --- a/src/libuuid/lib.rs +++ b/src/libuuid/lib.rs @@ -324,8 +324,8 @@ pub fn to_simple_str(&self) -> String { let mut s: Vec = Vec::from_elem(32, 0u8); for i in range(0u, 16u) { let digit = format!("{:02x}", self.bytes[i] as uint); - *s.get_mut(i*2+0) = digit.as_slice()[0]; - *s.get_mut(i*2+1) = digit.as_slice()[1]; + *s.get_mut(i*2+0) = digit.as_bytes()[0]; + *s.get_mut(i*2+1) = digit.as_bytes()[1]; } str::from_utf8(s.as_slice()).unwrap().to_string() } diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index 67be7d121a4..195c146c12f 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -183,7 +183,7 @@ fn main() { if line.len() == 0u { continue; } - match (line.as_slice()[0] as char, proc_mode) { + match (line.as_bytes()[0] as char, proc_mode) { // start processing if this is the one ('>', false) => { diff --git a/src/test/compile-fail/integral-indexing.rs b/src/test/compile-fail/integral-indexing.rs index 967229a3407..8b1f9eb1986 100644 --- a/src/test/compile-fail/integral-indexing.rs +++ b/src/test/compile-fail/integral-indexing.rs @@ -17,10 +17,10 @@ pub fn main() { assert_eq!(v.as_slice()[3u32], 3); //~ ERROR: mismatched types assert_eq!(v.as_slice()[3i32], 3); //~ ERROR: mismatched types println!("{}", v.as_slice()[3u8]); //~ ERROR: mismatched types - assert_eq!(s.as_slice()[3u], 'd' as u8); - assert_eq!(s.as_slice()[3u8], 'd' as u8); //~ ERROR: mismatched types - assert_eq!(s.as_slice()[3i8], 'd' as u8); //~ ERROR: mismatched types - assert_eq!(s.as_slice()[3u32], 'd' as u8); //~ ERROR: mismatched types - assert_eq!(s.as_slice()[3i32], 'd' as u8); //~ ERROR: mismatched types - println!("{}", s.as_slice()[3u8]); //~ ERROR: mismatched types + assert_eq!(s.as_bytes()[3u], 'd' as u8); + assert_eq!(s.as_bytes()[3u8], 'd' as u8); //~ ERROR: mismatched types + assert_eq!(s.as_bytes()[3i8], 'd' as u8); //~ ERROR: mismatched types + assert_eq!(s.as_bytes()[3u32], 'd' as u8); //~ ERROR: mismatched types + assert_eq!(s.as_bytes()[3i32], 'd' as u8); //~ ERROR: mismatched types + println!("{}", s.as_bytes()[3u8]); //~ ERROR: mismatched types } diff --git a/src/test/run-pass/str-idx.rs b/src/test/compile-fail/str-idx.rs similarity index 80% rename from src/test/run-pass/str-idx.rs rename to src/test/compile-fail/str-idx.rs index 8ac13e81463..25e4c90e774 100644 --- a/src/test/run-pass/str-idx.rs +++ b/src/test/compile-fail/str-idx.rs @@ -11,8 +11,6 @@ extern crate debug; pub fn main() { - let s = "hello".to_string(); - let c: u8 = s.as_slice()[4]; - println!("{:?}", c); - assert_eq!(c, 0x6f as u8); + let s: &str = "hello"; + let c: u8 = s[4]; //~ ERROR cannot index a value of type `&str` } diff --git a/src/test/run-fail/str-overrun.rs b/src/test/run-fail/str-overrun.rs index 26c5a6988cf..c3ee76047d1 100644 --- a/src/test/run-fail/str-overrun.rs +++ b/src/test/run-fail/str-overrun.rs @@ -14,5 +14,5 @@ fn main() { let s: String = "hello".to_string(); // Bounds-check failure. - assert_eq!(s.as_slice()[5], 0x0 as u8); + assert_eq!(s.as_bytes()[5], 0x0 as u8); } diff --git a/src/test/run-pass/estr-slice.rs b/src/test/run-pass/estr-slice.rs index 3d6b6ba626d..5364cdc627f 100644 --- a/src/test/run-pass/estr-slice.rs +++ b/src/test/run-pass/estr-slice.rs @@ -17,8 +17,8 @@ pub fn main() { println!("{}", x); println!("{}", y); - assert_eq!(x[0], 'h' as u8); - assert_eq!(x[4], 'o' as u8); + assert_eq!(x.as_bytes()[0], 'h' as u8); + assert_eq!(x.as_bytes()[4], 'o' as u8); let z : &str = "thing"; assert_eq!(v, x); diff --git a/src/test/run-pass/estr-uniq.rs b/src/test/run-pass/estr-uniq.rs index 1652016b51b..b562558822c 100644 --- a/src/test/run-pass/estr-uniq.rs +++ b/src/test/run-pass/estr-uniq.rs @@ -15,6 +15,6 @@ pub fn main() { let _y : String = "there".to_string(); let mut z = "thing".to_string(); z = x; - assert_eq!(z.as_slice()[0], ('h' as u8)); - assert_eq!(z.as_slice()[4], ('o' as u8)); + assert_eq!(z.as_bytes()[0], ('h' as u8)); + assert_eq!(z.as_bytes()[4], ('o' as u8)); } diff --git a/src/test/run-pass/str-concat.rs b/src/test/run-pass/str-concat.rs index 7141d0b9df5..ad0d2f11abd 100644 --- a/src/test/run-pass/str-concat.rs +++ b/src/test/run-pass/str-concat.rs @@ -16,5 +16,5 @@ pub fn main() { let b: String = "world".to_string(); let s: String = format!("{}{}", a, b); println!("{}", s.clone()); - assert_eq!(s.as_slice()[9], 'd' as u8); + assert_eq!(s.as_bytes()[9], 'd' as u8); } diff --git a/src/test/run-pass/task-comm-16.rs b/src/test/run-pass/task-comm-16.rs index 9263cd1d485..d45e7a20c3b 100644 --- a/src/test/run-pass/task-comm-16.rs +++ b/src/test/run-pass/task-comm-16.rs @@ -39,10 +39,10 @@ fn test_str() { let s0 = "test".to_string(); tx.send(s0); let s1 = rx.recv(); - assert_eq!(s1.as_slice()[0], 't' as u8); - assert_eq!(s1.as_slice()[1], 'e' as u8); - assert_eq!(s1.as_slice()[2], 's' as u8); - assert_eq!(s1.as_slice()[3], 't' as u8); + assert_eq!(s1.as_bytes()[0], 't' as u8); + assert_eq!(s1.as_bytes()[1], 'e' as u8); + assert_eq!(s1.as_bytes()[2], 's' as u8); + assert_eq!(s1.as_bytes()[3], 't' as u8); } #[deriving(Show)] diff --git a/src/test/run-pass/trait-bounds-in-arc.rs b/src/test/run-pass/trait-bounds-in-arc.rs index 18a0e5d471c..cfe9a772b2e 100644 --- a/src/test/run-pass/trait-bounds-in-arc.rs +++ b/src/test/run-pass/trait-bounds-in-arc.rs @@ -99,7 +99,7 @@ fn check_legs(arc: Arc>>) { fn check_names(arc: Arc>>) { for pet in arc.iter() { pet.name(|name| { - assert!(name[0] == 'a' as u8 && name[1] == 'l' as u8); + assert!(name.as_bytes()[0] == 'a' as u8 && name.as_bytes()[1] == 'l' as u8); }) } } diff --git a/src/test/run-pass/utf8.rs b/src/test/run-pass/utf8.rs index a79fcfa9417..557d2e5878e 100644 --- a/src/test/run-pass/utf8.rs +++ b/src/test/run-pass/utf8.rs @@ -46,7 +46,7 @@ fn check_str_eq(a: String, b: String) { for ab in a.as_slice().bytes() { println!("{}", i); println!("{}", ab); - let bb: u8 = b.as_slice()[i as uint]; + let bb: u8 = b.as_bytes()[i as uint]; println!("{}", bb); assert_eq!(ab, bb); i += 1;