about summary refs log tree commit diff
path: root/library
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-09-02 01:29:28 +0000
committerbors <bors@rust-lang.org>2020-09-02 01:29:28 +0000
commite36e4bd0f7e722d3c97d1ca45387e58f81e4e8ea (patch)
tree505c8905fbf0db875c1be97477b65cac833bb653 /library
parent130359cb05246fcacdde61baa2613419ef6570c7 (diff)
parent4dd75f8049b722ea8bd4ff9d7c6c4a438161bad6 (diff)
Auto merge of #76231 - tmandry:rollup-ilvs9fq, r=tmandry
Rollup of 14 pull requests

Successful merges:

 - #74880 (Add trailing comma support to matches macro)
 - #76074 (Add new `-Z dump-mir-spanview` option)
 - #76088 (Add more examples to lexicographic cmp on Iterators.)
 - #76099 (Add info about `!` and `impl Trait`)
 - #76126 (Use "Fira Sans" for crate list font)
 - #76132 (Factor out StmtKind::MacCall fields into `MacCallStmt` struct)
 - #76143 (Give a better error message for duplicate built-in macros)
 - #76158 (Stabilise link-self-contained option)
 - #76201 (Move to intra-doc links for library/core/src/panic.rs)
 - #76206 (Make all methods of `std::net::Ipv6Addr` const)
 - #76207 (# Move to intra-doc links for library/core/src/clone.rs)
 - #76212 (Document lint missing_doc_code_examples is nightly-only)
 - #76218 (lexer: Tiny improvement to shebang detection)
 - #76221 (Clean up header in `iter` docs for `for` loops)

Failed merges:

r? @ghost
Diffstat (limited to 'library')
-rw-r--r--library/core/src/clone.rs13
-rw-r--r--library/core/src/iter/mod.rs2
-rw-r--r--library/core/src/iter/traits/iterator.rs4
-rw-r--r--library/core/src/macros/mod.rs2
-rw-r--r--library/core/src/panic.rs9
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/net/ip.rs46
-rw-r--r--library/std/src/primitive_docs.rs43
8 files changed, 81 insertions, 39 deletions
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index 7784ec687ea..a953a3a4182 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -7,11 +7,9 @@
 //! contain owned boxes or implement [`Drop`]), so the compiler considers
 //! them cheap and safe to copy. For other types copies must be made
 //! explicitly, by convention implementing the [`Clone`] trait and calling
-//! the [`clone`][clone] method.
+//! the [`clone`] method.
 //!
-//! [`Clone`]: trait.Clone.html
-//! [clone]: trait.Clone.html#tymethod.clone
-//! [`Drop`]: ../../std/ops/trait.Drop.html
+//! [`clone`]: Clone::clone
 //!
 //! Basic usage example:
 //!
@@ -51,7 +49,9 @@
 /// ## Derivable
 ///
 /// This trait can be used with `#[derive]` if all fields are `Clone`. The `derive`d
-/// implementation of [`clone`] calls [`clone`] on each field.
+/// implementation of [`Clone`] calls [`clone`] on each field.
+///
+/// [`clone`]: Clone::clone
 ///
 /// For a generic struct, `#[derive]` implements `Clone` conditionally by adding bound `Clone` on
 /// generic parameters.
@@ -74,9 +74,6 @@
 /// An example is a generic struct holding a function pointer. In this case, the
 /// implementation of `Clone` cannot be `derive`d, but can be implemented as:
 ///
-/// [`Copy`]: ../../std/marker/trait.Copy.html
-/// [`clone`]: trait.Clone.html#tymethod.clone
-///
 /// ```
 /// struct Generate<T>(fn() -> T);
 ///
diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs
index 28b22f80e2c..1be9c4de916 100644
--- a/library/core/src/iter/mod.rs
+++ b/library/core/src/iter/mod.rs
@@ -135,7 +135,7 @@
 //! methods like `nth` and `fold` if an iterator can compute them more efficiently without calling
 //! `next`.
 //!
