about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_expand/src/lib.rs1
-rw-r--r--compiler/rustc_expand/src/mbe/macro_parser.rs9
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs6
-rw-r--r--compiler/rustc_typeck/src/collect.rs6
-rw-r--r--library/alloc/src/string.rs50
-rw-r--r--library/proc_macro/src/lib.rs14
-rw-r--r--library/std/src/io/impls.rs10
-rw-r--r--library/std/src/net/ip.rs82
m---------src/doc/reference0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/librustdoc/clean/auto_trait.rs5
-rw-r--r--src/librustdoc/clean/mod.rs13
-rw-r--r--src/librustdoc/clean/types.rs1
-rw-r--r--src/librustdoc/html/format.rs16
-rw-r--r--src/librustdoc/html/render/mod.rs164
-rw-r--r--src/librustdoc/json/conversions.rs4
-rw-r--r--src/librustdoc/json/mod.rs2
-rw-r--r--src/rustdoc-json-types/lib.rs2
-rw-r--r--src/test/rustdoc-ui/wasm-safe.rs7
-rw-r--r--src/test/rustdoc/const-generics/const-generic-defaults.rs6
-rw-r--r--src/test/ui/macros/local-ambiguity-multiple-parsing-options.stderr4
m---------src/tools/cargo0
22 files changed, 261 insertions, 141 deletions
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index f77eac2b068..efed41de23a 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -1,6 +1,7 @@
 #![feature(crate_visibility_modifier)]
 #![feature(decl_macro)]
 #![feature(destructuring_assignment)]
+#![feature(format_args_capture)]
 #![feature(iter_zip)]
 #![feature(proc_macro_diagnostic)]
 #![feature(proc_macro_internals)]
diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index 1aed42a24e2..a7434d73abe 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -85,6 +85,7 @@ use smallvec::{smallvec, SmallVec};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
+use rustc_span::symbol::Ident;
 use std::borrow::Cow;
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::mem;
@@ -615,7 +616,11 @@ fn inner_parse_loop<'root, 'tt>(
 
 /// Use the given sequence of token trees (`ms`) as a matcher. Match the token
 /// stream from the given `parser` against it and return the match.
-pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> NamedParseResult {
+pub(super) fn parse_tt(
+    parser: &mut Cow<'_, Parser<'_>>,
+    ms: &[TokenTree],
+    macro_name: Ident,
+) -> NamedParseResult {
     // A queue of possible matcher positions. We initialize it with the matcher position in which
     // the "dot" is before the first token of the first token tree in `ms`. `inner_parse_loop` then
     // processes all of these possible matcher positions and produces possible next positions into
@@ -711,7 +716,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na
             return Error(
                 parser.token.span,
                 format!(
-                    "local ambiguity: multiple parsing options: {}",
+                    "local ambiguity when calling macro `{macro_name}`: multiple parsing options: {}",
                     match next_items.len() {
                         0 => format!("built-in NTs {}.", nts),
                         1 => format!("built-in NTs {} or 1 other option.", nts),
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 6608573d720..abad190b072 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -245,7 +245,7 @@ fn generic_extension<'cx>(
         // are not recorded. On the first `Success(..)`ful matcher, the spans are merged.
         let mut gated_spans_snapshot = mem::take(&mut *sess.gated_spans.spans.borrow_mut());
 
-        match parse_tt(&mut Cow::Borrowed(&parser), lhs_tt) {
+        match parse_tt(&mut Cow::Borrowed(&parser), lhs_tt, name) {
             Success(named_matches) => {
                 // The matcher was `Success(..)`ful.
                 // Merge the gated spans from parsing the matcher with the pre-existing ones.
@@ -338,7 +338,7 @@ fn generic_extension<'cx>(
                 _ => continue,
             };
             if let Success(_) =
-                parse_tt(&mut Cow::Borrowed(&parser_from_cx(sess, arg.clone())), lhs_tt)
+                parse_tt(&mut Cow::Borrowed(&parser_from_cx(sess, arg.clone())), lhs_tt, name)
             {
                 if comma_span.is_dummy() {
                     err.note("you might be missing a comma");
@@ -432,7 +432,7 @@ pub fn compile_declarative_macro(
     ];
 
     let parser = Parser::new(&sess.parse_sess, body, true, rustc_parse::MACRO_ARGUMENTS);
-    let argument_map = match parse_tt(&mut Cow::Borrowed(&parser), &argument_gram) {
+    let argument_map = match parse_tt(&mut Cow::Borrowed(&parser), &argument_gram, def.ident) {
         Success(m) => m,
         Failure(token, msg) => {
             let s = parse_failure_msg(&token);
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index f5ee4b21ea6..ee3ac3b62d9 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -2771,7 +2771,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
             }
         } else if tcx.sess.check_name(attr, sym::target_feature) {
             if !tcx.is_closure(id) && tcx.fn_sig(id).unsafety() == hir::Unsafety::Normal {
-                if tcx.sess.target.is_like_wasm {
+                if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc {
                     // The `#[target_feature]` attribute is allowed on
                     // WebAssembly targets on all functions, including safe
                     // ones. Other targets require that `#[target_feature]` is
@@ -2785,6 +2785,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
                     // deterministic trap. There is no undefined behavior when
                     // executing WebAssembly so `#[target_feature]` is allowed
                     // on safe functions (but again, only for WebAssembly)
+                    //
+                    // Note that this is also allowed if `actually_rustdoc` so
+                    // if a target is documenting some wasm-specific code then
+                    // it's not spuriously denied.
                 } else if !tcx.features().target_feature_11 {
                     let mut err = feature_err(
                         &tcx.sess.parse_sess,
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 1fb645a302e..93f5fe45cd6 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -2491,6 +2491,9 @@ impl AsRef<[u8]> for String {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl From<&str> for String {
+    /// Converts a `&str` into a [`String`].
+    ///
+    /// The result is allocated on the heap.
     #[inline]
     fn from(s: &str) -> String {
         s.to_owned()
@@ -2500,7 +2503,7 @@ impl From<&str> for String {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "from_mut_str_for_string", since = "1.44.0")]
 impl From<&mut str> for String {
-    /// Converts a `&mut str` into a `String`.
+    /// Converts a `&mut str` into a [`String`].
     ///
     /// The result is allocated on the heap.
     #[inline]
@@ -2512,6 +2515,9 @@ impl From<&mut str> for String {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "from_ref_string", since = "1.35.0")]
 impl From<&String> for String {
+    /// Converts a `&String` into a [`String`].
+    ///
+    /// This clones `s` and returns the clone.
     #[inline]
     fn from(s: &String) -> String {
         s.clone()
@@ -2522,7 +2528,7 @@ impl From<&String> for String {
 #[cfg(not(test))]
 #[stable(feature = "string_from_box", since = "1.18.0")]
 impl From<Box<str>> for String {
-    /// Converts the given boxed `str` slice to a `String`.
+    /// Converts the given boxed `str` slice to a [`String`].
     /// It is notable that the `str` slice is owned.
     ///
     /// # Examples
@@ -2544,7 +2550,7 @@ impl From<Box<str>> for String {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "box_from_str", since = "1.20.0")]
 impl From<String> for Box<str> {
-    /// Converts the given `String` to a boxed `str` slice that is owned.
+    /// Converts the given [`String`] to a boxed `str` slice that is owned.
     ///
     /// # Examples
     ///
@@ -2565,6 +2571,22 @@ impl From<String> for Box<str> {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "string_from_cow_str", since = "1.14.0")]
 impl<'a> From<Cow<'a, str>> for String {
+    /// Converts a clone-on-write string to an owned
+    /// instance of [`String`].
+    ///
+    /// This extracts the owned string,
+    /// clones the string if it is not already owned.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # use std::borrow::Cow;
+    /// // If the string is not owned...
+    /// let cow: Cow<str> = Cow::Borrowed("eggplant");
+    /// // It will allocate on the heap and copy the string.
+    /// let owned: String = String::from(cow);
+    /// assert_eq!(&owned[..], "eggplant");
+    /// ```
     fn from(s: Cow<'a, str>) -> String {
         s.into_owned()
     }
@@ -2573,7 +2595,7 @@ impl<'a> From<Cow<'a, str>> for String {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> From<&'a str> for Cow<'a, str> {
-    /// Converts a string slice into a Borrowed variant.
+    /// Converts a string slice into a [`Borrowed`] variant.
     /// No heap allocation is performed, and the string
     /// is not copied.
     ///
@@ -2583,6 +2605,8 @@ impl<'a> From<&'a str> for Cow<'a, str> {
     /// # use std::borrow::Cow;
     /// assert_eq!(Cow::from("eggplant"), Cow::Borrowed("eggplant"));
     /// ```
+    ///
+    /// [`Borrowed`]: crate::borrow::Cow::Borrowed
     #[inline]
     fn from(s: &'a str) -> Cow<'a, str> {
         Cow::Borrowed(s)
@@ -2592,7 +2616,7 @@ impl<'a> From<&'a str> for Cow<'a, str> {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> From<String> for Cow<'a, str> {
-    /// Converts a String into an Owned variant.
+    /// Converts a [`String`] into an [`Owned`] variant.
     /// No heap allocation is performed, and the string
     /// is not copied.
     ///
@@ -2604,6 +2628,8 @@ impl<'a> From<String> for Cow<'a, str> {
     /// let s2 = "eggplant".to_string();
     /// assert_eq!(Cow::from(s), Cow::<'static, str>::Owned(s2));
     /// ```
+    ///
+    /// [`Owned`]: crate::borrow::Cow::Owned
     #[inline]
     fn from(s: String) -> Cow<'a, str> {
         Cow::Owned(s)
@@ -2613,7 +2639,7 @@ impl<'a> From<String> for Cow<'a, str> {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "cow_from_string_ref", since = "1.28.0")]
 impl<'a> From<&'a String> for Cow<'a, str> {
-    /// Converts a String reference into a Borrowed variant.
+    /// Converts a [`String`] reference into a [`Borrowed`] variant.
     /// No heap allocation is performed, and the string
     /// is not copied.
     ///
@@ -2624,6 +2650,8 @@ impl<'a> From<&'a String> for Cow<'a, str> {
     /// let s = "eggplant".to_string();
     /// assert_eq!(Cow::from(&s), Cow::Borrowed("eggplant"));
     /// ```
+    ///
+    /// [`Borrowed`]: crate::borrow::Cow::Borrowed
     #[inline]
     fn from(s: &'a String) -> Cow<'a, str> {
         Cow::Borrowed(s.as_str())
@@ -2656,7 +2684,7 @@ impl<'a> FromIterator<String> for Cow<'a, str> {
 
 #[stable(feature = "from_string_for_vec_u8", since = "1.14.0")]
 impl From<String> for Vec<u8> {
-    /// Converts the given `String` to a vector `Vec` that holds values of type `u8`.
+    /// Converts the given [`String`] to a vector [`Vec`] that holds values of type [`u8`].
     ///
     /// # Examples
     ///
@@ -2802,6 +2830,14 @@ impl FusedIterator for Drain<'_> {}
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "from_char_for_string", since = "1.46.0")]
 impl From<char> for String {
+    /// Allocates an owned [`String`] from a single character.
+    ///
+    /// # Example
+    /// ```rust
+    /// let c: char = 'a';
+    /// let s: String = String::from(c);
+    /// assert_eq!("a", &s[..]);
+    /// ```
     #[inline]
     fn from(c: char) -> Self {
         c.to_string()
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 3990826ce42..26fbf50e2df 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -31,6 +31,7 @@
 #![feature(restricted_std)]
 #![feature(rustc_attrs)]
 #![feature(min_specialization)]
+#![feature(bound_cloned)]
 #![recursion_limit = "256"]
 
 #[unstable(feature = "proc_macro_internals", issue = "27812")]
@@ -43,7 +44,7 @@ mod diagnostic;
 pub use diagnostic::{Diagnostic, Level, MultiSpan};
 
 use std::cmp::Ordering;
-use std::ops::{Bound, RangeBounds};
+use std::ops::RangeBounds;
 use std::path::PathBuf;
 use std::str::FromStr;
 use std::{error, fmt, iter, mem};
@@ -1162,16 +1163,7 @@ impl Literal {
     // was 'c' or whether it was '\u{63}'.
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
-        // HACK(eddyb) something akin to `Option::cloned`, but for `Bound<&T>`.
-        fn cloned_bound<T: Clone>(bound: Bound<&T>) -> Bound<T> {
-            match bound {
-                Bound::Included(x) => Bound::Included(x.clone()),
-                Bound::Excluded(x) => Bound::Excluded(x.clone()),
-                Bound::Unbounded => Bound::Unbounded,
-            }
-        }
-
-        self.0.subspan(cloned_bound(range.start_bound()), cloned_bound(range.end_bound())).map(Span)
+        self.0.subspan(range.start_bound().cloned(), range.end_bound().cloned()).map(Span)
     }
 }
 
diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs
index 6891bd8a664..7a2a49ba7d7 100644
--- a/library/std/src/io/impls.rs
+++ b/library/std/src/io/impls.rs
@@ -87,6 +87,11 @@ impl<S: Seek + ?Sized> Seek for &mut S {
     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
         (**self).seek(pos)
     }
+
+    #[inline]
+    fn stream_position(&mut self) -> io::Result<u64> {
+        (**self).stream_position()
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<B: BufRead + ?Sized> BufRead for &mut B {
@@ -186,6 +191,11 @@ impl<S: Seek + ?Sized> Seek for Box<S> {
     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
         (**self).seek(pos)
     }
+
+    #[inline]
+    fn stream_position(&mut self) -> io::Result<u64> {
+        (**self).stream_position()
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<B: BufRead + ?Sized> BufRead for Box<B> {
diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs
index 6c2f2eeabd6..2b6d0d7d5da 100644
--- a/library/std/src/net/ip.rs
+++ b/library/std/src/net/ip.rs
@@ -314,7 +314,7 @@ impl Ipv4Addr {
         Ipv4Addr { inner: c::in_addr { s_addr: u32::from_ne_bytes([a, b, c, d]) } }
     }
 
-    /// An IPv4 address with the address pointing to localhost: 127.0.0.1.
+    /// An IPv4 address with the address pointing to localhost: `127.0.0.1`
     ///
     /// # Examples
     ///
@@ -327,7 +327,7 @@ impl Ipv4Addr {
     #[stable(feature = "ip_constructors", since = "1.30.0")]
     pub const LOCALHOST: Self = Ipv4Addr::new(127, 0, 0, 1);
 
-    /// An IPv4 address representing an unspecified address: 0.0.0.0
+    /// An IPv4 address representing an unspecified address: `0.0.0.0`
     ///
     /// This corresponds to the constant `INADDR_ANY` in other languages.
     ///
@@ -343,7 +343,7 @@ impl Ipv4Addr {
     #[stable(feature = "ip_constructors", since = "1.30.0")]
     pub const UNSPECIFIED: Self = Ipv4Addr::new(0, 0, 0, 0);
 
-    /// An IPv4 address representing the broadcast address: 255.255.255.255
+    /// An IPv4 address representing the broadcast address: `255.255.255.255`
     ///
     /// # Examples
     ///
@@ -374,7 +374,7 @@ impl Ipv4Addr {
         self.inner.s_addr.to_ne_bytes()
     }
 
-    /// Returns [`true`] for the special 'unspecified' address (0.0.0.0).
+    /// Returns [`true`] for the special 'unspecified' address (`0.0.0.0`).
     ///
     /// This property is defined in _UNIX Network Programming, Second Edition_,
     /// W. Richard Stevens, p. 891; see also [ip7].
@@ -396,7 +396,7 @@ impl Ipv4Addr {
         self.inner.s_addr == 0
     }
 
-    /// Returns [`true`] if this is a loopback address (127.0.0.0/8).
+    /// Returns [`true`] if this is a loopback address (`127.0.0.0/8`).
     ///
     /// This property is defined by [IETF RFC 1122].
     ///
@@ -421,9 +421,9 @@ impl Ipv4Addr {
     ///
     /// The private address ranges are defined in [IETF RFC 1918] and include:
     ///
-    ///  - 10.0.0.0/8
-    ///  - 172.16.0.0/12
-    ///  - 192.168.0.0/16
+    ///  - `10.0.0.0/8`
+    ///  - `172.16.0.0/12`
+    ///  - `192.168.0.0/16`
     ///
     /// [IETF RFC 1918]: https://tools.ietf.org/html/rfc1918
     ///
@@ -452,7 +452,7 @@ impl Ipv4Addr {
         }
     }
 
-    /// Returns [`true`] if the address is link-local (169.254.0.0/16).
+    /// Returns [`true`] if the address is link-local (`169.254.0.0/16`).
     ///
     /// This property is defined by [IETF RFC 3927].
     ///
@@ -485,7 +485,7 @@ impl Ipv4Addr {
     /// - the broadcast address (see [`Ipv4Addr::is_broadcast()`])
     /// - addresses used for documentation (see [`Ipv4Addr::is_documentation()`])
     /// - the unspecified address (see [`Ipv4Addr::is_unspecified()`]), and the whole
-    ///   0.0.0.0/8 block
+    ///   `0.0.0.0/8` block
     /// - addresses reserved for future protocols (see
     /// [`Ipv4Addr::is_ietf_protocol_assignment()`], except
     /// `192.0.0.9/32` and `192.0.0.10/32` which are globally routable
@@ -682,9 +682,9 @@ impl Ipv4Addr {
         self.octets()[0] & 240 == 240 && !self.is_broadcast()
     }
 
-    /// Returns [`true`] if this is a multicast address (224.0.0.0/4).
+    /// Returns [`true`] if this is a multicast address (`224.0.0.0/4`).
     ///
-    /// Multicast addresses have a most significant octet between 224 and 239,
+    /// Multicast addresses have a most significant octet between `224` and `239`,
     /// and is defined by [IETF RFC 5771].
     ///
     /// [IETF RFC 5771]: https://tools.ietf.org/html/rfc5771
@@ -705,9 +705,9 @@ impl Ipv4Addr {
         self.octets()[0] >= 224 && self.octets()[0] <= 239
     }
 
-    /// Returns [`true`] if this is a broadcast address (255.255.255.255).
+    /// Returns [`true`] if this is a broadcast address (`255.255.255.255`).
     ///
-    /// A broadcast address has all octets set to 255 as defined in [IETF RFC 919].
+    /// A broadcast address has all octets set to `255` as defined in [IETF RFC 919].
     ///
     /// [IETF RFC 919]: https://tools.ietf.org/html/rfc919
     ///
@@ -730,9 +730,9 @@ impl Ipv4Addr {
     ///
     /// This is defined in [IETF RFC 5737]:
     ///
-    /// - 192.0.2.0/24 (TEST-NET-1)
-    /// - 198.51.100.0/24 (TEST-NET-2)
-    /// - 203.0.113.0/24 (TEST-NET-3)
+    /// - `192.0.2.0/24` (TEST-NET-1)
+    /// - `198.51.100.0/24` (TEST-NET-2)
+    /// - `203.0.113.0/24` (TEST-NET-3)
     ///
     /// [IETF RFC 5737]: https://tools.ietf.org/html/rfc5737
     ///
@@ -760,7 +760,7 @@ impl Ipv4Addr {
 
     /// Converts this address to an IPv4-compatible [`IPv6` address].
     ///
-    /// a.b.c.d becomes ::a.b.c.d
+    /// `a.b.c.d` becomes `::a.b.c.d`
     ///
     /// This isn't typically the method you want; these addresses don't typically
     /// function on modern systems. Use `to_ipv6_mapped` instead.
@@ -774,7 +774,7 @@ impl Ipv4Addr {
     ///
     /// assert_eq!(
     ///     Ipv4Addr::new(192, 0, 2, 255).to_ipv6_compatible(),
-    ///     Ipv6Addr::new(0, 0, 0, 0, 0, 0, 49152, 767)
+    ///     Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc000, 0x2ff)
     /// );
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
@@ -789,7 +789,7 @@ impl Ipv4Addr {
 
     /// Converts this address to an IPv4-mapped [`IPv6` address].
     ///
-    /// a.b.c.d becomes ::ffff:a.b.c.d
+    /// `a.b.c.d` becomes `::ffff:a.b.c.d`
     ///
     /// [`IPv6` address]: Ipv6Addr
     ///
@@ -799,7 +799,7 @@ impl Ipv4Addr {
     /// use std::net::{Ipv4Addr, Ipv6Addr};
     ///
     /// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).to_ipv6_mapped(),
-    ///            Ipv6Addr::new(0, 0, 0, 0, 0, 65535, 49152, 767));
+    ///            Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x2ff));
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -1172,7 +1172,7 @@ impl Ipv6Addr {
         ]
     }
 
-    /// Returns [`true`] for the special 'unspecified' address (::).
+    /// Returns [`true`] for the special 'unspecified' address (`::`).
     ///
     /// This property is defined in [IETF RFC 4291].
     ///
@@ -1267,6 +1267,34 @@ impl Ipv6Addr {
         (self.segments()[0] & 0xfe00) == 0xfc00
     }
 
+    /// Returns [`true`] if this is a unicast address, as defined by [IETF RFC 4291].
+    /// Any address that is not a [multicast address] (`ff00::/8`) is unicast.
+    ///
+    /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
+    /// [multicast address]: Ipv6Addr::is_multicast
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ip)]
+    ///
+    /// use std::net::Ipv6Addr;
+    ///
+    /// // The unspecified and loopback addresses are unicast.
+    /// assert_eq!(Ipv6Addr::UNSPECIFIED.is_unicast(), true);
+    /// assert_eq!(Ipv6Addr::LOCALHOST.is_unicast(), true);
+    ///
+    /// // Any address that is not a multicast address (`ff00::/8`) is unicast.
+    /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_unicast(), true);
+    /// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).is_unicast(), false);
+    /// ```
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    #[unstable(feature = "ip", issue = "27709")]
+    #[inline]
+    pub const fn is_unicast(&self) -> bool {
+        !self.is_multicast()
+    }
+
     /// Returns `true` if the address is a unicast address with link-local scope,
     /// as defined in [RFC 4291].
     ///
@@ -1318,7 +1346,7 @@ impl Ipv6Addr {
         (self.segments()[0] & 0xffc0) == 0xfe80
     }
 
-    /// Returns [`true`] if this is a deprecated unicast site-local address (fec0::/10). The
+    /// Returns [`true`] if this is a deprecated unicast site-local address (`fec0::/10`). The
     /// unicast site-local address format is defined in [RFC 4291 section 2.5.7] as:
     ///
     /// ```no_rust
@@ -1347,7 +1375,7 @@ impl Ipv6Addr {
     ///
     /// # Warning
     ///
-    /// As per [RFC 3879], the whole `FEC0::/10` prefix is
+    /// As per [RFC 3879], the whole `fec0::/10` prefix is
     /// deprecated. New software must not support site-local
     /// addresses.
     ///
@@ -1417,7 +1445,7 @@ impl Ipv6Addr {
     #[unstable(feature = "ip", issue = "27709")]
     #[inline]
     pub const fn is_unicast_global(&self) -> bool {
-        !self.is_multicast()
+        self.is_unicast()
             && !self.is_loopback()
             && !self.is_unicast_link_local()
             && !self.is_unique_local()
@@ -1460,7 +1488,7 @@ impl Ipv6Addr {
         }
     }
 
-    /// Returns [`true`] if this is a multicast address (ff00::/8).
+    /// Returns [`true`] if this is a multicast address (`ff00::/8`).
     ///
     /// This property is defined by [IETF RFC 4291].
     ///
@@ -1517,7 +1545,7 @@ impl Ipv6Addr {
     /// Converts this address to an [`IPv4` address]. Returns [`None`] if this address is
     /// neither IPv4-compatible or IPv4-mapped.
     ///
-    /// ::a.b.c.d and ::ffff:a.b.c.d become a.b.c.d
+    /// `::a.b.c.d` and `::ffff:a.b.c.d` become `a.b.c.d`
     ///
     /// [`IPv4` address]: Ipv4Addr
     ///
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 9c68af3ce6ccca2395e1868addef26a0542e9dd
+Subproject 8f598e2af6c25b4a7ee88ef6a8196d9b8ea50ca
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject 50de7f0682adc5d95ce858fe6318d19b4b95155
+Subproject c8da5bfd1c7c71d90ef1646f5e0a9f6609d5c78
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 35ff57f85a5..a3f63ea1046 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -664,7 +664,10 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                     }
                 }
                 GenericParamDefKind::Lifetime => {}
-                GenericParamDefKind::Const { .. } => {}
+                GenericParamDefKind::Const { ref mut default, .. } => {
+                    // We never want something like `impl<const N: usize = 10>`
+                    default.take();
+                }
             }
         }
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 231f13adeb6..d1c18821ea6 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -445,11 +445,15 @@ impl Clean<GenericParamDef> for ty::GenericParamDef {
                     },
                 )
             }
-            ty::GenericParamDefKind::Const { .. } => (
+            ty::GenericParamDefKind::Const { has_default, .. } => (
                 self.name,
                 GenericParamDefKind::Const {
                     did: self.def_id,
                     ty: cx.tcx.type_of(self.def_id).clean(cx),
+                    default: match has_default {
+                        true => Some(cx.tcx.const_param_default(self.def_id).to_string()),
+                        false => None,
+                    },
                 },
             ),
         };
@@ -487,12 +491,15 @@ impl Clean<GenericParamDef> for hir::GenericParam<'_> {
                     synthetic,
                 },
             ),
-            hir::GenericParamKind::Const { ref ty, default: _ } => (
+            hir::GenericParamKind::Const { ref ty, default } => (
                 self.name.ident().name,
                 GenericParamDefKind::Const {
                     did: cx.tcx.hir().local_def_id(self.hir_id).to_def_id(),
                     ty: ty.clean(cx),
-                    // FIXME(const_generics_defaults): add `default` field here for docs
+                    default: default.map(|ct| {
+                        let def_id = cx.tcx.hir().local_def_id(ct.hir_id);
+                        ty::Const::from_anon_const(cx.tcx, def_id).to_string()
+                    }),
                 },
             ),
         };
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index fa1639f9dc3..6a7c3f8caa4 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1220,6 +1220,7 @@ crate enum GenericParamDefKind {
     Const {
         did: DefId,
         ty: Type,
+        default: Option<String>,
     },
 }
 
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index d5213fd7711..918a5cb5094 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -177,12 +177,22 @@ impl clean::GenericParamDef {
 
                 Ok(())
             }
-            clean::GenericParamDefKind::Const { ref ty, .. } => {
+            clean::GenericParamDefKind::Const { ref ty, ref default, .. } => {
                 if f.alternate() {
-                    write!(f, "const {}: {:#}", self.name, ty.print(cx))
+                    write!(f, "const {}: {:#}", self.name, ty.print(cx))?;
                 } else {
-                    write!(f, "const {}:&nbsp;{}", self.name, ty.print(cx))
+                    write!(f, "const {}:&nbsp;{}", self.name, ty.print(cx))?;
                 }
+
+                if let Some(default) = default {
+                    if f.alternate() {
+                        write!(f, " = {:#}", default)?;
+                    } else {
+                        write!(f, "&nbsp;=&nbsp;{}", default)?;
+                    }
+                }
+
+                Ok(())
             }
         })
     }
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 4b6faefc2fb..2e940a31c2a 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -1286,7 +1286,6 @@ fn render_impl(
     // in documentation pages for trait with automatic implementations like "Send" and "Sync".
     aliases: &[String],
 ) {
-    let tcx = cx.tcx();
     let cache = cx.cache();
     let traits = &cache.traits;
     let trait_ = i.trait_did_full(cache).map(|did| &traits[&did]);
@@ -1558,94 +1557,34 @@ fn render_impl(
             );
         }
     }
-    let toggled = !impl_items.is_empty() || !default_impl_items.is_empty();
-    let open_details = |close_tags: &mut String, is_collapsed: bool| {
+    if render_mode == RenderMode::Normal {
+        let is_implementing_trait = i.inner_impl().trait_.is_some();
+        let toggled = !impl_items.is_empty() || !default_impl_items.is_empty();
         if toggled {
             close_tags.insert_str(0, "</details>");
-            if is_collapsed {
-                "<details class=\"rustdoc-toggle implementors-toggle\"><summary>"
+            if is_implementing_trait {
+                write!(w, "<details class=\"rustdoc-toggle implementors-toggle\">");
             } else {
-                "<details class=\"rustdoc-toggle implementors-toggle\" open><summary>"
+                write!(w, "<details class=\"rustdoc-toggle implementors-toggle\" open>");
             }
-        } else {
-            ""
         }
-    };
-    if render_mode == RenderMode::Normal {
-        let is_implementing_trait;
-        let id = cx.derive_id(match i.inner_impl().trait_ {
-            Some(ref t) => {
-                is_implementing_trait = true;
-                if is_on_foreign_type {
-                    get_id_for_impl_on_foreign_type(&i.inner_impl().for_, t, cx)
-                } else {
-                    format!("impl-{}", small_url_encode(format!("{:#}", t.print(cx))))
-                }
-            }
-            None => {
-                is_implementing_trait = false;
-                "impl".to_string()
-            }
-        });
-        let aliases = if aliases.is_empty() {
-            String::new()
-        } else {
-            format!(" data-aliases=\"{}\"", aliases.join(","))
-        };
-        if let Some(use_absolute) = use_absolute {
-            write!(
-                w,
-                "{}<div id=\"{}\" class=\"impl has-srclink\"{}>\
-                     <code class=\"in-band\">",
-                open_details(&mut close_tags, is_implementing_trait),
-                id,
-                aliases
-            );
-            write!(w, "{}", i.inner_impl().print(use_absolute, cx));
-            if show_def_docs {
-                for it in &i.inner_impl().items {
-                    if let clean::TypedefItem(ref tydef, _) = *it.kind {
-                        w.write_str("<span class=\"where fmt-newline\">  ");
-                        assoc_type(
-                            w,
-                            it,
-                            &[],
-                            Some(&tydef.type_),
-                            AssocItemLink::Anchor(None),
-                            "",
-                            cx,
-                        );
-                        w.write_str(";</span>");
-                    }
-                }
-            }
-            w.write_str("</code>");
-        } else {
-            write!(
-                w,
-                "{}<div id=\"{}\" class=\"impl has-srclink\"{}>\
-                     <code class=\"in-band\">{}</code>",
-                open_details(&mut close_tags, is_implementing_trait),
-                id,
-                aliases,
-                i.inner_impl().print(false, cx)
-            );
+        if toggled {
+            write!(w, "<summary>")
         }
-        write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
-        render_stability_since_raw(
+        render_impl_summary(
             w,
-            i.impl_item.stable_since(tcx).as_deref(),
-            i.impl_item.const_stable_since(tcx).as_deref(),
+            cx,
+            i,
             outer_version,
             outer_const_version,
+            show_def_docs,
+            use_absolute,
+            is_on_foreign_type,
+            aliases,
         );
-        write_srclink(cx, &i.impl_item, w);
-        if !toggled {
-            w.write_str("</div>");
-        } else {
-            w.write_str("</div></summary>");
+        if toggled {
+            write!(w, "</summary>")
         }
-
         if trait_.is_some() {
             if let Some(portability) = portability(&i.impl_item, Some(parent)) {
                 write!(w, "<div class=\"item-info\">{}</div>", portability);
@@ -1678,6 +1617,75 @@ fn render_impl(
     w.write_str(&close_tags);
 }
 
+fn render_impl_summary(
+    w: &mut Buffer,
+    cx: &Context<'_>,
+    i: &Impl,
+    outer_version: Option<&str>,
+    outer_const_version: Option<&str>,
+    show_def_docs: bool,
+    use_absolute: Option<bool>,
+    is_on_foreign_type: bool,
+    // This argument is used to reference same type with different paths to avoid duplication
+    // in documentation pages for trait with automatic implementations like "Send" and "Sync".
+    aliases: &[String],
+) {
+    let tcx = cx.tcx();
+    let id = cx.derive_id(match i.inner_impl().trait_ {
+        Some(ref t) => {
+            if is_on_foreign_type {
+                get_id_for_impl_on_foreign_type(&i.inner_impl().for_, t, cx)
+            } else {
+                format!("impl-{}", small_url_encode(format!("{:#}", t.print(cx))))
+            }
+        }
+        None => "impl".to_string(),
+    });
+    let aliases = if aliases.is_empty() {
+        String::new()
+    } else {
+        format!(" data-aliases=\"{}\"", aliases.join(","))
+    };
+    if let Some(use_absolute) = use_absolute {
+        write!(
+            w,
+            "<div id=\"{}\" class=\"impl has-srclink\"{}>\
+                     <code class=\"in-band\">",
+            id, aliases
+        );
+        write!(w, "{}", i.inner_impl().print(use_absolute, cx));
+        if show_def_docs {
+            for it in &i.inner_impl().items {
+                if let clean::TypedefItem(ref tydef, _) = *it.kind {
+                    w.write_str("<span class=\"where fmt-newline\">  ");
+                    assoc_type(w, it, &[], Some(&tydef.type_), AssocItemLink::Anchor(None), "", cx);
+                    w.write_str(";</span>");
+                }
+            }
+        }
+        w.write_str("</code>");
+    } else {
+        write!(
+            w,
+            "<div id=\"{}\" class=\"impl has-srclink\"{}>\
+                     <code class=\"in-band\">{}</code>",
+            id,
+            aliases,
+            i.inner_impl().print(false, cx)
+        );
+    }
+    write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
+    render_stability_since_raw(
+        w,
+        i.impl_item.stable_since(tcx).as_deref(),
+        i.impl_item.const_stable_since(tcx).as_deref(),
+        outer_version,
+        outer_const_version,
+    );
+    write_srclink(cx, &i.impl_item, w);
+    w.write_str("</div>");
+}
+
 fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) {
     let parentlen = cx.current.len() - if it.is_mod() { 1 } else { 0 };
 
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index bee62915ea9..7086dd8c4d2 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -317,7 +317,9 @@ impl FromWithTcx<clean::GenericParamDefKind> for GenericParamDefKind {
                 bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
                 default: default.map(|x| x.into_tcx(tcx)),
             },
-            Const { did: _, ty } => GenericParamDefKind::Const(ty.into_tcx(tcx)),
+            Const { did: _, ty, default } => {
+                GenericParamDefKind::Const { ty: ty.into_tcx(tcx), default }
+            }
         }
     }
 }
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index f8bd9710813..0d84bf250c9 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -234,7 +234,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
                     )
                 })
                 .collect(),
-            format_version: 5,
+            format_version: 6,
         };
         let mut p = self.out_path.clone();
         p.push(output.index.get(&output.root).unwrap().name.clone().unwrap());
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index 72a4d9a1830..6d9a5cb515a 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -324,7 +324,7 @@ pub struct GenericParamDef {
 pub enum GenericParamDefKind {
     Lifetime,
     Type { bounds: Vec<GenericBound>, default: Option<Type> },
-    Const(Type),
+    Const { ty: Type, default: Option<String> },
 }
 
 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
diff --git a/src/test/rustdoc-ui/wasm-safe.rs b/src/test/rustdoc-ui/wasm-safe.rs
new file mode 100644
index 00000000000..80b15ace0ee
--- /dev/null
+++ b/src/test/rustdoc-ui/wasm-safe.rs
@@ -0,0 +1,7 @@
+// check-pass
+
+#![feature(wasm_target_feature)]
+
+#[cfg(any(target_arch = "wasm32", doc))]
+#[target_feature(enable = "simd128")]
+pub fn foo() {}
diff --git a/src/test/rustdoc/const-generics/const-generic-defaults.rs b/src/test/rustdoc/const-generics/const-generic-defaults.rs
new file mode 100644
index 00000000000..efe35bf7aa4
--- /dev/null
+++ b/src/test/rustdoc/const-generics/const-generic-defaults.rs
@@ -0,0 +1,6 @@
+#![crate_name = "foo"]
+#![feature(const_generics_defaults)]
+
+// @has foo/struct.Foo.html '//pre[@class="rust struct"]' \
+//      'pub struct Foo<const M: usize = 10_usize, const N: usize = M, T = i32>(_);'
+pub struct Foo<const M: usize = 10, const N: usize = M, T = i32>(T);
diff --git a/src/test/ui/macros/local-ambiguity-multiple-parsing-options.stderr b/src/test/ui/macros/local-ambiguity-multiple-parsing-options.stderr
index 0ae56c42221..68b278fd3c8 100644
--- a/src/test/ui/macros/local-ambiguity-multiple-parsing-options.stderr
+++ b/src/test/ui/macros/local-ambiguity-multiple-parsing-options.stderr
@@ -1,10 +1,10 @@
-error: local ambiguity: multiple parsing options: built-in NTs ident ('i') or ident ('j').
+error: local ambiguity when calling macro `ambiguity`: multiple parsing options: built-in NTs ident ('i') or ident ('j').
   --> $DIR/local-ambiguity-multiple-parsing-options.rs:7:12
    |
 LL | ambiguity!(error);
    |            ^^^^^
 
-error: local ambiguity: multiple parsing options: built-in NTs ident ('i') or ident ('j').
+error: local ambiguity when calling macro `ambiguity`: multiple parsing options: built-in NTs ident ('i') or ident ('j').
   --> $DIR/local-ambiguity-multiple-parsing-options.rs:8:12
    |
 LL | ambiguity!(error);
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 0cecbd67323ca14a7eb6505900d0d7307b00355
+Subproject aa8b09297bb3156b849e73db48af4cd050492fe