diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index e15304a7e6e67..bfba1a0dede24 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -398,13 +398,14 @@ def run(self, args, env=None, cwd=None): sys.exit(ret) def output(self, args, env=None, cwd=None): + default_encoding = sys.getdefaultencoding() proc = subprocess.Popen(args, stdout=subprocess.PIPE, env=env, cwd=cwd) (out, err) = proc.communicate() ret = proc.wait() if ret != 0: print(out) sys.exit(ret) - return out + return out.decode(default_encoding) def build_triple(self): default_encoding = sys.getdefaultencoding() @@ -570,10 +571,10 @@ def update_submodules(self): for submod in submodules: path, status = submod - if path.endswith(b"llvm") and \ + if path.endswith('llvm') and \ (self.get_toml('llvm-config') or self.get_mk('CFG_LLVM_ROOT')): continue - if path.endswith(b"jemalloc") and \ + if path.endswith('jemalloc') and \ (self.get_toml('jemalloc') or self.get_mk('CFG_JEMALLOC_ROOT')): continue submod_path = os.path.join(self.rust_root, path) diff --git a/src/doc/unstable-book/src/library-features/iterator-step-by.md b/src/doc/unstable-book/src/library-features/iterator-step-by.md new file mode 100644 index 0000000000000..8467cb68862f7 --- /dev/null +++ b/src/doc/unstable-book/src/library-features/iterator-step-by.md @@ -0,0 +1,7 @@ +# `iterator_step_by` + +The tracking issue for this feature is: [#27741] + +[#27741]: https://github.com/rust-lang/rust/issues/27741 + +------------------------ diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 67b97afb9769a..77cbdb98c8304 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -11,7 +11,7 @@ use cmp::Ordering; use super::{Chain, Cycle, Cloned, Enumerate, Filter, FilterMap, FlatMap, Fuse}; -use super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, Take, TakeWhile, Rev}; +use super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, StepBy, Take, TakeWhile, Rev}; use super::{Zip, Sum, Product}; use super::{ChainState, FromIterator, ZipImpl}; @@ -258,6 +258,39 @@ pub trait Iterator { None } + /// Creates an iterator starting at the same point, but stepping by + /// the given amount at each iteration. + /// + /// Note that it will always return the first element of the range, + /// regardless of the step given. + /// + /// # Panics + /// + /// The method will panic if the given step is `0`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(iterator_step_by)] + /// let a = [0, 1, 2, 3, 4, 5]; + /// let mut iter = a.into_iter().step_by(2); + /// + /// assert_eq!(iter.next(), Some(&0)); + /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), Some(&4)); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[unstable(feature = "iterator_step_by", + reason = "unstable replacement of Range::step_by", + issue = "27741")] + fn step_by(self, step: usize) -> StepBy where Self: Sized { + assert!(step != 0); + StepBy{iter: self, step: step - 1, first_take: true} + } + /// Takes two iterators and creates a new iterator over both in sequence. /// /// `chain()` will return a new iterator which will first iterate over diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 273f9d0e6f6d3..420ff0f71193b 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -313,7 +313,7 @@ pub use self::iterator::Iterator; pub use self::range::Step; #[unstable(feature = "step_by", reason = "recent addition", issue = "27741")] -pub use self::range::StepBy; +pub use self::range::StepBy as DeprecatedStepBy; #[stable(feature = "rust1", since = "1.0.0")] pub use self::sources::{Repeat, repeat}; @@ -520,6 +520,41 @@ impl Iterator for Cycle where I: Clone + Iterator { #[unstable(feature = "fused", issue = "35602")] impl FusedIterator for Cycle where I: Clone + Iterator {} +/// An iterator that steps by n elements every iteration. +/// +/// This `struct` is created by the [`step_by`] method on [`Iterator`]. See +/// its documentation for more. +/// +/// [`step_by`]: trait.Iterator.html#method.step_by +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[unstable(feature = "iterator_step_by", + reason = "unstable replacement of Range::step_by", + issue = "27741")] +#[derive(Clone, Debug)] +pub struct StepBy { + iter: I, + step: usize, + first_take: bool, +} + +#[unstable(feature = "iterator_step_by", + reason = "unstable replacement of Range::step_by", + issue = "27741")] +impl Iterator for StepBy where I: Iterator { + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option { + if self.first_take { + self.first_take = false; + self.iter.next() + } else { + self.iter.nth(self.step) + } + } +} + /// An iterator that strings two iterators together. /// /// This `struct` is created by the [`chain`] method on [`Iterator`]. See its diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 001fa304cd08f..ad91ba9be58f2 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -144,6 +144,33 @@ fn test_iterator_chain_find() { assert_eq!(iter.next(), None); } +#[test] +fn test_iterator_step_by() { + // Identity + // Replace with (0..).step_by(1) after Range::step_by gets removed + let mut it = Iterator::step_by((0..), 1).take(3); + assert_eq!(it.next(), Some(0)); + assert_eq!(it.next(), Some(1)); + assert_eq!(it.next(), Some(2)); + assert_eq!(it.next(), None); + + // Replace with (0..).step_by(3) after Range::step_by gets removed + let mut it = Iterator::step_by((0..), 3).take(4); + assert_eq!(it.next(), Some(0)); + assert_eq!(it.next(), Some(3)); + assert_eq!(it.next(), Some(6)); + assert_eq!(it.next(), Some(9)); + assert_eq!(it.next(), None); +} + +#[test] +#[should_panic] +fn test_iterator_step_by_zero() { + // Replace with (0..).step_by(0) after Range::step_by gets removed + let mut it = Iterator::step_by((0..), 0); + it.next(); +} + #[test] fn test_filter_map() { let it = (0..).step_by(1).take(10) @@ -1119,4 +1146,4 @@ fn test_step_replace_no_between() { let y = x.replace_one(); assert_eq!(x, 1); assert_eq!(y, 5); -} \ No newline at end of file +} diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index f0c46a6f194d5..c52155ead4f0b 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -20,6 +20,7 @@ #![feature(fixed_size_array)] #![feature(flt2dec)] #![feature(fmt_internals)] +#![feature(iterator_step_by)] #![feature(i128_type)] #![feature(iter_rfind)] #![feature(libc)] diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index c115a6ccba609..f09ce1cc64849 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -215,14 +215,14 @@ } else if (ev.target.tagName === 'SPAN' && hasClass(ev.target.parentNode, 'line-numbers')) { var prev_id = 0; - function set_fragment(name) { + var set_fragment = function (name) { if (browserSupportsHistoryApi()) { history.replaceState(null, null, '#' + name); window.hashchange(); } else { location.replace('#' + name); } - } + }; var cur_id = parseInt(ev.target.id, 10); @@ -685,7 +685,7 @@ } function escape(content) { - let h1 = document.createElement('h1'); + var h1 = document.createElement('h1'); h1.textContent = content; return h1.innerHTML; } diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 64eb52e28bc42..96c10c5d10d1a 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -43,16 +43,19 @@ use sys::os as os_imp; /// use std::env; /// /// // We assume that we are in a valid directory. -/// let p = env::current_dir().unwrap(); -/// println!("The current directory is {}", p.display()); +/// let path = env::current_dir().unwrap(); +/// println!("The current directory is {}", path.display()); /// ``` #[stable(feature = "env", since = "1.0.0")] pub fn current_dir() -> io::Result { os_imp::getcwd() } -/// Changes the current working directory to the specified path, returning -/// whether the change was completed successfully or not. +/// Changes the current working directory to the specified path. +/// +/// Returns an [`Err`] if the operation fails. +/// +/// [`Err`]: ../../std/result/enum.Result.html#method.err /// /// # Examples /// @@ -65,8 +68,8 @@ pub fn current_dir() -> io::Result { /// println!("Successfully changed working directory to {}!", root.display()); /// ``` #[stable(feature = "env", since = "1.0.0")] -pub fn set_current_dir>(p: P) -> io::Result<()> { - os_imp::chdir(p.as_ref()) +pub fn set_current_dir>(path: P) -> io::Result<()> { + os_imp::chdir(path.as_ref()) } /// An iterator over a snapshot of the environment variables of this process. @@ -175,10 +178,10 @@ impl fmt::Debug for VarsOs { /// /// The returned result is [`Ok(s)`] if the environment variable is present and is /// valid unicode. If the environment variable is not present, or it is not -/// valid unicode, then [`Err`] will be returned. +/// valid unicode, then [`VarError`] will be returned. /// /// [`Ok(s)`]: ../result/enum.Result.html#variant.Ok -/// [`Err`]: ../result/enum.Result.html#variant.Err +/// [`VarError`]: enum.VarError.html /// /// # Examples /// @@ -199,7 +202,7 @@ pub fn var>(key: K) -> Result { fn _var(key: &OsStr) -> Result { match var_os(key) { Some(s) => s.into_string().map_err(VarError::NotUnicode), - None => Err(VarError::NotPresent) + None => Err(VarError::NotPresent), } } diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 3896fc20a2dde..d0e7defbbbb9a 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -754,6 +754,13 @@ impl fmt::Debug for Stdio { } /// Describes the result of a process after it has terminated. +/// +/// This `struct` is used to represent the exit status of a child process. +/// Child processes are created via the [`Command`] struct and their exit +/// status is exposed through the [`status`] method. +/// +/// [`Command`]: struct.Command.html +/// [`status`]: struct.Command.html#method.status #[derive(PartialEq, Eq, Clone, Copy, Debug)] #[stable(feature = "process", since = "1.0.0")] pub struct ExitStatus(imp::ExitStatus); @@ -788,6 +795,22 @@ impl ExitStatus { /// On Unix, this will return `None` if the process was terminated /// by a signal; `std::os::unix` provides an extension trait for /// extracting the signal and other details from the `ExitStatus`. + /// + /// # Examples + /// + /// ```no_run + /// use std::process::Command; + /// + /// let status = Command::new("mkdir") + /// .arg("projects") + /// .status() + /// .expect("failed to execute mkdir"); + /// + /// match status.code() { + /// Some(code) => println!("Exited with status code: {}", code), + /// None => println!("Process terminated by signal") + /// } + /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn code(&self) -> Option { self.0.code() diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 2cb649ce67b9c..284a5fbd9d506 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -1067,7 +1067,7 @@ impl Receiver { Receiver { inner: UnsafeCell::new(inner) } } - /// Attempts to return a pending value on this receiver without blocking + /// Attempts to return a pending value on this receiver without blocking. /// /// This method will never block the caller in order to wait for data to /// become available. Instead, this will always return immediately with a diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 00483b1ea5f77..1930f61121bb0 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -700,7 +700,7 @@ impl<'a> ExtCtxt<'a> { /// Returns span for the macro which originally caused the current expansion to happen. /// /// Stops backtracing at include! boundary. - pub fn expansion_cause(&self) -> Span { + pub fn expansion_cause(&self) -> Option { let mut ctxt = self.backtrace(); let mut last_macro = None; loop { @@ -716,7 +716,7 @@ impl<'a> ExtCtxt<'a> { break } } - last_macro.expect("missing expansion backtrace") + last_macro } pub fn struct_span_warn(&self, diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 4183583d66ffd..3cdd3a4b2c31d 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -35,7 +35,7 @@ pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree]) -> Box { base::check_zero_tts(cx, sp, tts, "line!"); - let topmost = cx.expansion_cause(); + let topmost = cx.expansion_cause().unwrap_or(sp); let loc = cx.codemap().lookup_char_pos(topmost.lo); base::MacEager::expr(cx.expr_u32(topmost, loc.line as u32)) @@ -46,7 +46,7 @@ pub fn expand_column(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree]) -> Box { base::check_zero_tts(cx, sp, tts, "column!"); - let topmost = cx.expansion_cause(); + let topmost = cx.expansion_cause().unwrap_or(sp); let loc = cx.codemap().lookup_char_pos(topmost.lo); base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32)) @@ -59,7 +59,7 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree]) -> Box { base::check_zero_tts(cx, sp, tts, "file!"); - let topmost = cx.expansion_cause(); + let topmost = cx.expansion_cause().unwrap_or(sp); let loc = cx.codemap().lookup_char_pos(topmost.lo); base::MacEager::expr(cx.expr_str(topmost, Symbol::intern(&loc.file.name))) } diff --git a/src/test/compile-fail/issue-41776.rs b/src/test/compile-fail/issue-41776.rs new file mode 100644 index 0000000000000..5f108e0a1ed81 --- /dev/null +++ b/src/test/compile-fail/issue-41776.rs @@ -0,0 +1,13 @@ +// Copyright 2017 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() { + include!(line!()); //~ ERROR argument must be a string literal +}