diff --git a/src/libcore/char.rs b/src/libcore/char.rs index c02704217a8de..61f9fa7a2b631 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -537,4 +537,94 @@ impl Iterator for EscapeDefault { EscapeDefaultState::Done => (0, Some(0)), } } + + fn count(self) -> usize { + match self.state { + EscapeDefaultState::Char(_) => 1, + EscapeDefaultState::Unicode(iter) => iter.count(), + EscapeDefaultState::Done => 0, + EscapeDefaultState::Backslash(_) => 2, + } + } + + fn nth(&mut self, n: usize) -> Option { + let ch = match self.state { + EscapeDefaultState::Backslash(c) => c, + EscapeDefaultState::Char(c) => c, + EscapeDefaultState::Done => return None, + EscapeDefaultState::Unicode(ref mut i) => return i.nth(n), + }; + + let start = if let Some(x) = self.get_offset() { + x + } else { + return None; + }; + let idx = start + n; + + // Update state + self.state = match idx { + 0 => EscapeDefaultState::Char(ch), + _ => EscapeDefaultState::Done, + }; + + match idx { + 0 => Some('\\'), + 1 => Some(ch), + _ => None, + } + } + + fn last(self) -> Option { + match self.state { + EscapeDefaultState::Unicode(iter) => iter.last(), + EscapeDefaultState::Done => None, + EscapeDefaultState::Backslash(c) | EscapeDefaultState::Char(c) => Some(c), + } + } +} + +#[test] +fn ed_iterator_specializations() { + use super::EscapeDefault; + + // Check counting + assert_eq!('\n'.escape_default().count(), 2); + assert_eq!('c'.escape_default().count(), 1); + assert_eq!(' '.escape_default().count(), 1); + assert_eq!('\\'.escape_default().count(), 2); + assert_eq!('\''.escape_default().count(), 2); + + // Check nth + + // Check that OoB is handled correctly + assert_eq!('\n'.escape_default().nth(2), None); + assert_eq!('c'.escape_default().nth(1), None); + assert_eq!(' '.escape_default().nth(1), None); + assert_eq!('\\'.escape_default().nth(2), None); + assert_eq!('\''.escape_default().nth(2), None); + + // Check the first char + assert_eq!('\n'.escape_default().nth(0), Some('\\')); + assert_eq!('c'.escape_default().nth(0), Some('c')); + assert_eq!(' '.escape_default().nth(0), Some(' ')); + assert_eq!('\\'.escape_default().nth(0), Some('\\')); + assert_eq!('\''.escape_default().nth(0), Some('\\')); + + // Check the second char + assert_eq!('\n'.escape_default().nth(1), Some('n')); + assert_eq!('\\'.escape_default().nth(1), Some('\\')); + assert_eq!('\''.escape_default().nth(1), Some('\'')); +} + + +impl EscapeDefault { + fn get_offset(&self) -> Option { + match self.state { + EscapeDefaultState::Backslash(_) => Some(0), + EscapeDefaultState::Char(_) => Some(1), + EscapeDefaultState::Done => None, + EscapeDefaultState::Unicode(_) => None, + } + } } diff --git a/src/librustc/front/map/blocks.rs b/src/librustc/front/map/blocks.rs index 0e24a4446fbe9..a294a8171ee53 100644 --- a/src/librustc/front/map/blocks.rs +++ b/src/librustc/front/map/blocks.rs @@ -130,7 +130,12 @@ struct ClosureParts<'a> { impl<'a> ClosureParts<'a> { fn new(d: &'a FnDecl, b: &'a Block, id: NodeId, s: Span) -> ClosureParts<'a> { - ClosureParts { decl: d, body: b, id: id, span: s } + ClosureParts { + decl: d, + body: b, + id: id, + span: s + } } } diff --git a/src/librustc/front/map/collector.rs b/src/librustc/front/map/collector.rs index e85b0ec77cbbd..1a446a4260834 100644 --- a/src/librustc/front/map/collector.rs +++ b/src/librustc/front/map/collector.rs @@ -22,9 +22,13 @@ use syntax::codemap::Span; /// A Visitor that walks over an AST and collects Node's into an AST /// Map. pub struct NodeCollector<'ast> { + /// The crate pub krate: &'ast Crate, + /// The node map pub map: Vec>, + /// The definitions, used for name resolution pub definitions: Definitions, + /// The parrent of this node pub parent_node: NodeId, } diff --git a/src/librustc/front/map/definitions.rs b/src/librustc/front/map/definitions.rs index e903fcf6a56c2..4ca6eb22ff552 100644 --- a/src/librustc/front/map/definitions.rs +++ b/src/librustc/front/map/definitions.rs @@ -16,6 +16,7 @@ use syntax::ast; use syntax::parse::token::InternedString; use util::nodemap::NodeMap; +/// A definition #[derive(Clone)] pub struct Definitions { data: Vec, @@ -66,36 +67,53 @@ pub type DefPath = Vec; pub enum DefPathData { // Root: these should only be used for the root nodes, because // they are treated specially by the `def_path` function. + /// The crate root (marker) CrateRoot, + /// An inlined root InlinedRoot(DefPath), // Catch-all for random DefId things like DUMMY_NODE_ID Misc, // Different kinds of items and item-like things: + /// An implementation Impl(ast::Name), + /// A type (struct, enum, etc.) Type(ast::Name), + /// A module declaration Mod(ast::Name), + /// A value Value(ast::Name), + /// A macro rule MacroDef(ast::Name), + /// A closure expression ClosureExpr, // Subportions of items + /// A type parameter (generic parameter) TypeParam(ast::Name), + /// A lifetime definition LifetimeDef(ast::Name), + /// A variant of a enum EnumVariant(ast::Name), + /// A positional field, for example a tuple field PositionalField, + /// A struct field Field(hir::StructFieldKind), - StructCtor, // implicit ctor for a tuple-like struct - Initializer, // initializer for a const - Binding(ast::Name), // pattern binding - - // An external crate that does not have an `extern crate` in this - // crate. + /// Implicit ctor for a tuple-like struct + StructCtor, + /// Initializer for a constant + Initializer, + /// A pattern binding + Binding(ast::Name), + + /// An external crate that does not have an `extern crate` in this + /// crate. DetachedCrate(ast::Name), } impl Definitions { + /// Create new empty definition map pub fn new() -> Definitions { Definitions { data: vec![], @@ -104,6 +122,7 @@ impl Definitions { } } + /// Get the number of definitions pub fn len(&self) -> usize { self.data.len() } @@ -138,6 +157,7 @@ impl Definitions { } } + /// Add a definition with a parrent definition pub fn create_def_with_parent(&mut self, parent: Option, node_id: ast::NodeId, diff --git a/src/librustc_back/sha2.rs b/src/librustc_back/sha2.rs index 840f9abce9363..0a5541b790708 100644 --- a/src/librustc_back/sha2.rs +++ b/src/librustc_back/sha2.rs @@ -25,11 +25,10 @@ fn write_u32_be(dst: &mut[u8], input: u32) { /// Read the value of a vector of bytes as a u32 value in big-endian format. fn read_u32_be(input: &[u8]) -> u32 { - return - (input[0] as u32) << 24 | + (input[0] as u32) << 24 | (input[1] as u32) << 16 | (input[2] as u32) << 8 | - (input[3] as u32); + (input[3] as u32) } /// Read a vector of bytes into a vector of u32s. The values are read in big-endian format. @@ -50,7 +49,7 @@ trait ToBits { impl ToBits for u64 { fn to_bits(self) -> (u64, u64) { - return (self >> 61, self << 3); + (self >> 61, self << 3) } } @@ -64,7 +63,7 @@ fn add_bytes_to_bits(bits: u64, bytes: u64) -> u64 { } match bits.checked_add(new_low_bits) { - Some(x) => return x, + Some(x) => x, None => panic!("numeric overflow occurred.") } } @@ -113,10 +112,10 @@ struct FixedBuffer64 { impl FixedBuffer64 { /// Create a new FixedBuffer64 fn new() -> FixedBuffer64 { - return FixedBuffer64 { + FixedBuffer64 { buffer: [0; 64], buffer_idx: 0 - }; + } } } @@ -175,13 +174,13 @@ impl FixedBuffer for FixedBuffer64 { fn next<'s>(&'s mut self, len: usize) -> &'s mut [u8] { self.buffer_idx += len; - return &mut self.buffer[self.buffer_idx - len..self.buffer_idx]; + &mut self.buffer[self.buffer_idx - len..self.buffer_idx] } fn full_buffer<'s>(&'s mut self) -> &'s [u8] { assert!(self.buffer_idx == 64); self.buffer_idx = 0; - return &self.buffer[..64]; + &self.buffer[..64] } fn position(&self) -> usize { self.buffer_idx } @@ -278,7 +277,7 @@ struct Engine256State { impl Engine256State { fn new(h: &[u32; 8]) -> Engine256State { - return Engine256State { + Engine256State { h0: h[0], h1: h[1], h2: h[2], @@ -287,7 +286,7 @@ impl Engine256State { h5: h[5], h6: h[6], h7: h[7] - }; + } } fn reset(&mut self, h: &[u32; 8]) { @@ -433,7 +432,7 @@ struct Engine256 { impl Engine256 { fn new(h: &[u32; 8]) -> Engine256 { - return Engine256 { + Engine256 { length_bits: 0, buffer: FixedBuffer64::new(), state: Engine256State::new(h), @@ -457,17 +456,15 @@ impl Engine256 { } fn finish(&mut self) { - if self.finished { - return; + if !self.finished { + let self_state = &mut self.state; + self.buffer.standard_padding(8, |input: &[u8]| { self_state.process_block(input) }); + write_u32_be(self.buffer.next(4), (self.length_bits >> 32) as u32 ); + write_u32_be(self.buffer.next(4), self.length_bits as u32); + self_state.process_block(self.buffer.full_buffer()); + + self.finished = true; } - - let self_state = &mut self.state; - self.buffer.standard_padding(8, |input: &[u8]| { self_state.process_block(input) }); - write_u32_be(self.buffer.next(4), (self.length_bits >> 32) as u32 ); - write_u32_be(self.buffer.next(4), self.length_bits as u32); - self_state.process_block(self.buffer.full_buffer()); - - self.finished = true; } } diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs index 2532882d0127d..c8c20ecbb3126 100644 --- a/src/librustc_back/svh.rs +++ b/src/librustc_back/svh.rs @@ -67,6 +67,15 @@ impl Svh { } pub fn calculate(metadata: &Vec, krate: &hir::Crate) -> Svh { + fn hex(b: u64) -> char { + let b = (b & 0xf) as u8; + let b = match b { + 0 ... 9 => '0' as u8 + b, + _ => 'a' as u8 + b - 10, + }; + b as char + } + // FIXME (#14132): This is better than it used to be, but it still not // ideal. We now attempt to hash only the relevant portions of the // Crate AST as well as the top-level crate attributes. (However, @@ -101,17 +110,8 @@ impl Svh { } let hash = state.finish(); - return Svh { + Svh { hash: (0..64).step_by(4).map(|i| hex(hash >> i)).collect() - }; - - fn hex(b: u64) -> char { - let b = (b & 0xf) as u8; - let b = match b { - 0 ... 9 => '0' as u8 + b, - _ => 'a' as u8 + b - 10, - }; - b as char } } } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 4420da5f9b87d..1262c2233a393 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -265,6 +265,9 @@ impl<'a> CrateReader<'a> { .as_ref().map(|s|&**s) .unwrap_or("an old version of rustc") ); + + span_help!(self.sess, span, + "consider removing the compiled binaries and recompile"); self.sess.abort_if_errors(); } } diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 90b108e677072..00ee2134fadaa 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -283,6 +283,12 @@ impl OsStr { self.to_bytes().and_then(|b| CString::new(b).ok()) } + /// Checks if the string is empty. + #[unstable(feature = "os_extras", reason = "recently added", issue = "30259")] + pub fn is_empty(&self) -> bool { + self.inner.inner.is_empty() + } + /// Gets the underlying byte representation. /// /// Note: it is *crucial* that this API is private, to avoid diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index cc158eba3c289..9d58ea0cf775b 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -225,6 +225,7 @@ #![feature(const_fn)] #![feature(core_float)] #![feature(core_intrinsics)] +#![feature(convert)] #![feature(decode_utf16)] #![feature(drop_in_place)] #![feature(dropck_parametricity)] @@ -243,6 +244,7 @@ #![feature(on_unimplemented)] #![feature(oom)] #![feature(optin_builtin_traits)] +#![feature(os_extras)] #![feature(placement_in_syntax)] #![feature(rand)] #![feature(range_inclusive)] diff --git a/src/libstd/path.rs b/src/libstd/path.rs index d0b9cc4c4602f..8f8b032735c87 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1146,6 +1146,7 @@ impl PathBuf { pub fn into_os_string(self) -> OsString { self.inner } + } #[stable(feature = "rust1", since = "1.0.0")] @@ -1859,6 +1860,22 @@ impl Path { pub fn is_dir(&self) -> bool { fs::metadata(self).map(|m| m.is_dir()).unwrap_or(false) } + + /// Checks if the path buffer is empty. + /// + /// # Examples + /// + /// ``` + /// use std::path::Path; + /// + /// let path = Path::new("/tmp/foo.rs"); + /// + /// assert!(!path.is_empty()); + /// ``` + #[unstable(feature = "os_extras", reason = "recently added", issue = "30259")] + pub fn is_empty(&self) -> bool { + self.inner.is_empty() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -3188,6 +3205,17 @@ mod tests { } } + #[test] + pub fn is_empty() { + let path = Path::new("/tmp/foo.rs"); + let mut path_buf = PathBuf::new(); + + assert!(!path.is_empty()); + assert!(path_buf.is_empty()); + path_buf.push("catsarecute"); + assert!(!path_buf.is_empty()); + } + #[test] pub fn test_set_extension() { macro_rules! tfe(