mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
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:
commit
c8381389ee
@ -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)]
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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> {
|
||||
|
@ -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
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
}),
|
||||
},
|
||||
),
|
||||
};
|
||||
|
@ -1220,6 +1220,7 @@ crate enum GenericParamDefKind {
|
||||
Const {
|
||||
did: DefId,
|
||||
ty: Type,
|
||||
default: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -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(())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -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 };
|
||||
|
||||
|
@ -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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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)]
|
||||
|
7
src/test/rustdoc-ui/wasm-safe.rs
Normal file
7
src/test/rustdoc-ui/wasm-safe.rs
Normal file
@ -0,0 +1,7 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(wasm_target_feature)]
|
||||
|
||||
#[cfg(any(target_arch = "wasm32", doc))]
|
||||
#[target_feature(enable = "simd128")]
|
||||
pub fn foo() {}
|
@ -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);
|
@ -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
|
Loading…
Reference in New Issue
Block a user