diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index f77eac2b068c2..efed41de23a89 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 1aed42a24e2b3..a7434d73abe68 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 6608573d720a8..abad190b072ab 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 f5ee4b21ea616..ee3ac3b62d9ec 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 1fb645a302e76..93f5fe45cd6aa 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> 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> for String { #[cfg(not(no_global_oom_handling))] #[stable(feature = "box_from_str", since = "1.20.0")] impl From for Box { - /// 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 for Box { #[cfg(not(no_global_oom_handling))] #[stable(feature = "string_from_cow_str", since = "1.14.0")] impl<'a> From> 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 = 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> 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 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 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 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 for Cow<'a, str> { #[stable(feature = "from_string_for_vec_u8", since = "1.14.0")] impl From for Vec { - /// 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 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 3990826ce42e0..26fbf50e2dfdf 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>(&self, range: R) -> Option { - // HACK(eddyb) something akin to `Option::cloned`, but for `Bound<&T>`. - fn cloned_bound(bound: Bound<&T>) -> Bound { - 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 6891bd8a66437..7a2a49ba7d707 100644 --- a/library/std/src/io/impls.rs +++ b/library/std/src/io/impls.rs @@ -87,6 +87,11 @@ impl Seek for &mut S { fn seek(&mut self, pos: SeekFrom) -> io::Result { (**self).seek(pos) } + + #[inline] + fn stream_position(&mut self) -> io::Result { + (**self).stream_position() + } } #[stable(feature = "rust1", since = "1.0.0")] impl BufRead for &mut B { @@ -186,6 +191,11 @@ impl Seek for Box { fn seek(&mut self, pos: SeekFrom) -> io::Result { (**self).seek(pos) } + + #[inline] + fn stream_position(&mut self) -> io::Result { + (**self).stream_position() + } } #[stable(feature = "rust1", since = "1.0.0")] impl BufRead for Box { diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs index 6c2f2eeabd61e..2b6d0d7d5daa7 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 index 9c68af3ce6ccc..8f598e2af6c25 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 9c68af3ce6ccca2395e1868addef26a0542e9ddd +Subproject commit 8f598e2af6c25b4a7ee88ef6a8196d9b8ea50ca8 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index 50de7f0682adc..c8da5bfd1c7c7 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit 50de7f0682adc5d95ce858fe6318d19b4b951553 +Subproject commit c8da5bfd1c7c71d90ef1646f5e0a9f6609d5c78a diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 35ff57f85a562..a3f63ea1046e3 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` + default.take(); + } } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 231f13adeb68c..d1c18821ea644 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -445,11 +445,15 @@ impl Clean 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 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 fa1639f9dc3dd..6a7c3f8caa49f 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, }, } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index d5213fd77117a..918a5cb509430 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 {}: {}", self.name, ty.print(cx)) + write!(f, "const {}: {}", self.name, ty.print(cx))?; } + + if let Some(default) = default { + if f.alternate() { + write!(f, " = {:#}", default)?; + } else { + write!(f, " = {}", default)?; + } + } + + Ok(()) } }) } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 4b6faefc2fb07..2e940a31c2aff 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, ""); - if is_collapsed { - "
" + if is_implementing_trait { + write!(w, "
"); } else { - "
" + write!(w, "
"); } - } 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, - "{}
\ - ", - 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(" "); - assoc_type( - w, - it, - &[], - Some(&tydef.type_), - AssocItemLink::Anchor(None), - "", - cx, - ); - w.write_str(";"); - } - } - } - w.write_str(""); - } else { - write!( - w, - "{}
\ - {}", - open_details(&mut close_tags, is_implementing_trait), - id, - aliases, - i.inner_impl().print(false, cx) - ); + if toggled { + write!(w, "") } - write!(w, "", 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("
"); - } else { - w.write_str("
"); + if toggled { + write!(w, "
") } - if trait_.is_some() { if let Some(portability) = portability(&i.impl_item, Some(parent)) { write!(w, "
{}
", 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, + 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, + "
\ + ", + 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(" "); + assoc_type(w, it, &[], Some(&tydef.type_), AssocItemLink::Anchor(None), "", cx); + w.write_str(";"); + } + } + } + w.write_str(""); + } else { + write!( + w, + "
\ + {}", + id, + aliases, + i.inner_impl().print(false, cx) + ); + } + write!(w, "", 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("
"); +} + 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 bee62915ea9b1..7086dd8c4d258 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -317,7 +317,9 @@ impl FromWithTcx 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 f8bd971081395..0d84bf250c9e3 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 72a4d9a183011..6d9a5cb515a48 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, default: Option }, - Const(Type), + Const { ty: Type, default: Option }, } #[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 0000000000000..80b15ace0ee95 --- /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 0000000000000..efe35bf7aa442 --- /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(_);' +pub struct Foo(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 0ae56c422213c..68b278fd3c886 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 index 0cecbd67323ca..aa8b09297bb31 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 0cecbd67323ca14a7eb6505900d0d7307b00355b +Subproject commit aa8b09297bb3156b849e73db48af4cd050492fe6