From 987560a16a22a43843bc27ee82fda03257d7faf4 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 12 Oct 2015 15:40:47 -0400 Subject: [PATCH 01/15] Add regression test for #22814 Closes #22814 --- src/test/run-pass/issue-22814.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/test/run-pass/issue-22814.rs diff --git a/src/test/run-pass/issue-22814.rs b/src/test/run-pass/issue-22814.rs new file mode 100644 index 00000000000..6afcd770746 --- /dev/null +++ b/src/test/run-pass/issue-22814.rs @@ -0,0 +1,22 @@ +// 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. + +trait Test {} + +macro_rules! test { +( $($name:ident)+) => ( + impl<$($name: Test),*> Test for ($($name,)*) { + } +) +} + +test!(A B C); + +fn main() {} From ed2a11da89252774fe15bd0eafdf94545ad4644f Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Mon, 12 Oct 2015 23:37:52 +0300 Subject: [PATCH 02/15] require a method callee's type to outlive the call This rather crucial requirement was not checked. In most cases, that didn't cause any trouble because the argument types are required to outlive the call and are subtypes of a subformula of the callee type. However, binary ops are taken by ref only indirectly, without it being marked in the argument types, which led to the argument types not being constrained anywhere causing spurious errors (as these are basically unconstrainable, I don't think this change can break code). Of course, the old way was also incorrent with contravariance, but that is still unsound for other reasons. This also improves rustc::front to get RUST_LOG to *somewhat* work. Fixes #28999 --- src/librustc/front/map/mod.rs | 5 ++++- src/librustc_typeck/check/regionck.rs | 4 ++++ src/test/run-pass/issue-28999.rs | 20 ++++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/issue-28999.rs diff --git a/src/librustc/front/map/mod.rs b/src/librustc/front/map/mod.rs index 396e2bb5703..9591ed2f71d 100644 --- a/src/librustc/front/map/mod.rs +++ b/src/librustc/front/map/mod.rs @@ -527,6 +527,10 @@ impl<'ast> Map<'ast> { NodeTraitItem(ti) => PathName(ti.name), NodeVariant(v) => PathName(v.node.name), NodeLifetime(lt) => PathName(lt.name), + NodeTyParam(tp) => PathName(tp.name), + NodeLocal(&Pat { node: PatIdent(_,l,_), .. }) => { + PathName(l.node.name) + }, _ => panic!("no path elem for {:?}", node) } } @@ -987,4 +991,3 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { } } } - diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index c2610da3944..31e6c942dc6 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -592,6 +592,8 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) { }; substs_wf_in_scope(rcx, origin, &callee.substs, expr.span, expr_region); + type_must_outlive(rcx, infer::ExprTypeIsNotInScope(callee.ty, expr.span), + callee.ty, expr_region); } // Check any autoderefs or autorefs that appear. @@ -664,6 +666,8 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) { } } + debug!("regionck::visit_expr(e={:?}, repeating_scope={}) - visiting subexprs", + expr, rcx.repeating_scope); match expr.node { hir::ExprPath(..) => { rcx.fcx.opt_node_ty_substs(expr.id, |item_substs| { diff --git a/src/test/run-pass/issue-28999.rs b/src/test/run-pass/issue-28999.rs new file mode 100644 index 00000000000..87112ef1719 --- /dev/null +++ b/src/test/run-pass/issue-28999.rs @@ -0,0 +1,20 @@ +// 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. + +pub struct Xyz<'a, V> { + pub v: (V, &'a u32), +} + +pub fn eq<'a, 's, 't, V>(this: &'s Xyz<'a, V>, other: &'t Xyz<'a, V>) -> bool + where V: PartialEq { + this.v == other.v +} + +fn main() {} From 42e0b8bc7eff10902679e7c9a7556ff43f25ec58 Mon Sep 17 00:00:00 2001 From: Chris C Cerami Date: Mon, 12 Oct 2015 22:24:51 -0400 Subject: [PATCH 03/15] Fix Lifetime Elision link in lifetimes.md --- src/doc/trpl/lifetimes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/trpl/lifetimes.md b/src/doc/trpl/lifetimes.md index 23569dd1b91..aea0fdcce5d 100644 --- a/src/doc/trpl/lifetimes.md +++ b/src/doc/trpl/lifetimes.md @@ -74,7 +74,7 @@ associated with it, but the compiler lets you elide (i.e. omit, see ["Lifetime Elision"][lifetime-elision] below) them in common cases. Before we get to that, though, let’s break the explicit example down: -[lifetime-elision]: #user-content-lifetime-elision +[lifetime-elision]: #lifetime-elision ```rust,ignore fn bar<'a>(...) From 22dc40821770db567915250af3f8c2fdb0c1ab81 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Tue, 13 Oct 2015 15:11:59 +0900 Subject: [PATCH 04/15] Avoid using getDataLayout, deprecated in LLVM 3.7 --- src/rustllvm/PassWrapper.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 4308023a9a5..16c35970bfe 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -335,8 +335,7 @@ LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module, LLVMTargetMachineRef TMR) { TargetMachine *Target = unwrap(TMR); #if LLVM_VERSION_MINOR >= 7 - if (const DataLayout *DL = Target->getDataLayout()) - unwrap(Module)->setDataLayout(*DL); + unwrap(Module)->setDataLayout(Target->createDataLayout()); #elif LLVM_VERSION_MINOR >= 6 if (const DataLayout *DL = Target->getSubtargetImpl()->getDataLayout()) unwrap(Module)->setDataLayout(DL); From 3db501268010caf4bc072453ef832c5cec25570e Mon Sep 17 00:00:00 2001 From: Jose Narvaez Date: Mon, 12 Oct 2015 11:28:54 +0100 Subject: [PATCH 05/15] rustfmt suggested changes. --- src/liblog/directive.rs | 86 +++++++++++++++-------------- src/liblog/lib.rs | 118 +++++++++++++++++++++++----------------- 2 files changed, 115 insertions(+), 89 deletions(-) diff --git a/src/liblog/directive.rs b/src/liblog/directive.rs index 362303869d7..82e93fa9e3a 100644 --- a/src/liblog/directive.rs +++ b/src/liblog/directive.rs @@ -17,15 +17,17 @@ pub struct LogDirective { pub level: u32, } -pub const LOG_LEVEL_NAMES: [&'static str; 4] = ["ERROR", "WARN", "INFO", - "DEBUG"]; +pub const LOG_LEVEL_NAMES: [&'static str; 4] = ["ERROR", "WARN", "INFO", "DEBUG"]; /// Parse an individual log level that is either a number or a symbolic log level fn parse_log_level(level: &str) -> Option { - level.parse::().ok().or_else(|| { - let pos = LOG_LEVEL_NAMES.iter().position(|&name| name.eq_ignore_ascii_case(level)); - pos.map(|p| p as u32 + 1) - }).map(|p| cmp::min(p, ::MAX_LOG_LEVEL)) + level.parse::() + .ok() + .or_else(|| { + let pos = LOG_LEVEL_NAMES.iter().position(|&name| name.eq_ignore_ascii_case(level)); + pos.map(|p| p as u32 + 1) + }) + .map(|p| cmp::min(p, ::MAX_LOG_LEVEL)) } /// Parse a logging specification string (e.g: "crate1,crate2::mod3,crate3::x=1/foo") @@ -40,44 +42,48 @@ pub fn parse_logging_spec(spec: &str) -> (Vec, Option) { let mods = parts.next(); let filter = parts.next(); if parts.next().is_some() { - println!("warning: invalid logging spec '{}', \ - ignoring it (too many '/'s)", spec); + println!("warning: invalid logging spec '{}', ignoring it (too many '/'s)", + spec); return (dirs, None); } - mods.map(|m| { for s in m.split(',') { - if s.is_empty() { continue } - let mut parts = s.split('='); - let (log_level, name) = match (parts.next(), parts.next().map(|s| s.trim()), parts.next()) { - (Some(part0), None, None) => { - // if the single argument is a log-level string or number, - // treat that as a global fallback - match parse_log_level(part0) { - Some(num) => (num, None), - None => (::MAX_LOG_LEVEL, Some(part0)), - } - } - (Some(part0), Some(""), None) => (::MAX_LOG_LEVEL, Some(part0)), - (Some(part0), Some(part1), None) => { - match parse_log_level(part1) { - Some(num) => (num, Some(part0)), - _ => { - println!("warning: invalid logging spec '{}', \ - ignoring it", part1); - continue - } - } - }, - _ => { - println!("warning: invalid logging spec '{}', \ - ignoring it", s); + mods.map(|m| { + for s in m.split(',') { + if s.is_empty() { continue } - }; - dirs.push(LogDirective { - name: name.map(str::to_owned), - level: log_level, - }); - }}); + let mut parts = s.split('='); + let (log_level, name) = match (parts.next(), + parts.next().map(|s| s.trim()), + parts.next()) { + (Some(part0), None, None) => { + // if the single argument is a log-level string or number, + // treat that as a global fallback + match parse_log_level(part0) { + Some(num) => (num, None), + None => (::MAX_LOG_LEVEL, Some(part0)), + } + } + (Some(part0), Some(""), None) => (::MAX_LOG_LEVEL, Some(part0)), + (Some(part0), Some(part1), None) => { + match parse_log_level(part1) { + Some(num) => (num, Some(part0)), + _ => { + println!("warning: invalid logging spec '{}', ignoring it", part1); + continue + } + } + } + _ => { + println!("warning: invalid logging spec '{}', ignoring it", s); + continue + } + }; + dirs.push(LogDirective { + name: name.map(str::to_owned), + level: log_level, + }); + } + }); (dirs, filter.map(str::to_owned)) } diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index 2c91a88f6ec..7b846e0bf57 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -235,7 +235,9 @@ pub trait Logger { fn log(&mut self, record: &LogRecord); } -struct DefaultLogger { handle: Stderr } +struct DefaultLogger { + handle: Stderr, +} /// Wraps the log level with fmt implementations. #[derive(Copy, Clone, PartialEq, PartialOrd, Debug)] @@ -246,7 +248,7 @@ impl fmt::Display for LogLevel { let LogLevel(level) = *self; match LOG_LEVEL_NAMES.get(level as usize - 1) { Some(ref name) => fmt::Display::fmt(name, fmt), - None => fmt::Display::fmt(&level, fmt) + None => fmt::Display::fmt(&level, fmt), } } } @@ -301,11 +303,10 @@ pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) { // Completely remove the local logger from TLS in case anyone attempts to // frob the slot while we're doing the logging. This will destroy any logger // set during logging. - let mut logger: Box = LOCAL_LOGGER.with(|s| { - s.borrow_mut().take() - }).unwrap_or_else(|| { - box DefaultLogger { handle: io::stderr() } - }); + let mut logger: Box = LOCAL_LOGGER.with(|s| s.borrow_mut().take()) + .unwrap_or_else(|| { + box DefaultLogger { handle: io::stderr() } + }); logger.log(&LogRecord { level: LogLevel(level), args: args, @@ -320,22 +321,21 @@ pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) { /// safely #[doc(hidden)] #[inline(always)] -pub fn log_level() -> u32 { unsafe { LOG_LEVEL } } +pub fn log_level() -> u32 { + unsafe { LOG_LEVEL } +} /// Replaces the thread-local logger with the specified logger, returning the old /// logger. pub fn set_logger(logger: Box) -> Option> { let mut l = Some(logger); - LOCAL_LOGGER.with(|slot| { - mem::replace(&mut *slot.borrow_mut(), l.take()) - }) + LOCAL_LOGGER.with(|slot| mem::replace(&mut *slot.borrow_mut(), l.take())) } /// A LogRecord is created by the logging macros, and passed as the only /// argument to Loggers. #[derive(Debug)] pub struct LogRecord<'a> { - /// The module path of where the LogRecord originated. pub module_path: &'a str, @@ -373,7 +373,9 @@ pub fn mod_enabled(level: u32, module: &str) -> bool { // again to whether they should really be here or not. Hence, despite this // check being expanded manually in the logging macro, this function checks // the log level again. - if level > unsafe { LOG_LEVEL } { return false } + if level > unsafe { LOG_LEVEL } { + return false + } // This assertion should never get tripped unless we're in an at_exit // handler after logging has been torn down and a logging attempt was made. @@ -385,14 +387,11 @@ pub fn mod_enabled(level: u32, module: &str) -> bool { } } -fn enabled(level: u32, - module: &str, - iter: slice::Iter) - -> bool { +fn enabled(level: u32, module: &str, iter: slice::Iter) -> bool { // Search for the longest match, the vector is assumed to be pre-sorted. for directive in iter.rev() { match directive.name { - Some(ref name) if !module.starts_with(&name[..]) => {}, + Some(ref name) if !module.starts_with(&name[..]) => {} Some(..) | None => { return level <= directive.level } @@ -445,16 +444,14 @@ mod tests { #[test] fn match_full_path() { - let dirs = [ - LogDirective { - name: Some("crate2".to_string()), - level: 3 - }, - LogDirective { - name: Some("crate1::mod1".to_string()), - level: 2 - } - ]; + let dirs = [LogDirective { + name: Some("crate2".to_string()), + level: 3, + }, + LogDirective { + name: Some("crate1::mod1".to_string()), + level: 2, + }]; assert!(enabled(2, "crate1::mod1", dirs.iter())); assert!(!enabled(3, "crate1::mod1", dirs.iter())); assert!(enabled(3, "crate2", dirs.iter())); @@ -463,49 +460,72 @@ mod tests { #[test] fn no_match() { - let dirs = [ - LogDirective { name: Some("crate2".to_string()), level: 3 }, - LogDirective { name: Some("crate1::mod1".to_string()), level: 2 } - ]; + let dirs = [LogDirective { + name: Some("crate2".to_string()), + level: 3, + }, + LogDirective { + name: Some("crate1::mod1".to_string()), + level: 2, + }]; assert!(!enabled(2, "crate3", dirs.iter())); } #[test] fn match_beginning() { - let dirs = [ - LogDirective { name: Some("crate2".to_string()), level: 3 }, - LogDirective { name: Some("crate1::mod1".to_string()), level: 2 } - ]; + let dirs = [LogDirective { + name: Some("crate2".to_string()), + level: 3, + }, + LogDirective { + name: Some("crate1::mod1".to_string()), + level: 2, + }]; assert!(enabled(3, "crate2::mod1", dirs.iter())); } #[test] fn match_beginning_longest_match() { - let dirs = [ - LogDirective { name: Some("crate2".to_string()), level: 3 }, - LogDirective { name: Some("crate2::mod".to_string()), level: 4 }, - LogDirective { name: Some("crate1::mod1".to_string()), level: 2 } - ]; + let dirs = [LogDirective { + name: Some("crate2".to_string()), + level: 3, + }, + LogDirective { + name: Some("crate2::mod".to_string()), + level: 4, + }, + LogDirective { + name: Some("crate1::mod1".to_string()), + level: 2, + }]; assert!(enabled(4, "crate2::mod1", dirs.iter())); assert!(!enabled(4, "crate2", dirs.iter())); } #[test] fn match_default() { - let dirs = [ - LogDirective { name: None, level: 3 }, - LogDirective { name: Some("crate1::mod1".to_string()), level: 2 } - ]; + let dirs = [LogDirective { + name: None, + level: 3, + }, + LogDirective { + name: Some("crate1::mod1".to_string()), + level: 2, + }]; assert!(enabled(2, "crate1::mod1", dirs.iter())); assert!(enabled(3, "crate2::mod2", dirs.iter())); } #[test] fn zero_level() { - let dirs = [ - LogDirective { name: None, level: 3 }, - LogDirective { name: Some("crate1::mod1".to_string()), level: 0 } - ]; + let dirs = [LogDirective { + name: None, + level: 3, + }, + LogDirective { + name: Some("crate1::mod1".to_string()), + level: 0, + }]; assert!(!enabled(1, "crate1::mod1", dirs.iter())); assert!(enabled(3, "crate2::mod2", dirs.iter())); } From 5943af31e7adbb6a713755dbfd4f60158d12b91e Mon Sep 17 00:00:00 2001 From: Jose Narvaez Date: Tue, 13 Oct 2015 10:44:09 +0100 Subject: [PATCH 06/15] Re-running updated rustfmt on liblog. --- src/liblog/lib.rs | 78 +++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index 7b846e0bf57..b3268c32f18 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -445,13 +445,13 @@ mod tests { #[test] fn match_full_path() { let dirs = [LogDirective { - name: Some("crate2".to_string()), - level: 3, - }, + name: Some("crate2".to_string()), + level: 3, + }, LogDirective { - name: Some("crate1::mod1".to_string()), - level: 2, - }]; + name: Some("crate1::mod1".to_string()), + level: 2, + }]; assert!(enabled(2, "crate1::mod1", dirs.iter())); assert!(!enabled(3, "crate1::mod1", dirs.iter())); assert!(enabled(3, "crate2", dirs.iter())); @@ -461,43 +461,43 @@ mod tests { #[test] fn no_match() { let dirs = [LogDirective { - name: Some("crate2".to_string()), - level: 3, - }, + name: Some("crate2".to_string()), + level: 3, + }, LogDirective { - name: Some("crate1::mod1".to_string()), - level: 2, - }]; + name: Some("crate1::mod1".to_string()), + level: 2, + }]; assert!(!enabled(2, "crate3", dirs.iter())); } #[test] fn match_beginning() { let dirs = [LogDirective { - name: Some("crate2".to_string()), - level: 3, - }, + name: Some("crate2".to_string()), + level: 3, + }, LogDirective { - name: Some("crate1::mod1".to_string()), - level: 2, - }]; + name: Some("crate1::mod1".to_string()), + level: 2, + }]; assert!(enabled(3, "crate2::mod1", dirs.iter())); } #[test] fn match_beginning_longest_match() { let dirs = [LogDirective { - name: Some("crate2".to_string()), - level: 3, - }, + name: Some("crate2".to_string()), + level: 3, + }, LogDirective { - name: Some("crate2::mod".to_string()), - level: 4, - }, + name: Some("crate2::mod".to_string()), + level: 4, + }, LogDirective { - name: Some("crate1::mod1".to_string()), - level: 2, - }]; + name: Some("crate1::mod1".to_string()), + level: 2, + }]; assert!(enabled(4, "crate2::mod1", dirs.iter())); assert!(!enabled(4, "crate2", dirs.iter())); } @@ -505,13 +505,13 @@ mod tests { #[test] fn match_default() { let dirs = [LogDirective { - name: None, - level: 3, - }, + name: None, + level: 3, + }, LogDirective { - name: Some("crate1::mod1".to_string()), - level: 2, - }]; + name: Some("crate1::mod1".to_string()), + level: 2, + }]; assert!(enabled(2, "crate1::mod1", dirs.iter())); assert!(enabled(3, "crate2::mod2", dirs.iter())); } @@ -519,13 +519,13 @@ mod tests { #[test] fn zero_level() { let dirs = [LogDirective { - name: None, - level: 3, - }, + name: None, + level: 3, + }, LogDirective { - name: Some("crate1::mod1".to_string()), - level: 0, - }]; + name: Some("crate1::mod1".to_string()), + level: 0, + }]; assert!(!enabled(1, "crate1::mod1", dirs.iter())); assert!(enabled(3, "crate2::mod2", dirs.iter())); } From 94946db60d84d1a6a5d45dc7be7e778882637367 Mon Sep 17 00:00:00 2001 From: Jose Narvaez Date: Tue, 13 Oct 2015 10:46:41 +0100 Subject: [PATCH 07/15] Manually alligned comments. --- src/liblog/directive.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/liblog/directive.rs b/src/liblog/directive.rs index 82e93fa9e3a..12a5c131170 100644 --- a/src/liblog/directive.rs +++ b/src/liblog/directive.rs @@ -56,8 +56,8 @@ pub fn parse_logging_spec(spec: &str) -> (Vec, Option) { parts.next().map(|s| s.trim()), parts.next()) { (Some(part0), None, None) => { - // if the single argument is a log-level string or number, - // treat that as a global fallback + // if the single argument is a log-level string or number, + // treat that as a global fallback match parse_log_level(part0) { Some(num) => (num, None), None => (::MAX_LOG_LEVEL, Some(part0)), From 1bdf4ad8dc7cdd098f22edb4627e37462ddbfd6b Mon Sep 17 00:00:00 2001 From: Marcello Seri Date: Tue, 13 Oct 2015 15:10:51 +0100 Subject: [PATCH 08/15] rustfmt libfmt_macros --- src/libfmt_macros/lib.rs | 380 ++++++++++++++++++++++----------------- 1 file changed, 220 insertions(+), 160 deletions(-) diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 9c02ccb08ac..41571366af5 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -75,7 +75,7 @@ pub struct FormatSpec<'a> { /// The descriptor string representing the name of the format desired for /// this argument, this can be empty or any number of characters, although /// it is required to be one word. - pub ty: &'a str + pub ty: &'a str, } /// Enum describing where an argument for a format can be located. @@ -202,7 +202,12 @@ impl<'a> Parser<'a> { /// returned, otherwise the character is consumed and true is returned. fn consume(&mut self, c: char) -> bool { if let Some(&(_, maybe)) = self.cur.peek() { - if c == maybe { self.cur.next(); true } else { false } + if c == maybe { + self.cur.next(); + true + } else { + false + } } else { false } @@ -227,7 +232,11 @@ impl<'a> Parser<'a> { /// character fn ws(&mut self) { while let Some(&(_, c)) = self.cur.peek() { - if c.is_whitespace() { self.cur.next(); } else { break } + if c.is_whitespace() { + self.cur.next(); + } else { + break + } } } @@ -237,8 +246,12 @@ impl<'a> Parser<'a> { // we may not consume the character, peek the iterator while let Some(&(pos, c)) = self.cur.peek() { match c { - '{' | '}' => { return &self.input[start..pos]; } - _ => { self.cur.next(); } + '{' | '}' => { + return &self.input[start..pos]; + } + _ => { + self.cur.next(); + } } } &self.input[start..self.input.len()] @@ -263,7 +276,7 @@ impl<'a> Parser<'a> { Some(&(_, c)) if c.is_alphabetic() => { ArgumentNamed(self.word()) } - _ => ArgumentNext + _ => ArgumentNext, } } } @@ -279,7 +292,9 @@ impl<'a> Parser<'a> { width: CountImplied, ty: &self.input[..0], }; - if !self.consume(':') { return spec } + if !self.consume(':') { + return spec + } // fill character if let Some(&(_, c)) = self.cur.peek() { @@ -347,7 +362,11 @@ impl<'a> Parser<'a> { /// width. fn count(&mut self) -> Count<'a> { if let Some(i) = self.integer() { - if self.consume('$') { CountIsParam(i) } else { CountIs(i) } + if self.consume('$') { + CountIsParam(i) + } else { + CountIs(i) + } } else { let tmp = self.cur.clone(); let word = self.word(); @@ -370,8 +389,13 @@ impl<'a> Parser<'a> { /// characters. fn word(&mut self) -> &'a str { let start = match self.cur.peek() { - Some(&(pos, c)) if c.is_xid_start() => { self.cur.next(); pos } - _ => { return &self.input[..0]; } + Some(&(pos, c)) if c.is_xid_start() => { + self.cur.next(); + pos + } + _ => { + return &self.input[..0]; + } }; while let Some(&(pos, c)) = self.cur.peek() { if c.is_xid_continue() { @@ -397,7 +421,11 @@ impl<'a> Parser<'a> { break } } - if found { Some(cur) } else { None } + if found { + Some(cur) + } else { + None + } } } @@ -437,178 +465,210 @@ mod tests { same("\\}}", &[String("\\"), String("}")]); } - #[test] fn invalid01() { musterr("{") } - #[test] fn invalid02() { musterr("}") } - #[test] fn invalid04() { musterr("{3a}") } - #[test] fn invalid05() { musterr("{:|}") } - #[test] fn invalid06() { musterr("{:>>>}") } + #[test] + fn invalid01() { + musterr("{") + } + #[test] + fn invalid02() { + musterr("}") + } + #[test] + fn invalid04() { + musterr("{3a}") + } + #[test] + fn invalid05() { + musterr("{:|}") + } + #[test] + fn invalid06() { + musterr("{:>>>}") + } #[test] fn format_nothing() { - same("{}", &[NextArgument(Argument { - position: ArgumentNext, - format: fmtdflt(), - })]); + same("{}", + &[NextArgument(Argument { + position: ArgumentNext, + format: fmtdflt(), + })]); } #[test] fn format_position() { - same("{3}", &[NextArgument(Argument { - position: ArgumentIs(3), - format: fmtdflt(), - })]); + same("{3}", + &[NextArgument(Argument { + position: ArgumentIs(3), + format: fmtdflt(), + })]); } #[test] fn format_position_nothing_else() { - same("{3:}", &[NextArgument(Argument { - position: ArgumentIs(3), - format: fmtdflt(), - })]); + same("{3:}", + &[NextArgument(Argument { + position: ArgumentIs(3), + format: fmtdflt(), + })]); } #[test] fn format_type() { - same("{3:a}", &[NextArgument(Argument { - position: ArgumentIs(3), - format: FormatSpec { - fill: None, - align: AlignUnknown, - flags: 0, - precision: CountImplied, - width: CountImplied, - ty: "a", - }, - })]); + same("{3:a}", + &[NextArgument(Argument { + position: ArgumentIs(3), + format: FormatSpec { + fill: None, + align: AlignUnknown, + flags: 0, + precision: CountImplied, + width: CountImplied, + ty: "a", + }, + })]); } #[test] fn format_align_fill() { - same("{3:>}", &[NextArgument(Argument { - position: ArgumentIs(3), - format: FormatSpec { - fill: None, - align: AlignRight, - flags: 0, - precision: CountImplied, - width: CountImplied, - ty: "", - }, - })]); - same("{3:0<}", &[NextArgument(Argument { - position: ArgumentIs(3), - format: FormatSpec { - fill: Some('0'), - align: AlignLeft, - flags: 0, - precision: CountImplied, - width: CountImplied, - ty: "", - }, - })]); - same("{3:*}", + &[NextArgument(Argument { + position: ArgumentIs(3), + format: FormatSpec { + fill: None, + align: AlignRight, + flags: 0, + precision: CountImplied, + width: CountImplied, + ty: "", + }, + })]); + same("{3:0<}", + &[NextArgument(Argument { + position: ArgumentIs(3), + format: FormatSpec { + fill: Some('0'), + align: AlignLeft, + flags: 0, + precision: CountImplied, + width: CountImplied, + ty: "", + }, + })]); + same("{3:* Date: Tue, 13 Oct 2015 15:12:34 +0100 Subject: [PATCH 09/15] fixups --- src/libfmt_macros/lib.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 41571366af5..4b70f5813bc 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -421,11 +421,7 @@ impl<'a> Parser<'a> { break } } - if found { - Some(cur) - } else { - None - } + if found { Some(cur) } else { None } } } From 12224bec21c486165b973bc8996f230bde6e78fb Mon Sep 17 00:00:00 2001 From: Seeker14491 Date: Tue, 13 Oct 2015 13:45:10 -0500 Subject: [PATCH 10/15] Unhide some code from the Traits section Having this code section hidden is misleading because it makes it look like implementing Circle for Foo automatically makes Foo implement Shape. --- src/doc/reference.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index 9ce191ee589..917ade83735 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -1435,11 +1435,11 @@ struct Foo; trait Shape { fn area(&self) -> f64; } trait Circle : Shape { fn radius(&self) -> f64; } -# impl Shape for Foo { -# fn area(&self) -> f64 { -# 0.0 -# } -# } +impl Shape for Foo { + fn area(&self) -> f64 { + 0.0 + } +} impl Circle for Foo { fn radius(&self) -> f64 { println!("calling area: {}", self.area()); From 70c70b739f6d956d6fbdafc101f8198a9476da92 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 13 Oct 2015 14:46:17 -0400 Subject: [PATCH 11/15] Document the free functions of std::iter Flesh the docs out with examples. --- src/libcore/iter.rs | 110 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-) diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 2f12579d674..834ba91a828 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -3032,7 +3032,52 @@ impl DoubleEndedIterator for Repeat { fn next_back(&mut self) -> Option { Some(self.element.clone()) } } -/// Creates a new iterator that endlessly repeats the element `elt`. +/// Creates a new iterator that endlessly repeats a single element. +/// +/// The `repeat()` function repeats a single value over and over and over and +/// over and over and 🔁. +/// +/// Infinite iterators like `repeat()` are often used with adapters like +/// [`take()`], in order to make them finite. +/// +/// [`take()`]: trait.Iterator.html#method.take +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::iter; +/// +/// // the number four 4ever: +/// let mut fours = iter::repeat(4); +/// +/// assert_eq!(Some(4), fours.next()); +/// assert_eq!(Some(4), fours.next()); +/// assert_eq!(Some(4), fours.next()); +/// assert_eq!(Some(4), fours.next()); +/// assert_eq!(Some(4), fours.next()); +/// +/// // yup, still four +/// assert_eq!(Some(4), fours.next()); +/// ``` +/// +/// Going finite with [`take()`]: +/// +/// ``` +/// use std::iter; +/// +/// // that last example was too many fours. Let's only have four fours. +/// let mut four_fours = iter::repeat(4).take(4); +/// +/// assert_eq!(Some(4), four_fours.next()); +/// assert_eq!(Some(4), four_fours.next()); +/// assert_eq!(Some(4), four_fours.next()); +/// assert_eq!(Some(4), four_fours.next()); +/// +/// // ... and now we're done +/// assert_eq!(None, four_fours.next()); +/// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn repeat(elt: T) -> Repeat { @@ -3089,6 +3134,19 @@ impl Default for Empty { } /// Creates an iterator that yields nothing. +/// +/// # Exampes +/// +/// Basic usage: +/// +/// ``` +/// use std::iter; +/// +/// // this could have been an iterator over i32, but alas, it's just not. +/// let mut nope = iter::empty::(); +/// +/// assert_eq!(None, nope.next()); +/// ``` #[stable(feature = "iter_empty", since = "1.2.0")] pub fn empty() -> Empty { Empty(marker::PhantomData) @@ -3129,6 +3187,56 @@ impl ExactSizeIterator for Once { } /// Creates an iterator that yields an element exactly once. +/// +/// This is commonly used to adapt a single value into a [`chain()`] of other +/// kinds of iteration. Maybe you have an iterator that covers almost +/// everything, but you need an extra special case. Maybe you have a function +/// which works on iterators, but you only need to process one value. +/// +/// [`chain()`]: trait.Iterator.html#method.chain +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::iter; +/// +/// // one is the loneliest number +/// let mut one = iter::once(1); +/// +/// assert_eq!(Some(1), one.next()); +/// +/// // just one, that's all we get +/// assert_eq!(None, one.next()); +/// ``` +/// +/// Chaining together with another iterator. Let's say that we want to iterate +/// over each file of the `.foo` directory, but also a configuration file, +/// `.foorc`: +/// +/// ```no_run +/// use std::iter; +/// use std::fs; +/// use std::path::PathBuf; +/// +/// let dirs = fs::read_dir(".foo").unwrap(); +/// +/// // we need to convert from an iterator of DirEntry-s to an iterator of +/// // PathBufs, so we use map +/// let dirs = dirs.map(|file| file.unwrap().path()); +/// +/// // now, our iterator just for our config file +/// let config = iter::once(PathBuf::from(".foorc")); +/// +/// // chain the two iterators together into one big iterator +/// let files = dirs.chain(config); +/// +/// // this will give us all of the files in .foo as well as .foorc +/// for f in files { +/// println!("{:?}", f); +/// } +/// ``` #[stable(feature = "iter_once", since = "1.2.0")] pub fn once(value: T) -> Once { Once { inner: Some(value).into_iter() } From 19a2a769a5d74d1c0fabc71a3829c4042824fb05 Mon Sep 17 00:00:00 2001 From: Jose Narvaez Date: Tue, 13 Oct 2015 23:14:32 +0100 Subject: [PATCH 12/15] Rustfmt-ing librustc_bitflags. --- src/librustc_bitflags/lib.rs | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/librustc_bitflags/lib.rs b/src/librustc_bitflags/lib.rs index 3ee45c3506e..16f586cf5e0 100644 --- a/src/librustc_bitflags/lib.rs +++ b/src/librustc_bitflags/lib.rs @@ -22,7 +22,9 @@ //! A typesafe bitmask flag generator. -#[cfg(test)] #[macro_use] extern crate std; +#[cfg(test)] +#[macro_use] +extern crate std; /// The `bitflags!` macro generates a `struct` that holds a set of C-style /// bitmask flags. It is useful for creating typesafe wrappers for C APIs. @@ -321,7 +323,7 @@ mod tests { } #[test] - fn test_bits(){ + fn test_bits() { assert_eq!(Flags::empty().bits(), 0b00000000); assert_eq!(Flags::FlagA.bits(), 0b00000001); assert_eq!(Flags::FlagABC.bits(), 0b00000111); @@ -354,7 +356,7 @@ mod tests { } #[test] - fn test_is_empty(){ + fn test_is_empty() { assert!(Flags::empty().is_empty()); assert!(!Flags::FlagA.is_empty()); assert!(!Flags::FlagABC.is_empty()); @@ -413,7 +415,7 @@ mod tests { } #[test] - fn test_insert(){ + fn test_insert() { let mut e1 = Flags::FlagA; let e2 = Flags::FlagA | Flags::FlagB; e1.insert(e2); @@ -425,7 +427,7 @@ mod tests { } #[test] - fn test_remove(){ + fn test_remove() { let mut e1 = Flags::FlagA | Flags::FlagB; let e2 = Flags::FlagA | Flags::FlagC; e1.remove(e2); @@ -484,12 +486,12 @@ mod tests { #[test] fn test_hash() { - let mut x = Flags::empty(); - let mut y = Flags::empty(); - assert!(hash(&x) == hash(&y)); - x = Flags::all(); - y = Flags::FlagABC; - assert!(hash(&x) == hash(&y)); + let mut x = Flags::empty(); + let mut y = Flags::empty(); + assert!(hash(&x) == hash(&y)); + x = Flags::all(); + y = Flags::FlagABC; + assert!(hash(&x) == hash(&y)); } fn hash(t: &T) -> u64 { From 1454b426f04f78b9c6a3de0ee7b1d47e355abdb0 Mon Sep 17 00:00:00 2001 From: Marcello Seri Date: Tue, 13 Oct 2015 23:21:05 +0100 Subject: [PATCH 13/15] Revert "fixups" This reverts commit 5b8335ede4214f802eab765ca99b5afa9057973c. --- src/libfmt_macros/lib.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 4b70f5813bc..41571366af5 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -421,7 +421,11 @@ impl<'a> Parser<'a> { break } } - if found { Some(cur) } else { None } + if found { + Some(cur) + } else { + None + } } } From fda2f733c5ef86f7bfca4e0d61c989fea4b69fd7 Mon Sep 17 00:00:00 2001 From: Vladimir Rutsky Date: Wed, 14 Oct 2015 02:17:31 +0300 Subject: [PATCH 14/15] fix link on std::result::Result The link is broken here: . Looks like crate documentation generator uses only first paragraph of the module documentation and so doesn't resolve the link defined below. --- src/libstd/io/error.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs index 773f9ac6a12..121eeae9e48 100644 --- a/src/libstd/io/error.rs +++ b/src/libstd/io/error.rs @@ -17,9 +17,8 @@ use option::Option::{self, Some, None}; use result; use sys; -/// A specialized [`Result`][result] type for I/O operations. -/// -/// [result]: ../result/enum.Result.html +/// A specialized [`Result`](../result/enum.Result.html) type for I/O +/// operations. /// /// This type is broadly used across `std::io` for any operation which may /// produce an error. From 66b58d19bdeceba7aa3f4043fefd796f8c8b426c Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 14 Oct 2015 12:52:14 +0530 Subject: [PATCH 15/15] fix tidy --- src/libstd/io/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs index 121eeae9e48..6f18aad6235 100644 --- a/src/libstd/io/error.rs +++ b/src/libstd/io/error.rs @@ -17,7 +17,7 @@ use option::Option::{self, Some, None}; use result; use sys; -/// A specialized [`Result`](../result/enum.Result.html) type for I/O +/// A specialized [`Result`](../result/enum.Result.html) type for I/O /// operations. /// /// This type is broadly used across `std::io` for any operation which may