From a89dc2dbf64c13480aaa77fd3b5e5cca6774c14d Mon Sep 17 00:00:00 2001 From: Wangshan Lu Date: Sun, 15 Mar 2015 21:42:58 +0800 Subject: [PATCH 01/13] 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 81e2113cfdfc..9864e35d9a4e 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 02/13] 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 c5f2ae53d22e..73c2464a6b2c 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 03/13] 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 82c54004e997..1e1b128d7123 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 04/13] 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 b2273646b959..f48b8d42ab10 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 05/13] 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 475c04101350..a754bd950f7f 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 b75f346c188f..c4a014967633 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 b2273646b959..781fc4f2ed00 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 d2bc98096f64..2a5f8db04968 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 bd46b093b76b..6b83338e1d21 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 38abf3881bdf..206fdd243c78 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 60102040bcad..97ed391fdfc7 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 e132e9833c16..0071e4434efa 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 a49c9db07a0e..99b3393c003d 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 49e44a6d4556..31c270dca6bb 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 81e2113cfdfc..41d5b3ce75ec 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 b53bb4bc75ee..9f217bba00ab 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 fb9e0480cebc..277f5365db3e 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 d9887c28e5c4..bb8f9da89171 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 89960d5d62f5..f517dca53cdd 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 917c2d2dfbe8..0fbc98ea73cf 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 06/13] 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 31bee612b78d..6dc6b6c3cde8 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 000000000000..e1ae3ae464f9 --- /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 000000000000..f71dc6869bee --- /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 } }; + } +} From c42067c9e9ac605fc330c3ed11d29477ac251d8a Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 17 Mar 2015 03:41:23 +0530 Subject: [PATCH 07/13] ast: Document Expr_, UnOp, and BinOp --- src/libsyntax/ast.rs | 71 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 657ffcaece9f..1188e2921eb7 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -594,23 +594,41 @@ pub enum Mutability { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] pub enum BinOp_ { + /// The `+` operator (addition) BiAdd, + /// The `-` operator (subtraction) BiSub, + /// The `*` operator (multiplication) BiMul, + /// The `/` operator (division) BiDiv, + /// The `%` operator (modulus) BiRem, + /// The `&&` operator (logical and) BiAnd, + /// The `||` operator (logical or) BiOr, + /// The `^` operator (bitwise xor) BiBitXor, + /// The `&` operator (bitwise and) BiBitAnd, + /// The `|` operator (bitwise or) BiBitOr, + /// The `<<` operator (shift left) BiShl, + /// The `>>` operator (shift right) BiShr, + /// The `==` operator (equality) BiEq, + /// The `<` operator (less than) BiLt, + /// The `<=` operator (less than or equal to) BiLe, + /// The `!=` operator (not equal to) BiNe, + /// The `>=` operator (greater than or equal to) BiGe, + /// The `>` operator (greater than) BiGt, } @@ -618,9 +636,13 @@ pub type BinOp = Spanned; #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] pub enum UnOp { + /// The `box` operator UnUniq, + /// The `*` operator for dereferencing UnDeref, + /// The `!` operator for logical inversion UnNot, + /// The `-` operator for negation UnNeg } @@ -725,34 +747,73 @@ pub struct Expr { pub enum Expr_ { /// First expr is the place; second expr is the value. ExprBox(Option>, P), + /// An array (`[a, b, c, d]`) ExprVec(Vec>), + /// A function cal ExprCall(P, Vec>), + /// A method call (`x.foo::(a, b, c, d)`) + /// The `SpannedIdent` is the identifier for the method name + /// The vector of `Ty`s are the ascripted type parameters for the method + /// (within the angle brackets) + /// The first element of the vector of `Expr`s is the expression that evaluates + /// to the object on which the method is being called on, and the remaining elements + /// are the arguments ExprMethodCall(SpannedIdent, Vec>, Vec>), + /// A tuple (`(a, b, c ,d)`) ExprTup(Vec>), + /// A binary operation (For example: `a + b`, `a * b`) ExprBinary(BinOp, P, P), + /// A unary operation (For example: `!x`, `*x`) ExprUnary(UnOp, P), + /// A literal (For example: `1u8`, `"foo"`) ExprLit(P), + /// A cast (`foo as f64`) ExprCast(P, P), + /// An `if` block, with an optional else block + /// `if expr { block } else { expr }` ExprIf(P, P, Option>), + /// An `if let` expression with an optional else block + /// `if let pat = expr { block } else { expr }` + /// This is desugared to a `match` expression ExprIfLet(P, P, P, Option>), // FIXME #6993: change to Option ... or not, if these are hygienic. + /// A while loop, with an optional label + /// `'label while expr { block }` ExprWhile(P, P, Option), // FIXME #6993: change to Option ... or not, if these are hygienic. + /// A while-let loop, with an optional label + /// `'label while let pat = expr { block }` + /// This is desugared to a combination of `loop` and `match` expressions ExprWhileLet(P, P, P, Option), // FIXME #6993: change to Option ... or not, if these are hygienic. + /// A for loop, with an optional label + /// `'label for pat in expr { block }` + /// This is desugared to a combination of `loop` and `match` expressions ExprForLoop(P, P, P, Option), - // Conditionless loop (can be exited with break, cont, or ret) + /// Conditionless loop (can be exited with break, cont, or ret) + /// `'label loop { block }` // FIXME #6993: change to Option ... or not, if these are hygienic. ExprLoop(P, Option), + /// A `match` block, with a desugar source ExprMatch(P, Vec, MatchSource), + /// A closure (for example, `move |a, b, c| {a + b + c}`) ExprClosure(CaptureClause, P, P), + /// A block ExprBlock(P), + /// An assignment (`a = foo()`) ExprAssign(P, P), + /// An assignment with an operator + /// For example, `a += 1` ExprAssignOp(BinOp, P, P), + /// Access of a named struct field (`obj.foo`) ExprField(P, SpannedIdent), + /// Access of an unnamed field of a struct or tuple-struct + /// For example, `foo.0` ExprTupField(P, Spanned), + /// An indexing operation (`foo[2]`) ExprIndex(P, P), + /// A range (`[1..2]`, `[1..]`, or `[..2]`) ExprRange(Option>, Option>), /// Variable reference, possibly containing `::` and/or type @@ -760,19 +821,27 @@ pub enum Expr_ { /// e.g. ` as SomeTrait>::SomeType`. ExprPath(Option, Path), + /// A referencing operation (`&a` or `&mut a`) ExprAddrOf(Mutability, P), + /// A `break`, with an optional label to break ExprBreak(Option), + /// A `continue`, with an optional label ExprAgain(Option), + /// A `return`, with an optional value to be returned ExprRet(Option>), + /// Output of the `asm!()` macro ExprInlineAsm(InlineAsm), + /// A macro invocation; pre-expansion ExprMac(Mac), /// A struct literal expression. + /// For example, `Foo {x: 1, y: 2}` ExprStruct(Path, Vec, Option> /* base */), /// A vector literal constructed from one repeated element. + /// For example, `[u8; 5]` ExprRepeat(P /* element */, P /* count */), /// No-op: used solely so we can pretty-print faithfully From 1debe9d112010a23c76711f557ee6fdc4728f4ec Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 17 Mar 2015 04:02:29 +0530 Subject: [PATCH 08/13] ast: Document paths and `where` clauses --- src/libsyntax/ast.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 1188e2921eb7..ec4316150fbb 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -150,7 +150,7 @@ impl PartialEq for Ident { /// A SyntaxContext represents a chain of macro-expandings /// and renamings. Each macro expansion corresponds to -/// a fresh usize +/// a fresh u32 // I'm representing this syntax context as an index into // a table, in order to work around a compiler bug @@ -216,6 +216,7 @@ pub struct Lifetime { } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +/// A lifetime definition, eg `'a: 'b+'c+'d` pub struct LifetimeDef { pub lifetime: Lifetime, pub bounds: Vec @@ -251,7 +252,9 @@ pub struct PathSegment { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum PathParameters { + /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>` AngleBracketedParameters(AngleBracketedParameterData), + /// The `(A,B)` and `C` in `Foo(A,B) -> C` ParenthesizedParameters(ParenthesizedParameterData), } @@ -436,27 +439,37 @@ impl Generics { } } +/// A `where` clause in a definition #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct WhereClause { pub id: NodeId, pub predicates: Vec, } +/// A single predicate in a `where` clause #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum WherePredicate { + /// A type binding, eg `for<'c> Foo: Send+Clone+'c` BoundPredicate(WhereBoundPredicate), + /// A lifetime predicate, e.g. `'a: 'b+'c` RegionPredicate(WhereRegionPredicate), + /// An equality predicate (unsupported) EqPredicate(WhereEqPredicate) } +/// A type bound, eg `for<'c> Foo: Send+Clone+'c` #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct WhereBoundPredicate { pub span: Span, + /// Any lifetimes from a `for` binding pub bound_lifetimes: Vec, + /// The type being bounded pub bounded_ty: P, + /// Trait and lifetime bounds (`Clone+Send+'static`) pub bounds: OwnedSlice, } +/// A lifetime predicate, e.g. `'a: 'b+'c` #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct WhereRegionPredicate { pub span: Span, @@ -464,6 +477,7 @@ pub struct WhereRegionPredicate { pub bounds: Vec, } +/// An equality predicate (unsupported), e.g. `T=int` #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct WhereEqPredicate { pub id: NodeId, From b08d5eee6a1bb3aaf7385c84b255be964caff9d1 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 17 Mar 2015 04:19:27 +0530 Subject: [PATCH 09/13] ast: Document Pat and Block --- src/libsyntax/ast.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index ec4316150fbb..479ae40f0d6a 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -535,9 +535,13 @@ impl PartialEq for MetaItem_ { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct Block { + /// Statements in a block pub stmts: Vec>, + /// An expression at the end of the block + /// without a semicolon, if any pub expr: Option>, pub id: NodeId, + /// Unsafety of the block pub rules: BlockCheckMode, pub span: Span, } @@ -550,8 +554,14 @@ pub struct Pat { } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +/// A single field in a struct pattern +/// +/// For patterns like `Foo {x, y, z}`, `pat` and `ident` point to the same identifier +/// and `is_shorthand` is true. pub struct FieldPat { + /// The identifier for the field pub ident: Ident, + /// The pattern the field is destructured to pub pat: P, pub is_shorthand: bool, } @@ -588,15 +598,23 @@ pub enum Pat_ { /// "None" means a * pattern where we don't bind the fields to names. PatEnum(Path, Option>>), + /// Destructuring of a struct, e.g. `Foo {x, y, ..}` + /// The `bool` is `true` in the presence of a `..` PatStruct(Path, Vec>, bool), + /// A tuple pattern (`a, b`) PatTup(Vec>), + /// A `box` pattern PatBox(P), - PatRegion(P, Mutability), // reference pattern + /// A reference pattern, e.g. `&mut (a, b)` + PatRegion(P, Mutability), + /// A literal PatLit(P), + /// A range pattern, e.g. `[1...2]` PatRange(P, P), /// [a, b, ..i, y, z] is represented as: /// PatVec(box [a, b], Some(i), box [y, z]) PatVec(Vec>, Option>, Vec>), + /// A macro pattern; pre-expansion PatMac(Mac), } From 084f3bcfd4e378d5c2b6daccda5c963c757c1bc5 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 17 Mar 2015 04:32:58 +0530 Subject: [PATCH 10/13] ast: Document Lit --- src/libsyntax/ast.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 479ae40f0d6a..a16cd8bfa19f 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -678,6 +678,7 @@ pub enum UnOp { UnNeg } +/// A statement pub type Stmt = Spanned; #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] @@ -722,6 +723,7 @@ pub enum LocalSource { pub struct Local { pub pat: P, pub ty: Option>, + /// Initializer expression to set the value, if any pub init: Option>, pub id: NodeId, pub span: Span, @@ -768,6 +770,7 @@ pub enum UnsafeSource { UserProvided, } +/// An expression #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct Expr { pub id: NodeId, @@ -981,7 +984,6 @@ pub enum KleeneOp { /// The RHS of an MBE macro is the only place `SubstNt`s are substituted. /// Nothing special happens to misnamed or misplaced `SubstNt`s. #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -#[doc="For macro invocations; parsing is delegated to the macro"] pub enum TokenTree { /// A single token TtToken(Span, token::Token), @@ -1092,10 +1094,14 @@ pub enum Mac_ { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] pub enum StrStyle { + /// A regular string, like `"fooo"` CookedStr, + /// A raw string, like `r##"foo"##` + /// The uint is the number of `#` symbols used RawStr(usize) } +/// A literal pub type Lit = Spanned; #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] @@ -1133,13 +1139,21 @@ impl LitIntType { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum Lit_ { + /// A string literal (`"foo"`) LitStr(InternedString, StrStyle), + /// A byte string (`b"foo"`) LitBinary(Rc>), + /// A byte char (`b'f'`) LitByte(u8), + /// A character literal (`'a'`) LitChar(char), + /// An integer liteal (`1u8`) LitInt(u64, LitIntType), + /// A float literal (`1f64` or `1E10f64`) LitFloat(InternedString, FloatTy), + /// A float literal without a suffix (`1.0 or 1.0E10`) LitFloatUnsuffixed(InternedString), + /// A boolean literal LitBool(bool), } From edf65c43f64861bc7fb660db32f9a10c38105957 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 17 Mar 2015 05:06:13 +0530 Subject: [PATCH 11/13] ast: Document Item and ForeignItem --- src/libsyntax/ast.rs | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a16cd8bfa19f..ccccc3bfb04e 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1476,9 +1476,9 @@ impl fmt::Display for Unsafety { #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] pub enum ImplPolarity { - /// impl Trait for Type + /// `impl Trait for Type` Positive, - /// impl !Trait for Type + /// `impl !Trait for Type` Negative, } @@ -1494,10 +1494,10 @@ impl fmt::Debug for ImplPolarity { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum FunctionRetTy { - /// Functions with return type ! that always + /// Functions with return type `!`that always /// raise an error or exit (i.e. never return to the caller) NoReturn(Span), - /// Return type is not specified. Functions default to () and + /// Return type is not specified. Functions default to `()` and /// closures default to inference. Span points to where return /// type would be inserted. DefaultReturn(Span), @@ -1553,7 +1553,9 @@ pub struct VariantArg { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum VariantKind { + /// Tuple variant, e.g. `Foo(A, B)` TupleVariantKind(Vec), + /// Struct variant, e.g. `Foo {x: A, y: B}` StructVariantKind(P), } @@ -1568,6 +1570,7 @@ pub struct Variant_ { pub attrs: Vec, pub kind: VariantKind, pub id: NodeId, + /// Explicit discriminant, eg `Foo = 1` pub disr_expr: Option>, pub vis: Visibility, } @@ -1718,6 +1721,9 @@ pub struct StructDef { FIXME (#3300): Should allow items to be anonymous. Right now we just use dummy names for anon items. */ +/// An item +/// +/// The name might be a dummy name in case of anonymous items #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct Item { pub ident: Ident, @@ -1730,19 +1736,27 @@ pub struct Item { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum Item_ { - // Optional location (containing arbitrary characters) from which - // to fetch the crate sources. - // For example, extern crate whatever = "github.com/rust-lang/rust". + /// An`extern crate` item, with optional original crate name, + /// e.g. `extern crate foo` or `extern crate "foo-bar" as foo` ItemExternCrate(Option<(InternedString, StrStyle)>), + /// A `use` or `pub use` item ItemUse(P), + /// A `static` item ItemStatic(P, Mutability, P), + /// A `const` item ItemConst(P, P), + /// A function declaration ItemFn(P, Unsafety, Abi, Generics, P), + /// A module ItemMod(Mod), + /// An external module ItemForeignMod(ForeignMod), + /// A type alias, e.g. `type Foo = Bar` ItemTy(P, Generics), + /// An enum definition, e.g. `enum Foo {C, D}` ItemEnum(EnumDef, Generics), + /// A struct definition, e.g. `struct Foo {x: A}` ItemStruct(P, Generics), /// Represents a Trait Declaration ItemTrait(Unsafety, @@ -1751,8 +1765,9 @@ pub enum Item_ { Vec>), // Default trait implementations - // `impl Trait for ..` + // `impl Trait for .. {}` ItemDefaultImpl(Unsafety, TraitRef), + /// An implementation, eg `impl Trait for Foo { .. }` ItemImpl(Unsafety, ImplPolarity, Generics, @@ -1794,10 +1809,13 @@ pub struct ForeignItem { pub vis: Visibility, } +/// An item within an `extern` block #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum ForeignItem_ { + /// A foreign function ForeignItemFn(P, Generics), - ForeignItemStatic(P, /* is_mutbl */ bool), + /// A foreign static item (`static ext: u8`), with optional mutability + ForeignItemStatic(P, bool), } impl ForeignItem_ { From 13881df1b2a188b1505b50fde47dfdd8c95a99ee Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 17 Mar 2015 17:42:20 +0530 Subject: [PATCH 12/13] Clarify Expr --- src/libsyntax/ast.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index ccccc3bfb04e..26e10a351504 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -784,15 +784,19 @@ pub enum Expr_ { ExprBox(Option>, P), /// An array (`[a, b, c, d]`) ExprVec(Vec>), - /// A function cal + /// A function call + /// The first field resolves to the function itself, + /// and the second field is the list of arguments ExprCall(P, Vec>), /// A method call (`x.foo::(a, b, c, d)`) /// The `SpannedIdent` is the identifier for the method name /// The vector of `Ty`s are the ascripted type parameters for the method /// (within the angle brackets) /// The first element of the vector of `Expr`s is the expression that evaluates - /// to the object on which the method is being called on, and the remaining elements - /// are the arguments + /// to the object on which the method is being called on (the receiver), + /// and the remaining elements are the rest of the arguments. + /// Thus, `x.foo::(a, b, c, d)` is represented as + /// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])` ExprMethodCall(SpannedIdent, Vec>, Vec>), /// A tuple (`(a, b, c ,d)`) ExprTup(Vec>), @@ -829,7 +833,8 @@ pub enum Expr_ { /// `'label loop { block }` // FIXME #6993: change to Option ... or not, if these are hygienic. ExprLoop(P, Option), - /// A `match` block, with a desugar source + /// A `match` block, with a source that indicates whether or not it is + /// the result of a desugaring, and if so, which kind ExprMatch(P, Vec, MatchSource), /// A closure (for example, `move |a, b, c| {a + b + c}`) ExprClosure(CaptureClause, P, P), @@ -1094,7 +1099,7 @@ pub enum Mac_ { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] pub enum StrStyle { - /// A regular string, like `"fooo"` + /// A regular string, like `"foo"` CookedStr, /// A raw string, like `r##"foo"##` /// The uint is the number of `#` symbols used From a5828ff7b0203ac378974c2d30ed94a14073895a Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 18 Mar 2015 18:06:10 +0530 Subject: [PATCH 13/13] Address huon's comments --- src/libsyntax/ast.rs | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 26e10a351504..5c2757153521 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -541,7 +541,7 @@ pub struct Block { /// without a semicolon, if any pub expr: Option>, pub id: NodeId, - /// Unsafety of the block + /// Distinguishes between `unsafe { ... }` and `{ ... }` pub rules: BlockCheckMode, pub span: Span, } @@ -553,11 +553,12 @@ pub struct Pat { pub span: Span, } -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] /// A single field in a struct pattern /// -/// For patterns like `Foo {x, y, z}`, `pat` and `ident` point to the same identifier -/// and `is_shorthand` is true. +/// Patterns like the fields of Foo `{ x, ref y, ref mut z }` +/// are treated the same as` x: x, y: ref y, z: ref mut z`, +/// except is_shorthand is true +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct FieldPat { /// The identifier for the field pub ident: Ident, @@ -601,7 +602,7 @@ pub enum Pat_ { /// Destructuring of a struct, e.g. `Foo {x, y, ..}` /// The `bool` is `true` in the presence of a `..` PatStruct(Path, Vec>, bool), - /// A tuple pattern (`a, b`) + /// A tuple pattern `(a, b)` PatTup(Vec>), /// A `box` pattern PatBox(P), @@ -609,7 +610,7 @@ pub enum Pat_ { PatRegion(P, Mutability), /// A literal PatLit(P), - /// A range pattern, e.g. `[1...2]` + /// A range pattern, e.g. `1...2` PatRange(P, P), /// [a, b, ..i, y, z] is represented as: /// PatVec(box [a, b], Some(i), box [y, z]) @@ -817,20 +818,20 @@ pub enum Expr_ { ExprIfLet(P, P, P, Option>), // FIXME #6993: change to Option ... or not, if these are hygienic. /// A while loop, with an optional label - /// `'label while expr { block }` + /// `'label: while expr { block }` ExprWhile(P, P, Option), // FIXME #6993: change to Option ... or not, if these are hygienic. /// A while-let loop, with an optional label - /// `'label while let pat = expr { block }` + /// `'label: while let pat = expr { block }` /// This is desugared to a combination of `loop` and `match` expressions ExprWhileLet(P, P, P, Option), // FIXME #6993: change to Option ... or not, if these are hygienic. /// A for loop, with an optional label - /// `'label for pat in expr { block }` + /// `'label: for pat in expr { block }` /// This is desugared to a combination of `loop` and `match` expressions ExprForLoop(P, P, P, Option), - /// Conditionless loop (can be exited with break, cont, or ret) - /// `'label loop { block }` + /// Conditionless loop (can be exited with break, continue, or return) + /// `'label: loop { block }` // FIXME #6993: change to Option ... or not, if these are hygienic. ExprLoop(P, Option), /// A `match` block, with a source that indicates whether or not it is @@ -838,7 +839,7 @@ pub enum Expr_ { ExprMatch(P, Vec, MatchSource), /// A closure (for example, `move |a, b, c| {a + b + c}`) ExprClosure(CaptureClause, P, P), - /// A block + /// A block (`{ ... }`) ExprBlock(P), /// An assignment (`a = foo()`) @@ -853,7 +854,7 @@ pub enum Expr_ { ExprTupField(P, Spanned), /// An indexing operation (`foo[2]`) ExprIndex(P, P), - /// A range (`[1..2]`, `[1..]`, or `[..2]`) + /// A range (`1..2`, `1..`, or `..2`) ExprRange(Option>, Option>), /// Variable reference, possibly containing `::` and/or type @@ -877,12 +878,14 @@ pub enum Expr_ { ExprMac(Mac), /// A struct literal expression. - /// For example, `Foo {x: 1, y: 2}` - ExprStruct(Path, Vec, Option> /* base */), + /// For example, `Foo {x: 1, y: 2}`, or + /// `Foo {x: 1, .. base}`, where `base` is the `Option` + ExprStruct(Path, Vec, Option>), /// A vector literal constructed from one repeated element. - /// For example, `[u8; 5]` - ExprRepeat(P /* element */, P /* count */), + /// For example, `[1u8; 5]`. The first expression is the element + /// to be repeated; the second is the number of times to repeat it + ExprRepeat(P, P), /// No-op: used solely so we can pretty-print faithfully ExprParen(P) @@ -1820,6 +1823,7 @@ pub enum ForeignItem_ { /// A foreign function ForeignItemFn(P, Generics), /// A foreign static item (`static ext: u8`), with optional mutability + /// (the boolean is true when mutable) ForeignItemStatic(P, bool), }