diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7441d51055ffb..741ced8f0912d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -400,30 +400,53 @@ labels to triage issues: * Magenta, **B**-prefixed labels identify bugs which are **blockers**. +* Dark blue, **beta-** labels track changes which need to be backported into + the beta branches. + +* Light purple, **C**-prefixed labels represent the **category** of an issue. + * Green, **E**-prefixed labels explain the level of **experience** necessary to fix the issue. +* The dark blue **final-comment-period** label marks bugs that are using the + RFC signoff functionality of [rfcbot][rfcbot] and are currenty in the final + comment period. + * Red, **I**-prefixed labels indicate the **importance** of the issue. The [I-nominated][inom] label indicates that an issue has been nominated for prioritizing at the next triage meeting. +* The purple **metabug** label marks lists of bugs collected by other + categories. + +* Purple gray, **O**-prefixed labels are the **operating system** or platform + that this issue is specific to. + * Orange, **P**-prefixed labels indicate a bug's **priority**. These labels are only assigned during triage meetings, and replace the [I-nominated][inom] label. -* Blue, **T**-prefixed bugs denote which **team** the issue belongs to. +* The gray **proposed-final-comment-period** label marks bugs that are using + the RFC signoff functionality of [rfcbot][rfcbot] and are currently awaiting + signoff of all team members in order to enter the final comment period. -* Dark blue, **beta-** labels track changes which need to be backported into - the beta branches. +* Pink, **regression**-prefixed labels track regressions from stable to the + release channels. -* The purple **metabug** label marks lists of bugs collected by other - categories. +* The light orange **relnotes** label marks issues that should be documented in + the release notes of the next release. + +* Gray, **S**-prefixed labels are used for tracking the **status** of pull + requests. + +* Blue, **T**-prefixed bugs denote which **team** the issue belongs to. If you're looking for somewhere to start, check out the [E-easy][eeasy] tag. [inom]: https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AI-nominated [eeasy]: https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AE-easy [lru]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-asc +[rfcbot]: https://github.com/dikaiosune/rust-dashboard/blob/master/RFCBOT.md ## Out-of-tree Contributions diff --git a/src/Cargo.lock b/src/Cargo.lock index 1bbe8ca7575f1..79822675364cf 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -490,6 +490,14 @@ dependencies = [ "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "error-chain" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "error-chain" version = "0.11.0" @@ -642,7 +650,7 @@ dependencies = [ [[package]] name = "handlebars" -version = "0.26.2" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -926,18 +934,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "mdbook" -version = "0.0.22" +version = "0.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clap 2.26.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "handlebars 0.26.2 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "handlebars 0.27.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1398,7 +1410,7 @@ name = "rustbook" version = "0.1.0" dependencies = [ "clap 2.26.0 (registry+https://github.com/rust-lang/crates.io-index)", - "mdbook 0.0.22 (registry+https://github.com/rust-lang/crates.io-index)", + "mdbook 0.0.25 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2463,6 +2475,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" "checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f" "checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" +"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5363ab8e4139b8568a6237db5248646e5a8a2f89bd5ccb02092182b11fd3e922" "checksum flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)" = "36df0166e856739905cd3d7e0b210fe818592211a008862599845e012d8d304c" @@ -2478,7 +2491,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum globset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "feeb1b6840809ef5efcf7a4a990bc4e1b7ee3df8cf9e2379a75aeb2ba42ac9c3" "checksum hamcrest 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bf088f042a467089e9baa4972f57f9247e42a0cc549ba264c7a04fbb8ecb89d4" -"checksum handlebars 0.26.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fbba80e74e9591a5f6a4ffff6b7f9d645759a896e431cfbdc853e9184370294a" +"checksum handlebars 0.27.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef7567daf271a32e60301e4821fcb5b51a5b535167115d1ce04f46c3f0a15f0b" "checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa" "checksum home 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f25ae61099d8f3fee8b483df0bd4ecccf4b2731897aad40d50eca1b641fe6db" "checksum html-diff 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5298d63081a642508fce965740ddb03a386c5d81bf1fef0579a815cf49cb8c68" @@ -2503,7 +2516,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum magenta-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40d014c7011ac470ae28e2f76a02bfea4a8480f73e701353b49ad7a8d75f4699" "checksum markup5ever 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff834ac7123c6a37826747e5ca09db41fd7a83126792021c2e636ad174bb77d3" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" -"checksum mdbook 0.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "22911d86cde6f80fa9f0fb2a68bbbde85d97af4fe0ce267141c83a4187d28700" +"checksum mdbook 0.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "146eadfc6d141452a364c351f07bb19208d1401e931f40b8532f87bba3ecc40f" "checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4" "checksum miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "28eaee17666671fa872e567547e8428e83308ebe5808cdf6a0e28397dbe2c726" diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 2cbae083fc464..a2c436627f6da 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -389,7 +389,8 @@ impl Step for Openssl { drop(fs::remove_dir_all(&dst)); build.run(Command::new("tar").arg("xf").arg(&tarball).current_dir(&out)); - let mut configure = Command::new(obj.join("Configure")); + let mut configure = Command::new("perl"); + configure.arg(obj.join("Configure")); configure.arg(format!("--prefix={}", dst.display())); configure.arg("no-dso"); configure.arg("no-ssl2"); diff --git a/src/liballoc/btree/set.rs b/src/liballoc/btree/set.rs index d32460da93923..7da6371cc1907 100644 --- a/src/liballoc/btree/set.rs +++ b/src/liballoc/btree/set.rs @@ -1110,15 +1110,13 @@ impl<'a, T: Ord> Iterator for Union<'a, T> { type Item = &'a T; fn next(&mut self) -> Option<&'a T> { - loop { - match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) { - Less => return self.a.next(), - Equal => { - self.b.next(); - return self.a.next(); - } - Greater => return self.b.next(), + match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) { + Less => self.a.next(), + Equal => { + self.b.next(); + self.a.next() } + Greater => self.b.next(), } } diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index f0c63a2eb55d5..62b5f13675c23 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -855,6 +855,19 @@ impl str { } /// Returns an iterator of `u16` over the string encoded as UTF-16. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let text = "Zażółć gęślą jaźń"; + /// + /// let utf8_len = text.len(); + /// let utf16_len = text.encode_utf16().count(); + /// + /// assert!(utf16_len <= utf8_len); + /// ``` #[stable(feature = "encode_utf16", since = "1.8.0")] pub fn encode_utf16(&self) -> EncodeUtf16 { EncodeUtf16 { encoder: Utf16Encoder::new(self[..].chars()) } @@ -1783,6 +1796,17 @@ impl str { } /// Converts a `Box` into a `Box<[u8]>` without copying or allocating. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let s = "this is a string"; + /// let boxed_str = s.to_owned().into_boxed_str(); + /// let boxed_bytes = boxed_str.into_boxed_bytes(); + /// assert_eq!(*boxed_bytes, *s.as_bytes()); + /// ``` #[stable(feature = "str_box_extras", since = "1.20.0")] pub fn into_boxed_bytes(self: Box) -> Box<[u8]> { self.into() @@ -2050,6 +2074,17 @@ impl str { /// Converts a boxed slice of bytes to a boxed string slice without checking /// that the string contains valid UTF-8. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// let smile_utf8 = Box::new([226, 152, 186]); +/// let smile = unsafe { std::str::from_boxed_utf8_unchecked(smile_utf8) }; +/// +/// assert_eq!("☺", &*smile); +/// ``` #[stable(feature = "str_box_extras", since = "1.20.0")] pub unsafe fn from_boxed_utf8_unchecked(v: Box<[u8]>) -> Box { mem::transmute(v) diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 1708f3e398756..46b96df1eabd7 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -622,6 +622,13 @@ impl String { /// Decode a UTF-16 encoded slice `v` into a `String`, replacing /// invalid data with the replacement character (U+FFFD). /// + /// Unlike [`from_utf8_lossy`] which returns a [`Cow<'a, str>`], + /// `from_utf16_lossy` returns a `String` since the UTF-16 to UTF-8 + /// conversion requires a memory allocation. + /// + /// [`from_utf8_lossy`]: #method.from_utf8_lossy + /// [`Cow<'a, str>`]: ../borrow/enum.Cow.html + /// /// # Examples /// /// Basic usage: @@ -759,7 +766,22 @@ impl String { self } - /// Extracts a string slice containing the entire string. + /// Converts a `String` into a mutable string slice. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::ascii::AsciiExt; + /// + /// let mut s = String::from("foobar"); + /// let s_mut_str = s.as_mut_str(); + /// + /// s_mut_str.make_ascii_uppercase(); + /// + /// assert_eq!("FOOBAR", s_mut_str); + /// ``` #[inline] #[stable(feature = "string_as_str", since = "1.7.0")] pub fn as_mut_str(&mut self) -> &mut str { diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 8141851b8c9af..45574bad9ac07 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -370,6 +370,7 @@ impl Vec { /// /// * `ptr` needs to have been previously allocated via [`String`]/`Vec` /// (at least, it's highly likely to be incorrect if it wasn't). + /// * `ptr`'s `T` needs to have the same size and alignment as it was allocated with. /// * `length` needs to be less than or equal to `capacity`. /// * `capacity` needs to be the capacity that the pointer was allocated with. /// @@ -1969,16 +1970,19 @@ impl Vec { /// Using this method is equivalent to the following code: /// /// ``` - /// # let some_predicate = |x: &mut i32| { *x == 2 }; - /// # let mut vec = vec![1, 2, 3, 4, 5]; + /// # let some_predicate = |x: &mut i32| { *x == 2 || *x == 3 || *x == 6 }; + /// # let mut vec = vec![1, 2, 3, 4, 5, 6]; /// let mut i = 0; /// while i != vec.len() { /// if some_predicate(&mut vec[i]) { /// let val = vec.remove(i); /// // your code here + /// } else { + /// i += 1; /// } - /// i += 1; /// } + /// + /// # assert_eq!(vec, vec![1, 4, 5]); /// ``` /// /// But `drain_filter` is easier to use. `drain_filter` is also more efficient, diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 607f6f3701799..f7f1dd12d28b1 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -848,12 +848,12 @@ extern "rust-intrinsic" { /// // The no-copy, unsafe way, still using transmute, but not UB. /// // This is equivalent to the original, but safer, and reuses the /// // same Vec internals. Therefore the new inner type must have the - /// // exact same size, and the same or lesser alignment, as the old - /// // type. The same caveats exist for this method as transmute, for + /// // exact same size, and the same alignment, as the old type. + /// // The same caveats exist for this method as transmute, for /// // the original inner type (`&i32`) to the converted inner type /// // (`Option<&i32>`), so read the nomicon pages linked above. /// let v_from_raw = unsafe { - /// Vec::from_raw_parts(v_orig.as_mut_ptr(), + /// Vec::from_raw_parts(v_orig.as_mut_ptr() as *mut Option<&i32>, /// v_orig.len(), /// v_orig.capacity()) /// }; diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index af2f876a2f359..bae1f4dee14f3 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -712,39 +712,39 @@ pub unsafe fn transmute_copy(src: &T) -> U { /// Opaque type representing the discriminant of an enum. /// /// See the `discriminant` function in this module for more information. -#[stable(feature = "discriminant_value", since = "1.22.0")] +#[stable(feature = "discriminant_value", since = "1.21.0")] pub struct Discriminant(u64, PhantomData<*const T>); // N.B. These trait implementations cannot be derived because we don't want any bounds on T. -#[stable(feature = "discriminant_value", since = "1.22.0")] +#[stable(feature = "discriminant_value", since = "1.21.0")] impl Copy for Discriminant {} -#[stable(feature = "discriminant_value", since = "1.22.0")] +#[stable(feature = "discriminant_value", since = "1.21.0")] impl clone::Clone for Discriminant { fn clone(&self) -> Self { *self } } -#[stable(feature = "discriminant_value", since = "1.22.0")] +#[stable(feature = "discriminant_value", since = "1.21.0")] impl cmp::PartialEq for Discriminant { fn eq(&self, rhs: &Self) -> bool { self.0 == rhs.0 } } -#[stable(feature = "discriminant_value", since = "1.22.0")] +#[stable(feature = "discriminant_value", since = "1.21.0")] impl cmp::Eq for Discriminant {} -#[stable(feature = "discriminant_value", since = "1.22.0")] +#[stable(feature = "discriminant_value", since = "1.21.0")] impl hash::Hash for Discriminant { fn hash(&self, state: &mut H) { self.0.hash(state); } } -#[stable(feature = "discriminant_value", since = "1.22.0")] +#[stable(feature = "discriminant_value", since = "1.21.0")] impl fmt::Debug for Discriminant { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_tuple("Discriminant") @@ -777,7 +777,7 @@ impl fmt::Debug for Discriminant { /// assert!(mem::discriminant(&Foo::B(1)) == mem::discriminant(&Foo::B(2))); /// assert!(mem::discriminant(&Foo::B(3)) != mem::discriminant(&Foo::C(3))); /// ``` -#[stable(feature = "discriminant_value", since = "1.22.0")] +#[stable(feature = "discriminant_value", since = "1.21.0")] pub fn discriminant(v: &T) -> Discriminant { unsafe { Discriminant(intrinsics::discriminant_value(v), PhantomData) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 62e84c9ebd017..d4fef45ae4e8f 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -302,6 +302,37 @@ pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { } /// Converts a mutable slice of bytes to a mutable string slice. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::str; +/// +/// // "Hello, Rust!" as a mutable vector +/// let mut hellorust = vec![72, 101, 108, 108, 111, 44, 32, 82, 117, 115, 116, 33]; +/// +/// // As we know these bytes are valid, we can use `unwrap()` +/// let outstr = str::from_utf8_mut(&mut hellorust).unwrap(); +/// +/// assert_eq!("Hello, Rust!", outstr); +/// ``` +/// +/// Incorrect bytes: +/// +/// ``` +/// use std::str; +/// +/// // Some invalid bytes in a mutable vector +/// let mut invalid = vec![128, 223]; +/// +/// assert!(str::from_utf8_mut(&mut invalid).is_err()); +/// ``` +/// See the docs for [`Utf8Error`][error] for more details on the kinds of +/// errors that can be returned. +/// +/// [error]: struct.Utf8Error.html #[stable(feature = "str_mut_extras", since = "1.20.0")] pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> { run_utf8_validation(v)?; @@ -382,6 +413,19 @@ pub unsafe fn from_utf8_unchecked(v: &[u8]) -> &str { /// See the immutable version, [`from_utf8_unchecked()`][fromutf8], for more information. /// /// [fromutf8]: fn.from_utf8_unchecked.html +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::str; +/// +/// let mut heart = vec![240, 159, 146, 150]; +/// let heart = unsafe { str::from_utf8_unchecked_mut(&mut heart) }; +/// +/// assert_eq!("💖", heart); +/// ``` #[inline] #[stable(feature = "str_mut_extras", since = "1.20.0")] pub unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 80beaaed051db..d4fa03b508566 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1487,12 +1487,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.ir.tcx.lint_node_note(lint::builtin::UNUSED_VARIABLES, id, sp, &format!("variable `{}` is assigned to, but never used", name), - &format!("to disable this warning, consider using `_{}` instead", + &format!("to avoid this warning, consider using `_{}` instead", name)); } else if name != "self" { self.ir.tcx.lint_node_note(lint::builtin::UNUSED_VARIABLES, id, sp, &format!("unused variable: `{}`", name), - &format!("to disable this warning, consider using `_{}` instead", + &format!("to avoid this warning, consider using `_{}` instead", name)); } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 49d4bd2324033..500b75ec659a1 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -54,13 +54,11 @@ use externalfiles::ExternalHtml; use serialize::json::{ToJson, Json, as_json}; use syntax::{abi, ast}; -use syntax::feature_gate::UnstableFeatures; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId}; use rustc::middle::privacy::AccessLevels; use rustc::middle::stability; use rustc::hir; use rustc::util::nodemap::{FxHashMap, FxHashSet}; -use rustc::session::config::nightly_options::is_nightly_build; use rustc_data_structures::flock; use clean::{self, AttributesExt, GetDefId, SelfTy, Mutability, Span}; @@ -1764,9 +1762,13 @@ fn render_markdown(w: &mut fmt::Formatter, prefix: &str, scx: &SharedContext) -> fmt::Result { - let hoedown_output = format!("{}", Markdown(md_text, RenderType::Hoedown)); // We only emit warnings if the user has opted-in to Pulldown rendering. let output = if render_type == RenderType::Pulldown { + // Save the state of USED_ID_MAP so it only gets updated once even + // though we're rendering twice. + let orig_used_id_map = USED_ID_MAP.with(|map| map.borrow().clone()); + let hoedown_output = format!("{}", Markdown(md_text, RenderType::Hoedown)); + USED_ID_MAP.with(|map| *map.borrow_mut() = orig_used_id_map); let pulldown_output = format!("{}", Markdown(md_text, RenderType::Pulldown)); let mut differences = html_diff::get_differences(&pulldown_output, &hoedown_output); differences.retain(|s| { @@ -1787,7 +1789,7 @@ fn render_markdown(w: &mut fmt::Formatter, pulldown_output } else { - hoedown_output + format!("{}", Markdown(md_text, RenderType::Hoedown)) }; write!(w, "
{}{}
", prefix, output) @@ -2192,14 +2194,9 @@ fn item_static(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, f: &clean::Function) -> fmt::Result { - // FIXME(#24111): remove when `const_fn` is stabilized - let vis_constness = match UnstableFeatures::from_environment() { - UnstableFeatures::Allow => f.constness, - _ => hir::Constness::NotConst - }; let name_len = format!("{}{}{}{:#}fn {}{:#}", VisSpace(&it.visibility), - ConstnessSpace(vis_constness), + ConstnessSpace(f.constness), UnsafetySpace(f.unsafety), AbiSpace(f.abi), it.name.as_ref().unwrap(), @@ -2209,7 +2206,7 @@ fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, write!(w, "{vis}{constness}{unsafety}{abi}fn \ {name}{generics}{decl}{where_clause}", vis = VisSpace(&it.visibility), - constness = ConstnessSpace(vis_constness), + constness = ConstnessSpace(f.constness), unsafety = UnsafetySpace(f.unsafety), abi = AbiSpace(f.abi), name = it.name.as_ref().unwrap(), @@ -2591,14 +2588,8 @@ fn render_assoc_item(w: &mut fmt::Formatter, href(did).map(|p| format!("{}#{}.{}", p.0, ty, name)).unwrap_or(anchor) } }; - // FIXME(#24111): remove when `const_fn` is stabilized - let vis_constness = if is_nightly_build() { - constness - } else { - hir::Constness::NotConst - }; let mut head_len = format!("{}{}{:#}fn {}{:#}", - ConstnessSpace(vis_constness), + ConstnessSpace(constness), UnsafetySpace(unsafety), AbiSpace(abi), name, @@ -2611,7 +2602,7 @@ fn render_assoc_item(w: &mut fmt::Formatter, }; write!(w, "{}{}{}fn {name}\ {generics}{decl}{where_clause}", - ConstnessSpace(vis_constness), + ConstnessSpace(constness), UnsafetySpace(unsafety), AbiSpace(abi), href = href, diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index a438b4afdd0c9..2a916b819cca3 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -560,14 +560,26 @@ impl OpenOptions { /// /// One maybe obvious note when using append-mode: make sure that all data /// that belongs together is written to the file in one operation. This - /// can be done by concatenating strings before passing them to `write()`, + /// can be done by concatenating strings before passing them to [`write()`], /// or using a buffered writer (with a buffer of adequate size), - /// and calling `flush()` when the message is complete. + /// and calling [`flush()`] when the message is complete. /// /// If a file is opened with both read and append access, beware that after /// opening, and after every write, the position for reading may be set at the /// end of the file. So, before writing, save the current position (using - /// `seek(SeekFrom::Current(0))`, and restore it before the next read. + /// [`seek`]`(`[`SeekFrom`]`::`[`Current`]`(0))`, and restore it before the next read. + /// + /// ## Note + /// + /// This function doesn't create the file if it doesn't exist. Use the [`create`] + /// method to do so. + /// + /// [`write()`]: ../../std/fs/struct.File.html#method.write + /// [`flush()`]: ../../std/fs/struct.File.html#method.flush + /// [`seek`]: ../../std/fs/struct.File.html#method.seek + /// [`SeekFrom`]: ../../std/io/enum.SeekFrom.html + /// [`Current`]: ../../std/io/enum.SeekFrom.html#variant.Current + /// [`create`]: #method.create /// /// # Examples /// @@ -605,9 +617,12 @@ impl OpenOptions { /// This option indicates whether a new file will be created if the file /// does not yet already exist. /// - /// In order for the file to be created, `write` or `append` access must + /// In order for the file to be created, [`write`] or [`append`] access must /// be used. /// + /// [`write`]: #method.write + /// [`append`]: #method.append + /// /// # Examples /// /// ```no_run @@ -630,12 +645,15 @@ impl OpenOptions { /// whether a file exists and creating a new one, the file may have been /// created by another process (a TOCTOU race condition / attack). /// - /// If `.create_new(true)` is set, `.create()` and `.truncate()` are + /// If `.create_new(true)` is set, [`.create()`] and [`.truncate()`] are /// ignored. /// /// The file must be opened with write or append access in order to create /// a new file. /// + /// [`.create()`]: #method.create + /// [`.truncate()`]: #method.truncate + /// /// # Examples /// /// ```no_run diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 5467eff202b02..943a83a95fb23 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -167,7 +167,7 @@ impl TcpStream { /// connection request. /// /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html - #[unstable(feature = "tcpstream_connect_timeout", issue = "43079")] + #[stable(feature = "tcpstream_connect_timeout", since = "1.22.0")] pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result { net_imp::TcpStream::connect_timeout(addr, timeout).map(TcpStream) } diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index 35001833383c0..a8a242846d7ce 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -48,11 +48,12 @@ use time::Duration; /// { /// let mut socket = UdpSocket::bind("127.0.0.1:34254")?; /// -/// // read from the socket +/// // Receives a single datagram message on the socket. If `buf` is too small to hold +/// // the message, it will be cut off. /// let mut buf = [0; 10]; /// let (amt, src) = socket.recv_from(&mut buf)?; /// -/// // send a reply to the socket we received data from +/// // Redeclare `buf` as slice of the received data and send reverse data back to origin. /// let buf = &mut buf[..amt]; /// buf.reverse(); /// socket.send_to(buf, &src)?; @@ -103,8 +104,12 @@ impl UdpSocket { super::each_addr(addr, net_imp::UdpSocket::bind).map(UdpSocket) } - /// Receives data from the socket. On success, returns the number of bytes - /// read and the address from whence the data came. + /// Receives a single datagram message on the socket. On success, returns the number + /// of bytes read and the origin. + /// + /// The function must be called with valid byte array `buf` of sufficient size to + /// hold the message bytes. If a message is too long to fit in the supplied buffer, + /// excess bytes may be discarded. /// /// # Examples /// @@ -115,19 +120,25 @@ impl UdpSocket { /// let mut buf = [0; 10]; /// let (number_of_bytes, src_addr) = socket.recv_from(&mut buf) /// .expect("Didn't receive data"); + /// let filled_buf = &mut buf[..number_of_bytes]; /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { self.0.recv_from(buf) } - /// Receives data from the socket, without removing it from the queue. + /// Receives a single datagram message on the socket, without removing it from the + /// queue. On success, returns the number of bytes read and the origin. + /// + /// The function must be called with valid byte array `buf` of sufficient size to + /// hold the message bytes. If a message is too long to fit in the supplied buffer, + /// excess bytes may be discarded. /// /// Successive calls return the same data. This is accomplished by passing /// `MSG_PEEK` as a flag to the underlying `recvfrom` system call. /// - /// On success, returns the number of bytes peeked and the address from - /// whence the data came. + /// Do not use this function to implement busy waiting, instead use `libc::poll` to + /// synchronize IO events on one or more sockets. /// /// # Examples /// @@ -138,6 +149,7 @@ impl UdpSocket { /// let mut buf = [0; 10]; /// let (number_of_bytes, src_addr) = socket.peek_from(&mut buf) /// .expect("Didn't receive data"); + /// let filled_buf = &mut buf[..number_of_bytes]; /// ``` #[stable(feature = "peek", since = "1.18.0")] pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { @@ -586,8 +598,11 @@ impl UdpSocket { /// receive data from the specified address. /// /// If `addr` yields multiple addresses, `connect` will be attempted with - /// each of the addresses until a connection is successful. If none of - /// the addresses are able to be connected, the error returned from the + /// each of the addresses until the underlying OS function returns no + /// error. Note that usually, a successful `connect` call does not specify + /// that there is a remote server listening on the port, rather, such an + /// error would only be detected after the first send. If the OS returns an + /// error for each of the specified addresses, the error returned from the /// last connection attempt (the last address) is returned. /// /// # Examples @@ -602,20 +617,10 @@ impl UdpSocket { /// socket.connect("127.0.0.1:8080").expect("connect function failed"); /// ``` /// - /// Create a UDP socket bound to `127.0.0.1:3400` and connect the socket to - /// `127.0.0.1:8080`. If that connection fails, then the UDP socket will - /// connect to `127.0.0.1:8081`: - /// - /// ```no_run - /// use std::net::{SocketAddr, UdpSocket}; - /// - /// let socket = UdpSocket::bind("127.0.0.1:3400").expect("couldn't bind to address"); - /// let connect_addrs = [ - /// SocketAddr::from(([127, 0, 0, 1], 8080)), - /// SocketAddr::from(([127, 0, 0, 1], 8081)), - /// ]; - /// socket.connect(&connect_addrs[..]).expect("connect function failed"); - /// ``` + /// Unlike in the TCP case, passing an array of addresses to the `connect` + /// function of a UDP socket is not a useful thing to do: The OS will be + /// unable to determine whether something is listening on the remote + /// address without the application sending data. #[stable(feature = "net2_mutators", since = "1.9.0")] pub fn connect(&self, addr: A) -> io::Result<()> { super::each_addr(addr, |addr| self.0.connect(addr)) @@ -642,8 +647,12 @@ impl UdpSocket { self.0.send(buf) } - /// Receives data on the socket from the remote address to which it is - /// connected. + /// Receives a single datagram message on the socket from the remote address to + /// which it is connected. On success, returns the number of bytes read. + /// + /// The function must be called with valid byte array `buf` of sufficient size to + /// hold the message bytes. If a message is too long to fit in the supplied buffer, + /// excess bytes may be discarded. /// /// The [`connect`] method will connect this socket to a remote address. This /// method will fail if the socket is not connected. @@ -659,7 +668,7 @@ impl UdpSocket { /// socket.connect("127.0.0.1:8080").expect("connect function failed"); /// let mut buf = [0; 10]; /// match socket.recv(&mut buf) { - /// Ok(received) => println!("received {} bytes", received), + /// Ok(received) => println!("received {} bytes {:?}", received, &buf[..received]), /// Err(e) => println!("recv function failed: {:?}", e), /// } /// ``` @@ -668,13 +677,25 @@ impl UdpSocket { self.0.recv(buf) } - /// Receives data on the socket from the remote address to which it is - /// connected, without removing that data from the queue. On success, - /// returns the number of bytes peeked. + /// Receives single datagram on the socket from the remote address to which it is + /// connected, without removing the message from input queue. On success, returns + /// the number of bytes peeked. + /// + /// The function must be called with valid byte array `buf` of sufficient size to + /// hold the message bytes. If a message is too long to fit in the supplied buffer, + /// excess bytes may be discarded. /// /// Successive calls return the same data. This is accomplished by passing /// `MSG_PEEK` as a flag to the underlying `recv` system call. /// + /// Do not use this function to implement busy waiting, instead use `libc::poll` to + /// synchronize IO events on one or more sockets. + /// + /// The [`connect`] method will connect this socket to a remote address. This + /// method will fail if the socket is not connected. + /// + /// [`connect`]: #method.connect + /// /// # Errors /// /// This method will fail if the socket is not connected. The `connect` method diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index 7dfcc996e18e2..9535ddfe5cada 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -32,6 +32,7 @@ pub type DWORD = c_ulong; pub type HANDLE = LPVOID; pub type HINSTANCE = HANDLE; pub type HMODULE = HINSTANCE; +pub type HRESULT = LONG; pub type BOOL = c_int; pub type BYTE = u8; pub type BOOLEAN = BYTE; @@ -197,6 +198,8 @@ pub const ERROR_OPERATION_ABORTED: DWORD = 995; pub const ERROR_IO_PENDING: DWORD = 997; pub const ERROR_TIMEOUT: DWORD = 0x5B4; +pub const E_NOTIMPL: HRESULT = 0x80004001u32 as HRESULT; + pub const INVALID_HANDLE_VALUE: HANDLE = !0 as HANDLE; pub const FACILITY_NT_BIT: DWORD = 0x1000_0000; @@ -1163,8 +1166,8 @@ extern "system" { timeout: *const timeval) -> c_int; } -// Functions that aren't available on Windows XP, but we still use them and just -// provide some form of a fallback implementation. +// Functions that aren't available on every version of Windows that we support, +// but we still use them and just provide some form of a fallback implementation. compat_fn! { kernel32: @@ -1182,6 +1185,10 @@ compat_fn! { pub fn SetThreadStackGuarantee(_size: *mut c_ulong) -> BOOL { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 } + pub fn SetThreadDescription(hThread: HANDLE, + lpThreadDescription: LPCWSTR) -> HRESULT { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); E_NOTIMPL + } pub fn SetFileInformationByHandle(_hFile: HANDLE, _FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, _lpFileInformation: LPVOID, diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs index 6aea9d1fb560f..c47baaa243402 100644 --- a/src/libstd/sys/windows/thread.rs +++ b/src/libstd/sys/windows/thread.rs @@ -19,6 +19,8 @@ use sys::handle::Handle; use sys_common::thread::*; use time::Duration; +use super::to_u16s; + pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024; pub struct Thread { @@ -55,11 +57,12 @@ impl Thread { } } - pub fn set_name(_name: &CStr) { - // Windows threads are nameless - // The names in MSVC debugger are obtained using a "magic" exception, - // which requires a use of MS C++ extensions. - // See https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx + pub fn set_name(name: &CStr) { + if let Ok(utf8) = name.to_str() { + if let Ok(utf16) = to_u16s(utf8) { + unsafe { c::SetThreadDescription(c::GetCurrentThread(), utf16.as_ptr()); }; + }; + }; } pub fn join(self) { diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index cba5c812b07ce..27fbca19dcc4c 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -434,6 +434,12 @@ impl From for MultiSpan { } } +impl From> for MultiSpan { + fn from(spans: Vec) -> MultiSpan { + MultiSpan::from_spans(spans) + } +} + pub const NO_EXPANSION: SyntaxContext = SyntaxContext::empty(); /// Identifies an offset of a multi-byte character in a FileMap diff --git a/src/test/rustdoc/const-fn.rs b/src/test/rustdoc/const-fn.rs new file mode 100644 index 0000000000000..c323681f60b0a --- /dev/null +++ b/src/test/rustdoc/const-fn.rs @@ -0,0 +1,27 @@ +// 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. + +#![feature(const_fn)] +#![crate_name = "foo"] + +// @has foo/fn.bar.html +// @has - '//*[@class="rust fn"]' 'pub const fn bar() -> ' +/// foo +pub const fn bar() -> usize { + 2 +} + +// @has foo/struct.Foo.html +// @has - '//*[@class="method"]' 'const fn new()' +pub struct Foo(usize); + +impl Foo { + pub const fn new() -> Foo { Foo(0) } +} diff --git a/src/test/ui/span/issue-24690.stderr b/src/test/ui/span/issue-24690.stderr index d4c0eb21342fa..718720ebf8383 100644 --- a/src/test/ui/span/issue-24690.stderr +++ b/src/test/ui/span/issue-24690.stderr @@ -10,7 +10,7 @@ note: lint level defined here 18 | #![warn(unused)] | ^^^^^^ = note: #[warn(unused_variables)] implied by #[warn(unused)] - = note: to disable this warning, consider using `_theOtherTwo` instead + = note: to avoid this warning, consider using `_theOtherTwo` instead warning: variable `theTwo` should have a snake case name such as `the_two` --> $DIR/issue-24690.rs:22:9 diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index e759e0bc13ac1..e57c105008ade 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -8,5 +8,5 @@ license = "MIT/Apache-2.0" clap = "2.25.0" [dependencies.mdbook] -version = "0.0.22" +version = "0.0.25" default-features = false diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs index 41e88aa245f42..a0c3e811a7aa2 100644 --- a/src/tools/rustbook/src/main.rs +++ b/src/tools/rustbook/src/main.rs @@ -13,13 +13,13 @@ extern crate mdbook; extern crate clap; use std::env; -use std::error::Error; use std::io::{self, Write}; use std::path::{Path, PathBuf}; use clap::{App, ArgMatches, SubCommand, AppSettings}; use mdbook::MDBook; +use mdbook::errors::Result; fn main() { let d_message = "-d, --dest-dir=[dest-dir] @@ -49,34 +49,21 @@ fn main() { ::std::process::exit(101); } } - // Build command implementation -fn build(args: &ArgMatches) -> Result<(), Box> { - let book = build_mdbook_struct(args); +pub fn build(args: &ArgMatches) -> Result<()> { + let book_dir = get_book_dir(args); + let book = MDBook::new(&book_dir).read_config()?; let mut book = match args.value_of("dest-dir") { - Some(dest_dir) => book.set_dest(Path::new(dest_dir)), - None => book + Some(dest_dir) => book.with_destination(dest_dir), + None => book, }; - try!(book.build()); + book.build()?; Ok(()) } -fn build_mdbook_struct(args: &ArgMatches) -> mdbook::MDBook { - let book_dir = get_book_dir(args); - let mut book = MDBook::new(&book_dir).read_config(); - - // By default mdbook will attempt to create non-existent files referenced - // from SUMMARY.md files. This is problematic on CI where we mount the - // source directory as readonly. To avoid any issues, we'll disabled - // mdbook's implicit file creation feature. - book.create_missing = false; - - book -} - fn get_book_dir(args: &ArgMatches) -> PathBuf { if let Some(dir) = args.value_of("dir") { // Check if path is relative from current dir, or absolute...