-//! # for Loops and IntoIterator
+//! # `for` loops and `IntoIterator`
 //!
 //! Rust's `for` loop syntax is actually sugar for iterators. Here's a basic
 //! example of `for`:
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index aca6699b9ef..0bac21406bf 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -3078,6 +3078,7 @@ pub trait Iterator {
     /// assert_eq!([1].iter().lt([1].iter()), false);
     /// assert_eq!([1].iter().lt([1, 2].iter()), true);
     /// assert_eq!([1, 2].iter().lt([1].iter()), false);
+    /// assert_eq!([1, 2].iter().lt([1, 2].iter()), false);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
     fn lt<I>(self, other: I) -> bool
@@ -3098,6 +3099,7 @@ pub trait Iterator {
     /// assert_eq!([1].iter().le([1].iter()), true);
     /// assert_eq!([1].iter().le([1, 2].iter()), true);
     /// assert_eq!([1, 2].iter().le([1].iter()), false);
+    /// assert_eq!([1, 2].iter().le([1, 2].iter()), true);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
     fn le<I>(self, other: I) -> bool
@@ -3118,6 +3120,7 @@ pub trait Iterator {
     /// assert_eq!([1].iter().gt([1].iter()), false);
     /// assert_eq!([1].iter().gt([1, 2].iter()), false);
     /// assert_eq!([1, 2].iter().gt([1].iter()), true);
+    /// assert_eq!([1, 2].iter().gt([1, 2].iter()), false);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
     fn gt<I>(self, other: I) -> bool
@@ -3138,6 +3141,7 @@ pub trait Iterator {
     /// assert_eq!([1].iter().ge([1].iter()), true);
     /// assert_eq!([1].iter().ge([1, 2].iter()), false);
     /// assert_eq!([1, 2].iter().ge([1].iter()), true);
+    /// assert_eq!([1, 2].iter().ge([1, 2].iter()), true);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
     fn ge<I>(self, other: I) -> bool
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 4e0da1fc4a6..a1b0821004b 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -242,7 +242,7 @@ macro_rules! debug_assert_ne {
 #[macro_export]
 #[stable(feature = "matches_macro", since = "1.42.0")]
 macro_rules! matches {
-    ($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )?) => {
+    ($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )? $(,)?) => {
         match $expression {
             $( $pattern )|+ $( if $guard )? => true,
             _ => false
diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs
index 316ecafe572..25ee73c626e 100644
--- a/library/core/src/panic.rs
+++ b/library/core/src/panic.rs
@@ -92,8 +92,6 @@ impl<'a> PanicInfo<'a> {
     /// If the `panic!` macro from the `core` crate (not from `std`)
     /// was used with a formatting string and some additional arguments,
     /// returns that message ready to be used for example with [`fmt::write`]
-    ///
-    /// [`fmt::write`]: ../fmt/fn.write.html
     #[unstable(feature = "panic_info_message", issue = "66745")]
     pub fn message(&self) -> Option<&fmt::Arguments<'_>> {
         self.message
@@ -105,8 +103,6 @@ impl<'a> PanicInfo<'a> {
     /// This method will currently always return [`Some`], but this may change
     /// in future versions.
     ///
-    /// [`Some`]: ../../std/option/enum.Option.html#variant.Some
-    ///
     /// # Examples
     ///
     /// ```should_panic
@@ -153,10 +149,7 @@ impl fmt::Display for PanicInfo<'_> {
 
 /// A struct containing information about the location of a panic.
 ///
-/// This structure is created by the [`location`] method of [`PanicInfo`].
-///
-/// [`location`]: ../../std/panic/struct.PanicInfo.html#method.location
-/// [`PanicInfo`]: ../../std/panic/struct.PanicInfo.html
+/// This structure is created by [`PanicInfo::location()`].
 ///
 /// # Examples
 ///
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 0797585e3df..3141b3b9526 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -238,6 +238,7 @@
 #![feature(concat_idents)]
 #![feature(const_cstr_unchecked)]
 #![feature(const_fn_transmute)]
+#![feature(const_ipv6)]
 #![feature(const_raw_ptr_deref)]
 #![feature(container_error_extra)]
 #![feature(core_intrinsics)]
diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs
index 10676b49d43..341a112df71 100644
--- a/library/std/src/net/ip.rs
+++ b/library/std/src/net/ip.rs
@@ -1102,8 +1102,9 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).segments(),
     ///            [0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff]);
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn segments(&self) -> [u16; 8] {
+    pub const fn segments(&self) -> [u16; 8] {
         // All elements in `s6_addr` must be big endian.
         // SAFETY: `[u8; 16]` is always safe to transmute to `[u16; 8]`.
         let [a, b, c, d, e, f, g, h] = unsafe { transmute::<_, [u16; 8]>(self.inner.s6_addr) };
@@ -1135,9 +1136,10 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unspecified(), false);
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).is_unspecified(), true);
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[stable(since = "1.7.0", feature = "ip_17")]
-    pub fn is_unspecified(&self) -> bool {
-        self.segments() == [0, 0, 0, 0, 0, 0, 0, 0]
+    pub const fn is_unspecified(&self) -> bool {
+        u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::UNSPECIFIED.octets())
     }
 
     /// Returns [`true`] if this is a loopback address (::1).
@@ -1155,9 +1157,10 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_loopback(), false);
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_loopback(), true);
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[stable(since = "1.7.0", feature = "ip_17")]
-    pub fn is_loopback(&self) -> bool {
-        self.segments() == [0, 0, 0, 0, 0, 0, 0, 1]
+    pub const fn is_loopback(&self) -> bool {
+        u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::LOCALHOST.octets())
     }
 
     /// Returns [`true`] if the address appears to be globally routable.
@@ -1182,7 +1185,8 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_global(), false);
     /// assert_eq!(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1).is_global(), true);
     /// ```
-    pub fn is_global(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    pub const fn is_global(&self) -> bool {
         match self.multicast_scope() {
             Some(Ipv6MulticastScope::Global) => true,
             None => self.is_unicast_global(),
@@ -1208,7 +1212,8 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unique_local(), false);
     /// assert_eq!(Ipv6Addr::new(0xfc02, 0, 0, 0, 0, 0, 0, 0).is_unique_local(), true);
     /// ```
-    pub fn is_unique_local(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    pub const fn is_unique_local(&self) -> bool {
         (self.segments()[0] & 0xfe00) == 0xfc00
     }
 
@@ -1263,7 +1268,8 @@ impl Ipv6Addr {
     /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
     /// [IETF RFC 4291 section 2.5.6]: https://tools.ietf.org/html/rfc4291#section-2.5.6
     /// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406
-    pub fn is_unicast_link_local_strict(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    pub const fn is_unicast_link_local_strict(&self) -> bool {
         (self.segments()[0] & 0xffff) == 0xfe80
             && (self.segments()[1] & 0xffff) == 0
             && (self.segments()[2] & 0xffff) == 0
@@ -1320,7 +1326,8 @@ impl Ipv6Addr {
     ///
     /// [IETF RFC 4291 section 2.4]: https://tools.ietf.org/html/rfc4291#section-2.4
     /// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406
-    pub fn is_unicast_link_local(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    pub const fn is_unicast_link_local(&self) -> bool {
         (self.segments()[0] & 0xffc0) == 0xfe80
     }
 
@@ -1359,7 +1366,8 @@ impl Ipv6Addr {
     /// addresses.
     ///
     /// [RFC 3879]: https://tools.ietf.org/html/rfc3879
-    pub fn is_unicast_site_local(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    pub const fn is_unicast_site_local(&self) -> bool {
         (self.segments()[0] & 0xffc0) == 0xfec0
     }
 
@@ -1381,7 +1389,8 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_documentation(), false);
     /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_documentation(), true);
     /// ```
-    pub fn is_documentation(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    pub const fn is_documentation(&self) -> bool {
         (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8)
     }
 
@@ -1416,7 +1425,8 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_unicast_global(), false);
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_global(), true);
     /// ```
-    pub fn is_unicast_global(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    pub const fn is_unicast_global(&self) -> bool {
         !self.is_multicast()
             && !self.is_loopback()
             && !self.is_unicast_link_local()
@@ -1440,7 +1450,8 @@ impl Ipv6Addr {
     /// );
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).multicast_scope(), None);
     /// ```
-    pub fn multicast_scope(&self) -> Option<Ipv6MulticastScope> {
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    pub const fn multicast_scope(&self) -> Option<Ipv6MulticastScope> {
         if self.is_multicast() {
             match self.segments()[0] & 0x000f {
                 1 => Some(Ipv6MulticastScope::InterfaceLocal),
@@ -1472,8 +1483,9 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).is_multicast(), true);
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_multicast(), false);
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[stable(since = "1.7.0", feature = "ip_17")]
-    pub fn is_multicast(&self) -> bool {
+    pub const fn is_multicast(&self) -> bool {
         (self.segments()[0] & 0xff00) == 0xff00
     }
 
@@ -1498,7 +1510,8 @@ impl Ipv6Addr {
     ///            Some(Ipv4Addr::new(192, 10, 2, 255)));
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_ipv4_mapped(), None);
     /// ```
-    pub fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> {
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    pub const fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> {
         match self.octets() {
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, a, b, c, d] => {
                 Some(Ipv4Addr::new(a, b, c, d))
@@ -1525,8 +1538,9 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_ipv4(),
     ///            Some(Ipv4Addr::new(0, 0, 0, 1)));
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn to_ipv4(&self) -> Option<Ipv4Addr> {
+    pub const fn to_ipv4(&self) -> Option<Ipv4Addr> {
         if let [0, 0, 0, 0, 0, 0 | 0xffff, ab, cd] = self.segments() {
             let [a, b] = ab.to_be_bytes();
             let [c, d] = cd.to_be_bytes();
diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs
index 2339ca527bd..d00824cfb3e 100644
--- a/library/std/src/primitive_docs.rs
+++ b/library/std/src/primitive_docs.rs
@@ -1,7 +1,6 @@
 #[doc(primitive = "bool")]
 #[doc(alias = "true")]
 #[doc(alias = "false")]
-//
 /// The boolean type.
 ///
 /// The `bool` represents a value, which could only be either `true` or `false`. If you cast
@@ -12,8 +11,8 @@
 /// `bool` implements various traits, such as [`BitAnd`], [`BitOr`], [`Not`], etc.,
 /// which allow us to perform boolean operations using `&`, `|` and `!`.
 ///
-/// `if` always demands a `bool` value. [`assert!`], being an important macro in testing,
-/// checks whether an expression returns `true`.
+/// `if` always demands a `bool` value. [`assert!`], which is an important macro in testing,
+/// checks whether an expression returns `true` and panics if it isn't.
 ///
 /// ```
 /// let bool_val = true & false | false;
@@ -194,14 +193,48 @@ mod prim_bool {}
 /// # `!` and traits
 ///
 /// When writing your own traits, `!` should have an `impl` whenever there is an obvious `impl`
-/// which doesn't `panic!`. As it turns out, most traits can have an `impl` for `!`. Take [`Debug`]
+/// which doesn't `panic!`. The reason is that functions returning an `impl Trait` where `!`
+/// does not have an `impl` of `Trait` cannot diverge as their only possible code path. In other
+/// words, they can't return `!` from every code path. As an example, this code doesn't compile:
+///
+/// ```compile_fail
+/// use core::ops::Add;
+///
+/// fn foo() -> impl Add<u32> {
+///     unimplemented!()
+/// }
+/// ```
+///
+/// But this code does:
+///
+/// ```
+/// use core::ops::Add;
+///
+/// fn foo() -> impl Add<u32> {
+///     if true {
+///         unimplemented!()
+///     } else {
+///         0
+///     }
+/// }
+/// ```
+///
+/// The reason is that, in the first example, there are many possible types that `!` could coerce
+/// to, because many types implement `Add<u32>`. However, in the second example,
+/// the `else` branch returns a `0`, which the compiler infers from the return type to be of type
+/// `u32`. Since `u32` is a concrete type, `!` can and will be coerced to it. See issue [#36375]
+/// for more information on this quirk of `!`.
+///
+/// [#36375]: https://github.com/rust-lang/rust/issues/36375
+///
+/// As it turns out, though, most traits can have an `impl` for `!`. Take [`Debug`]
 /// for example:
 ///
 /// ```
 /// #![feature(never_type)]
 /// # use std::fmt;
 /// # trait Debug {
-/// # fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result;
+/// #     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result;
 /// # }
 /// impl Debug for ! {
 ///     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {