diff --git a/RELEASES.md b/RELEASES.md index 39cef1e2a57..26dd5a5c7f6 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,209 @@ +Version 1.26.0 (2018-05-10) +========================== + +Language +-------- +- [Closures now implement `Copy` and/or `Clone` if all captured variables + implement either or both traits.][49299] +- [The inclusive range syntax e.g. `for x in 0..=10` is now stable.][47813] +- [Stablise `'_`. The underscore lifetime can be used anywhere where a + lifetime can be elided.][49458] +- [`impl Trait` is now stable allowing you to have abstract types in returns + or in function parameters.][49255] e.g. `fn foo() -> impl Iterator` or + `fn open(path: impl AsRef)`. +- [Pattern matching will now automatically apply dereferences.][49394] +- [128-bit integers in the form of `u128` and `i128` are now stable.][49101] +- [`main` can now return `Result<(), E: Debug>`][49162] in addition to `()`. +- [A lot of operations are now available in a const context.][46882] E.g. You + can now index into constant arrays, reference and dereference into constants, + and use Tuple struct constructors. +- [Fixed entry slice patterns are now stable.][48516] e.g. + ```rust + let points = [1, 2, 3, 4]; + match points { + [1, 2, 3, 4] => println!("All points were sequential."), + _ => println!("Not all points were sequential."), + } + ``` + + +Compiler +-------- +- [LLD is now used as the default linker for `wasm32-unknown-unknown`.][48125] +- [Fixed exponential projection complexity on nested types.][48296] + This can provide up to a ~12% reduction in compile times for certain crates. +- [Added the `--remap-path-prefix` option to rustc.][48359] Allowing you + to remap path prefixes outputted by the compiler. +- [Added `powerpc-unknown-netbsd` target.][48281] + +Libraries +--------- +- [Implemented `From for usize` & `From<{u8, i16}> for isize`.][49305] +- [Added hexadecimal formatting for integers with fmt::Debug][48978] + e.g. `assert!(format!("{:02x?}", b"Foo\0") == "[46, 6f, 6f, 00]")` +- [Implemented `Default, Hash` for `cmp::Reverse`.][48628] +- [Optimized `str::repeat` being 8x faster in large cases.][48657] +- [`ascii::escape_default` is now available in libcore.][48735] +- [Trailing commas are now supported in std and core macros.][48056] +- [Implemented `Copy, Clone` for `cmp::Reverse`][47379] +- [Implemented `Clone` for `char::{ToLowercase, ToUppercase}`.][48629] + +Stabilized APIs +--------------- +- [`*const T::add`] +- [`*const T::copy_to_nonoverlapping`] +- [`*const T::copy_to`] +- [`*const T::read_unaligned`] +- [`*const T::read_volatile`] +- [`*const T::read`] +- [`*const T::sub`] +- [`*const T::wrapping_add`] +- [`*const T::wrapping_sub`] +- [`*mut T::add`] +- [`*mut T::copy_to_nonoverlapping`] +- [`*mut T::copy_to`] +- [`*mut T::read_unaligned`] +- [`*mut T::read_volatile`] +- [`*mut T::read`] +- [`*mut T::replace`] +- [`*mut T::sub`] +- [`*mut T::swap`] +- [`*mut T::wrapping_add`] +- [`*mut T::wrapping_sub`] +- [`*mut T::write_bytes`] +- [`*mut T::write_unaligned`] +- [`*mut T::write_volatile`] +- [`*mut T::write`] +- [`Box::leak`] +- [`FromUtf8Error::as_bytes`] +- [`LocalKey::try_with`] +- [`Option::cloned`] +- [`btree_map::Entry::and_modify`] +- [`fs::read_to_string`] +- [`fs::read`] +- [`fs::write`] +- [`hash_map::Entry::and_modify`] +- [`iter::FusedIterator`] +- [`ops::RangeInclusive`] +- [`ops::RangeToInclusive`] +- [`process::id`] +- [`slice::rotate_left`] +- [`slice::rotate_right`] +- [`String::retain`] + + +Cargo +----- +- [Cargo will now output path to custom commands when `-v` is + passed with `--list`][cargo/5041] +- [The Cargo binary version is now the same as the Rust version][cargo/5083] +- [`Cargo.lock` files are now included in published crates.][cargo/5093] + +Misc +---- +- [The second edition of "The Rust Programming Language" book is now recommended + over the first.][48404] + +Compatibility Notes +------------------- + +- [aliasing a `Fn` trait as `dyn` no longer works.][48481] E.g. the following + syntax is now invalid. + ``` + use std::ops::Fn as dyn; + fn g(_: Box) {} + ``` +- [The result of dereferences are no longer promoted to `'static`.][47408] + e.g. + ```rust + fn main() { + const PAIR: &(i32, i32) = &(0, 1); + let _reversed_pair: &'static _ = &(PAIR.1, PAIR.0); // Doesn't work + } + ``` +- [Deprecate `AsciiExt` trait in favor of inherent methods.][49109] +- [`".e0"` will now no longer parse as `0.0` and will instead cause + an error.][48235] +- [Removed hoedown from rustdoc.][48274] +- [Bounds on higher-kinded lifetimes a hard error.][48326] + +[46882]: https://github.com/rust-lang/rust/pull/46882 +[47379]: https://github.com/rust-lang/rust/pull/47379 +[47408]: https://github.com/rust-lang/rust/pull/47408 +[47813]: https://github.com/rust-lang/rust/pull/47813 +[48056]: https://github.com/rust-lang/rust/pull/48056 +[48125]: https://github.com/rust-lang/rust/pull/48125 +[48166]: https://github.com/rust-lang/rust/pull/48166 +[48235]: https://github.com/rust-lang/rust/pull/48235 +[48274]: https://github.com/rust-lang/rust/pull/48274 +[48281]: https://github.com/rust-lang/rust/pull/48281 +[48296]: https://github.com/rust-lang/rust/pull/48296 +[48326]: https://github.com/rust-lang/rust/pull/48326 +[48359]: https://github.com/rust-lang/rust/pull/48359 +[48404]: https://github.com/rust-lang/rust/pull/48404 +[48481]: https://github.com/rust-lang/rust/pull/48481 +[48516]: https://github.com/rust-lang/rust/pull/48516 +[48628]: https://github.com/rust-lang/rust/pull/48628 +[48629]: https://github.com/rust-lang/rust/pull/48629 +[48657]: https://github.com/rust-lang/rust/pull/48657 +[48735]: https://github.com/rust-lang/rust/pull/48735 +[48978]: https://github.com/rust-lang/rust/pull/48978 +[49101]: https://github.com/rust-lang/rust/pull/49101 +[49109]: https://github.com/rust-lang/rust/pull/49109 +[49121]: https://github.com/rust-lang/rust/pull/49121 +[49162]: https://github.com/rust-lang/rust/pull/49162 +[49184]: https://github.com/rust-lang/rust/pull/49184 +[49234]: https://github.com/rust-lang/rust/pull/49234 +[49255]: https://github.com/rust-lang/rust/pull/49255 +[49299]: https://github.com/rust-lang/rust/pull/49299 +[49305]: https://github.com/rust-lang/rust/pull/49305 +[49394]: https://github.com/rust-lang/rust/pull/49394 +[49458]: https://github.com/rust-lang/rust/pull/49458 +[`*const T::add`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.add +[`*const T::copy_to_nonoverlapping`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.copy_to_nonoverlapping +[`*const T::copy_to`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.copy_to +[`*const T::read_unaligned`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.read_unaligned +[`*const T::read_volatile`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.read_volatile +[`*const T::read`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.read +[`*const T::sub`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.sub +[`*const T::wrapping_add`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_add +[`*const T::wrapping_sub`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_sub +[`*mut T::add`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.add-1 +[`*mut T::copy_to_nonoverlapping`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.copy_to_nonoverlapping-1 +[`*mut T::copy_to`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.copy_to-1 +[`*mut T::read_unaligned`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.read_unaligned-1 +[`*mut T::read_volatile`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.read_volatile-1 +[`*mut T::read`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.read-1 +[`*mut T::replace`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.replace +[`*mut T::sub`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.sub-1 +[`*mut T::swap`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.swap +[`*mut T::wrapping_add`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_add-1 +[`*mut T::wrapping_sub`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_sub-1 +[`*mut T::write_bytes`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.write_bytes +[`*mut T::write_unaligned`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.write_unaligned +[`*mut T::write_volatile`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.write_volatile +[`*mut T::write`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.write +[`Box::leak`]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.leak +[`FromUtf8Error::as_bytes`]: https://doc.rust-lang.org/std/string/struct.FromUtf8Error.html#method.as_bytes +[`LocalKey::try_with`]: https://doc.rust-lang.org/std/thread/struct.LocalKey.html#method.try_with +[`Option::cloned`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.cloned +[`btree_map::Entry::and_modify`]: https://doc.rust-lang.org/std/collections/btree_map/enum.Entry.html#method.and_modify +[`fs::read_to_string`]: https://doc.rust-lang.org/std/fs/fn.read_to_string.html +[`fs::read`]: https://doc.rust-lang.org/std/fs/fn.read.html +[`fs::write`]: https://doc.rust-lang.org/std/fs/fn.write.html +[`hash_map::Entry::and_modify`]: https://doc.rust-lang.org/std/collections/hash_map/enum.Entry.html#method.and_modify +[`iter::FusedIterator`]: https://doc.rust-lang.org/std/iter/trait.FusedIterator.html +[`ops::RangeInclusive`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html +[`ops::RangeToInclusive`]: https://doc.rust-lang.org/std/ops/struct.RangeToInclusive.html +[`process::id`]: https://doc.rust-lang.org/std/process/fn.id.html +[`slice::rotate_left`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rotate_left +[`slice::rotate_right`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rotate_right +[`String::retain`]: https://doc.rust-lang.org/std/string/struct.String.html#method.retain +[cargo/5041]: https://github.com/rust-lang/cargo/pull/5041 +[cargo/5083]: https://github.com/rust-lang/cargo/pull/5083 +[cargo/5093]: https://github.com/rust-lang/cargo/pull/5093 + + Version 1.25.0 (2018-03-29) ========================== diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index da4b76a4d52..bb78c14b905 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -125,6 +125,7 @@ #![feature(inclusive_range_methods)] #![cfg_attr(stage0, feature(generic_param_attrs))] #![feature(rustc_const_unstable)] +#![feature(const_vec_new)] #![cfg_attr(not(test), feature(fn_traits, i128))] #![cfg_attr(test, feature(test))] diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index eb25ae17511..4d73d3aa07e 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -748,7 +748,7 @@ mod tests { #[test] fn allocator_param() { - use allocator::{Alloc, AllocErr}; + use alloc::AllocErr; // Writing a test of integration between third-party // allocators and RawVec is a little tricky because the RawVec diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 0cbe65db53c..9e693c89be9 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -207,7 +207,8 @@ impl str { /// let s = "this is old"; /// assert_eq!(s, s.replace("cookie monster", "little lamb")); /// ``` - #[must_use] + #[must_use = "this returns the replaced string as a new allocation, \ + without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn replace<'a, P: Pattern<'a>>(&'a self, from: P, to: &str) -> String { @@ -247,7 +248,8 @@ impl str { /// let s = "this is old"; /// assert_eq!(s, s.replacen("cookie monster", "little lamb", 10)); /// ``` - #[must_use] + #[must_use = "this returns the replaced string as a new allocation, \ + without modifying the original"] #[stable(feature = "str_replacen", since = "1.16.0")] pub fn replacen<'a, P: Pattern<'a>>(&'a self, pat: P, to: &str, count: usize) -> String { // Hope to reduce the times of re-allocation diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 2f84d5f7f86..da9afdd2ca3 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -380,7 +380,8 @@ impl String { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn new() -> String { + #[rustc_const_unstable(feature = "const_string_new")] + pub const fn new() -> String { String { vec: Vec::new() } } diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs index a1f4c6995da..e8ea2e743da 100644 --- a/src/libcore/fmt/builders.rs +++ b/src/libcore/fmt/builders.rs @@ -84,7 +84,7 @@ impl<'a> fmt::Write for PadAdapter<'a> { /// // prints "Foo { bar: 10, baz: "Hello World" }" /// println!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() }); /// ``` -#[must_use] +#[must_use = "must eventually call `finish()` on Debug builders"] #[allow(missing_debug_implementations)] #[stable(feature = "debug_builders", since = "1.2.0")] pub struct DebugStruct<'a, 'b: 'a> { @@ -181,7 +181,7 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> { /// // prints "Foo(10, "Hello World")" /// println!("{:?}", Foo(10, "Hello World".to_string())); /// ``` -#[must_use] +#[must_use = "must eventually call `finish()` on Debug builders"] #[allow(missing_debug_implementations)] #[stable(feature = "debug_builders", since = "1.2.0")] pub struct DebugTuple<'a, 'b: 'a> { @@ -319,7 +319,7 @@ impl<'a, 'b: 'a> DebugInner<'a, 'b> { /// // prints "{10, 11}" /// println!("{:?}", Foo(vec![10, 11])); /// ``` -#[must_use] +#[must_use = "must eventually call `finish()` on Debug builders"] #[allow(missing_debug_implementations)] #[stable(feature = "debug_builders", since = "1.2.0")] pub struct DebugSet<'a, 'b: 'a> { @@ -390,7 +390,7 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> { /// // prints "[10, 11]" /// println!("{:?}", Foo(vec![10, 11])); /// ``` -#[must_use] +#[must_use = "must eventually call `finish()` on Debug builders"] #[allow(missing_debug_implementations)] #[stable(feature = "debug_builders", since = "1.2.0")] pub struct DebugList<'a, 'b: 'a> { @@ -461,7 +461,7 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> { /// // prints "{"A": 10, "B": 11}" /// println!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])); /// ``` -#[must_use] +#[must_use = "must eventually call `finish()` on Debug builders"] #[allow(missing_debug_implementations)] #[stable(feature = "debug_builders", since = "1.2.0")] pub struct DebugMap<'a, 'b: 'a> { diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 6cbe26afae9..20445def634 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -959,8 +959,9 @@ impl ManuallyDrop { /// ManuallyDrop::new(Box::new(())); /// ``` #[stable(feature = "manually_drop", since = "1.20.0")] + #[rustc_const_unstable(feature = "const_manually_drop_new")] #[inline] - pub fn new(value: T) -> ManuallyDrop { + pub const fn new(value: T) -> ManuallyDrop { ManuallyDrop { value: value } } diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 8d5f6f601da..672119eba7f 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -128,10 +128,18 @@ pub mod consts { #[stable(feature = "rust1", since = "1.0.0")] pub const LOG2_E: f32 = 1.44269504088896340735992468100189214_f32; + /// log2(10) + #[unstable(feature = "extra_log_consts", issue = "50540")] + pub const LOG2_10: f32 = 3.32192809488736234787031942948939018_f32; + /// log10(e) #[stable(feature = "rust1", since = "1.0.0")] pub const LOG10_E: f32 = 0.434294481903251827651128918916605082_f32; + /// log10(2) + #[unstable(feature = "extra_log_consts", issue = "50540")] + pub const LOG10_2: f32 = 0.301029995663981195213738894724493027_f32; + /// ln(2) #[stable(feature = "rust1", since = "1.0.0")] pub const LN_2: f32 = 0.693147180559945309417232121458176568_f32; diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 08b869734d4..220b23a1e6a 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -124,10 +124,18 @@ pub mod consts { #[stable(feature = "rust1", since = "1.0.0")] pub const E: f64 = 2.71828182845904523536028747135266250_f64; + /// log2(10) + #[unstable(feature = "extra_log_consts", issue = "50540")] + pub const LOG2_10: f64 = 3.32192809488736234787031942948939018_f64; + /// log2(e) #[stable(feature = "rust1", since = "1.0.0")] pub const LOG2_E: f64 = 1.44269504088896340735992468100189214_f64; + /// log10(2) + #[unstable(feature = "extra_log_consts", issue = "50540")] + pub const LOG10_2: f64 = 0.301029995663981195213738894724493027_f64; + /// log10(e) #[stable(feature = "rust1", since = "1.0.0")] pub const LOG10_E: f64 = 0.434294481903251827651128918916605082_f64; diff --git a/src/libcore/result.rs b/src/libcore/result.rs index c152d4979b9..e0cc669d035 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -251,7 +251,7 @@ use ops; /// [`Ok`]: enum.Result.html#variant.Ok /// [`Err`]: enum.Result.html#variant.Err #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] -#[must_use] +#[must_use = "this `Result` may be an `Err` variant, which should be handled"] #[stable(feature = "rust1", since = "1.0.0")] pub enum Result { /// Contains the success value diff --git a/src/libcore/tests/num/flt2dec/random.rs b/src/libcore/tests/num/flt2dec/random.rs index 315ac4d7d99..a1928657dab 100644 --- a/src/libcore/tests/num/flt2dec/random.rs +++ b/src/libcore/tests/num/flt2dec/random.rs @@ -11,7 +11,6 @@ #![cfg(not(target_arch = "wasm32"))] use std::i16; -use std::mem; use std::str; use core::num::flt2dec::MAX_SIG_DIGITS; @@ -75,8 +74,7 @@ pub fn f32_random_equivalence_test(f: F, g: G, k: usize, n: usize) let mut rng: XorShiftRng = Rand::rand(&mut rand::thread_rng()); let f32_range = Range::new(0x0000_0001u32, 0x7f80_0000); iterate("f32_random_equivalence_test", k, n, f, g, |_| { - let i: u32 = f32_range.ind_sample(&mut rng); - let x: f32 = unsafe {mem::transmute(i)}; + let x = f32::from_bits(f32_range.ind_sample(&mut rng)); decode_finite(x) }); } @@ -87,8 +85,7 @@ pub fn f64_random_equivalence_test(f: F, g: G, k: usize, n: usize) let mut rng: XorShiftRng = Rand::rand(&mut rand::thread_rng()); let f64_range = Range::new(0x0000_0000_0000_0001u64, 0x7ff0_0000_0000_0000); iterate("f64_random_equivalence_test", k, n, f, g, |_| { - let i: u64 = f64_range.ind_sample(&mut rng); - let x: f64 = unsafe {mem::transmute(i)}; + let x = f64::from_bits(f64_range.ind_sample(&mut rng)); decode_finite(x) }); } @@ -105,7 +102,8 @@ pub fn f32_exhaustive_equivalence_test(f: F, g: G, k: usize) // iterate from 0x0000_0001 to 0x7f7f_ffff, i.e. all finite ranges let (npassed, nignored) = iterate("f32_exhaustive_equivalence_test", k, 0x7f7f_ffff, f, g, |i: usize| { - let x: f32 = unsafe {mem::transmute(i as u32 + 1)}; + + let x = f32::from_bits(i as u32 + 1); decode_finite(x) }); assert_eq!((npassed, nignored), (2121451881, 17643158)); diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 919d9648297..437d7d74cae 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -116,6 +116,8 @@ mod prim_bool { } /// /// # `!` and generics /// +/// ## Infallible errors +/// /// The main place you'll see `!` used explicitly is in generic code. Consider the [`FromStr`] /// trait: /// @@ -144,9 +146,60 @@ mod prim_bool { } /// [`Ok`] variant. This illustrates another behaviour of `!` - it can be used to "delete" certain /// enum variants from generic types like `Result`. /// +/// ## Infinite loops +/// +/// While [`Result`] is very useful for removing errors, `!` can also be used to remove +/// successes as well. If we think of [`Result`] as "if this function returns, it has not +/// errored," we get a very intuitive idea of [`Result`] as well: if the function returns, it +/// *has* errored. +/// +/// For example, consider the case of a simple web server, which can be simplified to: +/// +/// ```ignore (hypothetical-example) +/// loop { +/// let (client, request) = get_request().expect("disconnected"); +/// let response = request.process(); +/// response.send(client); +/// } +/// ``` +/// +/// Currently, this isn't ideal, because we simply panic whenever we fail to get a new connection. +/// Instead, we'd like to keep track of this error, like this: +/// +/// ```ignore (hypothetical-example) +/// loop { +/// match get_request() { +/// Err(err) => break err, +/// Ok((client, request)) => { +/// let response = request.process(); +/// response.send(client); +/// }, +/// } +/// } +/// ``` +/// +/// Now, when the server disconnects, we exit the loop with an error instead of panicking. While it +/// might be intuitive to simply return the error, we might want to wrap it in a [`Result`] +/// instead: +/// +/// ```ignore (hypothetical-example) +/// fn server_loop() -> Result { +/// loop { +/// let (client, request) = get_request()?; +/// let response = request.process(); +/// response.send(client); +/// } +/// } +/// ``` +/// +/// Now, we can use `?` instead of `match`, and the return type makes a lot more sense: if the loop +/// ever stops, it means that an error occurred. We don't even have to wrap the loop in an `Ok` +/// because `!` coerces to `Result` automatically. +/// /// [`String::from_str`]: str/trait.FromStr.html#tymethod.from_str /// [`Result`]: result/enum.Result.html /// [`Result`]: result/enum.Result.html +/// [`Result`]: result/enum.Result.html /// [`Ok`]: result/enum.Result.html#variant.Ok /// [`String`]: string/struct.String.html /// [`Err`]: result/enum.Result.html#variant.Err diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 3b4904c98e8..f3503b0b3a6 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -150,7 +150,7 @@ unsafe impl Sync for Mutex { } /// [`lock`]: struct.Mutex.html#method.lock /// [`try_lock`]: struct.Mutex.html#method.try_lock /// [`Mutex`]: struct.Mutex.html -#[must_use] +#[must_use = "if unused the Mutex will immediately unlock"] #[stable(feature = "rust1", since = "1.0.0")] pub struct MutexGuard<'a, T: ?Sized + 'a> { // funny underscores due to how Deref/DerefMut currently work (they diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index f7fdedc0d21..e3db60cff84 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -94,7 +94,7 @@ unsafe impl Sync for RwLock {} /// [`read`]: struct.RwLock.html#method.read /// [`try_read`]: struct.RwLock.html#method.try_read /// [`RwLock`]: struct.RwLock.html -#[must_use] +#[must_use = "if unused the RwLock will immediately unlock"] #[stable(feature = "rust1", since = "1.0.0")] pub struct RwLockReadGuard<'a, T: ?Sized + 'a> { __lock: &'a RwLock, @@ -115,7 +115,7 @@ unsafe impl<'a, T: ?Sized + Sync> Sync for RwLockReadGuard<'a, T> {} /// [`write`]: struct.RwLock.html#method.write /// [`try_write`]: struct.RwLock.html#method.try_write /// [`RwLock`]: struct.RwLock.html -#[must_use] +#[must_use = "if unused the RwLock will immediately unlock"] #[stable(feature = "rust1", since = "1.0.0")] pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> { __lock: &'a RwLock, diff --git a/src/libstd/sys_common/remutex.rs b/src/libstd/sys_common/remutex.rs index ce43ec6d9ab..022056f8a8a 100644 --- a/src/libstd/sys_common/remutex.rs +++ b/src/libstd/sys_common/remutex.rs @@ -41,7 +41,7 @@ unsafe impl Sync for ReentrantMutex {} /// because implementation of the trait would violate Rust’s reference aliasing /// rules. Use interior mutability (usually `RefCell`) in order to mutate the /// guarded data. -#[must_use] +#[must_use = "if unused the ReentrantMutex will immediately unlock"] pub struct ReentrantMutexGuard<'a, T: 'a> { // funny underscores due to how Deref currently works (it disregards field // privacy). diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index f252020bc31..f26a6a53074 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -419,13 +419,24 @@ pub fn lit_token(lit: token::Lit, suf: Option, diag: Option<(Span, &Hand token::Integer(s) => (false, integer_lit(&s.as_str(), suf, diag)), token::Float(s) => (false, float_lit(&s.as_str(), suf, diag)), - token::Str_(s) => { - let s = Symbol::intern(&str_lit(&s.as_str(), diag)); - (true, Some(LitKind::Str(s, ast::StrStyle::Cooked))) + token::Str_(mut sym) => { + // If there are no characters requiring special treatment we can + // reuse the symbol from the Token. Otherwise, we must generate a + // new symbol because the string in the LitKind is different to the + // string in the Token. + let s = &sym.as_str(); + if s.as_bytes().iter().any(|&c| c == b'\\' || c == b'\r') { + sym = Symbol::intern(&str_lit(s, diag)); + } + (true, Some(LitKind::Str(sym, ast::StrStyle::Cooked))) } - token::StrRaw(s, n) => { - let s = Symbol::intern(&raw_str_lit(&s.as_str())); - (true, Some(LitKind::Str(s, ast::StrStyle::Raw(n)))) + token::StrRaw(mut sym, n) => { + // Ditto. + let s = &sym.as_str(); + if s.contains('\r') { + sym = Symbol::intern(&raw_str_lit(s)); + } + (true, Some(LitKind::Str(sym, ast::StrStyle::Raw(n)))) } token::ByteStr(i) => { (true, Some(LitKind::ByteStr(byte_str_lit(&i.as_str())))) diff --git a/src/stdsimd b/src/stdsimd index 1ea18a5cb43..2f86c75a247 160000 --- a/src/stdsimd +++ b/src/stdsimd @@ -1 +1 @@ -Subproject commit 1ea18a5cb431e24aa838b652ac305acc5e394d6b +Subproject commit 2f86c75a2479cf051b92fc98273daaf7f151e7a1 diff --git a/src/test/run-pass/vec-const-new.rs b/src/test/run-pass/collections-const-new.rs similarity index 77% rename from src/test/run-pass/vec-const-new.rs rename to src/test/run-pass/collections-const-new.rs index 62e2a36d7cc..4003c2ec4f7 100644 --- a/src/test/run-pass/vec-const-new.rs +++ b/src/test/run-pass/collections-const-new.rs @@ -8,10 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Test that Vec::new() can be used for constants +// Test several functions can be used for constants +// 1. Vec::new() +// 2. String::new() #![feature(const_vec_new)] +#![feature(const_string_new)] const MY_VEC: Vec = Vec::new(); +const MY_STRING: String = String::new(); + pub fn main() {} diff --git a/src/test/run-pass/issue-44333.rs b/src/test/run-pass/issue-44333.rs new file mode 100644 index 00000000000..72731f41321 --- /dev/null +++ b/src/test/run-pass/issue-44333.rs @@ -0,0 +1,29 @@ +// Copyright 2018 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. + +type Func = fn(usize, usize) -> usize; + +fn foo(a: usize, b: usize) -> usize { a + b } +fn bar(a: usize, b: usize) -> usize { a * b } +fn test(x: usize) -> Func { + if x % 2 == 0 { foo } + else { bar } +} + +const FOO: Func = foo; +const BAR: Func = bar; + +fn main() { + match test(std::env::consts::ARCH.len()) { + FOO => println!("foo"), + BAR => println!("bar"), + _ => unreachable!(), + } +} diff --git a/src/tools/cargo b/src/tools/cargo index af3f1cd29bc..9e53ac6e652 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit af3f1cd29bc872b932a13083e531255aab233a7e +Subproject commit 9e53ac6e6525da914cb05a85e5e8eff7b5dca81f diff --git a/src/tools/rls b/src/tools/rls index 1263f1ff25b..d2ade31a52a 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit 1263f1ff25bb329b76f74715ad4a7ec0d1f71430 +Subproject commit d2ade31a52a417257742de72c5936a8a342a34b5