From a89dc2dbf64c13480aaa77fd3b5e5cca6774c14d Mon Sep 17 00:00:00 2001 From: Wangshan Lu Date: Sun, 15 Mar 2015 21:42:58 +0800 Subject: [PATCH 1/6] Fix deprecated `comm` link. --- src/libstd/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 81e2113cfdfc1..9864e35d9a4ef 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -73,10 +73,10 @@ //! //! ## Concurrency, I/O, and the runtime //! -//! The [`thread`](thread/index.html) module contains Rust's threading abstractions, -//! while [`comm`](comm/index.html) contains the channel types for message -//! passing. [`sync`](sync/index.html) contains further, primitive, shared -//! memory types, including [`atomic`](sync/atomic/index.html). +//! The [`thread`](thread/index.html) module contains Rust's threading abstractions. +//! [`sync`](sync/index.html) contains further, primitive, shared memory types, +//! including [`atomic`](sync/atomic/index.html), and [`mpsc`](sync/mpmc/index.html), +//! which contains the channel types for message passing. //! //! Common types of I/O, including files, TCP, UDP, pipes, Unix domain sockets, //! timers, and process spawning, are defined in the From 730defc9d1c6e1a6c9724e0ea81d1df879ccd78f Mon Sep 17 00:00:00 2001 From: Ricardo Martins Date: Tue, 17 Mar 2015 14:51:47 +0000 Subject: [PATCH 2/6] Fix IPv6 address format in documentation Very minor fix: in `std::net::Ipv6Addr::new`, the documentation had an incomplete representation of the resulting address, missing the last two groups. --- src/libstd/net/ip.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index c5f2ae53d22ed..73c2464a6b2cb 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -202,7 +202,7 @@ impl FromInner for Ipv4Addr { impl Ipv6Addr { /// Create a new IPv6 address from eight 16-bit segments. /// - /// The result will represent the IP address a:b:c:d:e:f + /// The result will represent the IP address a:b:c:d:e:f:g:h #[stable(feature = "rust1", since = "1.0.0")] pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr { From 71982c21245489fd316fc9e82bf7bec4b09d45a6 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 17 Mar 2015 10:32:00 -0700 Subject: [PATCH 3/6] libc: Fix definition of sockaddr_storage on 32-bit linux The alignment field is actually a "pointer sized" type instead of always i64, requiring that the size of the padding field is also calculated slightly differently. Closes #23425 --- src/liblibc/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 82c54004e9975..1e1b128d71234 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -269,8 +269,8 @@ pub mod types { #[repr(C)] #[derive(Copy)] pub struct sockaddr_storage { pub ss_family: sa_family_t, - pub __ss_align: i64, - pub __ss_pad2: [u8; 112], + pub __ss_align: isize, + pub __ss_pad2: [u8; 128 - 2 * (::core::isize::BYTES as usize)], } #[repr(C)] #[derive(Copy)] pub struct sockaddr_in { From 34c48db8376dba3f5ec68b2d45bd2e9254a77792 Mon Sep 17 00:00:00 2001 From: Kevin Butler Date: Tue, 17 Mar 2015 20:23:42 +0000 Subject: [PATCH 4/6] Fix documentation for StrExt::trim_matches --- src/libcollections/str.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index b2273646b959e..f48b8d42ab106 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -923,11 +923,11 @@ pub trait StrExt: Index { /// Returns a string with all pre- and suffixes that match a pattern repeatedly removed. /// - /// The pattern can be a simple `&str`, or a closure that determines the split. + /// The pattern can be any `DoubleEndedSearcher`, including a closure that determines the split. /// /// # Examples /// - /// Simple `&str` patterns: + /// Simple `char` patterns: /// /// ``` /// assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar"); From aa88da63179b8ccd3b809e98b489c25199b06cf7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 10 Mar 2015 16:29:02 -0700 Subject: [PATCH 5/6] std: Tweak some unstable features of `str` This commit clarifies some of the unstable features in the `str` module by moving them out of the blanket `core` and `collections` features. The following methods were moved to the `str_char` feature which generally encompasses decoding specific characters from a `str` and dealing with the result. It is unclear if any of these methods need to be stabilized for 1.0 and the most conservative route for now is to continue providing them but to leave them as unstable under a more specific name. * `is_char_boundary` * `char_at` * `char_range_at` * `char_at_reverse` * `char_range_at_reverse` * `slice_shift_char` The following methods were moved into the generic `unicode` feature as they are specifically enabled by the `unicode` crate itself. * `nfd_chars` * `nfkd_chars` * `nfc_chars` * `graphemes` * `grapheme_indices` * `width` --- src/compiletest/runtest.rs | 18 +-- src/libcollections/lib.rs | 1 + src/libcollections/str.rs | 158 +++++++++++++++++--------- src/libcollections/string.rs | 9 +- src/libcore/str/mod.rs | 11 +- src/libgetopts/lib.rs | 14 +-- src/librustc/lib.rs | 1 + src/librustc_driver/lib.rs | 1 + src/librustc_lint/lib.rs | 1 + src/libserialize/lib.rs | 1 + src/libstd/lib.rs | 1 + src/libsyntax/lib.rs | 1 + src/libsyntax/parse/lexer/comments.rs | 7 +- src/libsyntax/parse/lexer/mod.rs | 16 +-- src/libterm/lib.rs | 1 + src/libunicode/u_str.rs | 7 +- 16 files changed, 156 insertions(+), 92 deletions(-) diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 475c041013500..a754bd950f7f6 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -1052,22 +1052,22 @@ fn scan_char(haystack: &str, needle: char, idx: &mut uint) -> bool { if *idx >= haystack.len() { return false; } - let range = haystack.char_range_at(*idx); - if range.ch != needle { + let ch = haystack.char_at(*idx); + if ch != needle { return false; } - *idx = range.next; + *idx += ch.len_utf8(); return true; } fn scan_integer(haystack: &str, idx: &mut uint) -> bool { let mut i = *idx; while i < haystack.len() { - let range = haystack.char_range_at(i); - if range.ch < '0' || '9' < range.ch { + let ch = haystack.char_at(i); + if ch < '0' || '9' < ch { break; } - i = range.next; + i += ch.len_utf8(); } if i == *idx { return false; @@ -1083,9 +1083,9 @@ fn scan_string(haystack: &str, needle: &str, idx: &mut uint) -> bool { if haystack_i >= haystack.len() { return false; } - let range = haystack.char_range_at(haystack_i); - haystack_i = range.next; - if !scan_char(needle, range.ch, &mut needle_i) { + let ch = haystack.char_at(haystack_i); + haystack_i += ch.len_utf8(); + if !scan_char(needle, ch, &mut needle_i) { return false; } } diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index b75f346c188fb..c4a0149676333 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -35,6 +35,7 @@ #![feature(unique)] #![feature(unsafe_no_drop_flag)] #![feature(step_by)] +#![feature(str_char)] #![cfg_attr(test, feature(rand, rustc_private, test))] #![cfg_attr(test, allow(deprecated))] // rand diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index b2273646b959e..781fc4f2ed002 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -175,7 +175,9 @@ enum DecompositionType { /// /// For use with the `std::iter` module. #[derive(Clone)] -#[unstable(feature = "collections")] +#[unstable(feature = "unicode", + reason = "this functionality may be replaced with a more generic \ + unicode crate on crates.io")] pub struct Decompositions<'a> { kind: DecompositionType, iter: Chars<'a>, @@ -266,7 +268,9 @@ enum RecompositionState { /// /// For use with the `std::iter` module. #[derive(Clone)] -#[unstable(feature = "collections")] +#[unstable(feature = "unicode", + reason = "this functionality may be replaced with a more generic \ + unicode crate on crates.io")] pub struct Recompositions<'a> { iter: Decompositions<'a>, state: RecompositionState, @@ -472,8 +476,9 @@ pub trait StrExt: Index { /// Returns an iterator over the string in Unicode Normalization Form D /// (canonical decomposition). #[inline] - #[unstable(feature = "collections", - reason = "this functionality may be moved to libunicode")] + #[unstable(feature = "unicode", + reason = "this functionality may be replaced with a more generic \ + unicode crate on crates.io")] fn nfd_chars(&self) -> Decompositions { Decompositions { iter: self[..].chars(), @@ -486,8 +491,9 @@ pub trait StrExt: Index { /// Returns an iterator over the string in Unicode Normalization Form KD /// (compatibility decomposition). #[inline] - #[unstable(feature = "collections", - reason = "this functionality may be moved to libunicode")] + #[unstable(feature = "unicode", + reason = "this functionality may be replaced with a more generic \ + unicode crate on crates.io")] fn nfkd_chars(&self) -> Decompositions { Decompositions { iter: self[..].chars(), @@ -500,8 +506,9 @@ pub trait StrExt: Index { /// An Iterator over the string in Unicode Normalization Form C /// (canonical decomposition followed by canonical composition). #[inline] - #[unstable(feature = "collections", - reason = "this functionality may be moved to libunicode")] + #[unstable(feature = "unicode", + reason = "this functionality may be replaced with a more generic \ + unicode crate on crates.io")] fn nfc_chars(&self) -> Recompositions { Recompositions { iter: self.nfd_chars(), @@ -515,8 +522,9 @@ pub trait StrExt: Index { /// An Iterator over the string in Unicode Normalization Form KC /// (compatibility decomposition followed by canonical composition). #[inline] - #[unstable(feature = "collections", - reason = "this functionality may be moved to libunicode")] + #[unstable(feature = "unicode", + reason = "this functionality may be replaced with a more generic \ + unicode crate on crates.io")] fn nfkc_chars(&self) -> Recompositions { Recompositions { iter: self.nfkd_chars(), @@ -1023,8 +1031,11 @@ pub trait StrExt: Index { /// // third byte of `老` /// assert!(!s.is_char_boundary(8)); /// ``` - #[unstable(feature = "collections", - reason = "naming is uncertain with container conventions")] + #[unstable(feature = "str_char", + reason = "it is unclear whether this method pulls its weight \ + with the existence of the char_indices iterator or \ + this method may want to be replaced with checked \ + slicing")] fn is_char_boundary(&self, index: usize) -> bool { core_str::StrExt::is_char_boundary(&self[..], index) } @@ -1069,8 +1080,10 @@ pub trait StrExt: Index { /// 14: a /// 15: m /// ``` - #[unstable(feature = "collections", - reason = "naming is uncertain with container conventions")] + #[unstable(feature = "str_char", + reason = "often replaced by char_indices, this method may \ + be removed in favor of just char_at() or eventually \ + removed altogether")] fn char_range_at(&self, start: usize) -> CharRange { core_str::StrExt::char_range_at(&self[..], start) } @@ -1117,8 +1130,10 @@ pub trait StrExt: Index { /// 6: 华 /// 3: 中 /// ``` - #[unstable(feature = "collections", - reason = "naming is uncertain with container conventions")] + #[unstable(feature = "str_char", + reason = "often replaced by char_indices, this method may \ + be removed in favor of just char_at() or eventually \ + removed altogether")] fn char_range_at_reverse(&self, start: usize) -> CharRange { core_str::StrExt::char_range_at_reverse(&self[..], start) } @@ -1137,8 +1152,12 @@ pub trait StrExt: Index { /// assert_eq!(s.char_at(1), 'b'); /// assert_eq!(s.char_at(2), 'π'); /// ``` - #[unstable(feature = "collections", - reason = "naming is uncertain with container conventions")] + #[unstable(feature = "str_char", + reason = "frequently replaced by the chars() iterator, this \ + method may be removed or possibly renamed in the \ + future; it is normally replaced by chars/char_indices \ + iterators or by getting the first char from a \ + subslice")] fn char_at(&self, i: usize) -> char { core_str::StrExt::char_at(&self[..], i) } @@ -1157,8 +1176,10 @@ pub trait StrExt: Index { /// assert_eq!(s.char_at_reverse(1), 'a'); /// assert_eq!(s.char_at_reverse(2), 'b'); /// ``` - #[unstable(feature = "collections", - reason = "naming is uncertain with container conventions")] + #[unstable(feature = "str_char", + reason = "see char_at for more details, but reverse semantics \ + are also somewhat unclear, especially with which \ + cases generate panics")] fn char_at_reverse(&self, i: usize) -> char { core_str::StrExt::char_at_reverse(&self[..], i) } @@ -1297,8 +1318,10 @@ pub trait StrExt: Index { /// assert_eq!(c, 'ö'); /// assert_eq!(s2, "we 老虎 Léopard"); /// ``` - #[unstable(feature = "collections", - reason = "awaiting conventions about shifting and slices")] + #[unstable(feature = "str_char", + reason = "awaiting conventions about shifting and slices and \ + may not be warranted with the existence of the chars \ + and/or char_indices iterators")] fn slice_shift_char(&self) -> Option<(char, &str)> { core_str::StrExt::slice_shift_char(&self[..]) } @@ -1421,8 +1444,9 @@ pub trait StrExt: Index { /// /// assert_eq!(gr2.as_slice(), b); /// ``` - #[unstable(feature = "collections", - reason = "this functionality may only be provided by libunicode")] + #[unstable(feature = "unicode", + reason = "this functionality may be replaced with a more generic \ + unicode crate on crates.io")] fn graphemes(&self, is_extended: bool) -> Graphemes { UnicodeStr::graphemes(&self[..], is_extended) } @@ -1438,8 +1462,9 @@ pub trait StrExt: Index { /// /// assert_eq!(gr_inds.as_slice(), b); /// ``` - #[unstable(feature = "collections", - reason = "this functionality may only be provided by libunicode")] + #[unstable(feature = "unicode", + reason = "this functionality may be replaced with a more generic \ + unicode crate on crates.io")] fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices { UnicodeStr::grapheme_indices(&self[..], is_extended) } @@ -1467,13 +1492,15 @@ pub trait StrExt: Index { /// /// Control characters have zero width. /// - /// `is_cjk` determines behavior for characters in the Ambiguous category: if `is_cjk` is - /// `true`, these are 2 columns wide; otherwise, they are 1. In CJK locales, `is_cjk` should be - /// `true`, else it should be `false`. - /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/) recommends that these - /// characters be treated as 1 column (i.e., `is_cjk = false`) if the locale is unknown. - #[unstable(feature = "collections", - reason = "this functionality may only be provided by libunicode")] + /// `is_cjk` determines behavior for characters in the Ambiguous category: + /// if `is_cjk` is `true`, these are 2 columns wide; otherwise, they are 1. + /// In CJK locales, `is_cjk` should be `true`, else it should be `false`. + /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/) + /// recommends that these characters be treated as 1 column (i.e., `is_cjk = + /// false`) if the locale is unknown. + #[unstable(feature = "unicode", + reason = "this functionality may be replaced with a more generic \ + unicode crate on crates.io")] fn width(&self, is_cjk: bool) -> usize { UnicodeStr::width(&self[..], is_cjk) } @@ -1615,8 +1642,9 @@ impl str { /// Returns an iterator over the string in Unicode Normalization Form D /// (canonical decomposition). #[inline] - #[unstable(feature = "collections", - reason = "this functionality may be moved to libunicode")] + #[unstable(feature = "unicode", + reason = "this functionality may be replaced with a more generic \ + unicode crate on crates.io")] pub fn nfd_chars(&self) -> Decompositions { Decompositions { iter: self[..].chars(), @@ -1629,8 +1657,9 @@ impl str { /// Returns an iterator over the string in Unicode Normalization Form KD /// (compatibility decomposition). #[inline] - #[unstable(feature = "collections", - reason = "this functionality may be moved to libunicode")] + #[unstable(feature = "unicode", + reason = "this functionality may be replaced with a more generic \ + unicode crate on crates.io")] pub fn nfkd_chars(&self) -> Decompositions { Decompositions { iter: self[..].chars(), @@ -1643,8 +1672,9 @@ impl str { /// An Iterator over the string in Unicode Normalization Form C /// (canonical decomposition followed by canonical composition). #[inline] - #[unstable(feature = "collections", - reason = "this functionality may be moved to libunicode")] + #[unstable(feature = "unicode", + reason = "this functionality may be replaced with a more generic \ + unicode crate on crates.io")] pub fn nfc_chars(&self) -> Recompositions { Recompositions { iter: self.nfd_chars(), @@ -1658,8 +1688,9 @@ impl str { /// An Iterator over the string in Unicode Normalization Form KC /// (compatibility decomposition followed by canonical composition). #[inline] - #[unstable(feature = "collections", - reason = "this functionality may be moved to libunicode")] + #[unstable(feature = "unicode", + reason = "this functionality may be replaced with a more generic \ + unicode crate on crates.io")] pub fn nfkc_chars(&self) -> Recompositions { Recompositions { iter: self.nfkd_chars(), @@ -2172,8 +2203,11 @@ impl str { /// // third byte of `老` /// assert!(!s.is_char_boundary(8)); /// ``` - #[unstable(feature = "collections", - reason = "naming is uncertain with container conventions")] + #[unstable(feature = "str_char", + reason = "it is unclear whether this method pulls its weight \ + with the existence of the char_indices iterator or \ + this method may want to be replaced with checked \ + slicing")] pub fn is_char_boundary(&self, index: usize) -> bool { core_str::StrExt::is_char_boundary(&self[..], index) } @@ -2218,8 +2252,10 @@ impl str { /// 14: a /// 15: m /// ``` - #[unstable(feature = "collections", - reason = "naming is uncertain with container conventions")] + #[unstable(feature = "str_char", + reason = "often replaced by char_indices, this method may \ + be removed in favor of just char_at() or eventually \ + removed altogether")] pub fn char_range_at(&self, start: usize) -> CharRange { core_str::StrExt::char_range_at(&self[..], start) } @@ -2266,8 +2302,10 @@ impl str { /// 6: 华 /// 3: 中 /// ``` - #[unstable(feature = "collections", - reason = "naming is uncertain with container conventions")] + #[unstable(feature = "str_char", + reason = "often replaced by char_indices, this method may \ + be removed in favor of just char_at_reverse() or \ + eventually removed altogether")] pub fn char_range_at_reverse(&self, start: usize) -> CharRange { core_str::StrExt::char_range_at_reverse(&self[..], start) } @@ -2286,8 +2324,12 @@ impl str { /// assert_eq!(s.char_at(1), 'b'); /// assert_eq!(s.char_at(2), 'π'); /// ``` - #[unstable(feature = "collections", - reason = "naming is uncertain with container conventions")] + #[unstable(feature = "str_char", + reason = "frequently replaced by the chars() iterator, this \ + method may be removed or possibly renamed in the \ + future; it is normally replaced by chars/char_indices \ + iterators or by getting the first char from a \ + subslice")] pub fn char_at(&self, i: usize) -> char { core_str::StrExt::char_at(&self[..], i) } @@ -2306,8 +2348,10 @@ impl str { /// assert_eq!(s.char_at_reverse(1), 'a'); /// assert_eq!(s.char_at_reverse(2), 'b'); /// ``` - #[unstable(feature = "collections", - reason = "naming is uncertain with container conventions")] + #[unstable(feature = "str_char", + reason = "see char_at for more details, but reverse semantics \ + are also somewhat unclear, especially with which \ + cases generate panics")] pub fn char_at_reverse(&self, i: usize) -> char { core_str::StrExt::char_at_reverse(&self[..], i) } @@ -2446,8 +2490,10 @@ impl str { /// assert_eq!(c, 'ö'); /// assert_eq!(s2, "we 老虎 Léopard"); /// ``` - #[unstable(feature = "collections", - reason = "awaiting conventions about shifting and slices")] + #[unstable(feature = "str_char", + reason = "awaiting conventions about shifting and slices and \ + may not be warranted with the existence of the chars \ + and/or char_indices iterators")] pub fn slice_shift_char(&self) -> Option<(char, &str)> { core_str::StrExt::slice_shift_char(&self[..]) } @@ -2570,7 +2616,7 @@ impl str { /// /// assert_eq!(gr2.as_slice(), b); /// ``` - #[unstable(feature = "collections", + #[unstable(feature = "unicode", reason = "this functionality may only be provided by libunicode")] pub fn graphemes(&self, is_extended: bool) -> Graphemes { UnicodeStr::graphemes(&self[..], is_extended) @@ -2587,7 +2633,7 @@ impl str { /// /// assert_eq!(gr_inds.as_slice(), b); /// ``` - #[unstable(feature = "collections", + #[unstable(feature = "unicode", reason = "this functionality may only be provided by libunicode")] pub fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices { UnicodeStr::grapheme_indices(&self[..], is_extended) @@ -2621,7 +2667,7 @@ impl str { /// `true`, else it should be `false`. /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/) recommends that these /// characters be treated as 1 column (i.e., `is_cjk = false`) if the locale is unknown. - #[unstable(feature = "collections", + #[unstable(feature = "unicode", reason = "this functionality may only be provided by libunicode")] pub fn width(&self, is_cjk: bool) -> usize { UnicodeStr::width(&self[..], is_cjk) diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index d2bc98096f647..2a5f8db049689 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -29,7 +29,7 @@ use unicode::str as unicode_str; use unicode::str::Utf16Item; use borrow::{Cow, IntoCow}; -use str::{self, CharRange, FromStr, Utf8Error}; +use str::{self, FromStr, Utf8Error}; use vec::{DerefVec, Vec, as_vec}; /// A growable string stored as a UTF-8 encoded buffer. @@ -561,9 +561,9 @@ impl String { return None } - let CharRange {ch, next} = self.char_range_at_reverse(len); + let ch = self.char_at_reverse(len); unsafe { - self.vec.set_len(next); + self.vec.set_len(len - ch.len_utf8()); } Some(ch) } @@ -595,7 +595,8 @@ impl String { let len = self.len(); assert!(idx <= len); - let CharRange { ch, next } = self.char_range_at(idx); + let ch = self.char_at(idx); + let next = idx + ch.len_utf8(); unsafe { ptr::copy(self.vec.as_mut_ptr().offset(idx as isize), self.vec.as_ptr().offset(next as isize), diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index bd46b093b76b0..6b83338e1d210 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -18,6 +18,7 @@ use self::OldSearcher::{TwoWay, TwoWayLong}; +use char::CharExt; use clone::Clone; use cmp::{self, Eq}; use default::Default; @@ -1112,8 +1113,10 @@ static UTF8_CHAR_WIDTH: [u8; 256] = [ /// the next `char` in a string. This can be used as a data structure /// for iterating over the UTF-8 bytes of a string. #[derive(Copy)] -#[unstable(feature = "core", - reason = "naming is uncertain with container conventions")] +#[unstable(feature = "str_char", + reason = "existence of this struct is uncertain as it is frequently \ + able to be replaced with char.len_utf8() and/or \ + char/char_indices iterators")] pub struct CharRange { /// Current `char` pub ch: char, @@ -1646,8 +1649,8 @@ impl StrExt for str { if self.is_empty() { None } else { - let CharRange {ch, next} = self.char_range_at(0); - let next_s = unsafe { self.slice_unchecked(next, self.len()) }; + let ch = self.char_at(0); + let next_s = unsafe { self.slice_unchecked(ch.len_utf8(), self.len()) }; Some((ch, next_s)) } } diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index 38abf3881bdf6..206fdd243c783 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -92,11 +92,10 @@ html_playground_url = "http://play.rust-lang.org/")] #![deny(missing_docs)] -#![feature(collections)] #![feature(int_uint)] #![feature(staged_api)] -#![feature(core)] #![feature(str_words)] +#![feature(str_char)] #![cfg_attr(test, feature(rustc_private))] #[cfg(test)] #[macro_use] extern crate log; @@ -620,8 +619,8 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result { let mut j = 1; names = Vec::new(); while j < curlen { - let range = cur.char_range_at(j); - let opt = Short(range.ch); + let ch = cur.char_at(j); + let opt = Short(ch); /* In a series of potential options (eg. -aheJ), if we see one which takes an argument, we assume all @@ -642,12 +641,13 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result { No => false }; - if arg_follows && range.next < curlen { - i_arg = Some((&cur[range.next..curlen]).to_string()); + let next = j + ch.len_utf8(); + if arg_follows && next < curlen { + i_arg = Some((&cur[next..curlen]).to_string()); break; } - j = range.next; + j = next; } } let mut name_pos = 0; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 60102040bcad8..97ed391fdfc78 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -42,6 +42,7 @@ #![feature(io)] #![feature(path_ext)] #![feature(str_words)] +#![feature(str_char)] #![cfg_attr(test, feature(test))] extern crate arena; diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index e132e9833c16d..0071e4434efa4 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -38,6 +38,7 @@ #![feature(exit_status)] #![feature(io)] #![feature(set_stdio)] +#![feature(unicode)] extern crate arena; extern crate flate; diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index a49c9db07a0e9..99b3393c003de 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -41,6 +41,7 @@ #![feature(unsafe_destructor)] #![feature(staged_api)] #![feature(std_misc)] +#![feature(str_char)] #![cfg_attr(test, feature(test))] extern crate syntax; diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 49e44a6d45563..31c270dca6bba 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -37,6 +37,7 @@ Core encoding and decoding interfaces. #![feature(staged_api)] #![feature(std_misc)] #![feature(unicode)] +#![feature(str_char)] #![cfg_attr(test, feature(test))] // test harness access diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 81e2113cfdfc1..41d5b3ce75ec7 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -127,6 +127,7 @@ #![feature(int_uint)] #![feature(unique)] #![feature(allow_internal_unstable)] +#![feature(str_char)] #![cfg_attr(test, feature(test, rustc_private))] // Don't link to std. We are std. diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index b53bb4bc75ee2..9f217bba00ab6 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -38,6 +38,7 @@ #![feature(std_misc)] #![feature(unicode)] #![feature(path_ext)] +#![feature(str_char)] extern crate arena; extern crate fmt_macros; diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs index fb9e0480cebc8..277f5365db3ec 100644 --- a/src/libsyntax/parse/lexer/comments.rs +++ b/src/libsyntax/parse/lexer/comments.rs @@ -20,7 +20,6 @@ use parse::lexer; use print::pprust; use std::io::Read; -use std::str; use std::usize; #[derive(Clone, Copy, PartialEq)] @@ -210,11 +209,11 @@ fn all_whitespace(s: &str, col: CharPos) -> Option { let mut col = col.to_usize(); let mut cursor: usize = 0; while col > 0 && cursor < len { - let r: str::CharRange = s.char_range_at(cursor); - if !r.ch.is_whitespace() { + let ch = s.char_at(cursor); + if !ch.is_whitespace() { return None; } - cursor = r.next; + cursor += ch.len_utf8(); col -= 1; } return Some(cursor); diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index d9887c28e5c4d..bb8f9da89171c 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -22,7 +22,6 @@ use std::fmt; use std::mem::replace; use std::num; use std::rc::Rc; -use std::str; pub use ext::tt::transcribe::{TtReader, new_tt_reader, new_tt_reader_with_doc_flag}; @@ -291,7 +290,8 @@ impl<'a> StringReader<'a> { s: &'b str, errmsg: &'b str) -> Cow<'b, str> { let mut i = 0; while i < s.len() { - let str::CharRange { ch, next } = s.char_range_at(i); + let ch = s.char_at(i); + let next = i + ch.len_utf8(); if ch == '\r' { if next < s.len() && s.char_at(next) == '\n' { return translate_crlf_(self, start, s, errmsg, i).into_cow(); @@ -309,7 +309,8 @@ 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 ch = s.char_at(i); + let next = i + ch.len_utf8(); if ch == '\r' { if j < i { buf.push_str(&s[j..i]); } j = next; @@ -335,10 +336,11 @@ impl<'a> StringReader<'a> { if current_byte_offset < self.source_text.len() { assert!(self.curr.is_some()); let last_char = self.curr.unwrap(); - let next = self.source_text.char_range_at(current_byte_offset); - let byte_offset_diff = next.next - current_byte_offset; + let ch = self.source_text.char_at(current_byte_offset); + let next = current_byte_offset + ch.len_utf8(); + let byte_offset_diff = next - current_byte_offset; self.pos = self.pos + Pos::from_usize(byte_offset_diff); - self.curr = Some(next.ch); + self.curr = Some(ch); self.col = self.col + CharPos(1); if last_char == '\n' { self.filemap.next_line(self.last_pos); @@ -370,7 +372,7 @@ impl<'a> StringReader<'a> { let offset = self.byte_offset(self.pos).to_usize(); let s = &self.source_text[..]; if offset >= s.len() { return None } - let str::CharRange { next, .. } = s.char_range_at(offset); + let next = offset + s.char_at(offset).len_utf8(); if next < s.len() { Some(s.char_at(next)) } else { diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index 89960d5d62f5b..f517dca53cdd2 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -60,6 +60,7 @@ #![feature(rustc_private)] #![feature(staged_api)] #![feature(std_misc)] +#![feature(str_char)] #![feature(path_ext)] #![cfg_attr(windows, feature(libc))] diff --git a/src/libunicode/u_str.rs b/src/libunicode/u_str.rs index 917c2d2dfbe88..0fbc98ea73cfb 100644 --- a/src/libunicode/u_str.rs +++ b/src/libunicode/u_str.rs @@ -244,7 +244,7 @@ impl<'a> Iterator for Graphemes<'a> { } self.cat = if take_curr { - idx = self.string.char_range_at(idx).next; + idx = idx + len_utf8(self.string.char_at(idx)); None } else { Some(cat) @@ -256,6 +256,11 @@ impl<'a> Iterator for Graphemes<'a> { } } +#[cfg(stage0)] +fn len_utf8(c: char) -> usize { UCharExt::len_utf8(c) } +#[cfg(not(stage0))] +fn len_utf8(c: char) -> usize { c.len_utf8() } + impl<'a> DoubleEndedIterator for Graphemes<'a> { #[inline] fn next_back(&mut self) -> Option<&'a str> { From 7364022e7ae4b738fb585dd2262ad67ceebd4266 Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Wed, 18 Mar 2015 01:19:53 -0400 Subject: [PATCH 6/6] Infer type ! for a loop that can only break out of other loops Closes #23451. Signed-off-by: Anders Kaseorg --- src/librustc_typeck/check/mod.rs | 2 +- .../compile-fail/loop-labeled-break-value.rs | 21 +++++++++++++++++++ src/test/run-pass/loop-labeled-break-value.rs | 18 ++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/loop-labeled-break-value.rs create mode 100644 src/test/run-pass/loop-labeled-break-value.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 31bee612b78d4..6dc6b6c3cde80 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5239,7 +5239,7 @@ pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &ast::Block) -> bool { // inside the loop? (loop_query(&*b, |e| { match *e { - ast::ExprBreak(_) => true, + ast::ExprBreak(None) => true, _ => false } })) || diff --git a/src/test/compile-fail/loop-labeled-break-value.rs b/src/test/compile-fail/loop-labeled-break-value.rs new file mode 100644 index 0000000000000..e1ae3ae464f98 --- /dev/null +++ b/src/test/compile-fail/loop-labeled-break-value.rs @@ -0,0 +1,21 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + loop { + let _: i32 = loop { break }; //~ ERROR mismatched types + } + loop { + let _: i32 = 'inner: loop { break 'inner }; //~ ERROR mismatched types + } + loop { + let _: i32 = 'inner: loop { loop { break 'inner } }; //~ ERROR mismatched types + } +} diff --git a/src/test/run-pass/loop-labeled-break-value.rs b/src/test/run-pass/loop-labeled-break-value.rs new file mode 100644 index 0000000000000..f71dc6869bee9 --- /dev/null +++ b/src/test/run-pass/loop-labeled-break-value.rs @@ -0,0 +1,18 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + 'outer: loop { + let _: i32 = loop { break 'outer }; + } + 'outer: loop { + let _: i32 = loop { loop { break 'outer } }; + } +}