Auto merge of #86160 - JohnTitor:rollup-8ark9x7, r=JohnTitor

Rollup of 11 pull requests

Successful merges:

 - #85676 (Fix documentation style inconsistencies for IP addresses)
 - #85715 (Document `From` impls in string.rs)
 - #85791 (Add `Ipv6Addr::is_unicast`)
 - #85957 (Display defaults on const params- rustdoc )
 - #85982 (Enable rustdoc to document safe wasm intrinsics)
 - #86121 (Forwarding implementation for Seek trait's stream_position method)
 - #86124 (Include macro name in 'local ambiguity' error)
 - #86128 (Refactor: Extract render_summary from render_impl.)
 - #86142 (Simplify proc_macro code using Bound::cloned().)
 - #86158 (Update books)
 - #86159 (Update cargo)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-06-09 03:15:34 +00:00
commit c8381389ee
22 changed files with 264 additions and 144 deletions

View File

@ -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)]

View File

@ -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),

View File

@ -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);

View File

@ -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,

View File

@ -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()

View File

@ -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)
}
}

View File

@ -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> {

View File

@ -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
///

@ -1 +1 @@
Subproject commit 9c68af3ce6ccca2395e1868addef26a0542e9ddd
Subproject commit 8f598e2af6c25b4a7ee88ef6a8196d9b8ea50ca8

@ -1 +1 @@
Subproject commit 50de7f0682adc5d95ce858fe6318d19b4b951553
Subproject commit c8da5bfd1c7c71d90ef1646f5e0a9f6609d5c78a

View File

@ -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();
}
}
}

View File

@ -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()
}),
},
),
};

View File

@ -1220,6 +1220,7 @@ crate enum GenericParamDefKind {
Const {
did: DefId,
ty: Type,
default: Option<String>,
},
}

View File

@ -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(())
}
})
}

View File

@ -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 };

View File

@ -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 }
}
}
}
}

View File

@ -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());

View File

@ -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)]

View File

@ -0,0 +1,7 @@
// check-pass
#![feature(wasm_target_feature)]
#[cfg(any(target_arch = "wasm32", doc))]
#[target_feature(enable = "simd128")]
pub fn foo() {}

View File

@ -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);

View File

@ -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);

@ -1 +1 @@
Subproject commit 0cecbd67323ca14a7eb6505900d0d7307b00355b
Subproject commit aa8b09297bb3156b849e73db48af4cd050492fe6