rustc_metadata: simplify the interactions between Lazy and Table.
These are small post-#59953 cleanups (including undoing some contrivances from that PR).
r? @michaelwoerister
#![stable(feature = "core_ascii", since = "1.26.0")]
use crate::fmt;
-use crate::ops::Range;
use crate::iter::FusedIterator;
+use crate::ops::Range;
use crate::str::from_utf8_unchecked;
/// An iterator over the escaped version of a byte.
b'\\' => ([b'\\', b'\\', 0, 0], 2),
b'\'' => ([b'\\', b'\'', 0, 0], 2),
b'"' => ([b'\\', b'"', 0, 0], 2),
- b'\x20' ..= b'\x7e' => ([c, 0, 0, 0], 1),
+ b'\x20'..=b'\x7e' => ([c, 0, 0, 0], 1),
_ => ([b'\\', b'x', hexify(c >> 4), hexify(c & 0xf)], 4),
};
fn hexify(b: u8) -> u8 {
match b {
- 0 ..= 9 => b'0' + b,
+ 0..=9 => b'0' + b,
_ => b'a' + b - 10,
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Iterator for EscapeDefault {
type Item = u8;
- fn next(&mut self) -> Option<u8> { self.range.next().map(|i| self.data[i]) }
- fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() }
- fn last(mut self) -> Option<u8> { self.next_back() }
+ fn next(&mut self) -> Option<u8> {
+ self.range.next().map(|i| self.data[i])
+ }
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.range.size_hint()
+ }
+ fn last(mut self) -> Option<u8> {
+ self.next_back()
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl DoubleEndedIterator for EscapeDefault {
}
}
-
/// An error which can be returned when parsing a char.
#[stable(feature = "char_from_str", since = "1.20.0")]
#[derive(Clone, Debug, PartialEq, Eq)]
}
impl ParseCharError {
- #[unstable(feature = "char_error_internals",
- reason = "this method should not be available publicly",
- issue = "0")]
+ #[unstable(
+ feature = "char_error_internals",
+ reason = "this method should not be available publicly",
+ issue = "0"
+ )]
#[doc(hidden)]
pub fn __description(&self) -> &str {
match self.kind {
- CharErrorKind::EmptyString => {
- "cannot parse char from empty string"
- },
- CharErrorKind::TooManyChars => "too many characters in string"
+ CharErrorKind::EmptyString => "cannot parse char from empty string",
+ CharErrorKind::TooManyChars => "too many characters in string",
}
}
}
}
}
-
#[stable(feature = "char_from_str", since = "1.20.0")]
impl FromStr for char {
type Err = ParseCharError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut chars = s.chars();
match (chars.next(), chars.next()) {
- (None, _) => {
- Err(ParseCharError { kind: CharErrorKind::EmptyString })
- },
+ (None, _) => Err(ParseCharError { kind: CharErrorKind::EmptyString }),
(Some(c), None) => Ok(c),
- _ => {
- Err(ParseCharError { kind: CharErrorKind::TooManyChars })
- }
+ _ => Err(ParseCharError { kind: CharErrorKind::TooManyChars }),
}
}
}
-
#[stable(feature = "try_from", since = "1.34.0")]
impl TryFrom<u32> for char {
type Error = CharTryFromError;
}
if num < radix {
let num = num as u8;
- if num < 10 {
- Some((b'0' + num) as char)
- } else {
- Some((b'a' + num - 10) as char)
- }
+ if num < 10 { Some((b'0' + num) as char) } else { Some((b'a' + num - 10) as char) }
} else {
None
}
#[stable(feature = "decode_utf16", since = "1.9.0")]
#[derive(Clone, Debug)]
pub struct DecodeUtf16<I>
- where I: Iterator<Item = u16>
+where
+ I: Iterator<Item = u16>,
{
iter: I,
buf: Option<u16>,
#[stable(feature = "decode_utf16", since = "1.9.0")]
#[inline]
pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> {
- DecodeUtf16 {
- iter: iter.into_iter(),
- buf: None,
- }
+ DecodeUtf16 { iter: iter.into_iter(), buf: None }
}
#[stable(feature = "decode_utf16", since = "1.9.0")]
fn next(&mut self) -> Option<Result<char, DecodeUtf16Error>> {
let u = match self.buf.take() {
Some(buf) => buf,
- None => self.iter.next()?
+ None => self.iter.next()?,
};
if u < 0xD800 || 0xDFFF < u {
}
};
- if val < radix {
- Some(val)
- } else {
- None
- }
+ if val < radix { Some(val) } else { None }
}
/// Returns an iterator that yields the hexadecimal Unicode escape of a
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
pub fn to_ascii_uppercase(&self) -> char {
- if self.is_ascii() {
- (*self as u8).to_ascii_uppercase() as char
- } else {
- *self
- }
+ if self.is_ascii() { (*self as u8).to_ascii_uppercase() as char } else { *self }
}
/// Makes a copy of the value in its ASCII lower case equivalent.
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
pub fn to_ascii_lowercase(&self) -> char {
- if self.is_ascii() {
- (*self as u8).to_ascii_lowercase() as char
- } else {
- *self
- }
+ if self.is_ascii() { (*self as u8).to_ascii_lowercase() as char } else { *self }
}
/// Checks that two values are an ASCII case-insensitive match.
mod methods;
// stable re-exports
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::convert::{from_u32, from_digit};
#[stable(feature = "char_from_unchecked", since = "1.5.0")]
pub use self::convert::from_u32_unchecked;
-#[stable(feature = "char_from_str", since = "1.20.0")]
-pub use self::convert::ParseCharError;
#[stable(feature = "try_from", since = "1.34.0")]
pub use self::convert::CharTryFromError;
+#[stable(feature = "char_from_str", since = "1.20.0")]
+pub use self::convert::ParseCharError;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use self::convert::{from_digit, from_u32};
#[stable(feature = "decode_utf16", since = "1.9.0")]
pub use self::decode::{decode_utf16, DecodeUtf16, DecodeUtf16Error};
use crate::iter::FusedIterator;
// UTF-8 ranges and tags for encoding characters
-const TAG_CONT: u8 = 0b1000_0000;
-const TAG_TWO_B: u8 = 0b1100_0000;
-const TAG_THREE_B: u8 = 0b1110_0000;
-const TAG_FOUR_B: u8 = 0b1111_0000;
-const MAX_ONE_B: u32 = 0x80;
-const MAX_TWO_B: u32 = 0x800;
-const MAX_THREE_B: u32 = 0x10000;
+const TAG_CONT: u8 = 0b1000_0000;
+const TAG_TWO_B: u8 = 0b1100_0000;
+const TAG_THREE_B: u8 = 0b1110_0000;
+const TAG_FOUR_B: u8 = 0b1111_0000;
+const MAX_ONE_B: u32 = 0x80;
+const MAX_TWO_B: u32 = 0x800;
+const MAX_THREE_B: u32 = 0x10000;
/*
Lu Uppercase_Letter an uppercase letter
match self.state {
EscapeUnicodeState::Done => None,
- EscapeUnicodeState::RightBrace |
- EscapeUnicodeState::Value |
- EscapeUnicodeState::LeftBrace |
- EscapeUnicodeState::Type |
- EscapeUnicodeState::Backslash => Some('}'),
+ EscapeUnicodeState::RightBrace
+ | EscapeUnicodeState::Value
+ | EscapeUnicodeState::LeftBrace
+ | EscapeUnicodeState::Type
+ | EscapeUnicodeState::Backslash => Some('}'),
}
}
}
#[inline]
fn len(&self) -> usize {
// The match is a single memory access with no branching
- self.hex_digit_idx + match self.state {
- EscapeUnicodeState::Done => 0,
- EscapeUnicodeState::RightBrace => 1,
- EscapeUnicodeState::Value => 2,
- EscapeUnicodeState::LeftBrace => 3,
- EscapeUnicodeState::Type => 4,
- EscapeUnicodeState::Backslash => 5,
- }
+ self.hex_digit_idx
+ + match self.state {
+ EscapeUnicodeState::Done => 0,
+ EscapeUnicodeState::RightBrace => 1,
+ EscapeUnicodeState::Value => 2,
+ EscapeUnicodeState::LeftBrace => 3,
+ EscapeUnicodeState::Type => 4,
+ EscapeUnicodeState::Backslash => 5,
+ }
}
}
#[derive(Clone, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct EscapeDefault {
- state: EscapeDefaultState
+ state: EscapeDefaultState,
}
#[derive(Clone, Debug)]
EscapeDefaultState::Backslash(c) if n == 0 => {
self.state = EscapeDefaultState::Char(c);
Some('\\')
- },
+ }
EscapeDefaultState::Backslash(c) if n == 1 => {
self.state = EscapeDefaultState::Done;
Some(c)
- },
+ }
EscapeDefaultState::Backslash(_) => {
self.state = EscapeDefaultState::Done;
None
- },
+ }
EscapeDefaultState::Char(c) => {
self.state = EscapeDefaultState::Done;
- if n == 0 {
- Some(c)
- } else {
- None
- }
- },
+ if n == 0 { Some(c) } else { None }
+ }
EscapeDefaultState::Done => None,
EscapeDefaultState::Unicode(ref mut i) => i.nth(n),
}
#[stable(feature = "char_escape_debug", since = "1.20.0")]
impl Iterator for EscapeDebug {
type Item = char;
- fn next(&mut self) -> Option<char> { self.0.next() }
- fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
+ fn next(&mut self) -> Option<char> {
+ self.0.next()
+ }
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.0.size_hint()
+ }
}
#[stable(feature = "char_escape_debug", since = "1.20.0")]
-impl ExactSizeIterator for EscapeDebug { }
+impl ExactSizeIterator for EscapeDebug {}
#[stable(feature = "fused", since = "1.26.0")]
impl FusedIterator for EscapeDebug {}
fn new(chars: [char; 3]) -> CaseMappingIter {
if chars[2] == '\0' {
if chars[1] == '\0' {
- CaseMappingIter::One(chars[0]) // Including if chars[0] == '\0'
+ CaseMappingIter::One(chars[0]) // Including if chars[0] == '\0'
} else {
CaseMappingIter::Two(chars[0], chars[1])
}
f.write_char(b)?;
f.write_char(c)
}
- CaseMappingIter::One(c) => {
- f.write_char(c)
- }
+ CaseMappingIter::One(c) => f.write_char(c),
CaseMappingIter::Zero => Ok(()),
}
}
/// [impls]: #implementors
#[stable(feature = "rust1", since = "1.0.0")]
#[lang = "clone"]
-pub trait Clone : Sized {
+pub trait Clone: Sized {
/// Returns a copy of the value.
///
/// # Examples
#[rustc_builtin_macro]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics, derive_clone_copy)]
-pub macro Clone($item:item) { /* compiler built-in */ }
+pub macro Clone($item:item) {
+ /* compiler built-in */
+}
// FIXME(aburka): these structs are used solely by #[derive] to
// assert that every component of a type implements Clone or Copy.
// These structs should never appear in user code.
#[doc(hidden)]
#[allow(missing_debug_implementations)]
-#[unstable(feature = "derive_clone_copy",
- reason = "deriving hack, should not be public",
- issue = "0")]
-pub struct AssertParamIsClone<T: Clone + ?Sized> { _field: crate::marker::PhantomData<T> }
+#[unstable(
+ feature = "derive_clone_copy",
+ reason = "deriving hack, should not be public",
+ issue = "0"
+)]
+pub struct AssertParamIsClone<T: Clone + ?Sized> {
+ _field: crate::marker::PhantomData<T>,
+}
#[doc(hidden)]
#[allow(missing_debug_implementations)]
-#[unstable(feature = "derive_clone_copy",
- reason = "deriving hack, should not be public",
- issue = "0")]
-pub struct AssertParamIsCopy<T: Copy + ?Sized> { _field: crate::marker::PhantomData<T> }
+#[unstable(
+ feature = "derive_clone_copy",
+ reason = "deriving hack, should not be public",
+ issue = "0"
+)]
+pub struct AssertParamIsCopy<T: Copy + ?Sized> {
+ _field: crate::marker::PhantomData<T>,
+}
/// Implementations of `Clone` for primitive types.
///
*self
}
}
-
}
/// ```
#[stable(feature = "convert_id", since = "1.33.0")]
#[inline]
-pub const fn identity<T>(x: T) -> T { x }
+pub const fn identity<T>(x: T) -> T {
+ x
+}
/// Used to do a cheap reference-to-reference conversion.
///
/// [`from`]: trait.From.html#tymethod.from
/// [book]: ../../book/ch09-00-error-handling.html
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(
- on(
- all(_Self="&str", T="std::string::String"),
- note="to coerce a `{T}` into a `{Self}`, use `&*` as a prefix",
- )
-)]
+#[rustc_on_unimplemented(on(
+ all(_Self = "&str", T = "std::string::String"),
+ note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix",
+))]
pub trait From<T>: Sized {
/// Performs the conversion.
#[stable(feature = "rust1", since = "1.0.0")]
// As lifts over &
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized, U: ?Sized> AsRef<U> for &T where T: AsRef<U>
+impl<T: ?Sized, U: ?Sized> AsRef<U> for &T
+where
+ T: AsRef<U>,
{
fn as_ref(&self) -> &U {
<T as AsRef<U>>::as_ref(*self)
// As lifts over &mut
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized, U: ?Sized> AsRef<U> for &mut T where T: AsRef<U>
+impl<T: ?Sized, U: ?Sized> AsRef<U> for &mut T
+where
+ T: AsRef<U>,
{
fn as_ref(&self) -> &U {
<T as AsRef<U>>::as_ref(*self)
// AsMut lifts over &mut
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized, U: ?Sized> AsMut<U> for &mut T where T: AsMut<U>
+impl<T: ?Sized, U: ?Sized> AsMut<U> for &mut T
+where
+ T: AsMut<U>,
{
fn as_mut(&mut self) -> &mut U {
(*self).as_mut()
// From implies Into
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U> Into<U> for T where U: From<T>
+impl<T, U> Into<U> for T
+where
+ U: From<T>,
{
fn into(self) -> U {
U::from(self)
// From (and thus Into) is reflexive
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> From<T> for T {
- fn from(t: T) -> T { t }
+ fn from(t: T) -> T {
+ t
+ }
}
/// **Stability note:** This impl does not yet exist, but we are
///
/// [#64715]: https://github.com/rust-lang/rust/issues/64715
#[stable(feature = "convert_infallible", since = "1.34.0")]
-#[rustc_reservation_impl="permitting this impl would forbid us from adding \
-`impl<T> From<!> for T` later; see rust-lang/rust#64715 for details"]
+#[rustc_reservation_impl = "permitting this impl would forbid us from adding \
+ `impl<T> From<!> for T` later; see rust-lang/rust#64715 for details"]
impl<T> From<!> for T {
- fn from(t: !) -> T { t }
+ fn from(t: !) -> T {
+ t
+ }
}
// TryFrom implies TryInto
#[stable(feature = "try_from", since = "1.34.0")]
-impl<T, U> TryInto<U> for T where U: TryFrom<T>
+impl<T, U> TryInto<U> for T
+where
+ U: TryFrom<T>,
{
type Error = U::Error;
// Infallible conversions are semantically equivalent to fallible conversions
// with an uninhabited error type.
#[stable(feature = "try_from", since = "1.34.0")]
-impl<T, U> TryFrom<U> for T where U: Into<T> {
+impl<T, U> TryFrom<U> for T
+where
+ U: Into<T>,
+{
type Error = Infallible;
fn try_from(value: U) -> Result<Self, Self::Error> {
#[rustc_builtin_macro]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics)]
-pub macro Default($item:item) { /* compiler built-in */ }
+pub macro Default($item:item) {
+ /* compiler built-in */
+}
macro_rules! default_impl {
($t:ty, $v:expr, $doc:tt) => {
#![stable(feature = "", since = "1.30.0")]
-
#![allow(non_camel_case_types)]
//! Utilities related to FFI bindings.
#[repr(u8)]
#[stable(feature = "core_c_void", since = "1.30.0")]
pub enum c_void {
- #[unstable(feature = "c_void_variant", reason = "temporary implementation detail",
- issue = "0")]
- #[doc(hidden)] __variant1,
- #[unstable(feature = "c_void_variant", reason = "temporary implementation detail",
- issue = "0")]
- #[doc(hidden)] __variant2,
+ #[unstable(
+ feature = "c_void_variant",
+ reason = "temporary implementation detail",
+ issue = "0"
+ )]
+ #[doc(hidden)]
+ __variant1,
+ #[unstable(
+ feature = "c_void_variant",
+ reason = "temporary implementation detail",
+ issue = "0"
+ )]
+ #[doc(hidden)]
+ __variant2,
}
#[stable(feature = "std_debug", since = "1.16.0")]
/// Basic implementation of a `va_list`.
// The name is WIP, using `VaListImpl` for now.
-#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
- not(target_arch = "x86_64")),
- all(target_arch = "aarch64", target_os = "ios"),
- target_arch = "wasm32",
- target_arch = "asmjs",
- windows))]
+#[cfg(any(
+ all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")),
+ all(target_arch = "aarch64", target_os = "ios"),
+ target_arch = "wasm32",
+ target_arch = "asmjs",
+ windows
+))]
#[repr(transparent)]
-#[unstable(feature = "c_variadic",
- reason = "the `c_variadic` feature has not been properly tested on \
- all supported platforms",
- issue = "44930")]
+#[unstable(
+ feature = "c_variadic",
+ reason = "the `c_variadic` feature has not been properly tested on \
+ all supported platforms",
+ issue = "44930"
+)]
#[lang = "va_list"]
pub struct VaListImpl<'f> {
ptr: *mut c_void,
_marker: PhantomData<&'f mut &'f c_void>,
}
-#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
- not(target_arch = "x86_64")),
- all(target_arch = "aarch64", target_os = "ios"),
- target_arch = "wasm32",
- target_arch = "asmjs",
- windows))]
-#[unstable(feature = "c_variadic",
- reason = "the `c_variadic` feature has not been properly tested on \
- all supported platforms",
- issue = "44930")]
+#[cfg(any(
+ all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")),
+ all(target_arch = "aarch64", target_os = "ios"),
+ target_arch = "wasm32",
+ target_arch = "asmjs",
+ windows
+))]
+#[unstable(
+ feature = "c_variadic",
+ reason = "the `c_variadic` feature has not been properly tested on \
+ all supported platforms",
+ issue = "44930"
+)]
impl<'f> fmt::Debug for VaListImpl<'f> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "va_list* {:p}", self.ptr)
#[cfg(all(target_arch = "aarch64", not(target_os = "ios"), not(windows)))]
#[repr(C)]
#[derive(Debug)]
-#[unstable(feature = "c_variadic",
- reason = "the `c_variadic` feature has not been properly tested on \
- all supported platforms",
- issue = "44930")]
+#[unstable(
+ feature = "c_variadic",
+ reason = "the `c_variadic` feature has not been properly tested on \
+ all supported platforms",
+ issue = "44930"
+)]
#[lang = "va_list"]
pub struct VaListImpl<'f> {
stack: *mut c_void,
#[cfg(all(target_arch = "powerpc", not(windows)))]
#[repr(C)]
#[derive(Debug)]
-#[unstable(feature = "c_variadic",
- reason = "the `c_variadic` feature has not been properly tested on \
- all supported platforms",
- issue = "44930")]
+#[unstable(
+ feature = "c_variadic",
+ reason = "the `c_variadic` feature has not been properly tested on \
+ all supported platforms",
+ issue = "44930"
+)]
#[lang = "va_list"]
pub struct VaListImpl<'f> {
gpr: u8,
#[cfg(all(target_arch = "x86_64", not(windows)))]
#[repr(C)]
#[derive(Debug)]
-#[unstable(feature = "c_variadic",
- reason = "the `c_variadic` feature has not been properly tested on \
- all supported platforms",
- issue = "44930")]
+#[unstable(
+ feature = "c_variadic",
+ reason = "the `c_variadic` feature has not been properly tested on \
+ all supported platforms",
+ issue = "44930"
+)]
#[lang = "va_list"]
pub struct VaListImpl<'f> {
gp_offset: i32,
/// A wrapper for a `va_list`
#[repr(transparent)]
#[derive(Debug)]
-#[unstable(feature = "c_variadic",
- reason = "the `c_variadic` feature has not been properly tested on \
- all supported platforms",
- issue = "44930")]
+#[unstable(
+ feature = "c_variadic",
+ reason = "the `c_variadic` feature has not been properly tested on \
+ all supported platforms",
+ issue = "44930"
+)]
pub struct VaList<'a, 'f: 'a> {
- #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
- not(target_arch = "x86_64")),
- all(target_arch = "aarch64", target_os = "ios"),
- target_arch = "wasm32",
- target_arch = "asmjs",
- windows))]
+ #[cfg(any(
+ all(
+ not(target_arch = "aarch64"),
+ not(target_arch = "powerpc"),
+ not(target_arch = "x86_64")
+ ),
+ all(target_arch = "aarch64", target_os = "ios"),
+ target_arch = "wasm32",
+ target_arch = "asmjs",
+ windows
+ ))]
inner: VaListImpl<'f>,
- #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc",
- target_arch = "x86_64"),
- any(not(target_arch = "aarch64"), not(target_os = "ios")),
- not(target_arch = "wasm32"),
- not(target_arch = "asmjs"),
- not(windows)))]
+ #[cfg(all(
+ any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
+ any(not(target_arch = "aarch64"), not(target_os = "ios")),
+ not(target_arch = "wasm32"),
+ not(target_arch = "asmjs"),
+ not(windows)
+ ))]
inner: &'a mut VaListImpl<'f>,
_marker: PhantomData<&'a mut VaListImpl<'f>>,
}
-#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
- not(target_arch = "x86_64")),
- all(target_arch = "aarch64", target_os = "ios"),
- target_arch = "wasm32",
- target_arch = "asmjs",
- windows))]
-#[unstable(feature = "c_variadic",
- reason = "the `c_variadic` feature has not been properly tested on \
- all supported platforms",
- issue = "44930")]
+#[cfg(any(
+ all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")),
+ all(target_arch = "aarch64", target_os = "ios"),
+ target_arch = "wasm32",
+ target_arch = "asmjs",
+ windows
+))]
+#[unstable(
+ feature = "c_variadic",
+ reason = "the `c_variadic` feature has not been properly tested on \
+ all supported platforms",
+ issue = "44930"
+)]
impl<'f> VaListImpl<'f> {
/// Convert a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`.
#[inline]
pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
- VaList {
- inner: VaListImpl { ..*self },
- _marker: PhantomData,
- }
+ VaList { inner: VaListImpl { ..*self }, _marker: PhantomData }
}
}
-#[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc",
- target_arch = "x86_64"),
- any(not(target_arch = "aarch64"), not(target_os = "ios")),
- not(target_arch = "wasm32"),
- not(target_arch = "asmjs"),
- not(windows)))]
-#[unstable(feature = "c_variadic",
- reason = "the `c_variadic` feature has not been properly tested on \
- all supported platforms",
- issue = "44930")]
+#[cfg(all(
+ any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
+ any(not(target_arch = "aarch64"), not(target_os = "ios")),
+ not(target_arch = "wasm32"),
+ not(target_arch = "asmjs"),
+ not(windows)
+))]
+#[unstable(
+ feature = "c_variadic",
+ reason = "the `c_variadic` feature has not been properly tested on \
+ all supported platforms",
+ issue = "44930"
+)]
impl<'f> VaListImpl<'f> {
/// Convert a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`.
#[inline]
pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
- VaList {
- inner: self,
- _marker: PhantomData,
- }
+ VaList { inner: self, _marker: PhantomData }
}
}
-#[unstable(feature = "c_variadic",
- reason = "the `c_variadic` feature has not been properly tested on \
- all supported platforms",
- issue = "44930")]
+#[unstable(
+ feature = "c_variadic",
+ reason = "the `c_variadic` feature has not been properly tested on \
+ all supported platforms",
+ issue = "44930"
+)]
impl<'a, 'f: 'a> Deref for VaList<'a, 'f> {
type Target = VaListImpl<'f>;
}
}
-#[unstable(feature = "c_variadic",
- reason = "the `c_variadic` feature has not been properly tested on \
- all supported platforms",
- issue = "44930")]
+#[unstable(
+ feature = "c_variadic",
+ reason = "the `c_variadic` feature has not been properly tested on \
+ all supported platforms",
+ issue = "44930"
+)]
impl<'a, 'f: 'a> DerefMut for VaList<'a, 'f> {
#[inline]
fn deref_mut(&mut self) -> &mut VaListImpl<'f> {
/// Trait which whitelists the allowed types to be used with [VaList::arg]
///
/// [VaList::va_arg]: struct.VaList.html#method.arg
- #[unstable(feature = "c_variadic",
- reason = "the `c_variadic` feature has not been properly tested on \
- all supported platforms",
- issue = "44930")]
+ #[unstable(
+ feature = "c_variadic",
+ reason = "the `c_variadic` feature has not been properly tested on \
+ all supported platforms",
+ issue = "44930"
+ )]
pub trait VaArgSafe {}
}
}
}
-impl_va_arg_safe!{i8, i16, i32, i64, usize}
-impl_va_arg_safe!{u8, u16, u32, u64, isize}
-impl_va_arg_safe!{f64}
+impl_va_arg_safe! {i8, i16, i32, i64, usize}
+impl_va_arg_safe! {u8, u16, u32, u64, isize}
+impl_va_arg_safe! {f64}
-#[unstable(feature = "c_variadic",
- reason = "the `c_variadic` feature has not been properly tested on \
- all supported platforms",
- issue = "44930")]
+#[unstable(
+ feature = "c_variadic",
+ reason = "the `c_variadic` feature has not been properly tested on \
+ all supported platforms",
+ issue = "44930"
+)]
impl<T> sealed_trait::VaArgSafe for *mut T {}
-#[unstable(feature = "c_variadic",
- reason = "the `c_variadic` feature has not been properly tested on \
- all supported platforms",
- issue = "44930")]
+#[unstable(
+ feature = "c_variadic",
+ reason = "the `c_variadic` feature has not been properly tested on \
+ all supported platforms",
+ issue = "44930"
+)]
impl<T> sealed_trait::VaArgSafe for *const T {}
-#[unstable(feature = "c_variadic",
- reason = "the `c_variadic` feature has not been properly tested on \
- all supported platforms",
- issue = "44930")]
+#[unstable(
+ feature = "c_variadic",
+ reason = "the `c_variadic` feature has not been properly tested on \
+ all supported platforms",
+ issue = "44930"
+)]
impl<'f> VaListImpl<'f> {
/// Advance to the next arg.
#[inline]
/// Copies the `va_list` at the current location.
pub unsafe fn with_copy<F, R>(&self, f: F) -> R
- where F: for<'copy> FnOnce(VaList<'copy, 'f>) -> R {
+ where
+ F: for<'copy> FnOnce(VaList<'copy, 'f>) -> R,
+ {
let mut ap = self.clone();
let ret = f(ap.as_va_list());
va_end(&mut ap);
}
}
-#[unstable(feature = "c_variadic",
- reason = "the `c_variadic` feature has not been properly tested on \
- all supported platforms",
- issue = "44930")]
+#[unstable(
+ feature = "c_variadic",
+ reason = "the `c_variadic` feature has not been properly tested on \
+ all supported platforms",
+ issue = "44930"
+)]
impl<'f> Clone for VaListImpl<'f> {
#[inline]
fn clone(&self) -> Self {
}
}
-#[unstable(feature = "c_variadic",
- reason = "the `c_variadic` feature has not been properly tested on \
- all supported platforms",
- issue = "44930")]
+#[unstable(
+ feature = "c_variadic",
+ reason = "the `c_variadic` feature has not been properly tested on \
+ all supported platforms",
+ issue = "44930"
+)]
impl<'f> Drop for VaListImpl<'f> {
fn drop(&mut self) {
// FIXME: this should call `va_end`, but there's no clean way to
-use crate::fmt::{Formatter, Result, LowerExp, UpperExp, Display, Debug};
+use crate::fmt::{Debug, Display, Formatter, LowerExp, Result, UpperExp};
use crate::mem::MaybeUninit;
use crate::num::flt2dec;
// Don't inline this so callers don't use the stack space this function
// requires unless they have to.
#[inline(never)]
-fn float_to_decimal_common_exact<T>(fmt: &mut Formatter<'_>, num: &T,
- sign: flt2dec::Sign, precision: usize) -> Result
- where T: flt2dec::DecodableFloat
+fn float_to_decimal_common_exact<T>(
+ fmt: &mut Formatter<'_>,
+ num: &T,
+ sign: flt2dec::Sign,
+ precision: usize,
+) -> Result
+where
+ T: flt2dec::DecodableFloat,
{
unsafe {
let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64
// we decided whether that is valid or not.
// We can do this only because we are libstd and coupled to the compiler.
// (FWIW, using `freeze` would not be enough; `flt2dec::Part` is an enum!)
- let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact,
- *num, sign, precision,
- false, buf.get_mut(), parts.get_mut());
+ let formatted = flt2dec::to_exact_fixed_str(
+ flt2dec::strategy::grisu::format_exact,
+ *num,
+ sign,
+ precision,
+ false,
+ buf.get_mut(),
+ parts.get_mut(),
+ );
fmt.pad_formatted_parts(&formatted)
}
}
// Don't inline this so callers that call both this and the above won't wind
// up using the combined stack space of both functions in some cases.
#[inline(never)]
-fn float_to_decimal_common_shortest<T>(fmt: &mut Formatter<'_>, num: &T,
- sign: flt2dec::Sign, precision: usize) -> Result
- where T: flt2dec::DecodableFloat
+fn float_to_decimal_common_shortest<T>(
+ fmt: &mut Formatter<'_>,
+ num: &T,
+ sign: flt2dec::Sign,
+ precision: usize,
+) -> Result
+where
+ T: flt2dec::DecodableFloat,
{
unsafe {
// enough for f32 and f64
let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninit();
let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 4]>::uninit();
// FIXME(#53491)
- let formatted = flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest, *num,
- sign, precision, false, buf.get_mut(),
- parts.get_mut());
+ let formatted = flt2dec::to_shortest_str(
+ flt2dec::strategy::grisu::format_shortest,
+ *num,
+ sign,
+ precision,
+ false,
+ buf.get_mut(),
+ parts.get_mut(),
+ );
fmt.pad_formatted_parts(&formatted)
}
}
// Common code of floating point Debug and Display.
-fn float_to_decimal_common<T>(fmt: &mut Formatter<'_>, num: &T,
- negative_zero: bool, min_precision: usize) -> Result
- where T: flt2dec::DecodableFloat
+fn float_to_decimal_common<T>(
+ fmt: &mut Formatter<'_>,
+ num: &T,
+ negative_zero: bool,
+ min_precision: usize,
+) -> Result
+where
+ T: flt2dec::DecodableFloat,
{
let force_sign = fmt.sign_plus();
let sign = match (force_sign, negative_zero) {
(false, false) => flt2dec::Sign::Minus,
- (false, true) => flt2dec::Sign::MinusRaw,
- (true, false) => flt2dec::Sign::MinusPlus,
- (true, true) => flt2dec::Sign::MinusPlusRaw,
+ (false, true) => flt2dec::Sign::MinusRaw,
+ (true, false) => flt2dec::Sign::MinusPlus,
+ (true, true) => flt2dec::Sign::MinusPlusRaw,
};
if let Some(precision) = fmt.precision {
// Don't inline this so callers don't use the stack space this function
// requires unless they have to.
#[inline(never)]
-fn float_to_exponential_common_exact<T>(fmt: &mut Formatter<'_>, num: &T,
- sign: flt2dec::Sign, precision: usize,
- upper: bool) -> Result
- where T: flt2dec::DecodableFloat
+fn float_to_exponential_common_exact<T>(
+ fmt: &mut Formatter<'_>,
+ num: &T,
+ sign: flt2dec::Sign,
+ precision: usize,
+ upper: bool,
+) -> Result
+where
+ T: flt2dec::DecodableFloat,
{
unsafe {
let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64
let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 6]>::uninit();
// FIXME(#53491)
- let formatted = flt2dec::to_exact_exp_str(flt2dec::strategy::grisu::format_exact,
- *num, sign, precision,
- upper, buf.get_mut(), parts.get_mut());
+ let formatted = flt2dec::to_exact_exp_str(
+ flt2dec::strategy::grisu::format_exact,
+ *num,
+ sign,
+ precision,
+ upper,
+ buf.get_mut(),
+ parts.get_mut(),
+ );
fmt.pad_formatted_parts(&formatted)
}
}
// Don't inline this so callers that call both this and the above won't wind
// up using the combined stack space of both functions in some cases.
#[inline(never)]
-fn float_to_exponential_common_shortest<T>(fmt: &mut Formatter<'_>,
- num: &T, sign: flt2dec::Sign,
- upper: bool) -> Result
- where T: flt2dec::DecodableFloat
+fn float_to_exponential_common_shortest<T>(
+ fmt: &mut Formatter<'_>,
+ num: &T,
+ sign: flt2dec::Sign,
+ upper: bool,
+) -> Result
+where
+ T: flt2dec::DecodableFloat,
{
unsafe {
// enough for f32 and f64
let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninit();
let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 6]>::uninit();
// FIXME(#53491)
- let formatted = flt2dec::to_shortest_exp_str(flt2dec::strategy::grisu::format_shortest,
- *num, sign, (0, 0), upper,
- buf.get_mut(), parts.get_mut());
+ let formatted = flt2dec::to_shortest_exp_str(
+ flt2dec::strategy::grisu::format_shortest,
+ *num,
+ sign,
+ (0, 0),
+ upper,
+ buf.get_mut(),
+ parts.get_mut(),
+ );
fmt.pad_formatted_parts(&formatted)
}
}
// Common code of floating point LowerExp and UpperExp.
fn float_to_exponential_common<T>(fmt: &mut Formatter<'_>, num: &T, upper: bool) -> Result
- where T: flt2dec::DecodableFloat
+where
+ T: flt2dec::DecodableFloat,
{
let force_sign = fmt.sign_plus();
let sign = match force_sign {
false => flt2dec::Sign::Minus,
- true => flt2dec::Sign::MinusPlus,
+ true => flt2dec::Sign::MinusPlus,
};
if let Some(precision) = fmt.precision {
}
macro_rules! floating {
- ($ty:ident) => (
+ ($ty:ident) => {
#[stable(feature = "rust1", since = "1.0.0")]
impl Debug for $ty {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
float_to_exponential_common(fmt, self, true)
}
}
- )
+ };
}
floating! { f32 }
#![stable(feature = "rust1", since = "1.0.0")]
-use crate::cell::{UnsafeCell, Cell, RefCell, Ref, RefMut};
+use crate::cell::{Cell, Ref, RefCell, RefMut, UnsafeCell};
use crate::marker::PhantomData;
use crate::mem;
use crate::num::flt2dec;
use crate::slice;
use crate::str;
+mod builders;
mod float;
mod num;
-mod builders;
#[stable(feature = "fmt_flags_align", since = "1.28.0")]
/// Possible alignments returned by `Formatter::align`
}
#[stable(feature = "debug_builders", since = "1.2.0")]
-pub use self::builders::{DebugStruct, DebugTuple, DebugSet, DebugList, DebugMap};
+pub use self::builders::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};
-#[unstable(feature = "fmt_internals", reason = "internal to format_args!",
- issue = "0")]
+#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "0")]
#[doc(hidden)]
pub mod rt {
pub mod v1;
width: Option<usize>,
precision: Option<usize>,
- buf: &'a mut (dyn Write+'a),
+ buf: &'a mut (dyn Write + 'a),
curarg: slice::Iter<'a, ArgumentV1<'a>>,
args: &'a [ArgumentV1<'a>],
}
/// types, and then this struct is used to canonicalize arguments to one type.
#[derive(Copy, Clone)]
#[allow(missing_debug_implementations)]
-#[unstable(feature = "fmt_internals", reason = "internal to format_args!",
- issue = "0")]
+#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "0")]
#[doc(hidden)]
pub struct ArgumentV1<'a> {
value: &'a Void,
}
#[doc(hidden)]
- #[unstable(feature = "fmt_internals", reason = "internal to format_args!",
- issue = "0")]
- pub fn new<'b, T>(x: &'b T,
- f: fn(&T, &mut Formatter<'_>) -> Result) -> ArgumentV1<'b> {
- unsafe {
- ArgumentV1 {
- formatter: mem::transmute(f),
- value: mem::transmute(x)
- }
- }
+ #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "0")]
+ pub fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter<'_>) -> Result) -> ArgumentV1<'b> {
+ unsafe { ArgumentV1 { formatter: mem::transmute(f), value: mem::transmute(x) } }
}
#[doc(hidden)]
- #[unstable(feature = "fmt_internals", reason = "internal to format_args!",
- issue = "0")]
+ #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "0")]
pub fn from_usize(x: &usize) -> ArgumentV1<'_> {
ArgumentV1::new(x, ArgumentV1::show_usize)
}
// flags available in the v1 format of format_args
#[derive(Copy, Clone)]
-enum FlagV1 { SignPlus, SignMinus, Alternate, SignAwareZeroPad, DebugLowerHex, DebugUpperHex }
+enum FlagV1 {
+ SignPlus,
+ SignMinus,
+ Alternate,
+ SignAwareZeroPad,
+ DebugLowerHex,
+ DebugUpperHex,
+}
impl<'a> Arguments<'a> {
/// When using the format_args!() macro, this function is used to generate the
/// Arguments structure.
- #[doc(hidden)] #[inline]
- #[unstable(feature = "fmt_internals", reason = "internal to format_args!",
- issue = "0")]
- pub fn new_v1(pieces: &'a [&'a str],
- args: &'a [ArgumentV1<'a>]) -> Arguments<'a> {
- Arguments {
- pieces,
- fmt: None,
- args,
- }
+ #[doc(hidden)]
+ #[inline]
+ #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "0")]
+ pub fn new_v1(pieces: &'a [&'a str], args: &'a [ArgumentV1<'a>]) -> Arguments<'a> {
+ Arguments { pieces, fmt: None, args }
}
/// This function is used to specify nonstandard formatting parameters.
/// `CountIsParam` or `CountIsNextParam` has to point to an argument
/// created with `argumentusize`. However, failing to do so doesn't cause
/// unsafety, but will ignore invalid .
- #[doc(hidden)] #[inline]
- #[unstable(feature = "fmt_internals", reason = "internal to format_args!",
- issue = "0")]
- pub fn new_v1_formatted(pieces: &'a [&'a str],
- args: &'a [ArgumentV1<'a>],
- fmt: &'a [rt::v1::Argument]) -> Arguments<'a> {
- Arguments {
- pieces,
- fmt: Some(fmt),
- args,
- }
+ #[doc(hidden)]
+ #[inline]
+ #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "0")]
+ pub fn new_v1_formatted(
+ pieces: &'a [&'a str],
+ args: &'a [ArgumentV1<'a>],
+ fmt: &'a [rt::v1::Argument],
+ ) -> Arguments<'a> {
+ Arguments { pieces, fmt: Some(fmt), args }
}
/// Estimates the length of the formatted text.
///
/// This is intended to be used for setting initial `String` capacity
/// when using `format!`. Note: this is neither the lower nor upper bound.
- #[doc(hidden)] #[inline]
- #[unstable(feature = "fmt_internals", reason = "internal to format_args!",
- issue = "0")]
+ #[doc(hidden)]
+ #[inline]
+ #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "0")]
pub fn estimated_capacity(&self) -> usize {
- let pieces_length: usize = self.pieces.iter()
- .map(|x| x.len()).sum();
+ let pieces_length: usize = self.pieces.iter().map(|x| x.len()).sum();
if self.args.is_empty() {
pieces_length
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented(
- on(crate_local, label="`{Self}` cannot be formatted using `{{:?}}`",
- note="add `#[derive(Debug)]` or manually implement `{Debug}`"),
- message="`{Self}` doesn't implement `{Debug}`",
- label="`{Self}` cannot be formatted using `{{:?}}` because it doesn't implement `{Debug}`",
+ on(
+ crate_local,
+ label = "`{Self}` cannot be formatted using `{{:?}}`",
+ note = "add `#[derive(Debug)]` or manually implement `{Debug}`"
+ ),
+ message = "`{Self}` doesn't implement `{Debug}`",
+ label = "`{Self}` cannot be formatted using `{{:?}}` because it doesn't implement `{Debug}`"
)]
#[doc(alias = "{:?}")]
#[rustc_diagnostic_item = "debug_trait"]
#[rustc_builtin_macro]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics)]
- pub macro Debug($item:item) { /* compiler built-in */ }
+ pub macro Debug($item:item) {
+ /* compiler built-in */
+ }
}
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[doc(inline)]
/// ```
#[rustc_on_unimplemented(
on(
- _Self="std::path::Path",
- label="`{Self}` cannot be formatted with the default formatter; call `.display()` on it",
- note="call `.display()` or `.to_string_lossy()` to safely print paths, \
- as they may contain non-Unicode data"
+ _Self = "std::path::Path",
+ label = "`{Self}` cannot be formatted with the default formatter; call `.display()` on it",
+ note = "call `.display()` or `.to_string_lossy()` to safely print paths, \
+ as they may contain non-Unicode data"
),
- message="`{Self}` doesn't implement `{Display}`",
- label="`{Self}` cannot be formatted with the default formatter",
- note="in format strings you may be able to use `{{:?}}` (or {{:#?}} for pretty-print) instead",
+ message = "`{Self}` doesn't implement `{Display}`",
+ label = "`{Self}` cannot be formatted with the default formatter",
+ note = "in format strings you may be able to use `{{:?}}` (or {{:#?}} for pretty-print) instead"
)]
#[doc(alias = "{}")]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Formatter<'a> {
fn wrap_buf<'b, 'c, F>(&'b mut self, wrap: F) -> Formatter<'c>
- where 'b: 'c, F: FnOnce(&'b mut (dyn Write+'b)) -> &'c mut (dyn Write+'c)
+ where
+ 'b: 'c,
+ F: FnOnce(&'b mut (dyn Write + 'b)) -> &'c mut (dyn Write + 'c),
{
Formatter {
// We want to change this
// Extract the correct argument
let value = match arg.position {
- rt::v1::Position::Next => { *self.curarg.next().unwrap() }
+ rt::v1::Position::Next => *self.curarg.next().unwrap(),
rt::v1::Position::At(i) => self.args[i],
};
match *cnt {
rt::v1::Count::Is(n) => Some(n),
rt::v1::Count::Implied => None,
- rt::v1::Count::Param(i) => {
- self.args[i].as_usize()
- }
- rt::v1::Count::NextParam => {
- self.curarg.next()?.as_usize()
- }
+ rt::v1::Count::Param(i) => self.args[i].as_usize(),
+ rt::v1::Count::NextParam => self.curarg.next()?.as_usize(),
}
}
/// assert_eq!(&format!("{:0>#8}", Foo::new(-1)), "00-Foo 1");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn pad_integral(&mut self,
- is_nonnegative: bool,
- prefix: &str,
- buf: &str)
- -> Result {
+ pub fn pad_integral(&mut self, is_nonnegative: bool, prefix: &str, buf: &str) -> Result {
let mut width = buf.len();
let mut sign = None;
if !is_nonnegative {
- sign = Some('-'); width += 1;
+ sign = Some('-');
+ width += 1;
} else if self.sign_plus() {
- sign = Some('+'); width += 1;
+ sign = Some('+');
+ width += 1;
}
let prefix = if self.alternate() {
if let Some(c) = sign {
f.buf.write_char(c)?;
}
- if let Some(prefix) = prefix {
- f.buf.write_str(prefix)
- } else {
- Ok(())
- }
+ if let Some(prefix) = prefix { f.buf.write_str(prefix) } else { Ok(()) }
}
// The `width` field is more of a `min-width` parameter at this point.
None => self.buf.write_str(s),
// If we're under the maximum width, check if we're over the minimum
// width, if so it's as easy as just emitting the string.
- Some(width) if s.chars().count() >= width => {
- self.buf.write_str(s)
- }
+ Some(width) if s.chars().count() >= width => self.buf.write_str(s),
// If we're under both the maximum and the minimum width, then fill
// up the minimum width with the specified string + some alignment.
Some(width) => {
fn padding(
&mut self,
padding: usize,
- default: rt::v1::Alignment
+ default: rt::v1::Alignment,
) -> result::Result<PostPadding, Error> {
let align = match self.align {
rt::v1::Alignment::Unknown => default,
- _ => self.align
+ _ => self.align,
};
let (pre_pad, post_pad) = match align {
rt::v1::Alignment::Left => (0, padding),
- rt::v1::Alignment::Right |
- rt::v1::Alignment::Unknown => (padding, 0),
+ rt::v1::Alignment::Right | rt::v1::Alignment::Unknown => (padding, 0),
rt::v1::Alignment::Center => (padding / 2, (padding + 1) / 2),
};
// remaining parts go through the ordinary padding process.
let len = formatted.len();
- let ret = if width <= len { // no padding
+ let ret = if width <= len {
+ // no padding
self.write_formatted_parts(&formatted)
} else {
let post_padding = self.padding(width - len, align)?;
/// Flags for formatting
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_deprecated(since = "1.24.0",
- reason = "use the `sign_plus`, `sign_minus`, `alternate`, \
- or `sign_aware_zero_pad` methods instead")]
- pub fn flags(&self) -> u32 { self.flags }
+ #[rustc_deprecated(
+ since = "1.24.0",
+ reason = "use the `sign_plus`, `sign_minus`, `alternate`, \
+ or `sign_aware_zero_pad` methods instead"
+ )]
+ pub fn flags(&self) -> u32 {
+ self.flags
+ }
/// Character used as 'fill' whenever there is alignment.
///
/// assert_eq!(&format!("{:t>6}", Foo), "tttttt");
/// ```
#[stable(feature = "fmt_flags", since = "1.5.0")]
- pub fn fill(&self) -> char { self.fill }
+ pub fn fill(&self) -> char {
+ self.fill
+ }
/// Flag indicating what form of alignment was requested.
///
/// assert_eq!(&format!("{}", Foo(23)), "Foo(23)");
/// ```
#[stable(feature = "fmt_flags", since = "1.5.0")]
- pub fn width(&self) -> Option<usize> { self.width }
+ pub fn width(&self) -> Option<usize> {
+ self.width
+ }
/// Optionally specified precision for numeric types.
///
/// assert_eq!(&format!("{}", Foo(23.2)), "Foo(23.20)");
/// ```
#[stable(feature = "fmt_flags", since = "1.5.0")]
- pub fn precision(&self) -> Option<usize> { self.precision }
+ pub fn precision(&self) -> Option<usize> {
+ self.precision
+ }
/// Determines if the `+` flag was specified.
///
/// assert_eq!(&format!("{}", Foo(23)), "Foo(23)");
/// ```
#[stable(feature = "fmt_flags", since = "1.5.0")]
- pub fn sign_plus(&self) -> bool { self.flags & (1 << FlagV1::SignPlus as u32) != 0 }
+ pub fn sign_plus(&self) -> bool {
+ self.flags & (1 << FlagV1::SignPlus as u32) != 0
+ }
/// Determines if the `-` flag was specified.
///
/// assert_eq!(&format!("{}", Foo(23)), "Foo(23)");
/// ```
#[stable(feature = "fmt_flags", since = "1.5.0")]
- pub fn sign_minus(&self) -> bool { self.flags & (1 << FlagV1::SignMinus as u32) != 0 }
+ pub fn sign_minus(&self) -> bool {
+ self.flags & (1 << FlagV1::SignMinus as u32) != 0
+ }
/// Determines if the `#` flag was specified.
///
/// assert_eq!(&format!("{}", Foo(23)), "23");
/// ```
#[stable(feature = "fmt_flags", since = "1.5.0")]
- pub fn alternate(&self) -> bool { self.flags & (1 << FlagV1::Alternate as u32) != 0 }
+ pub fn alternate(&self) -> bool {
+ self.flags & (1 << FlagV1::Alternate as u32) != 0
+ }
/// Determines if the `0` flag was specified.
///
// FIXME: Decide what public API we want for these two flags.
// https://github.com/rust-lang/rust/issues/48584
- fn debug_lower_hex(&self) -> bool { self.flags & (1 << FlagV1::DebugLowerHex as u32) != 0 }
+ fn debug_lower_hex(&self) -> bool {
+ self.flags & (1 << FlagV1::DebugLowerHex as u32) != 0
+ }
- fn debug_upper_hex(&self) -> bool { self.flags & (1 << FlagV1::DebugUpperHex as u32) != 0 }
+ fn debug_upper_hex(&self) -> bool {
+ self.flags & (1 << FlagV1::DebugUpperHex as u32) != 0
+ }
/// Creates a [`DebugStruct`] builder designed to assist with creation of
/// [`fmt::Debug`] implementations for structs.
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Debug for *const T {
- fn fmt(&self, f: &mut Formatter<'_>) -> Result { Pointer::fmt(self, f) }
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+ Pointer::fmt(self, f)
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Debug for *mut T {
- fn fmt(&self, f: &mut Formatter<'_>) -> Result { Pointer::fmt(self, f) }
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+ Pointer::fmt(self, f)
+ }
}
macro_rules! peel {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Copy + Debug> Debug for Cell<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
- f.debug_struct("Cell")
- .field("value", &self.get())
- .finish()
+ f.debug_struct("Cell").field("value", &self.get()).finish()
}
}
impl<T: ?Sized + Debug> Debug for RefCell<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
match self.try_borrow() {
- Ok(borrow) => {
- f.debug_struct("RefCell")
- .field("value", &borrow)
- .finish()
- }
+ Ok(borrow) => f.debug_struct("RefCell").field("value", &borrow).finish(),
Err(_) => {
// The RefCell is mutably borrowed so we can't look at its value
// here. Show a placeholder instead.
}
}
- f.debug_struct("RefCell")
- .field("value", &BorrowedPlaceholder)
- .finish()
+ f.debug_struct("RefCell").field("value", &BorrowedPlaceholder).finish()
}
}
}
/// [`Hasher`]: trait.Hasher.html
#[stable(feature = "hash_slice", since = "1.3.0")]
fn hash_slice<H: Hasher>(data: &[Self], state: &mut H)
- where Self: Sized
+ where
+ Self: Sized,
{
for piece in data {
piece.hash(state);
#[rustc_builtin_macro]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics)]
- pub macro Hash($item:item) { /* compiler built-in */ }
+ pub macro Hash($item:item) {
+ /* compiler built-in */
+ }
}
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[doc(inline)]
}
}
-
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + Hash> Hash for &T {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_usize(*self as *const () as usize);
} else {
// Fat pointer
- let (a, b) = unsafe {
- *(self as *const Self as *const (usize, usize))
- };
+ let (a, b) = unsafe { *(self as *const Self as *const (usize, usize)) };
state.write_usize(a);
state.write_usize(b);
}
state.write_usize(*self as *const () as usize);
} else {
// Fat pointer
- let (a, b) = unsafe {
- *(self as *const Self as *const (usize, usize))
- };
+ let (a, b) = unsafe { *(self as *const Self as *const (usize, usize)) };
state.write_usize(a);
state.write_usize(b);
}
#![allow(deprecated)] // the types in this module are deprecated
-use crate::marker::PhantomData;
-use crate::ptr;
use crate::cmp;
+use crate::marker::PhantomData;
use crate::mem;
+use crate::ptr;
/// An implementation of SipHash 1-3.
///
///
/// See: <https://131002.net/siphash>
#[unstable(feature = "hashmap_internals", issue = "0")]
-#[rustc_deprecated(since = "1.13.0",
- reason = "use `std::collections::hash_map::DefaultHasher` instead")]
+#[rustc_deprecated(
+ since = "1.13.0",
+ reason = "use `std::collections::hash_map::DefaultHasher` instead"
+)]
#[derive(Debug, Clone, Default)]
#[doc(hidden)]
pub struct SipHasher13 {
///
/// See: <https://131002.net/siphash/>
#[unstable(feature = "hashmap_internals", issue = "0")]
-#[rustc_deprecated(since = "1.13.0",
- reason = "use `std::collections::hash_map::DefaultHasher` instead")]
+#[rustc_deprecated(
+ since = "1.13.0",
+ reason = "use `std::collections::hash_map::DefaultHasher` instead"
+)]
#[derive(Debug, Clone, Default)]
struct SipHasher24 {
hasher: Hasher<Sip24Rounds>,
/// it is not intended for cryptographic purposes. As such, all
/// cryptographic uses of this implementation are _strongly discouraged_.
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_deprecated(since = "1.13.0",
- reason = "use `std::collections::hash_map::DefaultHasher` instead")]
+#[rustc_deprecated(
+ since = "1.13.0",
+ reason = "use `std::collections::hash_map::DefaultHasher` instead"
+)]
#[derive(Debug, Clone, Default)]
pub struct SipHasher(SipHasher24);
k0: u64,
k1: u64,
length: usize, // how many bytes we've processed
- state: State, // hash State
- tail: u64, // unprocessed bytes le
- ntail: usize, // how many bytes in tail are valid
+ state: State, // hash State
+ tail: u64, // unprocessed bytes le
+ ntail: usize, // how many bytes in tail are valid
_marker: PhantomData<S>,
}
}
macro_rules! compress {
- ($state:expr) => ({
- compress!($state.v0, $state.v1, $state.v2, $state.v3)
- });
- ($v0:expr, $v1:expr, $v2:expr, $v3:expr) =>
- ({
- $v0 = $v0.wrapping_add($v1); $v1 = $v1.rotate_left(13); $v1 ^= $v0;
+ ($state:expr) => {{ compress!($state.v0, $state.v1, $state.v2, $state.v3) }};
+ ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => {{
+ $v0 = $v0.wrapping_add($v1);
+ $v1 = $v1.rotate_left(13);
+ $v1 ^= $v0;
$v0 = $v0.rotate_left(32);
- $v2 = $v2.wrapping_add($v3); $v3 = $v3.rotate_left(16); $v3 ^= $v2;
- $v0 = $v0.wrapping_add($v3); $v3 = $v3.rotate_left(21); $v3 ^= $v0;
- $v2 = $v2.wrapping_add($v1); $v1 = $v1.rotate_left(17); $v1 ^= $v2;
+ $v2 = $v2.wrapping_add($v3);
+ $v3 = $v3.rotate_left(16);
+ $v3 ^= $v2;
+ $v0 = $v0.wrapping_add($v3);
+ $v3 = $v3.rotate_left(21);
+ $v3 ^= $v0;
+ $v2 = $v2.wrapping_add($v1);
+ $v1 = $v1.rotate_left(17);
+ $v1 ^= $v2;
$v2 = $v2.rotate_left(32);
- });
+ }};
}
/// Loads an integer of the desired type from a byte stream, in LE order. Uses
///
/// Unsafe because: unchecked indexing at i..i+size_of(int_ty)
macro_rules! load_int_le {
- ($buf:expr, $i:expr, $int_ty:ident) =>
- ({
- debug_assert!($i + mem::size_of::<$int_ty>() <= $buf.len());
- let mut data = 0 as $int_ty;
- ptr::copy_nonoverlapping($buf.get_unchecked($i),
- &mut data as *mut _ as *mut u8,
- mem::size_of::<$int_ty>());
- data.to_le()
- });
+ ($buf:expr, $i:expr, $int_ty:ident) => {{
+ debug_assert!($i + mem::size_of::<$int_ty>() <= $buf.len());
+ let mut data = 0 as $int_ty;
+ ptr::copy_nonoverlapping(
+ $buf.get_unchecked($i),
+ &mut data as *mut _ as *mut u8,
+ mem::size_of::<$int_ty>(),
+ );
+ data.to_le()
+ }};
}
/// Loads an u64 using up to 7 bytes of a byte slice.
/// Creates a new `SipHasher` with the two initial keys set to 0.
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_deprecated(since = "1.13.0",
- reason = "use `std::collections::hash_map::DefaultHasher` instead")]
+ #[rustc_deprecated(
+ since = "1.13.0",
+ reason = "use `std::collections::hash_map::DefaultHasher` instead"
+ )]
pub fn new() -> SipHasher {
SipHasher::new_with_keys(0, 0)
}
/// Creates a `SipHasher` that is keyed off the provided keys.
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_deprecated(since = "1.13.0",
- reason = "use `std::collections::hash_map::DefaultHasher` instead")]
+ #[rustc_deprecated(
+ since = "1.13.0",
+ reason = "use `std::collections::hash_map::DefaultHasher` instead"
+ )]
pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
- SipHasher(SipHasher24 {
- hasher: Hasher::new_with_keys(key0, key1)
- })
+ SipHasher(SipHasher24 { hasher: Hasher::new_with_keys(key0, key1) })
}
}
/// Creates a new `SipHasher13` with the two initial keys set to 0.
#[inline]
#[unstable(feature = "hashmap_internals", issue = "0")]
- #[rustc_deprecated(since = "1.13.0",
- reason = "use `std::collections::hash_map::DefaultHasher` instead")]
+ #[rustc_deprecated(
+ since = "1.13.0",
+ reason = "use `std::collections::hash_map::DefaultHasher` instead"
+ )]
pub fn new() -> SipHasher13 {
SipHasher13::new_with_keys(0, 0)
}
/// Creates a `SipHasher13` that is keyed off the provided keys.
#[inline]
#[unstable(feature = "hashmap_internals", issue = "0")]
- #[rustc_deprecated(since = "1.13.0",
- reason = "use `std::collections::hash_map::DefaultHasher` instead")]
+ #[rustc_deprecated(
+ since = "1.13.0",
+ reason = "use `std::collections::hash_map::DefaultHasher` instead"
+ )]
pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 {
- SipHasher13 {
- hasher: Hasher::new_with_keys(key0, key1)
- }
+ SipHasher13 { hasher: Hasher::new_with_keys(key0, key1) }
}
}
k0: key0,
k1: key1,
length: 0,
- state: State {
- v0: 0,
- v1: 0,
- v2: 0,
- v3: 0,
- },
+ state: State { v0: 0, v1: 0, v2: 0, v3: 0 },
tail: 0,
ntail: 0,
_marker: PhantomData,
self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << 8 * self.ntail;
if length < needed {
self.ntail += length;
- return
+ return;
} else {
self.state.v3 ^= self.tail;
S::c_rounds(&mut self.state);
use crate::fmt;
use crate::ops::Try;
-use super::super::{Iterator, DoubleEndedIterator, FusedIterator};
+use super::super::{DoubleEndedIterator, FusedIterator, Iterator};
use super::Map;
/// An iterator that maps each element to an iterator, and yields the elements
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct FlatMap<I, U: IntoIterator, F> {
- inner: FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>
+ inner: FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>,
}
impl<I: Iterator, U: IntoIterator, F: FnMut(I::Item) -> U> FlatMap<I, U, F> {
pub(in super::super) fn new(iter: I, f: F) -> FlatMap<I, U, F> {
where
U: Clone + IntoIterator<IntoIter: Clone>,
{
- fn clone(&self) -> Self { FlatMap { inner: self.inner.clone() } }
+ fn clone(&self) -> Self {
+ FlatMap { inner: self.inner.clone() }
+ }
}
#[stable(feature = "core_impl_debug", since = "1.9.0")]
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F>
- where F: FnMut(I::Item) -> U,
+where
+ F: FnMut(I::Item) -> U,
{
type Item = U::Item;
#[inline]
- fn next(&mut self) -> Option<U::Item> { self.inner.next() }
+ fn next(&mut self) -> Option<U::Item> {
+ self.inner.next()
+ }
#[inline]
- fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
#[inline]
- fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
- Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+ fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
{
self.inner.try_fold(init, fold)
}
#[inline]
fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
- where Fold: FnMut(Acc, Self::Item) -> Acc,
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
{
self.inner.fold(init, fold)
}
U: IntoIterator<IntoIter: DoubleEndedIterator>,
{
#[inline]
- fn next_back(&mut self) -> Option<U::Item> { self.inner.next_back() }
+ fn next_back(&mut self) -> Option<U::Item> {
+ self.inner.next_back()
+ }
#[inline]
- fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
- Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+ fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
{
self.inner.try_rfold(init, fold)
}
#[inline]
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
- where Fold: FnMut(Acc, Self::Item) -> Acc,
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
{
self.inner.rfold(init, fold)
}
#[stable(feature = "fused", since = "1.26.0")]
impl<I, U, F> FusedIterator for FlatMap<I, U, F>
- where I: FusedIterator, U: IntoIterator, F: FnMut(I::Item) -> U {}
+where
+ I: FusedIterator,
+ U: IntoIterator,
+ F: FnMut(I::Item) -> U,
+{
+}
/// An iterator that flattens one level of nesting in an iterator of things
/// that can be turned into iterators.
I: Clone + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
U: Clone + Iterator,
{
- fn clone(&self) -> Self { Flatten { inner: self.inner.clone() } }
+ fn clone(&self) -> Self {
+ Flatten { inner: self.inner.clone() }
+ }
}
#[stable(feature = "iterator_flatten", since = "1.29.0")]
type Item = U::Item;
#[inline]
- fn next(&mut self) -> Option<U::Item> { self.inner.next() }
+ fn next(&mut self) -> Option<U::Item> {
+ self.inner.next()
+ }
#[inline]
- fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
#[inline]
- fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
- Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+ fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
{
self.inner.try_fold(init, fold)
}
#[inline]
fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
- where Fold: FnMut(Acc, Self::Item) -> Acc,
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
{
self.inner.fold(init, fold)
}
U: DoubleEndedIterator,
{
#[inline]
- fn next_back(&mut self) -> Option<U::Item> { self.inner.next_back() }
+ fn next_back(&mut self) -> Option<U::Item> {
+ self.inner.next_back()
+ }
#[inline]
- fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
- Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+ fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
{
self.inner.try_rfold(init, fold)
}
#[inline]
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
- where Fold: FnMut(Acc, Self::Item) -> Acc,
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
{
self.inner.rfold(init, fold)
}
where
I: FusedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
U: Iterator,
-{}
+{
+}
/// Real logic of both `Flatten` and `FlatMap` which simply delegate to
/// this type.
fn next(&mut self) -> Option<U::Item> {
loop {
if let Some(ref mut inner) = self.frontiter {
- if let elt@Some(_) = inner.next() { return elt }
+ if let elt @ Some(_) = inner.next() {
+ return elt;
+ }
}
match self.iter.next() {
None => return self.backiter.as_mut()?.next(),
let lo = flo.saturating_add(blo);
match (self.iter.size_hint(), fhi, bhi) {
((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
- _ => (lo, None)
+ _ => (lo, None),
}
}
#[inline]
- fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R where
- Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+ fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
{
#[inline]
fn flatten<'a, T: IntoIterator, Acc, R: Try<Ok = Acc>>(
#[inline]
fn fold<Acc, Fold>(self, init: Acc, ref mut fold: Fold) -> Acc
- where Fold: FnMut(Acc, Self::Item) -> Acc,
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
fn flatten<U: Iterator, Acc>(
move |acc, iter| iter.fold(acc, &mut *fold)
}
- self.frontiter.into_iter()
+ self.frontiter
+ .into_iter()
.chain(self.iter.map(IntoIterator::into_iter))
.chain(self.backiter)
.fold(init, flatten(fold))
fn next_back(&mut self) -> Option<U::Item> {
loop {
if let Some(ref mut inner) = self.backiter {
- if let elt@Some(_) = inner.next_back() { return elt }
+ if let elt @ Some(_) = inner.next_back() {
+ return elt;
+ }
}
match self.iter.next_back() {
None => return self.frontiter.as_mut()?.next_back(),
}
#[inline]
- fn try_rfold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R where
- Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+ fn try_rfold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
{
#[inline]
fn flatten<'a, T: IntoIterator, Acc, R: Try<Ok = Acc>>(
backiter: &'a mut Option<T::IntoIter>,
fold: &'a mut impl FnMut(Acc, T::Item) -> R,
- ) -> impl FnMut(Acc, T) -> R + 'a where
+ ) -> impl FnMut(Acc, T) -> R + 'a
+ where
T::IntoIter: DoubleEndedIterator,
{
move |acc, x| {
#[inline]
fn rfold<Acc, Fold>(self, init: Acc, ref mut fold: Fold) -> Acc
- where Fold: FnMut(Acc, Self::Item) -> Acc,
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
fn flatten<U: DoubleEndedIterator, Acc>(
move |acc, iter| iter.rfold(acc, &mut *fold)
}
- self.frontiter.into_iter()
+ self.frontiter
+ .into_iter()
.chain(self.iter.map(IntoIterator::into_iter))
.chain(self.backiter)
.rfold(init, flatten(fold))
#[derive(Clone, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Repeat<A> {
- element: A
+ element: A,
}
#[stable(feature = "rust1", since = "1.0.0")]
type Item = A;
#[inline]
- fn next(&mut self) -> Option<A> { Some(self.element.clone()) }
+ fn next(&mut self) -> Option<A> {
+ Some(self.element.clone())
+ }
#[inline]
- fn size_hint(&self) -> (usize, Option<usize>) { (usize::MAX, None) }
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (usize::MAX, None)
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Clone> DoubleEndedIterator for Repeat<A> {
#[inline]
- fn next_back(&mut self) -> Option<A> { Some(self.element.clone()) }
+ fn next_back(&mut self) -> Option<A> {
+ Some(self.element.clone())
+ }
}
#[stable(feature = "fused", since = "1.26.0")]
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
- Repeat{element: elt}
+ Repeat { element: elt }
}
/// An iterator that repeats elements of type `A` endlessly by
#[derive(Copy, Clone, Debug)]
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
pub struct RepeatWith<F> {
- repeater: F
+ repeater: F,
}
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
type Item = A;
#[inline]
- fn next(&mut self) -> Option<A> { Some((self.repeater)()) }
+ fn next(&mut self) -> Option<A> {
+ Some((self.repeater)())
+ }
#[inline]
- fn size_hint(&self) -> (usize, Option<usize>) { (usize::MAX, None) }
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (usize::MAX, None)
+ }
}
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
None
}
- fn size_hint(&self) -> (usize, Option<usize>){
+ fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(0))
}
}
#[derive(Clone, Debug)]
#[stable(feature = "iter_once", since = "1.2.0")]
pub struct Once<T> {
- inner: crate::option::IntoIter<T>
+ inner: crate::option::IntoIter<T>,
}
#[stable(feature = "iter_once", since = "1.2.0")]
#[inline]
#[stable(feature = "iter_from_fn", since = "1.34.0")]
pub fn from_fn<T, F>(f: F) -> FromFn<F>
- where F: FnMut() -> Option<T>
+where
+ F: FnMut() -> Option<T>,
{
FromFn(f)
}
#[stable(feature = "iter_from_fn", since = "1.34.0")]
impl<T, F> Iterator for FromFn<F>
- where F: FnMut() -> Option<T>
+where
+ F: FnMut() -> Option<T>,
{
type Item = T;
/// ```
#[stable(feature = "iter_successors", since = "1.34.0")]
pub fn successors<T, F>(first: Option<T>, succ: F) -> Successors<T, F>
- where F: FnMut(&T) -> Option<T>
+where
+ F: FnMut(&T) -> Option<T>,
{
// If this function returned `impl Iterator<Item=T>`
// it could be based on `unfold` and not need a dedicated type.
// However having a named `Successors<T, F>` type allows it to be `Clone` when `T` and `F` are.
- Successors {
- next: first,
- succ,
- }
+ Successors { next: first, succ }
}
/// An new iterator where each successive item is computed based on the preceding one.
#[stable(feature = "iter_successors", since = "1.34.0")]
impl<T, F> Iterator for Successors<T, F>
- where F: FnMut(&T) -> Option<T>
+where
+ F: FnMut(&T) -> Option<T>,
{
type Item = T;
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
- if self.next.is_some() {
- (1, None)
- } else {
- (0, Some(0))
- }
+ if self.next.is_some() { (1, None) } else { (0, Some(0)) }
}
}
#[stable(feature = "iter_successors", since = "1.34.0")]
-impl<T, F> FusedIterator for Successors<T, F>
- where F: FnMut(&T) -> Option<T>
-{}
+impl<T, F> FusedIterator for Successors<T, F> where F: FnMut(&T) -> Option<T> {}
#[stable(feature = "iter_successors", since = "1.34.0")]
impl<T: fmt::Debug, F> fmt::Debug for Successors<T, F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Successors")
- .field("next", &self.next)
- .finish()
+ f.debug_struct("Successors").field("next", &self.next).finish()
}
}
-use crate::ops::{Mul, Add};
-use crate::num::Wrapping;
use crate::iter;
+use crate::num::Wrapping;
+use crate::ops::{Add, Mul};
/// Trait to represent types that can be created by summing up an iterator.
///
/// Method which takes an iterator and generates `Self` from the elements by
/// "summing up" the items.
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
- fn sum<I: Iterator<Item=A>>(iter: I) -> Self;
+ fn sum<I: Iterator<Item = A>>(iter: I) -> Self;
}
/// Trait to represent types that can be created by multiplying elements of an
/// Method which takes an iterator and generates `Self` from the elements by
/// multiplying the items.
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
- fn product<I: Iterator<Item=A>>(iter: I) -> Self;
+ fn product<I: Iterator<Item = A>>(iter: I) -> Self;
}
// N.B., explicitly use Add and Mul here to inherit overflow checks
integer_sum_product! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
float_sum_product! { f32 f64 }
-#[stable(feature = "iter_arith_traits_result", since="1.16.0")]
+#[stable(feature = "iter_arith_traits_result", since = "1.16.0")]
impl<T, U, E> Sum<Result<U, E>> for Result<T, E>
- where T: Sum<U>,
+where
+ T: Sum<U>,
{
/// Takes each element in the `Iterator`: if it is an `Err`, no further
/// elements are taken, and the `Err` is returned. Should no `Err` occur,
/// assert_eq!(res, Ok(3));
/// ```
fn sum<I>(iter: I) -> Result<T, E>
- where I: Iterator<Item = Result<U, E>>,
+ where
+ I: Iterator<Item = Result<U, E>>,
{
iter::process_results(iter, |i| i.sum())
}
}
-#[stable(feature = "iter_arith_traits_result", since="1.16.0")]
+#[stable(feature = "iter_arith_traits_result", since = "1.16.0")]
impl<T, U, E> Product<Result<U, E>> for Result<T, E>
- where T: Product<U>,
+where
+ T: Product<U>,
{
/// Takes each element in the `Iterator`: if it is an `Err`, no further
/// elements are taken, and the `Err` is returned. Should no `Err` occur,
/// the product of all elements is returned.
fn product<I>(iter: I) -> Result<T, E>
- where I: Iterator<Item = Result<U, E>>,
+ where
+ I: Iterator<Item = Result<U, E>>,
{
iter::process_results(iter, |i| i.product())
}
-use crate::ops::Try;
use crate::iter::LoopState;
+use crate::ops::Try;
/// An iterator able to yield elements from both ends.
///
#[stable(feature = "iter_nth_back", since = "1.37.0")]
fn nth_back(&mut self, mut n: usize) -> Option<Self::Item> {
for x in self.rev() {
- if n == 0 { return Some(x) }
+ if n == 0 {
+ return Some(x);
+ }
n -= 1;
}
None
where
Self: Sized,
F: FnMut(B, Self::Item) -> R,
- R: Try<Ok=B>
+ R: Try<Ok = B>,
{
let mut accum = init;
while let Some(x) = self.next_back() {
fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
where
Self: Sized,
- P: FnMut(&Self::Item) -> bool
+ P: FnMut(&Self::Item) -> bool,
{
#[inline]
fn check<T>(
#[rustc_deprecated(since = "1.39.0", reason = "use the `?` operator instead")]
#[doc(alias = "?")]
macro_rules! r#try {
- ($expr:expr) => (match $expr {
- $crate::result::Result::Ok(val) => val,
- $crate::result::Result::Err(err) => {
- return $crate::result::Result::Err($crate::convert::From::from(err))
+ ($expr:expr) => {
+ match $expr {
+ $crate::result::Result::Ok(val) => val,
+ $crate::result::Result::Err(err) => {
+ return $crate::result::Result::Err($crate::convert::From::from(err));
+ }
}
- });
- ($expr:expr,) => ($crate::r#try!($expr));
+ };
+ ($expr:expr,) => {
+ $crate::r#try!($expr)
+ };
}
/// Writes formatted data into a buffer.
#[rustc_builtin_macro]
#[macro_export]
macro_rules! compile_error {
- ($msg:expr) => ({ /* compiler built-in */ });
- ($msg:expr,) => ({ /* compiler built-in */ })
+ ($msg:expr) => {{ /* compiler built-in */ }};
+ ($msg:expr,) => {{ /* compiler built-in */ }};
}
/// Constructs parameters for the other string-formatting macros.
#[rustc_builtin_macro]
#[macro_export]
macro_rules! format_args {
- ($fmt:expr) => ({ /* compiler built-in */ });
- ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
+ ($fmt:expr) => {{ /* compiler built-in */ }};
+ ($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
}
/// Same as `format_args`, but adds a newline in the end.
- #[unstable(feature = "format_args_nl", issue = "0",
- reason = "`format_args_nl` is only for internal \
- language use and is subject to change")]
+ #[unstable(
+ feature = "format_args_nl",
+ issue = "0",
+ reason = "`format_args_nl` is only for internal \
+ language use and is subject to change"
+ )]
#[allow_internal_unstable(fmt_internals)]
#[rustc_builtin_macro]
#[macro_export]
macro_rules! format_args_nl {
- ($fmt:expr) => ({ /* compiler built-in */ });
- ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
+ ($fmt:expr) => {{ /* compiler built-in */ }};
+ ($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
}
/// Inspects an environment variable at compile time.
#[rustc_builtin_macro]
#[macro_export]
macro_rules! env {
- ($name:expr) => ({ /* compiler built-in */ });
- ($name:expr,) => ({ /* compiler built-in */ })
+ ($name:expr) => {{ /* compiler built-in */ }};
+ ($name:expr,) => {{ /* compiler built-in */ }};
}
/// Optionally inspects an environment variable at compile time.
#[rustc_builtin_macro]
#[macro_export]
macro_rules! option_env {
- ($name:expr) => ({ /* compiler built-in */ });
- ($name:expr,) => ({ /* compiler built-in */ })
+ ($name:expr) => {{ /* compiler built-in */ }};
+ ($name:expr,) => {{ /* compiler built-in */ }};
}
/// Concatenates identifiers into one identifier.
/// // fn concat_idents!(new, fun, name) { } // not usable in this way!
/// # }
/// ```
- #[unstable(feature = "concat_idents", issue = "29599",
- reason = "`concat_idents` is not stable enough for use and is subject to change")]
+ #[unstable(
+ feature = "concat_idents",
+ issue = "29599",
+ reason = "`concat_idents` is not stable enough for use and is subject to change"
+ )]
#[rustc_builtin_macro]
#[macro_export]
macro_rules! concat_idents {
- ($($e:ident),+) => ({ /* compiler built-in */ });
- ($($e:ident,)+) => ({ /* compiler built-in */ })
+ ($($e:ident),+) => {{ /* compiler built-in */ }};
+ ($($e:ident,)+) => {{ /* compiler built-in */ }};
}
/// Concatenates literals into a static string slice.
#[rustc_builtin_macro]
#[macro_export]
macro_rules! concat {
- ($($e:expr),*) => ({ /* compiler built-in */ });
- ($($e:expr,)*) => ({ /* compiler built-in */ })
+ ($($e:expr),*) => {{ /* compiler built-in */ }};
+ ($($e:expr,)*) => {{ /* compiler built-in */ }};
}
/// Expands to the line number on which it was invoked.
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
#[macro_export]
- macro_rules! line { () => { /* compiler built-in */ } }
+ macro_rules! line {
+ () => {
+ /* compiler built-in */
+ };
+ }
/// Expands to the column number at which it was invoked.
///
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
#[macro_export]
- macro_rules! column { () => { /* compiler built-in */ } }
+ macro_rules! column {
+ () => {
+ /* compiler built-in */
+ };
+ }
/// Expands to the file name in which it was invoked.
///
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
#[macro_export]
- macro_rules! file { () => { /* compiler built-in */ } }
+ macro_rules! file {
+ () => {
+ /* compiler built-in */
+ };
+ }
/// Stringifies its arguments.
///
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
#[macro_export]
- macro_rules! stringify { ($($t:tt)*) => { /* compiler built-in */ } }
+ macro_rules! stringify {
+ ($($t:tt)*) => {
+ /* compiler built-in */
+ };
+ }
/// Includes a utf8-encoded file as a string.
///
#[rustc_builtin_macro]
#[macro_export]
macro_rules! include_str {
- ($file:expr) => ({ /* compiler built-in */ });
- ($file:expr,) => ({ /* compiler built-in */ })
+ ($file:expr) => {{ /* compiler built-in */ }};
+ ($file:expr,) => {{ /* compiler built-in */ }};
}
/// Includes a file as a reference to a byte array.
#[rustc_builtin_macro]
#[macro_export]
macro_rules! include_bytes {
- ($file:expr) => ({ /* compiler built-in */ });
- ($file:expr,) => ({ /* compiler built-in */ })
+ ($file:expr) => {{ /* compiler built-in */ }};
+ ($file:expr,) => {{ /* compiler built-in */ }};
}
/// Expands to a string that represents the current module path.
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
#[macro_export]
- macro_rules! module_path { () => { /* compiler built-in */ } }
+ macro_rules! module_path {
+ () => {
+ /* compiler built-in */
+ };
+ }
/// Evaluates boolean combinations of configuration flags at compile-time.
///
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
#[macro_export]
- macro_rules! cfg { ($($cfg:tt)*) => { /* compiler built-in */ } }
+ macro_rules! cfg {
+ ($($cfg:tt)*) => {
+ /* compiler built-in */
+ };
+ }
/// Parses a file as an expression or an item according to the context.
///
#[rustc_builtin_macro]
#[macro_export]
macro_rules! include {
- ($file:expr) => ({ /* compiler built-in */ });
- ($file:expr,) => ({ /* compiler built-in */ })
+ ($file:expr) => {{ /* compiler built-in */ }};
+ ($file:expr,) => {{ /* compiler built-in */ }};
}
/// Asserts that a boolean expression is `true` at runtime.
#[rustc_builtin_macro]
#[macro_export]
macro_rules! assert {
- ($cond:expr) => ({ /* compiler built-in */ });
- ($cond:expr,) => ({ /* compiler built-in */ });
- ($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ })
+ ($cond:expr) => {{ /* compiler built-in */ }};
+ ($cond:expr,) => {{ /* compiler built-in */ }};
+ ($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }};
}
/// Inline assembly.
/// Read the [unstable book] for the usage.
///
/// [unstable book]: ../unstable-book/library-features/asm.html
- #[unstable(feature = "asm", issue = "29722",
- reason = "inline assembly is not stable enough for use and is subject to change")]
+ #[unstable(
+ feature = "asm",
+ issue = "29722",
+ reason = "inline assembly is not stable enough for use and is subject to change"
+ )]
#[rustc_builtin_macro]
#[macro_export]
- macro_rules! asm { ("assembly template"
+ macro_rules! asm {
+ ("assembly template"
: $("output"(operand),)*
: $("input"(operand),)*
: $("clobbers",)*
- : $("options",)*) => { /* compiler built-in */ } }
+ : $("options",)*) => {
+ /* compiler built-in */
+ };
+ }
/// Module-level inline assembly.
- #[unstable(feature = "global_asm", issue = "35119",
- reason = "`global_asm!` is not stable enough for use and is subject to change")]
+ #[unstable(
+ feature = "global_asm",
+ issue = "35119",
+ reason = "`global_asm!` is not stable enough for use and is subject to change"
+ )]
#[rustc_builtin_macro]
#[macro_export]
- macro_rules! global_asm { ("assembly") => { /* compiler built-in */ } }
+ macro_rules! global_asm {
+ ("assembly") => {
+ /* compiler built-in */
+ };
+ }
/// Prints passed tokens into the standard output.
- #[unstable(feature = "log_syntax", issue = "29598",
- reason = "`log_syntax!` is not stable enough for use and is subject to change")]
+ #[unstable(
+ feature = "log_syntax",
+ issue = "29598",
+ reason = "`log_syntax!` is not stable enough for use and is subject to change"
+ )]
#[rustc_builtin_macro]
#[macro_export]
- macro_rules! log_syntax { ($($arg:tt)*) => { /* compiler built-in */ } }
+ macro_rules! log_syntax {
+ ($($arg:tt)*) => {
+ /* compiler built-in */
+ };
+ }
/// Enables or disables tracing functionality used for debugging other macros.
- #[unstable(feature = "trace_macros", issue = "29598",
- reason = "`trace_macros` is not stable enough for use and is subject to change")]
+ #[unstable(
+ feature = "trace_macros",
+ issue = "29598",
+ reason = "`trace_macros` is not stable enough for use and is subject to change"
+ )]
#[rustc_builtin_macro]
#[macro_export]
macro_rules! trace_macros {
- (true) => ({ /* compiler built-in */ });
- (false) => ({ /* compiler built-in */ })
+ (true) => {{ /* compiler built-in */ }};
+ (false) => {{ /* compiler built-in */ }};
}
/// Attribute macro applied to a function to turn it into a unit test.
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable(test, rustc_attrs)]
#[rustc_builtin_macro]
- pub macro test($item:item) { /* compiler built-in */ }
+ pub macro test($item:item) {
+ /* compiler built-in */
+ }
/// Attribute macro applied to a function to turn it into a benchmark test.
- #[unstable(soft, feature = "test", issue = "50297",
- reason = "`bench` is a part of custom test frameworks which are unstable")]
+ #[unstable(
+ feature = "test",
+ issue = "50297",
+ soft,
+ reason = "`bench` is a part of custom test frameworks which are unstable"
+ )]
#[allow_internal_unstable(test, rustc_attrs)]
#[rustc_builtin_macro]
- pub macro bench($item:item) { /* compiler built-in */ }
+ pub macro bench($item:item) {
+ /* compiler built-in */
+ }
/// An implementation detail of the `#[test]` and `#[bench]` macros.
- #[unstable(feature = "custom_test_frameworks", issue = "50297",
- reason = "custom test frameworks are an unstable feature")]
+ #[unstable(
+ feature = "custom_test_frameworks",
+ issue = "50297",
+ reason = "custom test frameworks are an unstable feature"
+ )]
#[allow_internal_unstable(test, rustc_attrs)]
#[rustc_builtin_macro]
- pub macro test_case($item:item) { /* compiler built-in */ }
+ pub macro test_case($item:item) {
+ /* compiler built-in */
+ }
/// Attribute macro applied to a static to register it as a global allocator.
#[stable(feature = "global_allocator", since = "1.28.0")]
#[allow_internal_unstable(rustc_attrs)]
#[rustc_builtin_macro]
- pub macro global_allocator($item:item) { /* compiler built-in */ }
+ pub macro global_allocator($item:item) {
+ /* compiler built-in */
+ }
/// Unstable implementation detail of the `rustc` compiler, do not use.
#[rustc_builtin_macro]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable(core_intrinsics, libstd_sys_internals)]
- pub macro RustcDecodable($item:item) { /* compiler built-in */ }
+ pub macro RustcDecodable($item:item) {
+ /* compiler built-in */
+ }
/// Unstable implementation detail of the `rustc` compiler, do not use.
#[rustc_builtin_macro]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable(core_intrinsics)]
- pub macro RustcEncodable($item:item) { /* compiler built-in */ }
+ pub macro RustcEncodable($item:item) {
+ /* compiler built-in */
+ }
}
-use crate::ptr;
use crate::ops::{Deref, DerefMut};
+use crate::ptr;
/// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
///
// This module is only for dec2flt and flt2dec, and only public because of coretests.
// It is not intended to ever be stabilized.
#![doc(hidden)]
-#![unstable(feature = "core_private_bignum",
- reason = "internal routines only exposed for testing",
- issue = "0")]
+#![unstable(
+ feature = "core_private_bignum",
+ reason = "internal routines only exposed for testing",
+ issue = "0"
+)]
#![macro_use]
-use crate::mem;
use crate::intrinsics;
+use crate::mem;
/// Arithmetic operations required by bignums.
pub trait FullOps: Sized {
/// Returns `(quo, rem)` such that `borrow * 2^W + self = quo * other + rem`
/// and `0 <= rem < other`, where `W` is the number of bits in `Self`.
- fn full_div_rem(self,
- other: Self,
- borrow: Self)
- -> (Self /* quotient */, Self /* remainder */);
+ fn full_div_rem(self, other: Self, borrow: Self)
+ -> (Self /* quotient */, Self /* remainder */);
}
macro_rules! impl_full_ops {
const SMALL_POW5: [(u64, usize); 3] = [(125, 3), (15625, 6), (1_220_703_125, 13)];
macro_rules! define_bignum {
- ($name:ident: type=$ty:ty, n=$n:expr) => (
+ ($name:ident: type=$ty:ty, n=$n:expr) => {
/// Stack-allocated arbitrary-precision (up to certain limit) integer.
///
/// This is backed by a fixed-size array of given type ("digit").
size: usize,
/// Digits. `[a, b, c, ...]` represents `a + b*2^W + c*2^(2W) + ...`
/// where `W` is the number of bits in the digit type.
- base: [$ty; $n]
+ base: [$ty; $n],
}
impl $name {
}
// This could be optimized with leading_zeros() and bit shifts, but that's
// probably not worth the hassle.
- let digitbits = mem::size_of::<$ty>()* 8;
+ let digitbits = mem::size_of::<$ty>() * 8;
let mut i = nonzero.len() * digitbits - 1;
while self.get_bit(i) == 0 {
i -= 1;
let bits = bits % digitbits;
assert!(digits < $n);
- debug_assert!(self.base[$n-digits..].iter().all(|&v| v == 0));
- debug_assert!(bits == 0 || (self.base[$n-digits-1] >> (digitbits - bits)) == 0);
+ debug_assert!(self.base[$n - digits..].iter().all(|&v| v == 0));
+ debug_assert!(bits == 0 || (self.base[$n - digits - 1] >> (digitbits - bits)) == 0);
// shift by `digits * digitbits` bits
for i in (0..self.size).rev() {
- self.base[i+digits] = self.base[i];
+ self.base[i + digits] = self.base[i];
}
for i in 0..digits {
self.base[i] = 0;
let mut sz = self.size + digits;
if bits > 0 {
let last = sz;
- let overflow = self.base[last-1] >> (digitbits - bits);
+ let overflow = self.base[last - 1] >> (digitbits - bits);
if overflow > 0 {
self.base[last] = overflow;
sz += 1;
}
- for i in (digits+1..last).rev() {
- self.base[i] = (self.base[i] << bits) |
- (self.base[i-1] >> (digitbits - bits));
+ for i in (digits + 1..last).rev() {
+ self.base[i] =
+ (self.base[i] << bits) | (self.base[i - 1] >> (digitbits - bits));
}
self.base[digits] <<= bits;
// self.base[..digits] is zero, no need to shift
self
}
-
/// Multiplies itself by a number described by `other[0] + other[1] * 2^W +
/// other[2] * 2^(2W) + ...` (where `W` is the number of bits in the digit type)
/// and returns its own mutable reference.
let mut retsz = 0;
for (i, &a) in aa.iter().enumerate() {
- if a == 0 { continue; }
+ if a == 0 {
+ continue;
+ }
let mut sz = bb.len();
let mut carry = 0;
for (j, &b) in bb.iter().enumerate() {
}
impl crate::cmp::PartialEq for $name {
- fn eq(&self, other: &$name) -> bool { self.base[..] == other.base[..] }
+ fn eq(&self, other: &$name) -> bool {
+ self.base[..] == other.base[..]
+ }
}
- impl crate::cmp::Eq for $name {
- }
+ impl crate::cmp::Eq for $name {}
impl crate::cmp::PartialOrd for $name {
fn partial_cmp(&self, other: &$name) -> crate::option::Option<crate::cmp::Ordering> {
fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result {
use crate::mem;
- let sz = if self.size < 1 {1} else {self.size};
+ let sz = if self.size < 1 { 1 } else { self.size };
let digitlen = mem::size_of::<$ty>() * 2;
- write!(f, "{:#x}", self.base[sz-1])?;
- for &v in self.base[..sz-1].iter().rev() {
+ write!(f, "{:#x}", self.base[sz - 1])?;
+ for &v in self.base[..sz - 1].iter().rev() {
write!(f, "_{:01$x}", v, digitlen)?;
}
crate::result::Result::Ok(())
}
}
- )
+ };
}
/// The digit type for `Big32x40`.
//! The various algorithms from the paper.
use crate::cmp::min;
-use crate::cmp::Ordering::{Less, Equal, Greater};
-use crate::num::diy_float::Fp;
-use crate::num::dec2flt::table;
-use crate::num::dec2flt::rawfp::{self, Unpacked, RawFloat, fp_to_float, next_float, prev_float};
+use crate::cmp::Ordering::{Equal, Greater, Less};
use crate::num::dec2flt::num::{self, Big};
+use crate::num::dec2flt::rawfp::{self, fp_to_float, next_float, prev_float, RawFloat, Unpacked};
+use crate::num::dec2flt::table;
+use crate::num::diy_float::Fp;
/// Number of significand bits in Fp
const P: u32 = 64;
// In most architectures, floating point operations have an explicit bit size, therefore the
// precision of the computation is determined on a per-operation basis.
-#[cfg(any(not(target_arch="x86"), target_feature="sse2"))]
+#[cfg(any(not(target_arch = "x86"), target_feature = "sse2"))]
mod fpu_precision {
- pub fn set_precision<T>() { }
+ pub fn set_precision<T>() {}
}
// On x86, the x87 FPU is used for float operations if the SSE/SSE2 extensions are not available.
// round to 80 bits causing double rounding to happen when values are eventually represented as
// 32/64 bit float values. To overcome this, the FPU control word can be set so that the
// computations are performed in the desired precision.
-#[cfg(all(target_arch="x86", not(target_feature="sse2")))]
+#[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
mod fpu_precision {
use crate::mem::size_of;
//! turned into {positive,negative} {zero,infinity}.
#![doc(hidden)]
-#![unstable(feature = "dec2flt",
- reason = "internal routines only exposed for testing",
- issue = "0")]
+#![unstable(
+ feature = "dec2flt",
+ reason = "internal routines only exposed for testing",
+ issue = "0"
+)]
use crate::fmt;
use crate::str::FromStr;
-use self::parse::{parse_decimal, Decimal, Sign, ParseResult};
use self::num::digits_to_big;
+use self::parse::{parse_decimal, Decimal, ParseResult, Sign};
use self::rawfp::RawFloat;
mod algorithm;
-mod table;
mod num;
+mod table;
// These two have their own tests.
-pub mod rawfp;
pub mod parse;
+pub mod rawfp;
macro_rules! from_str_float_impl {
($t:ty) => {
dec2flt(src)
}
}
- }
+ };
}
from_str_float_impl!(f32);
from_str_float_impl!(f64);
#[derive(Debug, Clone, PartialEq, Eq)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct ParseFloatError {
- kind: FloatErrorKind
+ kind: FloatErrorKind,
}
#[derive(Debug, Clone, PartialEq, Eq)]
}
impl ParseFloatError {
- #[unstable(feature = "int_error_internals",
- reason = "available through Error trait and this method should \
- not be exposed publicly",
- issue = "0")]
+ #[unstable(
+ feature = "int_error_internals",
+ reason = "available through Error trait and this method should \
+ not be exposed publicly",
+ issue = "0"
+ )]
#[doc(hidden)]
pub fn __description(&self) -> &str {
match self.kind {
/// Converts a decimal string into a floating point number.
fn dec2flt<T: RawFloat>(s: &str) -> Result<T, ParseFloatError> {
if s.is_empty() {
- return Err(pfe_empty())
+ return Err(pfe_empty());
}
let (sign, s) = extract_sign(s);
let flt = match parse_decimal(s) {
ParseResult::Invalid => match s {
"inf" => T::INFINITY,
"NaN" => T::NAN,
- _ => { return Err(pfe_invalid()); }
- }
+ _ => {
+ return Err(pfe_invalid());
+ }
+ },
};
match sign {
// FIXME This module's name is a bit unfortunate, since other modules also import `core::num`.
-use crate::cmp::Ordering::{self, Less, Equal, Greater};
+use crate::cmp::Ordering::{self, Equal, Greater, Less};
pub use crate::num::bignum::Big32x40 as Big;
/// 1. using `FromStr` on `&[u8]` requires `from_utf8_unchecked`, which is bad, and
/// 2. piecing together the results of `integral.parse()` and `fractional.parse()` is
/// more complicated than this entire function.
-pub fn from_str_unchecked<'a, T>(bytes: T) -> u64 where T : IntoIterator<Item=&'a u8> {
+pub fn from_str_unchecked<'a, T>(bytes: T) -> u64
+where
+ T: IntoIterator<Item = &'a u8>,
+{
let mut result = 0;
for &c in bytes {
result = result * 10 + (c - b'0') as u64;
pub fn to_u64(x: &Big) -> u64 {
assert!(x.bit_length() < 64);
let d = x.digits();
- if d.len() < 2 {
- d[0] as u64
- } else {
- (d[1] as u64) << 32 | d[0] as u64
- }
+ if d.len() < 2 { d[0] as u64 } else { (d[1] as u64) << 32 | d[0] as u64 }
}
-
/// Extracts a range of bits.
/// Index 0 is the least significant bit and the range is half-open as usual.
//! modules rely on to not panic (or overflow) in turn.
//! To make matters worse, all that happens in a single pass over the input.
//! So, be careful when modifying anything, and double-check with the other modules.
+use self::ParseResult::{Invalid, ShortcutToInf, ShortcutToZero, Valid};
use super::num;
-use self::ParseResult::{Valid, ShortcutToInf, ShortcutToZero, Invalid};
#[derive(Debug)]
pub enum Sign {
//! Many functions in this module only handle normal numbers. The dec2flt routines conservatively
//! take the universally-correct slow path (Algorithm M) for very small and very large numbers.
//! That algorithm needs only next_float() which does handle subnormals and zeros.
-use crate::cmp::Ordering::{Less, Equal, Greater};
+use crate::cmp::Ordering::{Equal, Greater, Less};
use crate::convert::{TryFrom, TryInto};
-use crate::ops::{Add, Mul, Div, Neg};
use crate::fmt::{Debug, LowerExp};
-use crate::num::diy_float::Fp;
-use crate::num::FpCategory::{Infinite, Zero, Subnormal, Normal, Nan};
-use crate::num::FpCategory;
use crate::num::dec2flt::num::{self, Big};
use crate::num::dec2flt::table;
+use crate::num::diy_float::Fp;
+use crate::num::FpCategory;
+use crate::num::FpCategory::{Infinite, Nan, Normal, Subnormal, Zero};
+use crate::ops::{Add, Div, Mul, Neg};
#[derive(Copy, Clone, Debug)]
pub struct Unpacked {
/// See the parent module's doc comment for why this is necessary.
///
/// Should **never ever** be implemented for other types or be used outside the dec2flt module.
-pub trait RawFloat
- : Copy
- + Debug
- + LowerExp
- + Mul<Output=Self>
- + Div<Output=Self>
- + Neg<Output=Self>
+pub trait RawFloat:
+ Copy + Debug + LowerExp + Mul<Output = Self> + Div<Output = Self> + Neg<Output = Self>
{
const INFINITY: Self;
const NAN: Self;
const INFINITY: Self = $crate::$type::INFINITY;
const NAN: Self = $crate::$type::NAN;
const ZERO: Self = 0.0;
- }
+ };
}
impl RawFloat for f32 {
let bits = self.to_bits();
let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 };
let mut exponent: i16 = ((bits >> 23) & 0xff) as i16;
- let mantissa = if exponent == 0 {
- (bits & 0x7fffff) << 1
- } else {
- (bits & 0x7fffff) | 0x800000
- };
+ let mantissa =
+ if exponent == 0 { (bits & 0x7fffff) << 1 } else { (bits & 0x7fffff) | 0x800000 };
// Exponent bias + mantissa shift
exponent -= 127 + 23;
(mantissa as u64, exponent, sign)
table::F32_SHORT_POWERS[e]
}
- fn classify(self) -> FpCategory { self.classify() }
- fn to_bits(self) -> Self::Bits { self.to_bits() }
- fn from_bits(v: Self::Bits) -> Self { Self::from_bits(v) }
+ fn classify(self) -> FpCategory {
+ self.classify()
+ }
+ fn to_bits(self) -> Self::Bits {
+ self.to_bits()
+ }
+ fn from_bits(v: Self::Bits) -> Self {
+ Self::from_bits(v)
+ }
}
-
impl RawFloat for f64 {
type Bits = u64;
table::F64_SHORT_POWERS[e]
}
- fn classify(self) -> FpCategory { self.classify() }
- fn to_bits(self) -> Self::Bits { self.to_bits() }
- fn from_bits(v: Self::Bits) -> Self { Self::from_bits(v) }
+ fn classify(self) -> FpCategory {
+ self.classify()
+ }
+ fn to_bits(self) -> Self::Bits {
+ self.to_bits()
+ }
+ fn from_bits(v: Self::Bits) -> Self {
+ Self::from_bits(v)
+ }
}
/// Converts an `Fp` to the closest machine float type.
let e = x.e + 63;
if e > T::MAX_EXP {
panic!("fp_to_float: exponent {} too large", e)
- } else if e > T::MIN_EXP {
+ } else if e > T::MIN_EXP {
encode_normal(round_normal::<T>(x))
} else {
panic!("fp_to_float: exponent {} too small", e)
/// Inverse of `RawFloat::unpack()` for normalized numbers.
/// Panics if the significand or exponent are not valid for normalized numbers.
pub fn encode_normal<T: RawFloat>(x: Unpacked) -> T {
- debug_assert!(T::MIN_SIG <= x.sig && x.sig <= T::MAX_SIG,
- "encode_normal: significand not normalized");
+ debug_assert!(
+ T::MIN_SIG <= x.sig && x.sig <= T::MAX_SIG,
+ "encode_normal: significand not normalized"
+ );
// Remove the hidden bit
let sig_enc = x.sig & !(1 << T::EXPLICIT_SIG_BITS);
// Adjust the exponent for exponent bias and mantissa shift
let k_enc = x.k + T::MAX_EXP + T::EXPLICIT_SIG_BITS as i16;
- debug_assert!(k_enc != 0 && k_enc < T::MAX_ENCODED_EXP,
- "encode_normal: exponent out of range");
+ debug_assert!(k_enc != 0 && k_enc < T::MAX_ENCODED_EXP, "encode_normal: exponent out of range");
// Leave sign bit at 0 ("+"), our numbers are all positive
let bits = (k_enc as u64) << T::EXPLICIT_SIG_BITS | sig_enc;
T::from_bits(bits.try_into().unwrap_or_else(|_| unreachable!()))
Equal | Greater => match leading.checked_add(1) {
Some(f) => Fp { f, e }.normalize(),
None => Fp { f: 1 << 63, e: e + 1 },
- }
+ },
}
}
// want, and the mantissa bits become zero. Because of the hidden bit convention, this
// too is exactly what we want!
// Finally, f64::MAX + 1 = 7eff...f + 1 = 7ff0...0 = f64::INFINITY.
- Zero | Subnormal | Normal => {
- T::from_bits(x.to_bits() + T::Bits::from(1u8))
- }
+ Zero | Subnormal | Normal => T::from_bits(x.to_bits() + T::Bits::from(1u8)),
}
}
// This module is only for dec2flt and flt2dec, and only public because of coretests.
// It is not intended to ever be stabilized.
#![doc(hidden)]
-#![unstable(feature = "core_private_diy_float",
- reason = "internal routines only exposed for testing",
- issue = "0")]
+#![unstable(
+ feature = "core_private_diy_float",
+ reason = "internal routines only exposed for testing",
+ issue = "0"
+)]
/// A custom 64-bit floating point type, representing `f * 2^e`.
#[derive(Copy, Clone, Debug)]
assert!(edelta >= 0);
let edelta = edelta as usize;
assert_eq!(self.f << edelta >> edelta, self.f);
- Fp {
- f: self.f << edelta,
- e,
- }
+ Fp { f: self.f << edelta, e }
}
}
//! Decodes a floating-point value into individual parts and error ranges.
-use crate::{f32, f64};
-use crate::num::FpCategory;
use crate::num::dec2flt::rawfp::RawFloat;
+use crate::num::FpCategory;
+use crate::{f32, f64};
/// Decoded unsigned finite value, such that:
///
}
impl DecodableFloat for f32 {
- fn min_pos_norm_value() -> Self { f32::MIN_POSITIVE }
+ fn min_pos_norm_value() -> Self {
+ f32::MIN_POSITIVE
+ }
}
impl DecodableFloat for f64 {
- fn min_pos_norm_value() -> Self { f64::MIN_POSITIVE }
+ fn min_pos_norm_value() -> Self {
+ f64::MIN_POSITIVE
+ }
}
/// Returns a sign (true when negative) and `FullDecoded` value
// neighbors: (mant - 2, exp) -- (mant, exp) -- (mant + 2, exp)
// Float::integer_decode always preserves the exponent,
// so the mantissa is scaled for subnormals.
- FullDecoded::Finite(Decoded { mant, minus: 1, plus: 1,
- exp, inclusive: even })
+ FullDecoded::Finite(Decoded { mant, minus: 1, plus: 1, exp, inclusive: even })
}
FpCategory::Normal => {
let minnorm = <T as DecodableFloat>::min_pos_norm_value().integer_decode();
if mant == minnorm.0 {
// neighbors: (maxmant, exp - 1) -- (minnormmant, exp) -- (minnormmant + 1, exp)
// where maxmant = minnormmant * 2 - 1
- FullDecoded::Finite(Decoded { mant: mant << 2, minus: 1, plus: 2,
- exp: exp - 2, inclusive: even })
+ FullDecoded::Finite(Decoded {
+ mant: mant << 2,
+ minus: 1,
+ plus: 2,
+ exp: exp - 2,
+ inclusive: even,
+ })
} else {
// neighbors: (mant - 1, exp) -- (mant, exp) -- (mant + 1, exp)
- FullDecoded::Finite(Decoded { mant: mant << 1, minus: 1, plus: 1,
- exp: exp - 1, inclusive: even })
+ FullDecoded::Finite(Decoded {
+ mant: mant << 1,
+ minus: 1,
+ plus: 1,
+ exp: exp - 1,
+ inclusive: even,
+ })
}
}
};
// while this is extensively documented, this is in principle private which is
// only made public for testing. do not expose us.
#![doc(hidden)]
-#![unstable(feature = "flt2dec",
- reason = "internal routines only exposed for testing",
- issue = "0")]
+#![unstable(
+ feature = "flt2dec",
+ reason = "internal routines only exposed for testing",
+ issue = "0"
+)]
+pub use self::decoder::{decode, DecodableFloat, Decoded, FullDecoded};
use crate::i16;
-pub use self::decoder::{decode, DecodableFloat, FullDecoded, Decoded};
-pub mod estimator;
pub mod decoder;
+pub mod estimator;
/// Digit-generation algorithms.
pub mod strategy {
#[doc(hidden)]
pub fn round_up(d: &mut [u8], n: usize) -> Option<u8> {
match d[..n].iter().rposition(|&c| c != b'9') {
- Some(i) => { // d[i+1..n] is all nines
+ Some(i) => {
+ // d[i+1..n] is all nines
d[i] += 1;
- for j in i+1..n { d[j] = b'0'; }
+ for j in i + 1..n {
+ d[j] = b'0';
+ }
None
}
- None if n > 0 => { // 999..999 rounds to 1000..000 with an increased exponent
+ None if n > 0 => {
+ // 999..999 rounds to 1000..000 with an increased exponent
d[0] = b'1';
- for j in 1..n { d[j] = b'0'; }
+ for j in 1..n {
+ d[j] = b'0';
+ }
Some(b'0')
}
- None => { // an empty buffer rounds up (a bit strange but reasonable)
+ None => {
+ // an empty buffer rounds up (a bit strange but reasonable)
Some(b'1')
}
}
pub fn len(&self) -> usize {
match *self {
Part::Zero(nzeroes) => nzeroes,
- Part::Num(v) => if v < 1_000 { if v < 10 { 1 } else if v < 100 { 2 } else { 3 } }
- else { if v < 10_000 { 4 } else { 5 } },
+ Part::Num(v) => {
+ if v < 1_000 {
+ if v < 10 {
+ 1
+ } else if v < 100 {
+ 2
+ } else {
+ 3
+ }
+ } else {
+ if v < 10_000 { 4 } else { 5 }
+ }
+ }
Part::Copy(buf) => buf.len(),
}
}
if out.len() >= len {
match *self {
Part::Zero(nzeroes) => {
- for c in &mut out[..nzeroes] { *c = b'0'; }
+ for c in &mut out[..nzeroes] {
+ *c = b'0';
+ }
}
Part::Num(mut v) => {
for c in out[..len].iter_mut().rev() {
/// Returns the number of written bytes, or `None` if the buffer is not enough.
/// (It may still leave partially written bytes in the buffer; do not rely on that.)
pub fn write(&self, out: &mut [u8]) -> Option<usize> {
- if out.len() < self.sign.len() { return None; }
+ if out.len() < self.sign.len() {
+ return None;
+ }
out[..self.sign.len()].copy_from_slice(self.sign);
let mut written = self.sign.len();
/// it will be ignored and full digits will be printed. It is only used to print
/// additional zeroes after rendered digits. Thus `frac_digits` of 0 means that
/// it will only print given digits and nothing else.
-fn digits_to_dec_str<'a>(buf: &'a [u8], exp: i16, frac_digits: usize,
- parts: &'a mut [Part<'a>]) -> &'a [Part<'a>] {
+fn digits_to_dec_str<'a>(
+ buf: &'a [u8],
+ exp: i16,
+ frac_digits: usize,
+ parts: &'a mut [Part<'a>],
+) -> &'a [Part<'a>] {
assert!(!buf.is_empty());
assert!(buf[0] > b'0');
assert!(parts.len() >= 4);
/// it will be ignored and full digits will be printed. It is only used to print
/// additional zeroes after rendered digits. Thus, `min_digits == 0` means that
/// it will only print the given digits and nothing else.
-fn digits_to_exp_str<'a>(buf: &'a [u8], exp: i16, min_ndigits: usize, upper: bool,
- parts: &'a mut [Part<'a>]) -> &'a [Part<'a>] {
+fn digits_to_exp_str<'a>(
+ buf: &'a [u8],
+ exp: i16,
+ min_ndigits: usize,
+ upper: bool,
+ parts: &'a mut [Part<'a>],
+) -> &'a [Part<'a>] {
assert!(!buf.is_empty());
assert!(buf[0] > b'0');
assert!(parts.len() >= 6);
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum Sign {
/// Prints `-` only for the negative non-zero values.
- Minus, // -inf -1 0 0 1 inf nan
+ Minus, // -inf -1 0 0 1 inf nan
/// Prints `-` only for any negative values (including the negative zero).
- MinusRaw, // -inf -1 -0 0 1 inf nan
+ MinusRaw, // -inf -1 -0 0 1 inf nan
/// Prints `-` for the negative non-zero values, or `+` otherwise.
- MinusPlus, // -inf -1 +0 +0 +1 +inf nan
+ MinusPlus, // -inf -1 +0 +0 +1 +inf nan
/// Prints `-` for any negative values (including the negative zero), or `+` otherwise.
MinusPlusRaw, // -inf -1 -0 +0 +1 +inf nan
}
match (*decoded, sign) {
(FullDecoded::Nan, _) => b"",
(FullDecoded::Zero, Sign::Minus) => b"",
- (FullDecoded::Zero, Sign::MinusRaw) => if negative { b"-" } else { b"" },
+ (FullDecoded::Zero, Sign::MinusRaw) => {
+ if negative {
+ b"-"
+ } else {
+ b""
+ }
+ }
(FullDecoded::Zero, Sign::MinusPlus) => b"+",
- (FullDecoded::Zero, Sign::MinusPlusRaw) => if negative { b"-" } else { b"+" },
- (_, Sign::Minus) | (_, Sign::MinusRaw) => if negative { b"-" } else { b"" },
- (_, Sign::MinusPlus) | (_, Sign::MinusPlusRaw) => if negative { b"-" } else { b"+" },
+ (FullDecoded::Zero, Sign::MinusPlusRaw) => {
+ if negative {
+ b"-"
+ } else {
+ b"+"
+ }
+ }
+ (_, Sign::Minus) | (_, Sign::MinusRaw) => {
+ if negative {
+ b"-"
+ } else {
+ b""
+ }
+ }
+ (_, Sign::MinusPlus) | (_, Sign::MinusPlusRaw) => {
+ if negative {
+ b"-"
+ } else {
+ b"+"
+ }
+ }
}
}
/// The byte buffer should be at least `MAX_SIG_DIGITS` bytes long.
/// There should be at least 4 parts available, due to the worst case like
/// `[+][0.][0000][2][0000]` with `frac_digits = 10`.
-pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T,
- sign: Sign, frac_digits: usize, _upper: bool,
- buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a>
- where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
+pub fn to_shortest_str<'a, T, F>(
+ mut format_shortest: F,
+ v: T,
+ sign: Sign,
+ frac_digits: usize,
+ _upper: bool,
+ buf: &'a mut [u8],
+ parts: &'a mut [Part<'a>],
+) -> Formatted<'a>
+where
+ T: DecodableFloat,
+ F: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+{
assert!(parts.len() >= 4);
assert!(buf.len() >= MAX_SIG_DIGITS);
Formatted { sign, parts: &parts[..1] }
}
FullDecoded::Zero => {
- if frac_digits > 0 { // [0.][0000]
+ if frac_digits > 0 {
+ // [0.][0000]
parts[0] = Part::Copy(b"0.");
parts[1] = Part::Zero(frac_digits);
Formatted { sign, parts: &parts[..2] }
}
FullDecoded::Finite(ref decoded) => {
let (len, exp) = format_shortest(decoded, buf);
- Formatted { sign,
- parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) }
+ Formatted { sign, parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) }
}
}
}
/// The byte buffer should be at least `MAX_SIG_DIGITS` bytes long.
/// There should be at least 6 parts available, due to the worst case like
/// `[+][1][.][2345][e][-][6]`.
-pub fn to_shortest_exp_str<'a, T, F>(mut format_shortest: F, v: T,
- sign: Sign, dec_bounds: (i16, i16), upper: bool,
- buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a>
- where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
+pub fn to_shortest_exp_str<'a, T, F>(
+ mut format_shortest: F,
+ v: T,
+ sign: Sign,
+ dec_bounds: (i16, i16),
+ upper: bool,
+ buf: &'a mut [u8],
+ parts: &'a mut [Part<'a>],
+) -> Formatted<'a>
+where
+ T: DecodableFloat,
+ F: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+{
assert!(parts.len() >= 6);
assert!(buf.len() >= MAX_SIG_DIGITS);
assert!(dec_bounds.0 <= dec_bounds.1);
/// (The tipping point for `f64` is about 800, so 1000 bytes should be enough.)
/// There should be at least 6 parts available, due to the worst case like
/// `[+][1][.][2345][e][-][6]`.
-pub fn to_exact_exp_str<'a, T, F>(mut format_exact: F, v: T,
- sign: Sign, ndigits: usize, upper: bool,
- buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a>
- where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
+pub fn to_exact_exp_str<'a, T, F>(
+ mut format_exact: F,
+ v: T,
+ sign: Sign,
+ ndigits: usize,
+ upper: bool,
+ buf: &'a mut [u8],
+ parts: &'a mut [Part<'a>],
+) -> Formatted<'a>
+where
+ T: DecodableFloat,
+ F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16),
+{
assert!(parts.len() >= 6);
assert!(ndigits > 0);
Formatted { sign, parts: &parts[..1] }
}
FullDecoded::Zero => {
- if ndigits > 1 { // [0.][0000][e0]
+ if ndigits > 1 {
+ // [0.][0000][e0]
parts[0] = Part::Copy(b"0.");
parts[1] = Part::Zero(ndigits - 1);
parts[2] = Part::Copy(if upper { b"E0" } else { b"e0" });
let trunc = if ndigits < maxlen { ndigits } else { maxlen };
let (len, exp) = format_exact(decoded, &mut buf[..trunc], i16::MIN);
- Formatted { sign,
- parts: digits_to_exp_str(&buf[..len], exp, ndigits, upper, parts) }
+ Formatted { sign, parts: digits_to_exp_str(&buf[..len], exp, ndigits, upper, parts) }
}
}
}
/// (The tipping point for `f64` is about 800, and 1000 bytes should be enough.)
/// There should be at least 4 parts available, due to the worst case like
/// `[+][0.][0000][2][0000]` with `frac_digits = 10`.
-pub fn to_exact_fixed_str<'a, T, F>(mut format_exact: F, v: T,
- sign: Sign, frac_digits: usize, _upper: bool,
- buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a>
- where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
+pub fn to_exact_fixed_str<'a, T, F>(
+ mut format_exact: F,
+ v: T,
+ sign: Sign,
+ frac_digits: usize,
+ _upper: bool,
+ buf: &'a mut [u8],
+ parts: &'a mut [Part<'a>],
+) -> Formatted<'a>
+where
+ T: DecodableFloat,
+ F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16),
+{
assert!(parts.len() >= 4);
let (negative, full_decoded) = decode(v);
Formatted { sign, parts: &parts[..1] }
}
FullDecoded::Zero => {
- if frac_digits > 0 { // [0.][0000]
+ if frac_digits > 0 {
+ // [0.][0000]
parts[0] = Part::Copy(b"0.");
parts[1] = Part::Zero(frac_digits);
Formatted { sign, parts: &parts[..2] }
// `exp` was. this does not include the case that the restriction has been met
// only after the final rounding-up; it's a regular case with `exp = limit + 1`.
debug_assert_eq!(len, 0);
- if frac_digits > 0 { // [0.][0000]
+ if frac_digits > 0 {
+ // [0.][0000]
parts[0] = Part::Copy(b"0.");
parts[1] = Part::Zero(frac_digits);
Formatted { sign, parts: &parts[..2] }
Formatted { sign, parts: &parts[..1] }
}
} else {
- Formatted { sign,
- parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) }
+ Formatted { sign, parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) }
}
}
}
use crate::cmp::Ordering;
-use crate::num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
-use crate::num::flt2dec::estimator::estimate_scaling_factor;
-use crate::num::bignum::Digit32 as Digit;
use crate::num::bignum::Big32x40 as Big;
+use crate::num::bignum::Digit32 as Digit;
+use crate::num::flt2dec::estimator::estimate_scaling_factor;
+use crate::num::flt2dec::{round_up, Decoded, MAX_SIG_DIGITS};
-static POW10: [Digit; 10] = [1, 10, 100, 1000, 10000, 100000,
- 1000000, 10000000, 100000000, 1000000000];
-static TWOPOW10: [Digit; 10] = [2, 20, 200, 2000, 20000, 200000,
- 2000000, 20000000, 200000000, 2000000000];
+static POW10: [Digit; 10] =
+ [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000];
+static TWOPOW10: [Digit; 10] =
+ [2, 20, 200, 2000, 20000, 200000, 2000000, 20000000, 200000000, 2000000000];
// precalculated arrays of `Digit`s for 10^(2^n)
static POW10TO16: [Digit; 2] = [0x6fc10000, 0x2386f2];
static POW10TO32: [Digit; 4] = [0, 0x85acef81, 0x2d6d415b, 0x4ee];
static POW10TO64: [Digit; 7] = [0, 0, 0xbf6a1f01, 0x6e38ed64, 0xdaa797ed, 0xe93ff9f4, 0x184f03];
-static POW10TO128: [Digit; 14] =
- [0, 0, 0, 0, 0x2e953e01, 0x3df9909, 0xf1538fd, 0x2374e42f, 0xd3cff5ec, 0xc404dc08,
- 0xbccdb0da, 0xa6337f19, 0xe91f2603, 0x24e];
-static POW10TO256: [Digit; 27] =
- [0, 0, 0, 0, 0, 0, 0, 0, 0x982e7c01, 0xbed3875b, 0xd8d99f72, 0x12152f87, 0x6bde50c6,
- 0xcf4a6e70, 0xd595d80f, 0x26b2716e, 0xadc666b0, 0x1d153624, 0x3c42d35a, 0x63ff540e,
- 0xcc5573c0, 0x65f9ef17, 0x55bc28f2, 0x80dcc7f7, 0xf46eeddc, 0x5fdcefce, 0x553f7];
+static POW10TO128: [Digit; 14] = [
+ 0, 0, 0, 0, 0x2e953e01, 0x3df9909, 0xf1538fd, 0x2374e42f, 0xd3cff5ec, 0xc404dc08, 0xbccdb0da,
+ 0xa6337f19, 0xe91f2603, 0x24e,
+];
+static POW10TO256: [Digit; 27] = [
+ 0, 0, 0, 0, 0, 0, 0, 0, 0x982e7c01, 0xbed3875b, 0xd8d99f72, 0x12152f87, 0x6bde50c6, 0xcf4a6e70,
+ 0xd595d80f, 0x26b2716e, 0xadc666b0, 0x1d153624, 0x3c42d35a, 0x63ff540e, 0xcc5573c0, 0x65f9ef17,
+ 0x55bc28f2, 0x80dcc7f7, 0xf46eeddc, 0x5fdcefce, 0x553f7,
+];
#[doc(hidden)]
pub fn mul_pow10(x: &mut Big, n: usize) -> &mut Big {
debug_assert!(n < 512);
- if n & 7 != 0 { x.mul_small(POW10[n & 7]); }
- if n & 8 != 0 { x.mul_small(POW10[8]); }
- if n & 16 != 0 { x.mul_digits(&POW10TO16); }
- if n & 32 != 0 { x.mul_digits(&POW10TO32); }
- if n & 64 != 0 { x.mul_digits(&POW10TO64); }
- if n & 128 != 0 { x.mul_digits(&POW10TO128); }
- if n & 256 != 0 { x.mul_digits(&POW10TO256); }
+ if n & 7 != 0 {
+ x.mul_small(POW10[n & 7]);
+ }
+ if n & 8 != 0 {
+ x.mul_small(POW10[8]);
+ }
+ if n & 16 != 0 {
+ x.mul_digits(&POW10TO16);
+ }
+ if n & 32 != 0 {
+ x.mul_digits(&POW10TO32);
+ }
+ if n & 64 != 0 {
+ x.mul_digits(&POW10TO64);
+ }
+ if n & 128 != 0 {
+ x.mul_digits(&POW10TO128);
+ }
+ if n & 256 != 0 {
+ x.mul_digits(&POW10TO256);
+ }
x
}
}
// only usable when `x < 16 * scale`; `scaleN` should be `scale.mul_small(N)`
-fn div_rem_upto_16<'a>(x: &'a mut Big, scale: &Big,
- scale2: &Big, scale4: &Big, scale8: &Big) -> (u8, &'a mut Big) {
+fn div_rem_upto_16<'a>(
+ x: &'a mut Big,
+ scale: &Big,
+ scale2: &Big,
+ scale4: &Big,
+ scale8: &Big,
+) -> (u8, &'a mut Big) {
let mut d = 0;
- if *x >= *scale8 { x.sub(scale8); d += 8; }
- if *x >= *scale4 { x.sub(scale4); d += 4; }
- if *x >= *scale2 { x.sub(scale2); d += 2; }
- if *x >= *scale { x.sub(scale); d += 1; }
+ if *x >= *scale8 {
+ x.sub(scale8);
+ d += 8;
+ }
+ if *x >= *scale4 {
+ x.sub(scale4);
+ d += 4;
+ }
+ if *x >= *scale2 {
+ x.sub(scale2);
+ d += 2;
+ }
+ if *x >= *scale {
+ x.sub(scale);
+ d += 1;
+ }
debug_assert!(*x < *scale);
(d, x)
}
assert!(buf.len() >= MAX_SIG_DIGITS);
// `a.cmp(&b) < rounding` is `if d.inclusive {a <= b} else {a < b}`
- let rounding = if d.inclusive {Ordering::Greater} else {Ordering::Equal};
+ let rounding = if d.inclusive { Ordering::Greater } else { Ordering::Equal };
// estimate `k_0` from original inputs satisfying `10^(k_0-1) < high <= 10^(k_0+1)`.
// the tight bound `k` satisfying `10^(k-1) < high <= 10^k` is calculated later.
}
// cache `(2, 4, 8) * scale` for digit generation.
- let mut scale2 = scale.clone(); scale2.mul_pow2(1);
- let mut scale4 = scale.clone(); scale4.mul_pow2(2);
- let mut scale8 = scale.clone(); scale8.mul_pow2(3);
+ let mut scale2 = scale.clone();
+ scale2.mul_pow2(1);
+ let mut scale4 = scale.clone();
+ scale4.mul_pow2(2);
+ let mut scale8 = scale.clone();
+ scale8.mul_pow2(3);
let mut down;
let mut up;
// - keep generating otherwise.
down = mant.cmp(&minus) < rounding;
up = scale.cmp(mant.clone().add(&plus)) < rounding;
- if down || up { break; } // we have the shortest representation, proceed to the rounding
+ if down || up {
+ break;
+ } // we have the shortest representation, proceed to the rounding
// restore the invariants.
// this makes the algorithm always terminating: `minus` and `plus` always increases,
if len > 0 {
// cache `(2, 4, 8) * scale` for digit generation.
// (this can be expensive, so do not calculate them when the buffer is empty.)
- let mut scale2 = scale.clone(); scale2.mul_pow2(1);
- let mut scale4 = scale.clone(); scale4.mul_pow2(2);
- let mut scale8 = scale.clone(); scale8.mul_pow2(3);
+ let mut scale2 = scale.clone();
+ scale2.mul_pow2(1);
+ let mut scale4 = scale.clone();
+ scale4.mul_pow2(2);
+ let mut scale8 = scale.clone();
+ scale8.mul_pow2(3);
for i in 0..len {
- if mant.is_zero() { // following digits are all zeroes, we stop here
+ if mant.is_zero() {
+ // following digits are all zeroes, we stop here
// do *not* try to perform rounding! rather, fill remaining digits.
- for c in &mut buf[i..len] { *c = b'0'; }
+ for c in &mut buf[i..len] {
+ *c = b'0';
+ }
return (len, k);
}
let mut d = 0;
- if mant >= scale8 { mant.sub(&scale8); d += 8; }
- if mant >= scale4 { mant.sub(&scale4); d += 4; }
- if mant >= scale2 { mant.sub(&scale2); d += 2; }
- if mant >= scale { mant.sub(&scale); d += 1; }
+ if mant >= scale8 {
+ mant.sub(&scale8);
+ d += 8;
+ }
+ if mant >= scale4 {
+ mant.sub(&scale4);
+ d += 4;
+ }
+ if mant >= scale2 {
+ mant.sub(&scale2);
+ d += 2;
+ }
+ if mant >= scale {
+ mant.sub(&scale);
+ d += 1;
+ }
debug_assert!(mant < scale);
debug_assert!(d < 10);
buf[i] = b'0' + d;
// if the following digits are exactly 5000..., check the prior digit and try to
// round to even (i.e., avoid rounding up when the prior digit is even).
let order = mant.cmp(scale.mul_small(5));
- if order == Ordering::Greater || (order == Ordering::Equal &&
- (len == 0 || buf[len-1] & 1 == 1)) {
+ if order == Ordering::Greater
+ || (order == Ordering::Equal && (len == 0 || buf[len - 1] & 1 == 1))
+ {
// if rounding up changes the length, the exponent should also change.
// but we've been requested a fixed number of digits, so do not alter the buffer...
if let Some(c) = round_up(buf, len) {
//! accurately with integers. SIGPLAN Not. 45, 6 (June 2010), 233-243.
use crate::num::diy_float::Fp;
-use crate::num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
-
+use crate::num::flt2dec::{round_up, Decoded, MAX_SIG_DIGITS};
// see the comments in `format_shortest_opt` for the rationale.
-#[doc(hidden)] pub const ALPHA: i16 = -60;
-#[doc(hidden)] pub const GAMMA: i16 = -32;
+#[doc(hidden)]
+pub const ALPHA: i16 = -60;
+#[doc(hidden)]
+pub const GAMMA: i16 = -32;
/*
# the following Python code generates this table:
*/
#[doc(hidden)]
-pub static CACHED_POW10: [(u64, i16, i16); 81] = [ // (f, e, k)
+pub static CACHED_POW10: [(u64, i16, i16); 81] = [
+ // (f, e, k)
(0xe61acf033d1a45df, -1087, -308),
(0xab70fe17c79ac6ca, -1060, -300),
(0xff77b1fcbebcdc4f, -1034, -292),
(0xbe5691ef416bd60c, -1007, -284),
- (0x8dd01fad907ffc3c, -980, -276),
- (0xd3515c2831559a83, -954, -268),
- (0x9d71ac8fada6c9b5, -927, -260),
- (0xea9c227723ee8bcb, -901, -252),
- (0xaecc49914078536d, -874, -244),
- (0x823c12795db6ce57, -847, -236),
- (0xc21094364dfb5637, -821, -228),
- (0x9096ea6f3848984f, -794, -220),
- (0xd77485cb25823ac7, -768, -212),
- (0xa086cfcd97bf97f4, -741, -204),
- (0xef340a98172aace5, -715, -196),
- (0xb23867fb2a35b28e, -688, -188),
- (0x84c8d4dfd2c63f3b, -661, -180),
- (0xc5dd44271ad3cdba, -635, -172),
- (0x936b9fcebb25c996, -608, -164),
- (0xdbac6c247d62a584, -582, -156),
- (0xa3ab66580d5fdaf6, -555, -148),
- (0xf3e2f893dec3f126, -529, -140),
- (0xb5b5ada8aaff80b8, -502, -132),
- (0x87625f056c7c4a8b, -475, -124),
- (0xc9bcff6034c13053, -449, -116),
- (0x964e858c91ba2655, -422, -108),
- (0xdff9772470297ebd, -396, -100),
- (0xa6dfbd9fb8e5b88f, -369, -92),
- (0xf8a95fcf88747d94, -343, -84),
- (0xb94470938fa89bcf, -316, -76),
- (0x8a08f0f8bf0f156b, -289, -68),
- (0xcdb02555653131b6, -263, -60),
- (0x993fe2c6d07b7fac, -236, -52),
- (0xe45c10c42a2b3b06, -210, -44),
- (0xaa242499697392d3, -183, -36),
- (0xfd87b5f28300ca0e, -157, -28),
- (0xbce5086492111aeb, -130, -20),
- (0x8cbccc096f5088cc, -103, -12),
- (0xd1b71758e219652c, -77, -4),
- (0x9c40000000000000, -50, 4),
- (0xe8d4a51000000000, -24, 12),
- (0xad78ebc5ac620000, 3, 20),
- (0x813f3978f8940984, 30, 28),
- (0xc097ce7bc90715b3, 56, 36),
- (0x8f7e32ce7bea5c70, 83, 44),
- (0xd5d238a4abe98068, 109, 52),
- (0x9f4f2726179a2245, 136, 60),
- (0xed63a231d4c4fb27, 162, 68),
- (0xb0de65388cc8ada8, 189, 76),
- (0x83c7088e1aab65db, 216, 84),
- (0xc45d1df942711d9a, 242, 92),
- (0x924d692ca61be758, 269, 100),
- (0xda01ee641a708dea, 295, 108),
- (0xa26da3999aef774a, 322, 116),
- (0xf209787bb47d6b85, 348, 124),
- (0xb454e4a179dd1877, 375, 132),
- (0x865b86925b9bc5c2, 402, 140),
- (0xc83553c5c8965d3d, 428, 148),
- (0x952ab45cfa97a0b3, 455, 156),
- (0xde469fbd99a05fe3, 481, 164),
- (0xa59bc234db398c25, 508, 172),
- (0xf6c69a72a3989f5c, 534, 180),
- (0xb7dcbf5354e9bece, 561, 188),
- (0x88fcf317f22241e2, 588, 196),
- (0xcc20ce9bd35c78a5, 614, 204),
- (0x98165af37b2153df, 641, 212),
- (0xe2a0b5dc971f303a, 667, 220),
- (0xa8d9d1535ce3b396, 694, 228),
- (0xfb9b7cd9a4a7443c, 720, 236),
- (0xbb764c4ca7a44410, 747, 244),
- (0x8bab8eefb6409c1a, 774, 252),
- (0xd01fef10a657842c, 800, 260),
- (0x9b10a4e5e9913129, 827, 268),
- (0xe7109bfba19c0c9d, 853, 276),
- (0xac2820d9623bf429, 880, 284),
- (0x80444b5e7aa7cf85, 907, 292),
- (0xbf21e44003acdd2d, 933, 300),
- (0x8e679c2f5e44ff8f, 960, 308),
- (0xd433179d9c8cb841, 986, 316),
- (0x9e19db92b4e31ba9, 1013, 324),
- (0xeb96bf6ebadf77d9, 1039, 332),
+ (0x8dd01fad907ffc3c, -980, -276),
+ (0xd3515c2831559a83, -954, -268),
+ (0x9d71ac8fada6c9b5, -927, -260),
+ (0xea9c227723ee8bcb, -901, -252),
+ (0xaecc49914078536d, -874, -244),
+ (0x823c12795db6ce57, -847, -236),
+ (0xc21094364dfb5637, -821, -228),
+ (0x9096ea6f3848984f, -794, -220),
+ (0xd77485cb25823ac7, -768, -212),
+ (0xa086cfcd97bf97f4, -741, -204),
+ (0xef340a98172aace5, -715, -196),
+ (0xb23867fb2a35b28e, -688, -188),
+ (0x84c8d4dfd2c63f3b, -661, -180),
+ (0xc5dd44271ad3cdba, -635, -172),
+ (0x936b9fcebb25c996, -608, -164),
+ (0xdbac6c247d62a584, -582, -156),
+ (0xa3ab66580d5fdaf6, -555, -148),
+ (0xf3e2f893dec3f126, -529, -140),
+ (0xb5b5ada8aaff80b8, -502, -132),
+ (0x87625f056c7c4a8b, -475, -124),
+ (0xc9bcff6034c13053, -449, -116),
+ (0x964e858c91ba2655, -422, -108),
+ (0xdff9772470297ebd, -396, -100),
+ (0xa6dfbd9fb8e5b88f, -369, -92),
+ (0xf8a95fcf88747d94, -343, -84),
+ (0xb94470938fa89bcf, -316, -76),
+ (0x8a08f0f8bf0f156b, -289, -68),
+ (0xcdb02555653131b6, -263, -60),
+ (0x993fe2c6d07b7fac, -236, -52),
+ (0xe45c10c42a2b3b06, -210, -44),
+ (0xaa242499697392d3, -183, -36),
+ (0xfd87b5f28300ca0e, -157, -28),
+ (0xbce5086492111aeb, -130, -20),
+ (0x8cbccc096f5088cc, -103, -12),
+ (0xd1b71758e219652c, -77, -4),
+ (0x9c40000000000000, -50, 4),
+ (0xe8d4a51000000000, -24, 12),
+ (0xad78ebc5ac620000, 3, 20),
+ (0x813f3978f8940984, 30, 28),
+ (0xc097ce7bc90715b3, 56, 36),
+ (0x8f7e32ce7bea5c70, 83, 44),
+ (0xd5d238a4abe98068, 109, 52),
+ (0x9f4f2726179a2245, 136, 60),
+ (0xed63a231d4c4fb27, 162, 68),
+ (0xb0de65388cc8ada8, 189, 76),
+ (0x83c7088e1aab65db, 216, 84),
+ (0xc45d1df942711d9a, 242, 92),
+ (0x924d692ca61be758, 269, 100),
+ (0xda01ee641a708dea, 295, 108),
+ (0xa26da3999aef774a, 322, 116),
+ (0xf209787bb47d6b85, 348, 124),
+ (0xb454e4a179dd1877, 375, 132),
+ (0x865b86925b9bc5c2, 402, 140),
+ (0xc83553c5c8965d3d, 428, 148),
+ (0x952ab45cfa97a0b3, 455, 156),
+ (0xde469fbd99a05fe3, 481, 164),
+ (0xa59bc234db398c25, 508, 172),
+ (0xf6c69a72a3989f5c, 534, 180),
+ (0xb7dcbf5354e9bece, 561, 188),
+ (0x88fcf317f22241e2, 588, 196),
+ (0xcc20ce9bd35c78a5, 614, 204),
+ (0x98165af37b2153df, 641, 212),
+ (0xe2a0b5dc971f303a, 667, 220),
+ (0xa8d9d1535ce3b396, 694, 228),
+ (0xfb9b7cd9a4a7443c, 720, 236),
+ (0xbb764c4ca7a44410, 747, 244),
+ (0x8bab8eefb6409c1a, 774, 252),
+ (0xd01fef10a657842c, 800, 260),
+ (0x9b10a4e5e9913129, 827, 268),
+ (0xe7109bfba19c0c9d, 853, 276),
+ (0xac2820d9623bf429, 880, 284),
+ (0x80444b5e7aa7cf85, 907, 292),
+ (0xbf21e44003acdd2d, 933, 300),
+ (0x8e679c2f5e44ff8f, 960, 308),
+ (0xd433179d9c8cb841, 986, 316),
+ (0x9e19db92b4e31ba9, 1013, 324),
+ (0xeb96bf6ebadf77d9, 1039, 332),
];
-#[doc(hidden)] pub const CACHED_POW10_FIRST_E: i16 = -1087;
-#[doc(hidden)] pub const CACHED_POW10_LAST_E: i16 = 1039;
+#[doc(hidden)]
+pub const CACHED_POW10_FIRST_E: i16 = -1087;
+#[doc(hidden)]
+pub const CACHED_POW10_LAST_E: i16 = 1039;
#[doc(hidden)]
pub fn cached_power(alpha: i16, gamma: i16) -> (i16, Fp) {
debug_assert!(x > 0);
const X9: u32 = 10_0000_0000;
- const X8: u32 = 1_0000_0000;
- const X7: u32 = 1000_0000;
- const X6: u32 = 100_0000;
- const X5: u32 = 10_0000;
- const X4: u32 = 1_0000;
- const X3: u32 = 1000;
- const X2: u32 = 100;
- const X1: u32 = 10;
+ const X8: u32 = 1_0000_0000;
+ const X7: u32 = 1000_0000;
+ const X6: u32 = 100_0000;
+ const X5: u32 = 10_0000;
+ const X4: u32 = 1_0000;
+ const X3: u32 = 1000;
+ const X2: u32 = 100;
+ const X1: u32 = 10;
if x < X4 {
- if x < X2 { if x < X1 {(0, 1)} else {(1, X1)} }
- else { if x < X3 {(2, X2)} else {(3, X3)} }
+ if x < X2 {
+ if x < X1 { (0, 1) } else { (1, X1) }
+ } else {
+ if x < X3 { (2, X2) } else { (3, X3) }
+ }
} else {
- if x < X6 { if x < X5 {(4, X4)} else {(5, X5)} }
- else if x < X8 { if x < X7 {(6, X6)} else {(7, X7)} }
- else { if x < X9 {(8, X8)} else {(9, X9)} }
+ if x < X6 {
+ if x < X5 { (4, X4) } else { (5, X5) }
+ } else if x < X8 {
+ if x < X7 { (6, X6) } else { (7, X7) }
+ } else {
+ if x < X9 { (8, X8) } else { (9, X9) }
+ }
}
}
/// The shortest mode implementation for Grisu.
///
/// It returns `None` when it would return an inexact representation otherwise.
-pub fn format_shortest_opt(d: &Decoded,
- buf: &mut [u8]) -> Option<(/*#digits*/ usize, /*exp*/ i16)> {
+pub fn format_shortest_opt(
+ d: &Decoded,
+ buf: &mut [u8],
+) -> Option<(/*#digits*/ usize, /*exp*/ i16)> {
assert!(d.mant > 0);
assert!(d.minus > 0);
assert!(d.plus > 0);
// we start with the correct repr within the unsafe region, and try to find the closest repr
// to `v` which is also within the safe region. if we can't, we give up.
let plus1 = plus.f + 1;
-// let plus0 = plus.f - 1; // only for explanation
-// let minus0 = minus.f + 1; // only for explanation
+ // let plus0 = plus.f - 1; // only for explanation
+ // let minus0 = minus.f + 1; // only for explanation
let minus1 = minus.f - 1;
let e = -plus.e as usize; // shared exponent
// (e.g., `x` = 32000, `y` = 32777; `kappa` = 2 since `y mod 10^3 = 777 < y - x = 777`.)
// the algorithm relies on the later verification phase to exclude `y`.
let delta1 = plus1 - minus1;
-// let delta1int = (delta1 >> e) as usize; // only for explanation
+ // let delta1int = (delta1 >> e) as usize; // only for explanation
let delta1frac = delta1 & ((1 << e) - 1);
// render integral parts, while checking for the accuracy at each step.
let mut kappa = max_kappa as i16;
let mut ten_kappa = max_ten_kappa; // 10^kappa
let mut remainder = plus1int; // digits yet to be rendered
- loop { // we always have at least one digit to render, as `plus1 >= 10^kappa`
+ loop {
+ // we always have at least one digit to render, as `plus1 >= 10^kappa`
// invariants:
// - `delta1int <= remainder < 10^(kappa+1)`
// - `plus1int = d[0..n-1] * 10^(kappa+1) + remainder`
let mut remainder = plus1frac;
let mut threshold = delta1frac;
let mut ulp = 1;
- loop { // the next digit should be significant as we've tested that before breaking out
+ loop {
+ // the next digit should be significant as we've tested that before breaking out
// invariants, where `m = max_kappa + 1` (# of digits in the integral part):
// - `remainder < 2^e`
// - `plus1frac * 10^(n-m) = d[m..n-1] * 2^e + remainder`
if r < threshold {
let ten_kappa = 1 << e; // implicit divisor
- return round_and_weed(&mut buf[..i], exp, r, threshold,
- (plus1 - v.f) * ulp, ten_kappa, ulp);
+ return round_and_weed(
+ &mut buf[..i],
+ exp,
+ r,
+ threshold,
+ (plus1 - v.f) * ulp,
+ ten_kappa,
+ ulp,
+ );
}
// restore invariants
// - `plus1v = (plus1 - v) * k` (and also, `threshold > plus1v` from prior invariants)
// - `ten_kappa = 10^kappa * k`
// - `ulp = 2^-e * k`
- fn round_and_weed(buf: &mut [u8], exp: i16, remainder: u64, threshold: u64, plus1v: u64,
- ten_kappa: u64, ulp: u64) -> Option<(usize, i16)> {
+ fn round_and_weed(
+ buf: &mut [u8],
+ exp: i16,
+ remainder: u64,
+ threshold: u64,
+ plus1v: u64,
+ ten_kappa: u64,
+ ulp: u64,
+ ) -> Option<(usize, i16)> {
assert!(!buf.is_empty());
// produce two approximations to `v` (actually `plus1 - v`) within 1.5 ulps.
//
// consequently, we should stop when `TC1 || TC2 || (TC3a && TC3b)`. the following is
// equal to its inverse, `!TC1 && !TC2 && (!TC3a || !TC3b)`.
- while plus1w < plus1v_up &&
- threshold - plus1w >= ten_kappa &&
- (plus1w + ten_kappa < plus1v_up ||
- plus1v_up - plus1w >= plus1w + ten_kappa - plus1v_up) {
+ while plus1w < plus1v_up
+ && threshold - plus1w >= ten_kappa
+ && (plus1w + ten_kappa < plus1v_up
+ || plus1v_up - plus1w >= plus1w + ten_kappa - plus1v_up)
+ {
*last -= 1;
debug_assert!(*last > b'0'); // the shortest repr cannot end with `0`
plus1w += ten_kappa;
//
// this is simply same to the terminating conditions for `v + 1 ulp`, with all `plus1v_up`
// replaced by `plus1v_down` instead. overflow analysis equally holds.
- if plus1w < plus1v_down &&
- threshold - plus1w >= ten_kappa &&
- (plus1w + ten_kappa < plus1v_down ||
- plus1v_down - plus1w >= plus1w + ten_kappa - plus1v_down) {
+ if plus1w < plus1v_down
+ && threshold - plus1w >= ten_kappa
+ && (plus1w + ten_kappa < plus1v_down
+ || plus1v_down - plus1w >= plus1w + ten_kappa - plus1v_down)
+ {
return None;
}
/// The exact and fixed mode implementation for Grisu.
///
/// It returns `None` when it would return an inexact representation otherwise.
-pub fn format_exact_opt(d: &Decoded, buf: &mut [u8], limit: i16)
- -> Option<(/*#digits*/ usize, /*exp*/ i16)> {
+pub fn format_exact_opt(
+ d: &Decoded,
+ buf: &mut [u8],
+ limit: i16,
+) -> Option<(/*#digits*/ usize, /*exp*/ i16)> {
assert!(d.mant > 0);
assert!(d.mant < (1 << 61)); // we need at least three bits of additional precision
assert!(!buf.is_empty());
let mut kappa = max_kappa as i16;
let mut ten_kappa = max_ten_kappa; // 10^kappa
let mut remainder = vint; // digits yet to be rendered
- loop { // we always have at least one digit to render
+ loop {
+ // we always have at least one digit to render
// invariants:
// - `remainder < 10^(kappa+1)`
// - `vint = d[0..n-1] * 10^(kappa+1) + remainder`
// - `remainder = (v % 10^kappa) * k`
// - `ten_kappa = 10^kappa * k`
// - `ulp = 2^-e * k`
- fn possibly_round(buf: &mut [u8], mut len: usize, mut exp: i16, limit: i16,
- remainder: u64, ten_kappa: u64, ulp: u64) -> Option<(usize, i16)> {
+ fn possibly_round(
+ buf: &mut [u8],
+ mut len: usize,
+ mut exp: i16,
+ limit: i16,
+ remainder: u64,
+ ten_kappa: u64,
+ ulp: u64,
+ ) -> Option<(usize, i16)> {
debug_assert!(remainder < ten_kappa);
// 10^kappa
//
// error is too large that there are at least three possible representations
// between `v - 1 ulp` and `v + 1 ulp`. we cannot determine which one is correct.
- if ulp >= ten_kappa { return None; }
+ if ulp >= ten_kappa {
+ return None;
+ }
// 10^kappa
// :<------->:
// in fact, 1/2 ulp is enough to introduce two possible representations.
// (remember that we need a unique representation for both `v - 1 ulp` and `v + 1 ulp`.)
// this won't overflow, as `ulp < ten_kappa` from the first check.
- if ten_kappa - ulp <= ulp { return None; }
+ if ten_kappa - ulp <= ulp {
+ return None;
+ }
// remainder
// :<->| :
#[allow(unused_macros)]
macro_rules! sh_impl_signed {
- ($t:ident, $f:ident) => (
+ ($t:ident, $f:ident) => {
#[stable(feature = "rust1", since = "1.0.0")]
impl Shl<$f> for Wrapping<$t> {
type Output = Wrapping<$t>;
}
}
forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f,
- #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
+ #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
#[stable(feature = "op_assign_traits", since = "1.8.0")]
impl ShlAssign<$f> for Wrapping<$t> {
}
}
forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f,
- #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
+ #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
#[stable(feature = "op_assign_traits", since = "1.8.0")]
impl ShrAssign<$f> for Wrapping<$t> {
}
}
forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f }
- )
+ };
}
macro_rules! sh_impl_unsigned {
- ($t:ident, $f:ident) => (
+ ($t:ident, $f:ident) => {
#[stable(feature = "rust1", since = "1.0.0")]
impl Shl<$f> for Wrapping<$t> {
type Output = Wrapping<$t>;
}
}
forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f,
- #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
+ #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
#[stable(feature = "op_assign_traits", since = "1.8.0")]
impl ShlAssign<$f> for Wrapping<$t> {
}
}
forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f,
- #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
+ #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
#[stable(feature = "op_assign_traits", since = "1.8.0")]
impl ShrAssign<$f> for Wrapping<$t> {
}
}
forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f }
- )
+ };
}
// FIXME (#23545): uncomment the remaining impls
#[lang = "add"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented(
- on(
- all(_Self="{integer}", Rhs="{float}"),
- message="cannot add a float to an integer",
- ),
- on(
- all(_Self="{float}", Rhs="{integer}"),
- message="cannot add an integer to a float",
- ),
- message="cannot add `{Rhs}` to `{Self}`",
- label="no implementation for `{Self} + {Rhs}`",
+ on(all(_Self = "{integer}", Rhs = "{float}"), message = "cannot add a float to an integer",),
+ on(all(_Self = "{float}", Rhs = "{integer}"), message = "cannot add an integer to a float",),
+ message = "cannot add `{Rhs}` to `{Self}`",
+ label = "no implementation for `{Self} + {Rhs}`"
)]
#[doc(alias = "+")]
-pub trait Add<Rhs=Self> {
+pub trait Add<Rhs = Self> {
/// The resulting type after applying the `+` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
/// ```
#[lang = "sub"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(message="cannot subtract `{Rhs}` from `{Self}`",
- label="no implementation for `{Self} - {Rhs}`")]
+#[rustc_on_unimplemented(
+ message = "cannot subtract `{Rhs}` from `{Self}`",
+ label = "no implementation for `{Self} - {Rhs}`"
+)]
#[doc(alias = "-")]
-pub trait Sub<Rhs=Self> {
+pub trait Sub<Rhs = Self> {
/// The resulting type after applying the `-` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
/// ```
#[lang = "mul"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(message="cannot multiply `{Rhs}` to `{Self}`",
- label="no implementation for `{Self} * {Rhs}`")]
+#[rustc_on_unimplemented(
+ message = "cannot multiply `{Rhs}` to `{Self}`",
+ label = "no implementation for `{Self} * {Rhs}`"
+)]
#[doc(alias = "*")]
-pub trait Mul<Rhs=Self> {
+pub trait Mul<Rhs = Self> {
/// The resulting type after applying the `*` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
/// ```
#[lang = "div"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(message="cannot divide `{Self}` by `{Rhs}`",
- label="no implementation for `{Self} / {Rhs}`")]
+#[rustc_on_unimplemented(
+ message = "cannot divide `{Self}` by `{Rhs}`",
+ label = "no implementation for `{Self} / {Rhs}`"
+)]
#[doc(alias = "/")]
-pub trait Div<Rhs=Self> {
+pub trait Div<Rhs = Self> {
/// The resulting type after applying the `/` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
/// ```
#[lang = "rem"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(message="cannot mod `{Self}` by `{Rhs}`",
- label="no implementation for `{Self} % {Rhs}`")]
+#[rustc_on_unimplemented(
+ message = "cannot mod `{Self}` by `{Rhs}`",
+ label = "no implementation for `{Self} % {Rhs}`"
+)]
#[doc(alias = "%")]
-pub trait Rem<Rhs=Self> {
+pub trait Rem<Rhs = Self> {
/// The resulting type after applying the `%` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
rem_impl_integer! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
-
macro_rules! rem_impl_float {
($($t:ty)*) => ($(
fn neg(self) -> Self::Output;
}
-
-
macro_rules! neg_impl_core {
($id:ident => $body:expr, $($t:ty)*) => ($(
#[stable(feature = "rust1", since = "1.0.0")]
/// ```
#[lang = "add_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented(message="cannot add-assign `{Rhs}` to `{Self}`",
- label="no implementation for `{Self} += {Rhs}`")]
+#[rustc_on_unimplemented(
+ message = "cannot add-assign `{Rhs}` to `{Self}`",
+ label = "no implementation for `{Self} += {Rhs}`"
+)]
#[doc(alias = "+")]
#[doc(alias = "+=")]
-pub trait AddAssign<Rhs=Self> {
+pub trait AddAssign<Rhs = Self> {
/// Performs the `+=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn add_assign(&mut self, rhs: Rhs);
/// ```
#[lang = "sub_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented(message="cannot subtract-assign `{Rhs}` from `{Self}`",
- label="no implementation for `{Self} -= {Rhs}`")]
+#[rustc_on_unimplemented(
+ message = "cannot subtract-assign `{Rhs}` from `{Self}`",
+ label = "no implementation for `{Self} -= {Rhs}`"
+)]
#[doc(alias = "-")]
#[doc(alias = "-=")]
-pub trait SubAssign<Rhs=Self> {
+pub trait SubAssign<Rhs = Self> {
/// Performs the `-=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn sub_assign(&mut self, rhs: Rhs);
/// ```
#[lang = "mul_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented(message="cannot multiply-assign `{Rhs}` to `{Self}`",
- label="no implementation for `{Self} *= {Rhs}`")]
+#[rustc_on_unimplemented(
+ message = "cannot multiply-assign `{Rhs}` to `{Self}`",
+ label = "no implementation for `{Self} *= {Rhs}`"
+)]
#[doc(alias = "*")]
#[doc(alias = "*=")]
-pub trait MulAssign<Rhs=Self> {
+pub trait MulAssign<Rhs = Self> {
/// Performs the `*=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn mul_assign(&mut self, rhs: Rhs);
/// ```
#[lang = "div_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented(message="cannot divide-assign `{Self}` by `{Rhs}`",
- label="no implementation for `{Self} /= {Rhs}`")]
+#[rustc_on_unimplemented(
+ message = "cannot divide-assign `{Self}` by `{Rhs}`",
+ label = "no implementation for `{Self} /= {Rhs}`"
+)]
#[doc(alias = "/")]
#[doc(alias = "/=")]
-pub trait DivAssign<Rhs=Self> {
+pub trait DivAssign<Rhs = Self> {
/// Performs the `/=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn div_assign(&mut self, rhs: Rhs);
/// ```
#[lang = "rem_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented(message="cannot mod-assign `{Self}` by `{Rhs}``",
- label="no implementation for `{Self} %= {Rhs}`")]
+#[rustc_on_unimplemented(
+ message = "cannot mod-assign `{Self}` by `{Rhs}``",
+ label = "no implementation for `{Self} %= {Rhs}`"
+)]
#[doc(alias = "%")]
#[doc(alias = "%=")]
-pub trait RemAssign<Rhs=Self> {
+pub trait RemAssign<Rhs = Self> {
/// Performs the `%=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn rem_assign(&mut self, rhs: Rhs);
#[lang = "bitand"]
#[doc(alias = "&")]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(message="no implementation for `{Self} & {Rhs}`",
- label="no implementation for `{Self} & {Rhs}`")]
-pub trait BitAnd<Rhs=Self> {
+#[rustc_on_unimplemented(
+ message = "no implementation for `{Self} & {Rhs}`",
+ label = "no implementation for `{Self} & {Rhs}`"
+)]
+pub trait BitAnd<Rhs = Self> {
/// The resulting type after applying the `&` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
#[lang = "bitor"]
#[doc(alias = "|")]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(message="no implementation for `{Self} | {Rhs}`",
- label="no implementation for `{Self} | {Rhs}`")]
-pub trait BitOr<Rhs=Self> {
+#[rustc_on_unimplemented(
+ message = "no implementation for `{Self} | {Rhs}`",
+ label = "no implementation for `{Self} | {Rhs}`"
+)]
+pub trait BitOr<Rhs = Self> {
/// The resulting type after applying the `|` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
#[lang = "bitxor"]
#[doc(alias = "^")]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(message="no implementation for `{Self} ^ {Rhs}`",
- label="no implementation for `{Self} ^ {Rhs}`")]
-pub trait BitXor<Rhs=Self> {
+#[rustc_on_unimplemented(
+ message = "no implementation for `{Self} ^ {Rhs}`",
+ label = "no implementation for `{Self} ^ {Rhs}`"
+)]
+pub trait BitXor<Rhs = Self> {
/// The resulting type after applying the `^` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
#[lang = "shl"]
#[doc(alias = "<<")]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(message="no implementation for `{Self} << {Rhs}`",
- label="no implementation for `{Self} << {Rhs}`")]
-pub trait Shl<Rhs=Self> {
+#[rustc_on_unimplemented(
+ message = "no implementation for `{Self} << {Rhs}`",
+ label = "no implementation for `{Self} << {Rhs}`"
+)]
+pub trait Shl<Rhs = Self> {
/// The resulting type after applying the `<<` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
}
macro_rules! shl_impl {
- ($t:ty, $f:ty) => (
+ ($t:ty, $f:ty) => {
#[stable(feature = "rust1", since = "1.0.0")]
impl Shl<$f> for $t {
type Output = $t;
}
forward_ref_binop! { impl Shl, shl for $t, $f }
- )
+ };
}
macro_rules! shl_impl_all {
#[lang = "shr"]
#[doc(alias = ">>")]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(message="no implementation for `{Self} >> {Rhs}`",
- label="no implementation for `{Self} >> {Rhs}`")]
-pub trait Shr<Rhs=Self> {
+#[rustc_on_unimplemented(
+ message = "no implementation for `{Self} >> {Rhs}`",
+ label = "no implementation for `{Self} >> {Rhs}`"
+)]
+pub trait Shr<Rhs = Self> {
/// The resulting type after applying the `>>` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
}
macro_rules! shr_impl {
- ($t:ty, $f:ty) => (
+ ($t:ty, $f:ty) => {
#[stable(feature = "rust1", since = "1.0.0")]
impl Shr<$f> for $t {
type Output = $t;
}
forward_ref_binop! { impl Shr, shr for $t, $f }
- )
+ };
}
macro_rules! shr_impl_all {
#[lang = "bitand_assign"]
#[doc(alias = "&=")]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented(message="no implementation for `{Self} &= {Rhs}`",
- label="no implementation for `{Self} &= {Rhs}`")]
-pub trait BitAndAssign<Rhs=Self> {
+#[rustc_on_unimplemented(
+ message = "no implementation for `{Self} &= {Rhs}`",
+ label = "no implementation for `{Self} &= {Rhs}`"
+)]
+pub trait BitAndAssign<Rhs = Self> {
/// Performs the `&=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn bitand_assign(&mut self, rhs: Rhs);
#[lang = "bitor_assign"]
#[doc(alias = "|=")]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented(message="no implementation for `{Self} |= {Rhs}`",
- label="no implementation for `{Self} |= {Rhs}`")]
-pub trait BitOrAssign<Rhs=Self> {
+#[rustc_on_unimplemented(
+ message = "no implementation for `{Self} |= {Rhs}`",
+ label = "no implementation for `{Self} |= {Rhs}`"
+)]
+pub trait BitOrAssign<Rhs = Self> {
/// Performs the `|=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn bitor_assign(&mut self, rhs: Rhs);
#[lang = "bitxor_assign"]
#[doc(alias = "^=")]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented(message="no implementation for `{Self} ^= {Rhs}`",
- label="no implementation for `{Self} ^= {Rhs}`")]
-pub trait BitXorAssign<Rhs=Self> {
+#[rustc_on_unimplemented(
+ message = "no implementation for `{Self} ^= {Rhs}`",
+ label = "no implementation for `{Self} ^= {Rhs}`"
+)]
+pub trait BitXorAssign<Rhs = Self> {
/// Performs the `^=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn bitxor_assign(&mut self, rhs: Rhs);
#[lang = "shl_assign"]
#[doc(alias = "<<=")]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented(message="no implementation for `{Self} <<= {Rhs}`",
- label="no implementation for `{Self} <<= {Rhs}`")]
-pub trait ShlAssign<Rhs=Self> {
+#[rustc_on_unimplemented(
+ message = "no implementation for `{Self} <<= {Rhs}`",
+ label = "no implementation for `{Self} <<= {Rhs}`"
+)]
+pub trait ShlAssign<Rhs = Self> {
/// Performs the `<<=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn shl_assign(&mut self, rhs: Rhs);
}
macro_rules! shl_assign_impl {
- ($t:ty, $f:ty) => (
+ ($t:ty, $f:ty) => {
#[stable(feature = "op_assign_traits", since = "1.8.0")]
impl ShlAssign<$f> for $t {
#[inline]
}
forward_ref_op_assign! { impl ShlAssign, shl_assign for $t, $f }
- )
+ };
}
macro_rules! shl_assign_impl_all {
#[lang = "shr_assign"]
#[doc(alias = ">>=")]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented(message="no implementation for `{Self} >>= {Rhs}`",
- label="no implementation for `{Self} >>= {Rhs}`")]
-pub trait ShrAssign<Rhs=Self> {
+#[rustc_on_unimplemented(
+ message = "no implementation for `{Self} >>= {Rhs}`",
+ label = "no implementation for `{Self} >>= {Rhs}`"
+)]
+pub trait ShrAssign<Rhs = Self> {
/// Performs the `>>=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn shr_assign(&mut self, rhs: Rhs);
}
macro_rules! shr_assign_impl {
- ($t:ty, $f:ty) => (
+ ($t:ty, $f:ty) => {
#[stable(feature = "op_assign_traits", since = "1.8.0")]
impl ShrAssign<$f> for $t {
#[inline]
}
forward_ref_op_assign! { impl ShrAssign, shr_assign for $t, $f }
- )
+ };
}
macro_rules! shr_assign_impl_all {
impl<T: ?Sized> Deref for &T {
type Target = T;
- fn deref(&self) -> &T { *self }
+ fn deref(&self) -> &T {
+ *self
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Deref for &mut T {
type Target = T;
- fn deref(&self) -> &T { *self }
+ fn deref(&self) -> &T {
+ *self
+ }
}
/// Used for mutable dereferencing operations, like in `*v = 1;`.
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> DerefMut for &mut T {
- fn deref_mut(&mut self) -> &mut T { *self }
+ fn deref_mut(&mut self) -> &mut T {
+ *self
+ }
}
/// Indicates that a struct can be used as a method receiver, without the
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
#[rustc_on_unimplemented(
- on(Args="()", note="wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"),
- message="expected a `{Fn}<{Args}>` closure, found `{Self}`",
- label="expected an `Fn<{Args}>` closure, found `{Self}`",
+ on(
+ Args = "()",
+ note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"
+ ),
+ message = "expected a `{Fn}<{Args}>` closure, found `{Self}`",
+ label = "expected an `Fn<{Args}>` closure, found `{Self}`"
)]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
-pub trait Fn<Args> : FnMut<Args> {
+pub trait Fn<Args>: FnMut<Args> {
/// Performs the call operation.
#[unstable(feature = "fn_traits", issue = "29625")]
extern "rust-call" fn call(&self, args: Args) -> Self::Output;
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
#[rustc_on_unimplemented(
- on(Args="()", note="wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"),
- message="expected a `{FnMut}<{Args}>` closure, found `{Self}`",
- label="expected an `FnMut<{Args}>` closure, found `{Self}`",
+ on(
+ Args = "()",
+ note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"
+ ),
+ message = "expected a `{FnMut}<{Args}>` closure, found `{Self}`",
+ label = "expected an `FnMut<{Args}>` closure, found `{Self}`"
)]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
-pub trait FnMut<Args> : FnOnce<Args> {
+pub trait FnMut<Args>: FnOnce<Args> {
/// Performs the call operation.
#[unstable(feature = "fn_traits", issue = "29625")]
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
#[rustc_on_unimplemented(
- on(Args="()", note="wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"),
- message="expected a `{FnOnce}<{Args}>` closure, found `{Self}`",
- label="expected an `FnOnce<{Args}>` closure, found `{Self}`",
+ on(
+ Args = "()",
+ note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"
+ ),
+ message = "expected a `{FnOnce}<{Args}>` closure, found `{Self}`",
+ label = "expected an `FnOnce<{Args}>` closure, found `{Self}`"
)]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
mod impls {
#[stable(feature = "rust1", since = "1.0.0")]
- impl<A,F:?Sized> Fn<A> for &F
- where F : Fn<A>
+ impl<A, F: ?Sized> Fn<A> for &F
+ where
+ F: Fn<A>,
{
extern "rust-call" fn call(&self, args: A) -> F::Output {
(**self).call(args)
}
#[stable(feature = "rust1", since = "1.0.0")]
- impl<A,F:?Sized> FnMut<A> for &F
- where F : Fn<A>
+ impl<A, F: ?Sized> FnMut<A> for &F
+ where
+ F: Fn<A>,
{
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
(**self).call(args)
}
#[stable(feature = "rust1", since = "1.0.0")]
- impl<A,F:?Sized> FnOnce<A> for &F
- where F : Fn<A>
+ impl<A, F: ?Sized> FnOnce<A> for &F
+ where
+ F: Fn<A>,
{
type Output = F::Output;
}
#[stable(feature = "rust1", since = "1.0.0")]
- impl<A,F:?Sized> FnMut<A> for &mut F
- where F : FnMut<A>
+ impl<A, F: ?Sized> FnMut<A> for &mut F
+ where
+ F: FnMut<A>,
{
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
(*self).call_mut(args)
}
#[stable(feature = "rust1", since = "1.0.0")]
- impl<A,F:?Sized> FnOnce<A> for &mut F
- where F : FnMut<A>
+ impl<A, F: ?Sized> FnOnce<A> for &mut F
+ where
+ F: FnMut<A>,
{
type Output = F::Output;
extern "rust-call" fn call_once(self, args: A) -> F::Output {
/// ```
#[lang = "index"]
#[rustc_on_unimplemented(
- message="the type `{Self}` cannot be indexed by `{Idx}`",
- label="`{Self}` cannot be indexed by `{Idx}`",
+ message = "the type `{Self}` cannot be indexed by `{Idx}`",
+ label = "`{Self}` cannot be indexed by `{Idx}`"
)]
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(alias = "]")]
#[lang = "index_mut"]
#[rustc_on_unimplemented(
on(
- _Self="&str",
- note="you can use `.chars().nth()` or `.bytes().nth()`
+ _Self = "&str",
+ note = "you can use `.chars().nth()` or `.bytes().nth()`
see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
),
on(
- _Self="str",
- note="you can use `.chars().nth()` or `.bytes().nth()`
+ _Self = "str",
+ note = "you can use `.chars().nth()` or `.bytes().nth()`
see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
),
on(
- _Self="std::string::String",
- note="you can use `.chars().nth()` or `.bytes().nth()`
+ _Self = "std::string::String",
+ note = "you can use `.chars().nth()` or `.bytes().nth()`
see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
),
- message="the type `{Self}` cannot be mutably indexed by `{Idx}`",
- label="`{Self}` cannot be mutably indexed by `{Idx}`",
+ message = "the type `{Self}` cannot be mutably indexed by `{Idx}`",
+ label = "`{Self}` cannot be mutably indexed by `{Idx}`"
)]
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(alias = "[")]
mod unsize;
#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::arith::{Add, Sub, Mul, Div, Rem, Neg};
+pub use self::arith::{Add, Div, Mul, Neg, Rem, Sub};
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-pub use self::arith::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
+pub use self::arith::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};
#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::bit::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
+pub use self::bit::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
#[stable(feature = "op_assign_traits", since = "1.8.0")]
pub use self::bit::{BitAndAssign, BitOrAssign, BitXorAssign, ShlAssign, ShrAssign};
pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};
#[stable(feature = "inclusive_range", since = "1.26.0")]
-pub use self::range::{RangeInclusive, RangeToInclusive, RangeBounds, Bound};
+pub use self::range::{Bound, RangeBounds, RangeInclusive, RangeToInclusive};
#[unstable(feature = "try_trait", issue = "42327")]
pub use self::r#try::Try;
#[inline]
#[rustc_promotable]
pub const fn new(start: Idx, end: Idx) -> Self {
- Self {
- start,
- end,
- is_empty: None,
- }
+ Self { start, end, is_empty: None }
}
/// Returns the lower bound of the range (inclusive).
// &mut T -> &mut U
#[unstable(feature = "coerce_unsized", issue = "27732")]
-impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
// &mut T -> &U
#[unstable(feature = "coerce_unsized", issue = "27732")]
-impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {}
+impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {}
// &mut T -> *mut U
#[unstable(feature = "coerce_unsized", issue = "27732")]
-impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {}
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {}
// &mut T -> *const U
#[unstable(feature = "coerce_unsized", issue = "27732")]
-impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {}
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {}
// &T -> &U
#[unstable(feature = "coerce_unsized", issue = "27732")]
-impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
+impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
// &T -> *const U
#[unstable(feature = "coerce_unsized", issue = "27732")]
-impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {}
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {}
// *mut T -> *mut U
#[unstable(feature = "coerce_unsized", issue = "27732")]
-impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
+impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
// *mut T -> *const U
#[unstable(feature = "coerce_unsized", issue = "27732")]
-impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
+impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
// *const T -> *const U
#[unstable(feature = "coerce_unsized", issue = "27732")]
-impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
-
+impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
/// This is used for object safety, to check that a method's receiver type can be dispatched on.
///
// &T -> &U
#[unstable(feature = "dispatch_from_dyn", issue = "0")]
-impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {}
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {}
// &mut T -> &mut U
#[unstable(feature = "dispatch_from_dyn", issue = "0")]
-impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {}
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {}
// *const T -> *const U
#[unstable(feature = "dispatch_from_dyn", issue = "0")]
-impl<T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {}
+impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {}
// *mut T -> *mut U
#[unstable(feature = "dispatch_from_dyn", issue = "0")]
-impl<T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}
+impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}
#![stable(feature = "rust1", since = "1.0.0")]
use crate::iter::{FromIterator, FusedIterator, TrustedLen};
-use crate::{convert, fmt, hint, mem, ops::{self, Deref, DerefMut}};
use crate::pin::Pin;
+use crate::{
+ convert, fmt, hint, mem,
+ ops::{self, Deref, DerefMut},
+};
// Note that this is not a lang item per se, but it has a hidden dependency on
// `Iterator`, which is one. The compiler assumes that the `next` method of
#[must_use]
#[inline]
#[unstable(feature = "option_result_contains", issue = "62358")]
- pub fn contains<U>(&self, x: &U) -> bool where U: PartialEq<T> {
+ pub fn contains<U>(&self, x: &U) -> bool
+ where
+ U: PartialEq<T>,
+ {
match self {
Some(y) => x == y,
None => false,
}
}
-
/// Converts from [`Pin`]`<&Option<T>>` to `Option<`[`Pin`]`<&T>>`.
///
/// [`Pin`]: ../pin/struct.Pin.html
#[inline]
#[stable(feature = "pin", since = "1.33.0")]
pub fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>> {
- unsafe {
- Pin::get_ref(self).as_ref().map(|x| Pin::new_unchecked(x))
- }
+ unsafe { Pin::get_ref(self).as_ref().map(|x| Pin::new_unchecked(x)) }
}
/// Converts from [`Pin`]`<&mut Option<T>>` to `Option<`[`Pin`]`<&mut T>>`.
#[inline]
#[stable(feature = "pin", since = "1.33.0")]
pub fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut T>> {
- unsafe {
- Pin::get_unchecked_mut(self).as_mut().map(|x| Pin::new_unchecked(x))
- }
+ unsafe { Pin::get_unchecked_mut(self).as_mut().map(|x| Pin::new_unchecked(x)) }
}
/////////////////////////////////////////////////////////////////////////
pub fn filter<P: FnOnce(&T) -> bool>(self, predicate: P) -> Self {
if let Some(x) = self {
if predicate(&x) {
- return Some(x)
+ return Some(x);
}
}
None
/// assert!(opt.is_none());
/// ```
#[inline]
- fn default() -> Option<T> { None }
+ fn default() -> Option<T> {
+ None
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone, Debug)]
struct Item<A> {
- opt: Option<A>
+ opt: Option<A>,
}
impl<A> Iterator for Item<A> {
/// [`Option::iter`]: enum.Option.html#method.iter
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Debug)]
-pub struct Iter<'a, A: 'a> { inner: Item<&'a A> }
+pub struct Iter<'a, A: 'a> {
+ inner: Item<&'a A>,
+}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, A> Iterator for Iter<'a, A> {
type Item = &'a A;
#[inline]
- fn next(&mut self) -> Option<&'a A> { self.inner.next() }
+ fn next(&mut self) -> Option<&'a A> {
+ self.inner.next()
+ }
#[inline]
- fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, A> DoubleEndedIterator for Iter<'a, A> {
#[inline]
- fn next_back(&mut self) -> Option<&'a A> { self.inner.next_back() }
+ fn next_back(&mut self) -> Option<&'a A> {
+ self.inner.next_back()
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
/// [`Option::iter_mut`]: enum.Option.html#method.iter_mut
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Debug)]
-pub struct IterMut<'a, A: 'a> { inner: Item<&'a mut A> }
+pub struct IterMut<'a, A: 'a> {
+ inner: Item<&'a mut A>,
+}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, A> Iterator for IterMut<'a, A> {
type Item = &'a mut A;
#[inline]
- fn next(&mut self) -> Option<&'a mut A> { self.inner.next() }
+ fn next(&mut self) -> Option<&'a mut A> {
+ self.inner.next()
+ }
#[inline]
- fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, A> DoubleEndedIterator for IterMut<'a, A> {
#[inline]
- fn next_back(&mut self) -> Option<&'a mut A> { self.inner.next_back() }
+ fn next_back(&mut self) -> Option<&'a mut A> {
+ self.inner.next_back()
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
/// [`Option::into_iter`]: enum.Option.html#method.into_iter
#[derive(Clone, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
-pub struct IntoIter<A> { inner: Item<A> }
+pub struct IntoIter<A> {
+ inner: Item<A>,
+}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A> Iterator for IntoIter<A> {
type Item = A;
#[inline]
- fn next(&mut self) -> Option<A> { self.inner.next() }
+ fn next(&mut self) -> Option<A> {
+ self.inner.next()
+ }
#[inline]
- fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A> DoubleEndedIterator for IntoIter<A> {
#[inline]
- fn next_back(&mut self) -> Option<A> { self.inner.next_back() }
+ fn next_back(&mut self) -> Option<A> {
+ self.inner.next_back()
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
///
/// [`Iterator`]: ../iter/trait.Iterator.html
#[inline]
- fn from_iter<I: IntoIterator<Item=Option<A>>>(iter: I) -> Option<V> {
+ fn from_iter<I: IntoIterator<Item = Option<A>>>(iter: I) -> Option<V> {
// FIXME(#11084): This could be replaced with Iterator::scan when this
// performance bug is closed.
- iter.into_iter()
- .map(|x| x.ok_or(()))
- .collect::<Result<_, _>>()
- .ok()
+ iter.into_iter().map(|x| x.ok_or(())).collect::<Result<_, _>>().ok()
}
}
#![stable(feature = "pin", since = "1.33.0")]
+use crate::cmp::{self, PartialEq, PartialOrd};
use crate::fmt;
use crate::marker::{Sized, Unpin};
-use crate::cmp::{self, PartialEq, PartialOrd};
-use crate::ops::{Deref, DerefMut, Receiver, CoerceUnsized, DispatchFromDyn};
+use crate::ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Receiver};
/// A pinned pointer.
///
///
/// [`pin` module]: ../../std/pin/index.html#projections-and-structural-pinning
#[stable(feature = "pin", since = "1.33.0")]
- pub unsafe fn map_unchecked<U, F>(self, func: F) -> Pin<&'a U> where
+ pub unsafe fn map_unchecked<U, F>(self, func: F) -> Pin<&'a U>
+ where
F: FnOnce(&T) -> &U,
{
let pointer = &*self.pointer;
#[stable(feature = "pin", since = "1.33.0")]
#[inline(always)]
pub fn get_mut(self) -> &'a mut T
- where T: Unpin,
+ where
+ T: Unpin,
{
self.pointer
}
///
/// [`pin` module]: ../../std/pin/index.html#projections-and-structural-pinning
#[stable(feature = "pin", since = "1.33.0")]
- pub unsafe fn map_unchecked_mut<U, F>(self, func: F) -> Pin<&'a mut U> where
+ pub unsafe fn map_unchecked_mut<U, F>(self, func: F) -> Pin<&'a mut U>
+ where
F: FnOnce(&mut T) -> &mut U,
{
let pointer = Pin::get_unchecked_mut(self);
// for other reasons, though, so we just need to take care not to allow such
// impls to land in std.
#[stable(feature = "pin", since = "1.33.0")]
-impl<P, U> CoerceUnsized<Pin<U>> for Pin<P>
-where
- P: CoerceUnsized<U>,
-{}
+impl<P, U> CoerceUnsized<Pin<U>> for Pin<P> where P: CoerceUnsized<U> {}
#[stable(feature = "pin", since = "1.33.0")]
-impl<P, U> DispatchFromDyn<Pin<U>> for Pin<P>
-where
- P: DispatchFromDyn<U>,
-{}
+impl<P, U> DispatchFromDyn<Pin<U>> for Pin<P> where P: DispatchFromDyn<U> {}
pub use crate::clone::Clone;
#[stable(feature = "core_prelude", since = "1.4.0")]
#[doc(no_inline)]
-pub use crate::cmp::{PartialEq, PartialOrd, Eq, Ord};
+pub use crate::cmp::{Eq, Ord, PartialEq, PartialOrd};
#[stable(feature = "core_prelude", since = "1.4.0")]
#[doc(no_inline)]
-pub use crate::convert::{AsRef, AsMut, Into, From};
+pub use crate::convert::{AsMut, AsRef, From, Into};
#[stable(feature = "core_prelude", since = "1.4.0")]
#[doc(no_inline)]
pub use crate::default::Default;
#[stable(feature = "core_prelude", since = "1.4.0")]
#[doc(no_inline)]
-pub use crate::iter::{Iterator, Extend, IntoIterator};
+pub use crate::iter::{DoubleEndedIterator, ExactSizeIterator};
#[stable(feature = "core_prelude", since = "1.4.0")]
#[doc(no_inline)]
-pub use crate::iter::{DoubleEndedIterator, ExactSizeIterator};
+pub use crate::iter::{Extend, IntoIterator, Iterator};
#[stable(feature = "core_prelude", since = "1.4.0")]
#[doc(no_inline)]
-pub use crate::option::Option::{self, Some, None};
+pub use crate::option::Option::{self, None, Some};
#[stable(feature = "core_prelude", since = "1.4.0")]
#[doc(no_inline)]
-pub use crate::result::Result::{self, Ok, Err};
+pub use crate::result::Result::{self, Err, Ok};
// Re-exported built-in macros
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[doc(no_inline)]
pub use crate::{
- asm,
- assert,
- cfg,
- column,
- compile_error,
- concat,
- concat_idents,
- env,
- file,
- format_args,
- format_args_nl,
- global_asm,
- include,
- include_bytes,
- include_str,
- line,
- log_syntax,
- module_path,
- option_env,
- stringify,
- trace_macros,
+ asm, assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args,
+ format_args_nl, global_asm, include, include_bytes, include_str, line, log_syntax, module_path,
+ option_env, stringify, trace_macros,
};
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow(deprecated)]
#[doc(no_inline)]
pub use crate::macros::builtin::{
- RustcDecodable,
- RustcEncodable,
- bench,
- global_allocator,
- test,
- test_case,
+ bench, global_allocator, test, test_case, RustcDecodable, RustcEncodable,
};
+use crate::cmp::Ordering;
use crate::convert::From;
-use crate::ops::{CoerceUnsized, DispatchFromDyn};
use crate::fmt;
use crate::hash;
use crate::marker::Unsize;
use crate::mem;
+use crate::ops::{CoerceUnsized, DispatchFromDyn};
use crate::ptr::Unique;
-use crate::cmp::Ordering;
// ignore-tidy-undocumented-unsafe
/// `NonNull` pointers are not `Send` because the data they reference may be aliased.
// N.B., this impl is unnecessary, but should provide better error messages.
#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> !Send for NonNull<T> { }
+impl<T: ?Sized> !Send for NonNull<T> {}
/// `NonNull` pointers are not `Sync` because the data they reference may be aliased.
// N.B., this impl is unnecessary, but should provide better error messages.
#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> !Sync for NonNull<T> { }
+impl<T: ?Sized> !Sync for NonNull<T> {}
impl<T: Sized> NonNull<T> {
/// Creates a new `NonNull` that is dangling, but well-aligned.
#[stable(feature = "nonnull", since = "1.25.0")]
#[inline]
pub fn new(ptr: *mut T) -> Option<Self> {
- if !ptr.is_null() {
- Some(unsafe { Self::new_unchecked(ptr) })
- } else {
- None
- }
+ if !ptr.is_null() { Some(unsafe { Self::new_unchecked(ptr) }) } else { None }
}
/// Acquires the underlying `*mut` pointer.
#[stable(feature = "nonnull_cast", since = "1.27.0")]
#[inline]
pub const fn cast<U>(self) -> NonNull<U> {
- unsafe {
- NonNull::new_unchecked(self.as_ptr() as *mut U)
- }
+ unsafe { NonNull::new_unchecked(self.as_ptr() as *mut U) }
}
}
}
#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> Copy for NonNull<T> { }
+impl<T: ?Sized> Copy for NonNull<T> {}
#[unstable(feature = "coerce_unsized", issue = "27732")]
-impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> { }
+impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
#[unstable(feature = "dispatch_from_dyn", issue = "0")]
-impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> { }
+impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
#[stable(feature = "nonnull", since = "1.25.0")]
impl<T: ?Sized> fmt::Debug for NonNull<T> {
use crate::convert::From;
-use crate::ops::{CoerceUnsized, DispatchFromDyn};
use crate::fmt;
use crate::marker::{PhantomData, Unsize};
use crate::mem;
+use crate::ops::{CoerceUnsized, DispatchFromDyn};
use crate::ptr::NonNull;
// ignore-tidy-undocumented-unsafe
///
/// Unlike `*mut T`, `Unique<T>` is covariant over `T`. This should always be correct
/// for any type which upholds Unique's aliasing requirements.
-#[unstable(feature = "ptr_internals", issue = "0",
- reason = "use `NonNull` instead and consider `PhantomData<T>` \
- (if you also use `#[may_dangle]`), `Send`, and/or `Sync`")]
+#[unstable(
+ feature = "ptr_internals",
+ issue = "0",
+ reason = "use `NonNull` instead and consider `PhantomData<T>` \
+ (if you also use `#[may_dangle]`), `Send`, and/or `Sync`"
+)]
#[doc(hidden)]
#[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(1)]
/// unenforced by the type system; the abstraction using the
/// `Unique` must enforce it.
#[unstable(feature = "ptr_internals", issue = "0")]
-unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
+unsafe impl<T: Send + ?Sized> Send for Unique<T> {}
/// `Unique` pointers are `Sync` if `T` is `Sync` because the data they
/// reference is unaliased. Note that this aliasing invariant is
/// unenforced by the type system; the abstraction using the
/// `Unique` must enforce it.
#[unstable(feature = "ptr_internals", issue = "0")]
-unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
+unsafe impl<T: Sync + ?Sized> Sync for Unique<T> {}
#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: Sized> Unique<T> {
// FIXME: rename to dangling() to match NonNull?
#[inline]
pub const fn empty() -> Self {
- unsafe {
- Unique::new_unchecked(mem::align_of::<T>() as *mut T)
- }
+ unsafe { Unique::new_unchecked(mem::align_of::<T>() as *mut T) }
}
}
/// Casts to a pointer of another type.
#[inline]
pub const fn cast<U>(self) -> Unique<U> {
- unsafe {
- Unique::new_unchecked(self.as_ptr() as *mut U)
- }
+ unsafe { Unique::new_unchecked(self.as_ptr() as *mut U) }
}
}
}
#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized> Copy for Unique<T> { }
+impl<T: ?Sized> Copy for Unique<T> {}
#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> { }
+impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {}
#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> { }
+impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {}
#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized> fmt::Debug for Unique<T> {
impl<T> Drop for CopyOnDrop<T> {
fn drop(&mut self) {
- unsafe { ptr::copy_nonoverlapping(self.src, self.dest, 1); }
+ unsafe {
+ ptr::copy_nonoverlapping(self.src, self.dest, 1);
+ }
}
}
/// Shifts the first element to the right until it encounters a greater or equal element.
fn shift_head<T, F>(v: &mut [T], is_less: &mut F)
- where F: FnMut(&T, &T) -> bool
+where
+ F: FnMut(&T, &T) -> bool,
{
let len = v.len();
unsafe {
// operation panics, `hole` will get dropped and automatically write the element back
// into the slice.
let mut tmp = mem::ManuallyDrop::new(ptr::read(v.get_unchecked(0)));
- let mut hole = CopyOnDrop {
- src: &mut *tmp,
- dest: v.get_unchecked_mut(1),
- };
+ let mut hole = CopyOnDrop { src: &mut *tmp, dest: v.get_unchecked_mut(1) };
ptr::copy_nonoverlapping(v.get_unchecked(1), v.get_unchecked_mut(0), 1);
for i in 2..len {
/// Shifts the last element to the left until it encounters a smaller or equal element.
fn shift_tail<T, F>(v: &mut [T], is_less: &mut F)
- where F: FnMut(&T, &T) -> bool
+where
+ F: FnMut(&T, &T) -> bool,
{
let len = v.len();
unsafe {
// operation panics, `hole` will get dropped and automatically write the element back
// into the slice.
let mut tmp = mem::ManuallyDrop::new(ptr::read(v.get_unchecked(len - 1)));
- let mut hole = CopyOnDrop {
- src: &mut *tmp,
- dest: v.get_unchecked_mut(len - 2),
- };
+ let mut hole = CopyOnDrop { src: &mut *tmp, dest: v.get_unchecked_mut(len - 2) };
ptr::copy_nonoverlapping(v.get_unchecked(len - 2), v.get_unchecked_mut(len - 1), 1);
- for i in (0..len-2).rev() {
+ for i in (0..len - 2).rev() {
if !is_less(&*tmp, v.get_unchecked(i)) {
break;
}
/// Returns `true` if the slice is sorted at the end. This function is `O(n)` worst-case.
#[cold]
fn partial_insertion_sort<T, F>(v: &mut [T], is_less: &mut F) -> bool
- where F: FnMut(&T, &T) -> bool
+where
+ F: FnMut(&T, &T) -> bool,
{
// Maximum number of adjacent out-of-order pairs that will get shifted.
const MAX_STEPS: usize = 5;
/// Sorts a slice using insertion sort, which is `O(n^2)` worst-case.
fn insertion_sort<T, F>(v: &mut [T], is_less: &mut F)
- where F: FnMut(&T, &T) -> bool
+where
+ F: FnMut(&T, &T) -> bool,
{
for i in 1..v.len() {
- shift_tail(&mut v[..i+1], is_less);
+ shift_tail(&mut v[..i + 1], is_less);
}
}
/// Sorts `v` using heapsort, which guarantees `O(n log n)` worst-case.
#[cold]
pub fn heapsort<T, F>(v: &mut [T], is_less: &mut F)
- where F: FnMut(&T, &T) -> bool
+where
+ F: FnMut(&T, &T) -> bool,
{
// This binary heap respects the invariant `parent >= child`.
let mut sift_down = |v: &mut [T], mut node| {
let right = 2 * node + 2;
// Choose the greater child.
- let greater = if right < v.len() && is_less(&v[left], &v[right]) {
- right
- } else {
- left
- };
+ let greater =
+ if right < v.len() && is_less(&v[left], &v[right]) { right } else { left };
// Stop if the invariant holds at `node`.
if greater >= v.len() || !is_less(&v[node], &v[greater]) {
};
// Build the heap in linear time.
- for i in (0 .. v.len() / 2).rev() {
+ for i in (0..v.len() / 2).rev() {
sift_down(v, i);
}
// Pop maximal elements from the heap.
- for i in (1 .. v.len()).rev() {
+ for i in (1..v.len()).rev() {
v.swap(0, i);
sift_down(&mut v[..i], 0);
}
///
/// [pdf]: http://drops.dagstuhl.de/opus/volltexte/2016/6389/pdf/LIPIcs-ESA-2016-38.pdf
fn partition_in_blocks<T, F>(v: &mut [T], pivot: &T, is_less: &mut F) -> usize
- where F: FnMut(&T, &T) -> bool
+where
+ F: FnMut(&T, &T) -> bool,
{
// Number of elements in a typical block.
const BLOCK: usize = 128;
let count = cmp::min(width(start_l, end_l), width(start_r, end_r));
if count > 0 {
- macro_rules! left { () => { l.offset(*start_l as isize) } }
- macro_rules! right { () => { r.offset(-(*start_r as isize) - 1) } }
+ macro_rules! left {
+ () => {
+ l.offset(*start_l as isize)
+ };
+ }
+ macro_rules! right {
+ () => {
+ r.offset(-(*start_r as isize) - 1)
+ };
+ }
// Instead of swapping one pair at the time, it is more efficient to perform a cyclic
// permutation. This is not strictly equivalent to swapping, but produces a similar
/// 1. Number of elements smaller than `v[pivot]`.
/// 2. True if `v` was already partitioned.
fn partition<T, F>(v: &mut [T], pivot: usize, is_less: &mut F) -> (usize, bool)
- where F: FnMut(&T, &T) -> bool
+where
+ F: FnMut(&T, &T) -> bool,
{
let (mid, was_partitioned) = {
// Place the pivot at the beginning of slice.
// Read the pivot into a stack-allocated variable for efficiency. If a following comparison
// operation panics, the pivot will be automatically written back into the slice.
let mut tmp = mem::ManuallyDrop::new(unsafe { ptr::read(pivot) });
- let _pivot_guard = CopyOnDrop {
- src: &mut *tmp,
- dest: pivot,
- };
+ let _pivot_guard = CopyOnDrop { src: &mut *tmp, dest: pivot };
let pivot = &*tmp;
// Find the first pair of out-of-order elements.
/// Returns the number of elements equal to the pivot. It is assumed that `v` does not contain
/// elements smaller than the pivot.
fn partition_equal<T, F>(v: &mut [T], pivot: usize, is_less: &mut F) -> usize
- where F: FnMut(&T, &T) -> bool
+where
+ F: FnMut(&T, &T) -> bool,
{
// Place the pivot at the beginning of slice.
v.swap(0, pivot);
// Read the pivot into a stack-allocated variable for efficiency. If a following comparison
// operation panics, the pivot will be automatically written back into the slice.
let mut tmp = mem::ManuallyDrop::new(unsafe { ptr::read(pivot) });
- let _pivot_guard = CopyOnDrop {
- src: &mut *tmp,
- dest: pivot,
- };
+ let _pivot_guard = CopyOnDrop { src: &mut *tmp, dest: pivot };
let pivot = &*tmp;
// Now partition the slice.
///
/// Elements in `v` might be reordered in the process.
fn choose_pivot<T, F>(v: &mut [T], is_less: &mut F) -> (usize, bool)
- where F: FnMut(&T, &T) -> bool
+where
+ F: FnMut(&T, &T) -> bool,
{
// Minimum length to choose the median-of-medians method.
// Shorter slices use the simple median-of-three method.
/// `limit` is the number of allowed imbalanced partitions before switching to `heapsort`. If zero,
/// this function will immediately switch to heapsort.
fn recurse<'a, T, F>(mut v: &'a mut [T], is_less: &mut F, mut pred: Option<&'a T>, mut limit: usize)
- where F: FnMut(&T, &T) -> bool
+where
+ F: FnMut(&T, &T) -> bool,
{
// Slices of up to this length get sorted using insertion sort.
const MAX_INSERTION: usize = 20;
let mid = partition_equal(v, pivot, is_less);
// Continue sorting elements greater than the pivot.
- v = &mut {v}[mid..];
+ v = &mut { v }[mid..];
continue;
}
}
was_partitioned = was_p;
// Split the slice into `left`, `pivot`, and `right`.
- let (left, right) = {v}.split_at_mut(mid);
+ let (left, right) = { v }.split_at_mut(mid);
let (pivot, right) = right.split_at_mut(1);
let pivot = &pivot[0];
/// Sorts `v` using pattern-defeating quicksort, which is `O(n log n)` worst-case.
pub fn quicksort<T, F>(v: &mut [T], mut is_less: F)
- where F: FnMut(&T, &T) -> bool
+where
+ F: FnMut(&T, &T) -> bool,
{
// Sorting has no meaningful behavior on zero-sized types.
if mem::size_of::<T>() == 0 {
recurse(v, &mut is_less, None, limit);
}
-fn partition_at_index_loop<'a, T, F>( mut v: &'a mut [T], mut index: usize, is_less: &mut F
- , mut pred: Option<&'a T>) where F: FnMut(&T, &T) -> bool
+fn partition_at_index_loop<'a, T, F>(
+ mut v: &'a mut [T],
+ mut index: usize,
+ is_less: &mut F,
+ mut pred: Option<&'a T>,
+) where
+ F: FnMut(&T, &T) -> bool,
{
loop {
// For slices of up to this length it's probably faster to simply sort them.
let (mid, _) = partition(v, pivot, is_less);
// Split the slice into `left`, `pivot`, and `right`.
- let (left, right) = {v}.split_at_mut(mid);
+ let (left, right) = { v }.split_at_mut(mid);
let (pivot, right) = right.split_at_mut(1);
let pivot = &pivot[0];
}
}
-pub fn partition_at_index<T, F>(v: &mut [T], index: usize, mut is_less: F)
- -> (&mut [T], &mut T, &mut [T]) where F: FnMut(&T, &T) -> bool
+pub fn partition_at_index<T, F>(
+ v: &mut [T],
+ index: usize,
+ mut is_less: F,
+) -> (&mut [T], &mut T, &mut [T])
+where
+ F: FnMut(&T, &T) -> bool,
{
- use cmp::Ordering::Less;
use cmp::Ordering::Greater;
+ use cmp::Ordering::Less;
if index >= v.len() {
panic!("partition_at_index index {} greater than length of slice {}", index, v.len());
} else if index == v.len() - 1 {
// Find max element and place it in the last position of the array. We're free to use
// `unwrap()` here because we know v must not be empty.
- let (max_index, _) = v.iter().enumerate().max_by(
- |&(_, x), &(_, y)| if is_less(x, y) { Less } else { Greater }).unwrap();
+ let (max_index, _) = v
+ .iter()
+ .enumerate()
+ .max_by(|&(_, x), &(_, y)| if is_less(x, y) { Less } else { Greater })
+ .unwrap();
v.swap(max_index, index);
} else if index == 0 {
// Find min element and place it in the first position of the array. We're free to use
// `unwrap()` here because we know v must not be empty.
- let (min_index, _) = v.iter().enumerate().min_by(
- |&(_, x), &(_, y)| if is_less(x, y) { Less } else { Greater }).unwrap();
+ let (min_index, _) = v
+ .iter()
+ .enumerate()
+ .min_by(|&(_, x), &(_, y)| if is_less(x, y) { Less } else { Greater })
+ .unwrap();
v.swap(min_index, index);
} else {
partition_at_index_loop(v, index, &mut is_less, None);
mod wake;
#[stable(feature = "futures_api", since = "1.36.0")]
-pub use self::wake::{Context, Waker, RawWaker, RawWakerVTable};
+pub use self::wake::{Context, RawWaker, RawWakerVTable, Waker};
pub enum Poll<T> {
/// Represents that a value is immediately ready.
#[stable(feature = "futures_api", since = "1.36.0")]
- Ready(
- #[stable(feature = "futures_api", since = "1.36.0")]
- T
- ),
+ Ready(#[stable(feature = "futures_api", since = "1.36.0")] T),
/// Represents that a value is not ready yet.
///
/// Changes the ready value of this `Poll` with the closure provided.
#[stable(feature = "futures_api", since = "1.36.0")]
pub fn map<U, F>(self, f: F) -> Poll<U>
- where F: FnOnce(T) -> U
+ where
+ F: FnOnce(T) -> U,
{
match self {
Poll::Ready(t) => Poll::Ready(f(t)),
/// Changes the success value of this `Poll` with the closure provided.
#[stable(feature = "futures_api", since = "1.36.0")]
pub fn map_ok<U, F>(self, f: F) -> Poll<Result<U, E>>
- where F: FnOnce(T) -> U
+ where
+ F: FnOnce(T) -> U,
{
match self {
Poll::Ready(Ok(t)) => Poll::Ready(Ok(f(t))),
/// Changes the error value of this `Poll` with the closure provided.
#[stable(feature = "futures_api", since = "1.36.0")]
pub fn map_err<U, F>(self, f: F) -> Poll<Result<T, U>>
- where F: FnOnce(E) -> U
+ where
+ F: FnOnce(E) -> U,
{
match self {
Poll::Ready(Ok(t)) => Poll::Ready(Ok(t)),
/// Changes the success value of this `Poll` with the closure provided.
#[unstable(feature = "poll_map", issue = "63514")]
pub fn map_ok<U, F>(self, f: F) -> Poll<Option<Result<U, E>>>
- where F: FnOnce(T) -> U
+ where
+ F: FnOnce(T) -> U,
{
match self {
Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(f(t)))),
/// Changes the error value of this `Poll` with the closure provided.
#[unstable(feature = "poll_map", issue = "63514")]
pub fn map_err<U, F>(self, f: F) -> Poll<Option<Result<T, U>>>
- where F: FnOnce(E) -> U
+ where
+ F: FnOnce(E) -> U,
{
match self {
Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(t))),
#[rustc_promotable]
#[stable(feature = "futures_api", since = "1.36.0")]
pub const fn new(data: *const (), vtable: &'static RawWakerVTable) -> RawWaker {
- RawWaker {
- data,
- vtable,
- }
+ RawWaker { data, vtable }
}
}
wake_by_ref: unsafe fn(*const ()),
drop: unsafe fn(*const ()),
) -> Self {
- Self {
- clone,
- wake,
- wake_by_ref,
- drop,
- }
+ Self { clone, wake, wake_by_ref, drop }
}
}
#[stable(feature = "futures_api", since = "1.36.0")]
#[inline]
pub fn from_waker(waker: &'a Waker) -> Self {
- Context {
- waker,
- _marker: PhantomData,
- }
+ Context { waker, _marker: PhantomData }
}
/// Returns a reference to the `Waker` for the current task.
#[stable(feature = "futures_api", since = "1.36.0")]
impl fmt::Debug for Context<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Context")
- .field("waker", &self.waker)
- .finish()
+ f.debug_struct("Context").field("waker", &self.waker).finish()
}
}
#[inline]
#[stable(feature = "futures_api", since = "1.36.0")]
pub unsafe fn from_raw(waker: RawWaker) -> Waker {
- Waker {
- waker,
- }
+ Waker { waker }
}
}
//! assert_eq!(Duration::new(5, 0), Duration::from_secs(5));
//! ```
-use crate::{fmt, u64};
use crate::iter::Sum;
-use crate::ops::{Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign, DivAssign};
+use crate::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
+use crate::{fmt, u64};
const NANOS_PER_SEC: u32 = 1_000_000_000;
const NANOS_PER_MILLI: u32 = 1_000_000;
#[stable(feature = "duration", since = "1.3.0")]
#[inline]
pub fn new(secs: u64, nanos: u32) -> Duration {
- let secs = secs.checked_add((nanos / NANOS_PER_SEC) as u64)
- .expect("overflow in Duration::new");
+ let secs =
+ secs.checked_add((nanos / NANOS_PER_SEC) as u64).expect("overflow in Duration::new");
let nanos = nanos % NANOS_PER_SEC;
Duration { secs, nanos }
}
/// [`subsec_nanos`]: #method.subsec_nanos
#[stable(feature = "duration", since = "1.3.0")]
#[inline]
- pub const fn as_secs(&self) -> u64 { self.secs }
+ pub const fn as_secs(&self) -> u64 {
+ self.secs
+ }
/// Returns the fractional part of this `Duration`, in whole milliseconds.
///
/// ```
#[stable(feature = "duration_extras", since = "1.27.0")]
#[inline]
- pub const fn subsec_millis(&self) -> u32 { self.nanos / NANOS_PER_MILLI }
+ pub const fn subsec_millis(&self) -> u32 {
+ self.nanos / NANOS_PER_MILLI
+ }
/// Returns the fractional part of this `Duration`, in whole microseconds.
///
/// ```
#[stable(feature = "duration_extras", since = "1.27.0")]
#[inline]
- pub const fn subsec_micros(&self) -> u32 { self.nanos / NANOS_PER_MICRO }
+ pub const fn subsec_micros(&self) -> u32 {
+ self.nanos / NANOS_PER_MICRO
+ }
/// Returns the fractional part of this `Duration`, in nanoseconds.
///
/// ```
#[stable(feature = "duration", since = "1.3.0")]
#[inline]
- pub const fn subsec_nanos(&self) -> u32 { self.nanos }
+ pub const fn subsec_nanos(&self) -> u32 {
+ self.nanos
+ }
/// Returns the total number of whole milliseconds contained by this `Duration`.
///
}
}
debug_assert!(nanos < NANOS_PER_SEC);
- Some(Duration {
- secs,
- nanos,
- })
+ Some(Duration { secs, nanos })
} else {
None
}
let total_nanos = self.nanos as u64 * rhs as u64;
let extra_secs = total_nanos / (NANOS_PER_SEC as u64);
let nanos = (total_nanos % (NANOS_PER_SEC as u64)) as u32;
- if let Some(secs) = self.secs
- .checked_mul(rhs as u64)
- .and_then(|s| s.checked_add(extra_secs)) {
+ if let Some(secs) =
+ self.secs.checked_mul(rhs as u64).and_then(|s| s.checked_add(extra_secs))
+ {
debug_assert!(nanos < NANOS_PER_SEC);
- Some(Duration {
- secs,
- nanos,
- })
+ Some(Duration { secs, nanos })
} else {
None
}
#[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
pub fn from_secs_f64(secs: f64) -> Duration {
- const MAX_NANOS_F64: f64 =
- ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64;
- let nanos = secs * (NANOS_PER_SEC as f64);
+ const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1) * (NANOS_PER_SEC as u128)) as f64;
+ let nanos = secs * (NANOS_PER_SEC as f64);
if !nanos.is_finite() {
panic!("got non-finite value when converting float to duration");
}
if nanos < 0.0 {
panic!("underflow when converting float to duration");
}
- let nanos = nanos as u128;
+ let nanos = nanos as u128;
Duration {
secs: (nanos / (NANOS_PER_SEC as u128)) as u64,
nanos: (nanos % (NANOS_PER_SEC as u128)) as u32,
#[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
pub fn from_secs_f32(secs: f32) -> Duration {
- const MAX_NANOS_F32: f32 =
- ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f32;
- let nanos = secs * (NANOS_PER_SEC as f32);
+ const MAX_NANOS_F32: f32 = ((u64::MAX as u128 + 1) * (NANOS_PER_SEC as u128)) as f32;
+ let nanos = secs * (NANOS_PER_SEC as f32);
if !nanos.is_finite() {
panic!("got non-finite value when converting float to duration");
}
if nanos < 0.0 {
panic!("underflow when converting float to duration");
}
- let nanos = nanos as u128;
+ let nanos = nanos as u128;
Duration {
secs: (nanos / (NANOS_PER_SEC as u128)) as u64,
nanos: (nanos % (NANOS_PER_SEC as u128)) as u32,
let mut total_nanos: u64 = 0;
for entry in $iter {
- total_secs = total_secs
- .checked_add(entry.secs)
- .expect("overflow in iter::sum over durations");
+ total_secs =
+ total_secs.checked_add(entry.secs).expect("overflow in iter::sum over durations");
total_nanos = match total_nanos.checked_add(entry.nanos as u64) {
Some(n) => n,
None => {
.checked_add(total_nanos / NANOS_PER_SEC as u64)
.expect("overflow in iter::sum over durations");
total_nanos = total_nanos % NANOS_PER_SEC as u64;
- Duration {
- secs: total_secs,
- nanos: total_nanos as u32,
- }
+ Duration { secs: total_secs, nanos: total_nanos as u32 }
}};
}
#[stable(feature = "duration_sum", since = "1.16.0")]
impl Sum for Duration {
- fn sum<I: Iterator<Item=Duration>>(iter: I) -> Duration {
+ fn sum<I: Iterator<Item = Duration>>(iter: I) -> Duration {
sum_durations!(iter)
}
}
#[stable(feature = "duration_sum", since = "1.16.0")]
impl<'a> Sum<&'a Duration> for Duration {
- fn sum<I: Iterator<Item=&'a Duration>>(iter: I) -> Duration {
+ fn sum<I: Iterator<Item = &'a Duration>>(iter: I) -> Duration {
sum_durations!(iter)
}
}
} else {
// SAFETY: We are only writing ASCII digits into the buffer and it was
// initialized with '0's, so it contains valid UTF8.
- let s = unsafe {
- crate::str::from_utf8_unchecked(&buf[..end])
- };
+ let s = unsafe { crate::str::from_utf8_unchecked(&buf[..end]) };
// If the user request a precision > 9, we pad '0's at the end.
let w = f.precision().unwrap_or(pos);
// See src/libstd/primitive_docs.rs for documentation.
-use crate::cmp::*;
use crate::cmp::Ordering::*;
+use crate::cmp::*;
// macro for implementing n-ary tuple functions and operations
macro_rules! tuple_impls {
/// non-BMP range of most Unicode sets.
pub struct BoolTrie {
// 0..0x800 (corresponding to 1 and 2 byte utf-8 sequences)
- pub r1: [u64; 32], // leaves
+ pub r1: [u64; 32], // leaves
// 0x800..0x10000 (corresponding to 3 byte utf-8 sequences)
pub r2: [u8; 992], // first level
- pub r3: &'static [u64], // leaves
+ pub r3: &'static [u64], // leaves
// 0x10000..0x110000 (corresponding to 4 byte utf-8 sequences)
- pub r4: [u8; 256], // first level
- pub r5: &'static [u8], // second level
- pub r6: &'static [u64], // leaves
+ pub r4: [u8; 256], // first level
+ pub r5: &'static [u8], // second level
+ pub r6: &'static [u64], // leaves
}
impl BoolTrie {
pub fn lookup(&self, c: char) -> bool {
pub struct SmallBoolTrie {
pub(crate) r1: &'static [u8], // first level
- pub(crate) r2: &'static [u64], // leaves
+ pub(crate) r2: &'static [u64], // leaves
}
impl SmallBoolTrie {
/// ```
#[stable(feature = "unit_from_iter", since = "1.23.0")]
impl FromIterator<()> for () {
- fn from_iter<I: IntoIterator<Item=()>>(iter: I) -> Self {
+ fn from_iter<I: IntoIterator<Item = ()>>(iter: I) -> Self {
iter.into_iter().for_each(|()| {})
}
}
/// This is used for the "rust-call" ABI.
pub spread_arg: Option<Local>,
- /// Names and capture modes of all the closure upvars, assuming
- /// the first argument is either the closure or a reference to it.
- //
- // NOTE(eddyb) This is *strictly* a temporary hack for codegen
- // debuginfo generation, and will be removed at some point.
- // Do **NOT** use it for anything else; upvar information should not be
- // in the MIR, so please rely on local crate HIR or other side-channels.
- pub __upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
+ /// Debug information pertaining to user variables, including captures.
+ pub var_debug_info: Vec<VarDebugInfo<'tcx>>,
/// Mark this MIR of a const context other than const functions as having converted a `&&` or
/// `||` expression into `&` or `|` respectively. This is problematic because if we ever stop
basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
source_scopes: IndexVec<SourceScope, SourceScopeData>,
source_scope_local_data: ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
- yield_ty: Option<Ty<'tcx>>,
local_decls: LocalDecls<'tcx>,
user_type_annotations: CanonicalUserTypeAnnotations<'tcx>,
arg_count: usize,
- __upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
+ var_debug_info: Vec<VarDebugInfo<'tcx>>,
span: Span,
control_flow_destroyed: Vec<(Span, String)>,
) -> Self {
basic_blocks,
source_scopes,
source_scope_local_data,
- yield_ty,
+ yield_ty: None,
generator_drop: None,
generator_layout: None,
local_decls,
user_type_annotations,
arg_count,
- __upvar_debuginfo_codegen_only_do_not_use,
spread_arg: None,
+ var_debug_info,
span,
cache: cache::Cache::new(),
control_flow_destroyed,
LocalKind::ReturnPointer
} else if index < self.arg_count + 1 {
LocalKind::Arg
- } else if self.local_decls[local].name.is_some() {
+ } else if self.local_decls[local].is_user_variable() {
LocalKind::Var
} else {
LocalKind::Temp
// FIXME(matthewjasper) Don't store in this in `Body`
pub user_ty: UserTypeProjections,
- /// The name of the local, used in debuginfo and pretty-printing.
- ///
- /// Note that function arguments can also have this set to `Some(_)`
- /// to generate better debuginfo.
- pub name: Option<Name>,
-
/// The *syntactic* (i.e., not visibility) source scope the local is defined
/// in. If the local was defined in a let-statement, this
/// is *within* the let-statement, rather than outside
/// `drop(x)`, we want it to refer to `x: u32`.
///
/// To allow both uses to work, we need to have more than a single scope
- /// for a local. We have the `source_info.scope` represent the
- /// "syntactic" lint scope (with a variable being under its let
- /// block) while the `visibility_scope` represents the "local variable"
+ /// for a local. We have the `source_info.scope` represent the "syntactic"
+ /// lint scope (with a variable being under its let block) while the
+ /// `var_debug_info.source_info.scope` represents the "local variable"
/// scope (where the "rest" of a block is under all prior let-statements).
///
/// The end result looks like this:
/// │ │
/// │ │ │{ let y: u32 }
/// │ │ │
- /// │ │ │← y.visibility_scope
+ /// │ │ │← y.var_debug_info.source_info.scope
/// │ │ │← `y + 2`
/// │
/// │ │{ let x: u32 }
- /// │ │← x.visibility_scope
+ /// │ │← x.var_debug_info.source_info.scope
/// │ │← `drop(x)` // This accesses `x: u32`.
/// ```
pub source_info: SourceInfo,
-
- /// Source scope within which the local is visible (for debuginfo)
- /// (see `source_info` for more details).
- pub visibility_scope: SourceScope,
}
/// Extra information about a local that's used for diagnostics.
mutability,
ty,
user_ty: UserTypeProjections::none(),
- name: None,
source_info: SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE },
- visibility_scope: OUTERMOST_SOURCE_SCOPE,
internal,
local_info: LocalInfo::Other,
is_block_tail: None,
ty: return_ty,
user_ty: UserTypeProjections::none(),
source_info: SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE },
- visibility_scope: OUTERMOST_SOURCE_SCOPE,
internal: false,
is_block_tail: None,
- name: None, // FIXME maybe we do want some name here?
local_info: LocalInfo::Other,
}
}
}
-/// A closure capture, with its name and mode.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub struct UpvarDebuginfo {
- pub debug_name: Name,
+/// Debug information pertaining to a user variable.
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+pub struct VarDebugInfo<'tcx> {
+ pub name: Name,
- /// If true, the capture is behind a reference.
- pub by_ref: bool,
+ /// Source info of the user variable, including the scope
+ /// within which the variable is visible (to debuginfo)
+ /// (see `LocalDecl`'s `source_info` field for more details).
+ pub source_info: SourceInfo,
+
+ /// Where the data for this user variable is to be found.
+ /// NOTE(eddyb) There's an unenforced invariant that this `Place` is
+ /// based on a `Local`, not a `Static`, and contains no indexing.
+ pub place: Place<'tcx>,
}
///////////////////////////////////////////////////////////////////////////
/// have conflicts with each other are allowed to overlap in the computed
/// layout.
pub storage_conflicts: BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal>,
-
- /// The names and scopes of all the stored generator locals.
- ///
- /// N.B., this is *strictly* a temporary hack for codegen
- /// debuginfo generation, and will be removed at some point.
- /// Do **NOT** use it for anything else, local information should not be
- /// in the MIR, please rely on local crate HIR or other side-channels.
- //
- // FIXME(tmandry): see above.
- pub __local_debuginfo_codegen_only_do_not_use: IndexVec<GeneratorSavedLocal, LocalDecl<'tcx>>,
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
MirPhase,
Mutability,
SourceInfo,
- UpvarDebuginfo,
FakeReadCause,
RetagKind,
SourceScope,
self.super_local_decl(local, local_decl);
}
+ fn visit_var_debug_info(&mut self,
+ var_debug_info: & $($mutability)* VarDebugInfo<'tcx>) {
+ self.super_var_debug_info(var_debug_info);
+ }
+
fn visit_local(&mut self,
_local: & $($mutability)? Local,
_context: PlaceContext,
);
}
+ for var_debug_info in &$($mutability)? body.var_debug_info {
+ self.visit_var_debug_info(var_debug_info);
+ }
+
self.visit_span(&$($mutability)? body.span);
}
mutability: _,
ty,
user_ty,
- name: _,
source_info,
- visibility_scope,
internal: _,
local_info: _,
is_block_tail: _,
self.visit_user_type_projection(user_ty);
}
self.visit_source_info(source_info);
- self.visit_source_scope(visibility_scope);
+ }
+
+ fn super_var_debug_info(&mut self,
+ var_debug_info: & $($mutability)? VarDebugInfo<'tcx>) {
+ let VarDebugInfo {
+ name: _,
+ source_info,
+ place,
+ } = var_debug_info;
+
+ self.visit_source_info(source_info);
+ let location = START_BLOCK.start_location();
+ self.visit_place(
+ place,
+ PlaceContext::NonUse(NonUseContext::VarDebugInfo),
+ location,
+ );
}
fn super_source_scope(&mut self,
StorageDead,
/// User type annotation assertions for NLL.
AscribeUserTy,
+ /// The data of an user variable, for debug info.
+ VarDebugInfo,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
) {
// Find all the scopes with variables defined in them.
let mut has_variables = BitSet::new_empty(mir.source_scopes.len());
- // FIXME(eddyb) base this on `decl.name`, or even better, on debuginfo.
// FIXME(eddyb) take into account that arguments always have debuginfo,
// irrespective of their name (assuming full debuginfo is enabled).
- for var in mir.vars_iter() {
- let decl = &mir.local_decls[var];
- has_variables.insert(decl.visibility_scope);
+ for var_debug_info in &mir.var_debug_info {
+ has_variables.insert(var_debug_info.source_info.scope);
}
// Instantiate all scopes.
use crate::value::Value;
use rustc_codegen_ssa::traits::*;
+use rustc_index::vec::{Idx, IndexVec};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc::hir::CodegenFnAttrFlags;
use rustc::hir::def::CtorKind;
use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
use rustc::ich::NodeIdHashingMode;
-use rustc::mir::Field;
-use rustc::mir::GeneratorLayout;
+use rustc::mir::{self, Field, GeneratorLayout};
use rustc::mir::interpret::truncate;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc::ty::Instance;
|| llvm_util::get_major_version() < 8;
}
+// FIXME(eddyb) maybe precompute this? Right now it's computed once
+// per generator monomorphization, but it doesn't depend on substs.
+fn generator_layout_and_saved_local_names(
+ tcx: TyCtxt<'tcx>,
+ def_id: DefId,
+) -> (&'tcx GeneratorLayout<'tcx>, IndexVec<mir::GeneratorSavedLocal, Option<ast::Name>>) {
+ let body = tcx.optimized_mir(def_id);
+ let generator_layout = body.generator_layout.as_ref().unwrap();
+ let mut generator_saved_local_names =
+ IndexVec::from_elem(None, &generator_layout.field_tys);
+
+ let state_arg = mir::PlaceBase::Local(mir::Local::new(1));
+ for var in &body.var_debug_info {
+ if var.place.base != state_arg {
+ continue;
+ }
+ match var.place.projection[..] {
+ [
+ // Deref of the `Pin<&mut Self>` state argument.
+ mir::ProjectionElem::Field(..),
+ mir::ProjectionElem::Deref,
+
+ // Field of a variant of the state.
+ mir::ProjectionElem::Downcast(_, variant),
+ mir::ProjectionElem::Field(field, _),
+ ] => {
+ let name = &mut generator_saved_local_names[
+ generator_layout.variant_fields[variant][field]
+ ];
+ if name.is_none() {
+ name.replace(var.name);
+ }
+ }
+ _ => {}
+ }
+ }
+ (generator_layout, generator_saved_local_names)
+}
+
/// Describes the members of an enum value; an enum is described as a union of
/// structs in DWARF. This `MemberDescriptionFactory` provides the description for
/// the members of this union; so for every variant of the given enum, this
impl EnumMemberDescriptionFactory<'ll, 'tcx> {
fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
-> Vec<MemberDescription<'ll>> {
+ let generator_variant_info_data = match self.enum_type.kind {
+ ty::Generator(def_id, ..) => {
+ Some(generator_layout_and_saved_local_names(cx.tcx, def_id))
+ }
+ _ => None,
+ };
+
let variant_info_for = |index: VariantIdx| {
- match &self.enum_type.kind {
+ match self.enum_type.kind {
ty::Adt(adt, _) => VariantInfo::Adt(&adt.variants[index]),
- ty::Generator(def_id, substs, _) => {
- let generator_layout = cx.tcx.generator_layout(*def_id);
- VariantInfo::Generator(substs, generator_layout, index)
+ ty::Generator(_, substs, _) => {
+ let (generator_layout, generator_saved_local_names) =
+ generator_variant_info_data.as_ref().unwrap();
+ VariantInfo::Generator {
+ substs,
+ generator_layout: *generator_layout,
+ generator_saved_local_names,
+ variant_index: index,
+ }
}
_ => bug!(),
}
}
#[derive(Copy, Clone)]
-enum VariantInfo<'tcx> {
+enum VariantInfo<'a, 'tcx> {
Adt(&'tcx ty::VariantDef),
- Generator(SubstsRef<'tcx>, &'tcx GeneratorLayout<'tcx>, VariantIdx),
+ Generator {
+ substs: SubstsRef<'tcx>,
+ generator_layout: &'tcx GeneratorLayout<'tcx>,
+ generator_saved_local_names: &'a IndexVec<mir::GeneratorSavedLocal, Option<ast::Name>>,
+ variant_index: VariantIdx,
+ },
}
-impl<'tcx> VariantInfo<'tcx> {
+impl<'tcx> VariantInfo<'_, 'tcx> {
fn map_struct_name<R>(&self, f: impl FnOnce(&str) -> R) -> R {
match self {
VariantInfo::Adt(variant) => f(&variant.ident.as_str()),
- VariantInfo::Generator(substs, _, variant_index) =>
+ VariantInfo::Generator { substs, variant_index, .. } =>
f(&substs.as_generator().variant_name(*variant_index)),
}
}
fn variant_name(&self) -> String {
match self {
VariantInfo::Adt(variant) => variant.ident.to_string(),
- VariantInfo::Generator(_, _, variant_index) => {
+ VariantInfo::Generator { variant_index, .. } => {
// Since GDB currently prints out the raw discriminant along
// with every variant, make each variant name be just the value
// of the discriminant. The struct name for the variant includes
}
fn field_name(&self, i: usize) -> String {
- let field_name = match self {
+ let field_name = match *self {
VariantInfo::Adt(variant) if variant.ctor_kind != CtorKind::Fn =>
- Some(variant.fields[i].ident.to_string()),
- VariantInfo::Generator(_, generator_layout, variant_index) => {
- let field = generator_layout.variant_fields[*variant_index][i.into()];
- let decl = &generator_layout.__local_debuginfo_codegen_only_do_not_use[field];
- decl.name.map(|name| name.to_string())
- }
+ Some(variant.fields[i].ident.name),
+ VariantInfo::Generator {
+ generator_layout,
+ generator_saved_local_names,
+ variant_index,
+ ..
+ } => generator_saved_local_names[
+ generator_layout.variant_fields[variant_index][i.into()]
+ ],
_ => None,
};
- field_name.unwrap_or_else(|| format!("__{}", i))
+ field_name.map(|name| name.to_string()).unwrap_or_else(|| format!("__{}", i))
}
}
fn describe_enum_variant(
cx: &CodegenCx<'ll, 'tcx>,
layout: layout::TyLayout<'tcx>,
- variant: VariantInfo<'tcx>,
+ variant: VariantInfo<'_, 'tcx>,
discriminant_info: EnumDiscriminantInfo<'ll>,
containing_scope: &'ll DIScope,
span: Span,
use rustc_data_structures::graph::dominators::Dominators;
use rustc_index::vec::{Idx, IndexVec};
use rustc::mir::{self, Location, TerminatorKind};
-use rustc::mir::visit::{Visitor, PlaceContext, MutatingUseContext, NonMutatingUseContext};
+use rustc::mir::visit::{
+ Visitor, PlaceContext, MutatingUseContext, NonMutatingUseContext, NonUseContext,
+};
use rustc::mir::traversal;
use rustc::session::config::DebugInfo;
use rustc::ty;
// FIXME(eddyb): We should figure out how to use llvm.dbg.value instead
// of putting everything in allocas just so we can use llvm.dbg.declare.
if fx.cx.sess().opts.debuginfo == DebugInfo::Full {
- if mir.local_kind(local) == mir::LocalKind::Arg || decl.name.is_some() {
+ if mir.local_kind(local) == mir::LocalKind::Arg {
analyzer.not_ssa(local);
continue;
}
let cx = self.fx.cx;
if let [proj_base @ .., elem] = place_ref.projection {
+ let mut base_context = if context.is_mutating_use() {
+ PlaceContext::MutatingUse(MutatingUseContext::Projection)
+ } else {
+ PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
+ };
+
// Allow uses of projections that are ZSTs or from scalar fields.
let is_consume = match context {
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
// Recurse with the same context, instead of `Projection`,
// potentially stopping at non-operand projections,
// which would trigger `not_ssa` on locals.
- self.process_place(
- &mir::PlaceRef {
- base: place_ref.base,
- projection: proj_base,
- },
- context,
- location,
- );
- return;
+ base_context = context;
}
}
}
- // A deref projection only reads the pointer, never needs the place.
if let mir::ProjectionElem::Deref = elem {
- self.process_place(
- &mir::PlaceRef {
- base: place_ref.base,
- projection: proj_base,
- },
+ // Deref projections typically only read the pointer.
+ // (the exception being `VarDebugInfo` contexts, handled below)
+ base_context = PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy);
+
+ // Indirect debuginfo requires going through memory, that only
+ // the debugger accesses, following our emitted DWARF pointer ops.
+ //
+ // FIXME(eddyb) Investigate the possibility of relaxing this, but
+ // note that `llvm.dbg.declare` *must* be used for indirect places,
+ // even if we start using `llvm.dbg.value` for all other cases,
+ // as we don't necessarily know when the value changes, but only
+ // where it lives in memory.
+ //
+ // It's possible `llvm.dbg.declare` could support starting from
+ // a pointer that doesn't point to an `alloca`, but this would
+ // only be useful if we know the pointer being `Deref`'d comes
+ // from an immutable place, and if `llvm.dbg.declare` calls
+ // must be at the very start of the function, then only function
+ // arguments could contain such pointers.
+ if context == PlaceContext::NonUse(NonUseContext::VarDebugInfo) {
+ // We use `NonUseContext::VarDebugInfo` for the base,
+ // which might not force the base local to memory,
+ // so we have to do it manually.
+ if let mir::PlaceBase::Local(local) = place_ref.base {
+ self.visit_local(&local, context, location);
+ }
+ }
+ }
+
+ // `NonUseContext::VarDebugInfo` needs to flow all the
+ // way down to the base local (see `visit_local`).
+ if context == PlaceContext::NonUse(NonUseContext::VarDebugInfo) {
+ base_context = context;
+ }
+
+ self.process_place(
+ &mir::PlaceRef {
+ base: place_ref.base,
+ projection: proj_base,
+ },
+ base_context,
+ location
+ );
+ // HACK(eddyb) this emulates the old `visit_projection_elem`, this
+ // entire `visit_place`-like `process_place` method should be rewritten,
+ // now that we have moved to the "slice of projections" representation.
+ if let mir::ProjectionElem::Index(local) = elem {
+ self.visit_local(
+ local,
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
location
);
- return;
}
- }
+ } else {
+ // FIXME this is super_place code, is repeated here to avoid cloning place or changing
+ // visit_place API
+ let mut context = context;
- // FIXME this is super_place code, is repeated here to avoid cloning place or changing
- // visit_place API
- let mut context = context;
+ if !place_ref.projection.is_empty() {
+ context = if context.is_mutating_use() {
+ PlaceContext::MutatingUse(MutatingUseContext::Projection)
+ } else {
+ PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
+ };
+ }
- if !place_ref.projection.is_empty() {
- context = if context.is_mutating_use() {
- PlaceContext::MutatingUse(MutatingUseContext::Projection)
- } else {
- PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
- };
+ self.visit_place_base(place_ref.base, context, location);
+ self.visit_projection(place_ref.base, place_ref.projection, context, location);
}
-
- self.visit_place_base(place_ref.base, context, location);
- self.visit_projection(place_ref.base, place_ref.projection, context, location);
}
}
self.assign(local, location);
}
+ PlaceContext::NonUse(NonUseContext::VarDebugInfo) => {
+ // We need to keep locals in `alloca`s for debuginfo.
+ // FIXME(eddyb): We should figure out how to use `llvm.dbg.value` instead
+ // of putting everything in allocas just so we can use `llvm.dbg.declare`.
+ if self.fx.cx.sess().opts.debuginfo == DebugInfo::Full {
+ self.not_ssa(local);
+ }
+ }
+
PlaceContext::NonUse(_) |
PlaceContext::MutatingUse(MutatingUseContext::Retag) => {}
-use rustc_index::vec::{Idx, IndexVec};
+use rustc_index::vec::IndexVec;
use rustc::hir::def_id::CrateNum;
use rustc::mir;
use rustc::session::config::DebugInfo;
-use rustc::ty::{self, TyCtxt};
-use rustc::ty::layout::{LayoutOf, Size, VariantIdx};
+use rustc::ty::TyCtxt;
+use rustc::ty::layout::{LayoutOf, Size};
use crate::traits::*;
-use syntax_pos::{BytePos, Span, Symbol};
+use syntax_pos::{BytePos, Span};
use syntax::symbol::kw;
use super::{FunctionCx, LocalRef};
Some(per_local) => &per_local[local],
None => return,
};
- let whole_local_var = vars.iter().find(|var| {
+ let whole_local_var = vars.iter().copied().find(|var| {
var.place.projection.is_empty()
});
let has_proj = || vars.iter().any(|var| {
// be offset to account for the hidden environment?
None
} else {
- Some(VarDebugInfo {
+ Some(mir::VarDebugInfo {
name: kw::Invalid,
source_info: self.mir.local_decls[local].source_info,
place: local.into(),
_ => return,
};
- let vars = vars.iter().chain(if whole_local_var.is_none() {
+ let vars = vars.iter().copied().chain(if whole_local_var.is_none() {
fallback_var.as_ref()
} else {
None
}
}
+/// Partition all `VarDebuginfo` in `body`, by their base `Local`.
pub fn per_local_var_debug_info(
tcx: TyCtxt<'tcx>,
- body: &mir::Body<'tcx>,
-) -> Option<IndexVec<mir::Local, Vec<VarDebugInfo<'tcx>>>> {
+ body: &'a mir::Body<'tcx>,
+) -> Option<IndexVec<mir::Local, Vec<&'a mir::VarDebugInfo<'tcx>>>> {
if tcx.sess.opts.debuginfo == DebugInfo::Full || !tcx.sess.fewer_names() {
let mut per_local = IndexVec::from_elem(vec![], &body.local_decls);
- for (local, decl) in body.local_decls.iter_enumerated() {
- if let Some(name) = decl.name {
- per_local[local].push(VarDebugInfo {
- name,
- source_info: mir::SourceInfo {
- span: decl.source_info.span,
- scope: decl.visibility_scope,
- },
- place: local.into(),
- });
- }
- }
-
- let upvar_debuginfo = &body.__upvar_debuginfo_codegen_only_do_not_use;
- if !upvar_debuginfo.is_empty() {
-
- let env_arg = mir::Local::new(1);
- let mut env_projs = vec![];
-
- let pin_did = tcx.lang_items().pin_type();
- match body.local_decls[env_arg].ty.kind {
- ty::RawPtr(_) |
- ty::Ref(..) => {
- env_projs.push(mir::ProjectionElem::Deref);
- }
- ty::Adt(def, substs) if Some(def.did) == pin_did => {
- if let ty::Ref(..) = substs.type_at(0).kind {
- env_projs.push(mir::ProjectionElem::Field(
- mir::Field::new(0),
- // HACK(eddyb) field types aren't used or needed here.
- tcx.types.err,
- ));
- env_projs.push(mir::ProjectionElem::Deref);
- }
- }
- _ => {}
- }
-
- let extra_locals = {
- let upvars = upvar_debuginfo
- .iter()
- .enumerate()
- .map(|(i, upvar)| {
- let source_info = mir::SourceInfo {
- span: body.span,
- scope: mir::OUTERMOST_SOURCE_SCOPE,
- };
- (None, i, upvar.debug_name, upvar.by_ref, source_info)
- });
-
- let generator_fields = body.generator_layout.as_ref().map(|generator_layout| {
- generator_layout.variant_fields.iter()
- .enumerate()
- .flat_map(move |(variant_idx, fields)| {
- let variant_idx = Some(VariantIdx::from(variant_idx));
- fields.iter()
- .enumerate()
- .filter_map(move |(i, field)| {
- let decl = &generator_layout.
- __local_debuginfo_codegen_only_do_not_use[*field];
- if let Some(name) = decl.name {
- let source_info = mir::SourceInfo {
- span: decl.source_info.span,
- scope: decl.visibility_scope,
- };
- Some((variant_idx, i, name, false, source_info))
- } else {
- None
- }
- })
- })
- }).into_iter().flatten();
-
- upvars.chain(generator_fields)
- };
-
- for (variant_idx, field, name, by_ref, source_info) in extra_locals {
- let mut projs = env_projs.clone();
-
- if let Some(variant_idx) = variant_idx {
- projs.push(mir::ProjectionElem::Downcast(None, variant_idx));
- }
-
- projs.push(mir::ProjectionElem::Field(
- mir::Field::new(field),
- // HACK(eddyb) field types aren't used or needed here.
- tcx.types.err,
- ));
-
- if by_ref {
- projs.push(mir::ProjectionElem::Deref);
- }
-
- per_local[env_arg].push(VarDebugInfo {
- name,
- source_info,
- place: mir::Place {
- base: mir::PlaceBase::Local(env_arg),
- projection: tcx.intern_place_elems(&projs),
- },
- });
+ for var in &body.var_debug_info {
+ if let mir::PlaceBase::Local(local) = var.place.base {
+ per_local[local].push(var);
}
}
-
Some(per_local)
} else {
None
}
}
-
-/// Debug information relatating to an user variable.
-// FIXME(eddyb) move this to the MIR bodies themselves.
-#[derive(Clone)]
-pub struct VarDebugInfo<'tcx> {
- pub name: Symbol,
-
- /// Source info of the user variable, including the scope
- /// within which the variable is visible (to debuginfo)
- /// (see `LocalDecl`'s `source_info` field for more details).
- pub source_info: mir::SourceInfo,
-
- /// Where the data for this user variable is to be found.
- pub place: mir::Place<'tcx>,
-}
/// notably `expect`.
locals: IndexVec<mir::Local, LocalRef<'tcx, Bx::Value>>,
- per_local_var_debug_info: Option<IndexVec<mir::Local, Vec<debuginfo::VarDebugInfo<'tcx>>>>,
+ /// All `VarDebuginfo` from the MIR body, partitioned by `Local`.
+ /// This is `None` if no variable debuginfo/names are needed.
+ per_local_var_debug_info: Option<IndexVec<mir::Local, Vec<&'a mir::VarDebugInfo<'tcx>>>>,
}
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
+
+ /// Check if the type is array and emit an unsafe type lint.
+ fn check_for_array_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
+ if let ty::Array(..) = ty.kind {
+ self.emit_ffi_unsafe_type_lint(
+ ty,
+ sp,
+ "passing raw arrays by value is not FFI-safe",
+ Some("consider passing a pointer to the array"),
+ );
+ true
+ } else {
+ false
+ }
+ }
+
+
/// Checks if the given type is "ffi-safe" (has a stable, well-defined
/// representation which can be exported to C code).
fn check_type_for_ffi(&self,
ty::RawPtr(ty::TypeAndMut { ty, .. }) |
ty::Ref(_, ty, _) => self.check_type_for_ffi(cache, ty),
- ty::Array(ty, _) => self.check_type_for_ffi(cache, ty),
+ ty::Array(inner_ty, _) => self.check_type_for_ffi(cache, inner_ty),
ty::FnPtr(sig) => {
match sig.abi() {
}
}
- fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>) {
+ fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>, is_static: bool) {
// We have to check for opaque types before `normalize_erasing_regions`,
// which will replace opaque types with their underlying concrete type.
if self.check_for_opaque_ty(sp, ty) {
// it is only OK to use this function because extern fns cannot have
// any generic types right now:
let ty = self.cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
+ // C doesn't really support passing arrays by value.
+ // The only way to pass an array by value is through a struct.
+ // So we first test that the top level isn't an array,
+ // and then recursively check the types inside.
+ if !is_static && self.check_for_array_ty(sp, ty) {
+ return;
+ }
match self.check_type_for_ffi(&mut FxHashSet::default(), ty) {
FfiResult::FfiSafe => {}
let sig = self.cx.tcx.erase_late_bound_regions(&sig);
for (input_ty, input_hir) in sig.inputs().iter().zip(&decl.inputs) {
- self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty);
+ self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty, false);
}
if let hir::Return(ref ret_hir) = decl.output {
let ret_ty = sig.output();
if !ret_ty.is_unit() {
- self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty);
+ self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty, false);
}
}
}
fn check_foreign_static(&mut self, id: hir::HirId, span: Span) {
let def_id = self.cx.tcx.hir().local_def_id(id);
let ty = self.cx.tcx.type_of(def_id);
- self.check_type_for_ffi_and_report_errors(span, ty);
+ self.check_type_for_ffi_and_report_errors(span, ty, true);
}
}
location,
borrow,
None,
- ).add_explanation_to_diagnostic(self.infcx.tcx, self.body, &mut err, "", Some(borrow_span));
+ ).add_explanation_to_diagnostic(
+ self.infcx.tcx,
+ self.body,
+ &self.local_names,
+ &mut err,
+ "",
+ Some(borrow_span),
+ );
err.buffer(&mut self.errors_buffer);
}
});
self.explain_why_borrow_contains_point(location, borrow, None)
- .add_explanation_to_diagnostic(self.infcx.tcx, self.body, &mut err, "", None);
+ .add_explanation_to_diagnostic(
+ self.infcx.tcx,
+ self.body,
+ &self.local_names,
+ &mut err,
+ "",
+ None,
+ );
err
}
explanation.add_explanation_to_diagnostic(
self.infcx.tcx,
self.body,
+ &self.local_names,
&mut err,
first_borrow_desc,
None,
explanation.add_explanation_to_diagnostic(
self.infcx.tcx,
self.body,
+ &self.local_names,
&mut err,
"",
None,
);
explanation.add_explanation_to_diagnostic(
- self.infcx.tcx, self.body, &mut err, "", None);
+ self.infcx.tcx, self.body, &self.local_names, &mut err, "", None);
}
err
_ => {}
}
- explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.body, &mut err, "", None);
+ explanation.add_explanation_to_diagnostic(
+ self.infcx.tcx,
+ self.body,
+ &self.local_names,
+ &mut err,
+ "",
+ None,
+ );
err.buffer(&mut self.errors_buffer);
}
}
_ => {}
}
- explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.body, &mut err, "", None);
+ explanation.add_explanation_to_diagnostic(
+ self.infcx.tcx,
+ self.body,
+ &self.local_names,
+ &mut err,
+ "",
+ None,
+ );
let within = if borrow_spans.for_generator() {
" by generator"
);
self.explain_why_borrow_contains_point(location, loan, None)
- .add_explanation_to_diagnostic(self.infcx.tcx, self.body, &mut err, "", None);
+ .add_explanation_to_diagnostic(
+ self.infcx.tcx,
+ self.body,
+ &self.local_names,
+ &mut err,
+ "",
+ None,
+ );
err.buffer(&mut self.errors_buffer);
}
assigned_span: Span,
err_place: &Place<'tcx>,
) {
- let (from_arg, local_decl) = if let Some(local) = err_place.as_local() {
- if let LocalKind::Arg = self.body.local_kind(local) {
- (true, Some(&self.body.local_decls[local]))
- } else {
- (false, Some(&self.body.local_decls[local]))
- }
- } else {
- (false, None)
+ let (from_arg, local_decl, local_name) = match err_place.as_local() {
+ Some(local) => (
+ self.body.local_kind(local) == LocalKind::Arg,
+ Some(&self.body.local_decls[local]),
+ self.local_names[local],
+ ),
+ None => (false, None, None),
};
// If root local is initialized immediately (everything apart from let
}
}
if let Some(decl) = local_decl {
- if let Some(name) = decl.name {
+ if let Some(name) = local_name {
if decl.can_be_made_mutable() {
err.span_suggestion(
decl.source_info.span,
/// Appends end-user visible description of the `local` place to `buf`. If `local` doesn't have
/// a name, or its name was generated by the compiler, then `Err` is returned
- fn append_local_to_string(&self, local_index: Local, buf: &mut String) -> Result<(), ()> {
- let local = &self.body.local_decls[local_index];
- match local.name {
- Some(name) if !local.from_compiler_desugaring() => {
+ fn append_local_to_string(&self, local: Local, buf: &mut String) -> Result<(), ()> {
+ let decl = &self.body.local_decls[local];
+ match self.local_names[local] {
+ Some(name) if !decl.from_compiler_desugaring() => {
buf.push_str(&name.as_str());
Ok(())
}
.as_local_hir_id(def_id)
.expect("do_mir_borrowck: non-local DefId");
+ let mut local_names = IndexVec::from_elem(None, &input_body.local_decls);
+ for var_debug_info in &input_body.var_debug_info {
+ if let Some(local) = var_debug_info.place.as_local() {
+ if let Some(prev_name) = local_names[local] {
+ if var_debug_info.name != prev_name {
+ span_bug!(var_debug_info.source_info.span,
+ "local {:?} has many names (`{}` vs `{}`)",
+ local, prev_name, var_debug_info.name);
+ }
+ }
+ local_names[local] = Some(var_debug_info.name);
+ }
+ }
+
// Gather the upvars of a closure, if any.
let tables = tcx.typeck_tables_of(def_id);
let upvars: Vec<_> = tables
free_regions,
body,
&promoted,
+ &local_names,
&upvars,
location_table,
param_env,
borrow_set,
dominators,
upvars,
+ local_names,
};
let mut state = Flows::new(
if let ClearCrossCrate::Set(ref vsi) = mbcx.body.source_scope_local_data {
let local_decl = &mbcx.body.local_decls[local];
- // Skip implicit `self` argument for closures
- if local.index() == 1 && tcx.is_closure(mbcx.mir_def_id) {
- continue;
- }
-
// Skip over locals that begin with an underscore or have no name
- match local_decl.name {
+ match mbcx.local_names[local] {
Some(name) => if name.as_str().starts_with("_") {
continue;
},
/// Information about upvars not necessarily preserved in types or MIR
upvars: Vec<Upvar>,
+
+ /// Names of local (user) variables (extracted from `var_debug_info`).
+ local_names: IndexVec<Local, Option<Name>>,
}
// Check that:
if decl.is_ref_for_guard() {
let mut err = self.cannot_move_out_of(
span,
- &format!("`{}` in pattern guard", decl.name.unwrap()),
+ &format!("`{}` in pattern guard", self.local_names[*local].unwrap()),
);
err.note(
"variables bound in patterns cannot be moved from \
if binds_to.len() == 1 {
self.note_type_does_not_implement_copy(
err,
- &format!("`{}`", bind_to.name.unwrap()),
+ &format!("`{}`", self.local_names[*local].unwrap()),
bind_to.ty,
Some(binding_span)
);
if access_place.as_local().is_some() {
reason = ", as it is not declared as mutable".to_string();
} else {
- let name = self.body.local_decls[*local]
- .name
+ let name = self.local_names[*local]
.expect("immutable unnamed local");
reason = format!(", as `{}` is not declared as mutable", name);
}
// Deliberately fall into this case for all implicit self types,
// so that we don't fall in to the next case with them.
kind == mir::ImplicitSelfKind::MutRef
- } else if Some(kw::SelfLower) == local_decl.name {
+ } else if Some(kw::SelfLower) == self.local_names[*local] {
// Otherwise, check if the name is the self kewyord - in which case
// we have an explicit self. Do the same thing in this case and check
// for a `self: &mut Self` to suggest removing the `&mut`.
err.span_suggestion(
local_decl.source_info.span,
"consider changing this to be mutable",
- format!("mut {}", local_decl.name.unwrap()),
+ format!("mut {}", self.local_names[*local].unwrap()),
Applicability::MachineApplicable,
);
}
);
}
- match local_decl.name {
+ match self.local_names[*local] {
Some(name) if !local_decl.from_compiler_desugaring() => {
err.span_label(
span,
};
use rustc::ty::{self, TyCtxt};
use rustc::ty::adjustment::{PointerCast};
+use rustc_index::vec::IndexVec;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::DiagnosticBuilder;
use syntax_pos::Span;
+use syntax_pos::symbol::Symbol;
mod find_use;
&self,
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
+ local_names: &IndexVec<Local, Option<Symbol>>,
err: &mut DiagnosticBuilder<'_>,
borrow_desc: &str,
borrow_span: Option<Span>,
_ => ("destructor", format!("type `{}`", local_decl.ty)),
};
- match local_decl.name {
+ match local_names[dropped_local] {
Some(local_name) if !local_decl.from_compiler_desugaring() => {
let message = format!(
"{B}borrow might be used here, when `{LOC}` is dropped \
Some(Cause::DropVar(local, location)) => {
let mut should_note_order = false;
- if body.local_decls[local].name.is_some() {
+ if self.local_names[local].is_some() {
if let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place {
if let Some(borrowed_local) = place.as_local() {
- if body.local_decls[borrowed_local].name.is_some()
+ if self.local_names[borrowed_local].is_some()
&& local != borrowed_local
{
should_note_order = true;
let (category, from_closure, span, region_name) =
self.nonlexical_regioncx.free_region_constraint_info(
self.body,
+ &self.local_names,
&self.upvars,
self.mir_def_id,
self.infcx,
Operand::Move(place) => {
if let Some(l) = place.as_local() {
let local_decl = &self.body.local_decls[l];
- if local_decl.name.is_none() {
+ if self.local_names[l].is_none() {
local_decl.source_info.span
} else {
span
use rustc::ty::{self, RegionKind, RegionVid};
use rustc_index::vec::IndexVec;
use rustc_errors::Diagnostic;
+use syntax_pos::symbol::Symbol;
use std::fmt::Debug;
use std::env;
use std::io;
universal_regions: UniversalRegions<'tcx>,
body: &Body<'tcx>,
promoted: &IndexVec<Promoted, Body<'tcx>>,
+ local_names: &IndexVec<Local, Option<Symbol>>,
upvars: &[Upvar],
location_table: &LocationTable,
param_env: ty::ParamEnv<'tcx>,
// Solve the region constraints.
let closure_region_requirements =
- regioncx.solve(infcx, &body, upvars, def_id, errors_buffer);
+ regioncx.solve(infcx, body, local_names, upvars, def_id, errors_buffer);
// Dump MIR results into a file, if that is enabled. This let us
// write unit-tests, as well as helping with debugging.
use rustc::infer::error_reporting::nice_region_error::NiceRegionError;
use rustc::infer::InferCtxt;
use rustc::infer::NLLRegionVariableOrigin;
-use rustc::mir::{ConstraintCategory, Location, Body};
+use rustc::mir::{ConstraintCategory, Local, Location, Body};
use rustc::ty::{self, RegionVid};
use rustc_index::vec::IndexVec;
use rustc_errors::DiagnosticBuilder;
use syntax::errors::Applicability;
use syntax::symbol::kw;
use syntax_pos::Span;
+use syntax_pos::symbol::Symbol;
use self::outlives_suggestion::OutlivesSuggestionBuilder;
/// The MIR body we are reporting errors on (for convenience).
body: &'b Body<'tcx>,
+ /// User variable names for MIR locals (where applicable).
+ local_names: &'b IndexVec<Local, Option<Symbol>>,
+
/// Any upvars for the MIR body we have kept track of during borrow checking.
upvars: &'b [Upvar],
}
pub(super) fn report_error<'a>(
&'a self,
body: &Body<'tcx>,
+ local_names: &IndexVec<Local, Option<Symbol>>,
upvars: &[Upvar],
infcx: &'a InferCtxt<'a, 'tcx>,
mir_def_id: DefId,
fr: RegionVid,
fr_origin: NLLRegionVariableOrigin,
outlived_fr: RegionVid,
- outlives_suggestion: &mut OutlivesSuggestionBuilder,
+ outlives_suggestion: &mut OutlivesSuggestionBuilder<'_>,
renctx: &mut RegionErrorNamingCtx,
) -> DiagnosticBuilder<'a> {
debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr);
infcx,
mir_def_id,
body,
+ local_names,
upvars,
};
renctx: &mut RegionErrorNamingCtx,
) -> DiagnosticBuilder<'_> {
let ErrorReportingCtx {
- infcx, body, upvars, ..
+ infcx, body, upvars, local_names, ..
} = errctx;
let ErrorConstraintInfo {
} = errci;
let fr_name_and_span =
- self.get_var_name_and_span_for_region(infcx.tcx, body, upvars, errci.fr);
- let outlived_fr_name_and_span =
- self.get_var_name_and_span_for_region(infcx.tcx, body, upvars, errci.outlived_fr);
+ self.get_var_name_and_span_for_region(infcx.tcx, body, local_names, upvars, errci.fr);
+ let outlived_fr_name_and_span = self.get_var_name_and_span_for_region(
+ infcx.tcx,
+ body,
+ local_names,
+ upvars,
+ errci.outlived_fr,
+ );
let escapes_from = match self.universal_regions.defining_ty {
DefiningTy::Closure(..) => "closure",
crate fn free_region_constraint_info(
&self,
body: &Body<'tcx>,
+ local_names: &IndexVec<Local, Option<Symbol>>,
upvars: &[Upvar],
mir_def_id: DefId,
infcx: &InferCtxt<'_, 'tcx>,
let mut renctx = RegionErrorNamingCtx::new();
let errctx = ErrorReportingCtx {
- infcx, body, upvars, mir_def_id,
+ infcx, body, local_names, upvars, mir_def_id,
region_infcx: self,
};
let outlived_fr_name = self.give_region_a_name(&errctx, &mut renctx, outlived_region);
use std::collections::BTreeMap;
use log::debug;
-use rustc::{hir::def_id::DefId, infer::InferCtxt, mir::Body, ty::RegionVid};
+use rustc::{hir::def_id::DefId, infer::InferCtxt, ty::RegionVid};
+use rustc::mir::{Body, Local};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{Diagnostic, DiagnosticBuilder};
+use rustc_index::vec::IndexVec;
+use syntax_pos::symbol::Symbol;
use smallvec::SmallVec;
/// corresponding to a function definition.
///
/// Adds a help note suggesting adding a where clause with the needed constraints.
-pub struct OutlivesSuggestionBuilder {
+pub struct OutlivesSuggestionBuilder<'a> {
/// The MIR DefId of the fn with the lifetime error.
mir_def_id: DefId,
+ local_names: &'a IndexVec<Local, Option<Symbol>>,
+
/// The list of outlives constraints that need to be added. Specifically, we map each free
/// region to all other regions that it must outlive. I will use the shorthand `fr:
/// outlived_frs`. Not all of these regions will already have names necessarily. Some could be
constraints_to_add: BTreeMap<RegionVid, Vec<RegionVid>>,
}
-impl OutlivesSuggestionBuilder {
+impl OutlivesSuggestionBuilder<'a> {
/// Create a new builder for the given MIR node representing a fn definition.
- crate fn new(mir_def_id: DefId) -> Self {
- OutlivesSuggestionBuilder { mir_def_id, constraints_to_add: BTreeMap::default() }
+ crate fn new(
+ mir_def_id: DefId,
+ local_names: &'a IndexVec<Local, Option<Symbol>>,
+ ) -> Self {
+ OutlivesSuggestionBuilder {
+ mir_def_id,
+ local_names,
+ constraints_to_add: BTreeMap::default(),
+ }
}
/// Returns `true` iff the `RegionNameSource` is a valid source for an outlives
infcx,
body,
mir_def_id: self.mir_def_id,
+ local_names: self.local_names,
// We should not be suggesting naming upvars, so we pass in a dummy set of upvars that
// should never be used.
use rustc::hir::def::{Res, DefKind};
use rustc::hir::def_id::DefId;
use rustc::infer::InferCtxt;
-use rustc::mir::Body;
+use rustc::mir::{Local, Body};
use rustc::ty::subst::{SubstsRef, GenericArgKind};
use rustc::ty::{self, RegionKind, RegionVid, Ty, TyCtxt};
use rustc::ty::print::RegionHighlightMode;
+use rustc_index::vec::IndexVec;
use rustc_errors::DiagnosticBuilder;
use syntax::symbol::kw;
use rustc_data_structures::fx::FxHashMap;
fr: RegionVid,
) -> Option<RegionName> {
let ErrorReportingCtx {
- infcx, body, mir_def_id, upvars, ..
+ infcx, body, mir_def_id, local_names, upvars, ..
} = errctx;
debug!("give_region_a_name(fr={:?}, counter={:?})", fr, renctx.counter);
.give_name_from_error_region(infcx.tcx, *mir_def_id, fr, renctx)
.or_else(|| {
self.give_name_if_anonymous_region_appears_in_arguments(
- infcx, body, *mir_def_id, fr, renctx,
+ infcx, body, local_names, *mir_def_id, fr, renctx,
)
})
.or_else(|| {
&self,
infcx: &InferCtxt<'_, 'tcx>,
body: &Body<'tcx>,
+ local_names: &IndexVec<Local, Option<Symbol>>,
mir_def_id: DefId,
fr: RegionVid,
renctx: &mut RegionErrorNamingCtx,
return Some(region_name);
}
- self.give_name_if_we_cannot_match_hir_ty(infcx, body, fr, arg_ty, renctx)
+ self.give_name_if_we_cannot_match_hir_ty(infcx, body, local_names, fr, arg_ty, renctx)
}
fn give_name_if_we_can_match_hir_ty_from_argument(
&self,
infcx: &InferCtxt<'_, 'tcx>,
body: &Body<'tcx>,
+ local_names: &IndexVec<Local, Option<Symbol>>,
needle_fr: RegionVid,
argument_ty: Ty<'tcx>,
renctx: &mut RegionErrorNamingCtx,
let assigned_region_name = if type_name.find(&format!("'{}", counter)).is_some() {
// Only add a label if we can confirm that a region was labelled.
let argument_index = self.get_argument_index_for_region(infcx.tcx, needle_fr)?;
- let (_, span) = self.get_argument_name_and_span_for_region(body, argument_index);
+ let (_, span) =
+ self.get_argument_name_and_span_for_region(body, local_names, argument_index);
Some(RegionName {
// This counter value will already have been used, so this function will increment
use crate::borrow_check::Upvar;
use rustc::mir::{Local, Body};
use rustc::ty::{RegionVid, TyCtxt};
-use rustc_index::vec::Idx;
+use rustc_index::vec::{Idx, IndexVec};
use syntax::source_map::Span;
use syntax_pos::symbol::Symbol;
&self,
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
+ local_names: &IndexVec<Local, Option<Symbol>>,
upvars: &[Upvar],
fr: RegionVid,
) -> Option<(Option<Symbol>, Span)> {
})
.or_else(|| {
debug!("get_var_name_and_span_for_region: attempting argument");
- self.get_argument_index_for_region(tcx, fr)
- .map(|index| self.get_argument_name_and_span_for_region(body, index))
+ self.get_argument_index_for_region(tcx, fr).map(|index| {
+ self.get_argument_name_and_span_for_region(body, local_names, index)
+ })
})
}
crate fn get_argument_name_and_span_for_region(
&self,
body: &Body<'tcx>,
+ local_names: &IndexVec<Local, Option<Symbol>>,
argument_index: usize,
) -> (Option<Symbol>, Span) {
let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
let argument_local = Local::new(implicit_inputs + argument_index + 1);
debug!("get_argument_name_and_span_for_region: argument_local={:?}", argument_local);
- let argument_name = body.local_decls[argument_local].name;
+ let argument_name = local_names[argument_local];
let argument_span = body.local_decls[argument_local].source_info.span;
debug!("get_argument_name_and_span_for_region: argument_name={:?} argument_span={:?}",
argument_name, argument_span);
use rustc_index::vec::IndexVec;
use rustc_errors::{Diagnostic, DiagnosticBuilder};
use syntax_pos::Span;
+use syntax_pos::symbol::Symbol;
crate use self::error_reporting::{RegionName, RegionNameSource, RegionErrorNamingCtx};
use self::values::{LivenessValues, RegionValueElements, RegionValues};
&mut self,
infcx: &InferCtxt<'_, 'tcx>,
body: &Body<'tcx>,
+ local_names: &IndexVec<Local, Option<Symbol>>,
upvars: &[Upvar],
mir_def_id: DefId,
errors_buffer: &mut Vec<Diagnostic>,
self.check_universal_regions(
infcx,
body,
+ local_names,
upvars,
mir_def_id,
outlives_requirements.as_mut(),
&self,
infcx: &InferCtxt<'_, 'tcx>,
body: &Body<'tcx>,
+ local_names: &IndexVec<Local, Option<Symbol>>,
upvars: &[Upvar],
mir_def_id: DefId,
mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
errors_buffer: &mut Vec<Diagnostic>,
region_naming: &mut RegionErrorNamingCtx,
) {
- let mut outlives_suggestion = OutlivesSuggestionBuilder::new(mir_def_id);
+ let mut outlives_suggestion = OutlivesSuggestionBuilder::new(mir_def_id, local_names);
for (fr, fr_definition) in self.definitions.iter_enumerated() {
match fr_definition.origin {
self.check_universal_region(
infcx,
body,
+ local_names,
upvars,
mir_def_id,
fr,
&self,
infcx: &InferCtxt<'_, 'tcx>,
body: &Body<'tcx>,
+ local_names: &IndexVec<Local, Option<Symbol>>,
upvars: &[Upvar],
mir_def_id: DefId,
longer_fr: RegionVid,
propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
- outlives_suggestion: &mut OutlivesSuggestionBuilder,
+ outlives_suggestion: &mut OutlivesSuggestionBuilder<'_>,
errors_buffer: &mut Vec<Diagnostic>,
region_naming: &mut RegionErrorNamingCtx,
) {
representative,
infcx,
body,
+ local_names,
upvars,
mir_def_id,
propagated_outlives_requirements,
shorter_fr,
infcx,
body,
+ local_names,
upvars,
mir_def_id,
propagated_outlives_requirements,
shorter_fr: RegionVid,
infcx: &InferCtxt<'_, 'tcx>,
body: &Body<'tcx>,
+ local_names: &IndexVec<Local, Option<Symbol>>,
upvars: &[Upvar],
mir_def_id: DefId,
propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
- outlives_suggestion: &mut OutlivesSuggestionBuilder,
+ outlives_suggestion: &mut OutlivesSuggestionBuilder<'_>,
errors_buffer: &mut Vec<Diagnostic>,
region_naming: &mut RegionErrorNamingCtx,
) -> Option<ErrorReported> {
// error. This gives better error messages in some cases.
let db = self.report_error(
body,
+ local_names,
upvars,
infcx,
mir_def_id,
};
// If the user explicitly annotated the output types, enforce those.
+ // Note that this only happens for closures.
if let Some(user_provided_sig) = user_provided_sig {
let user_provided_output_ty = user_provided_sig.output();
let user_provided_output_ty =
self.normalize(user_provided_output_ty, Locations::All(output_span));
- self.equate_normalized_input_or_output(
- user_provided_output_ty,
+ if let Err(err) = self.eq_opaque_type_and_type(
mir_output_ty,
- output_span,
- );
+ user_provided_output_ty,
+ self.mir_def_id,
+ Locations::All(output_span),
+ ConstraintCategory::BoringNoLocation
+ ) {
+ span_mirbug!(
+ self,
+ Location::START,
+ "equate_inputs_and_outputs: `{:?}=={:?}` failed with `{:?}`",
+ mir_output_ty,
+ user_provided_output_ty,
+ err
+ );
+ }
}
}
mutability: Mutability::Mut,
ty: ptr_ty,
user_ty: UserTypeProjections::none(),
- name: None,
source_info,
- visibility_scope: source_info.scope,
internal: true,
local_info: LocalInfo::Other,
is_block_tail: None,
);
let tcx = self.hir.tcx();
+ let debug_source_info = SourceInfo {
+ span: source_info.span,
+ scope: visibility_scope,
+ };
let binding_mode = match mode {
BindingMode::ByValue => ty::BindingMode::BindByValue(mutability.into()),
BindingMode::ByRef(_) => ty::BindingMode::BindByReference(mutability.into()),
mutability,
ty: var_ty,
user_ty,
- name: Some(name),
source_info,
- visibility_scope,
internal: false,
is_block_tail: None,
local_info: LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
))),
};
let for_arm_body = self.local_decls.push(local);
+ self.var_debug_info.push(VarDebugInfo {
+ name,
+ source_info: debug_source_info,
+ place: for_arm_body.into(),
+ });
let locals = if has_guard.0 {
let ref_for_guard = self.local_decls.push(LocalDecl::<'tcx> {
// This variable isn't mutated but has a name, so has to be
mutability: Mutability::Not,
ty: tcx.mk_imm_ref(tcx.lifetimes.re_erased, var_ty),
user_ty: UserTypeProjections::none(),
- name: Some(name),
source_info,
- visibility_scope,
internal: false,
is_block_tail: None,
local_info: LocalInfo::User(ClearCrossCrate::Set(BindingForm::RefForGuard)),
});
+ self.var_debug_info.push(VarDebugInfo {
+ name,
+ source_info: debug_source_info,
+ place: ref_for_guard.into(),
+ });
LocalsForNode::ForGuard {
ref_for_guard,
for_arm_body,
(None, fn_sig.output())
};
- build::construct_fn(cx, id, arguments, safety, abi,
- return_ty, yield_ty, return_ty_span, body)
+ let mut mir = build::construct_fn(
+ cx,
+ id,
+ arguments,
+ safety,
+ abi,
+ return_ty,
+ return_ty_span,
+ body,
+ );
+ mir.yield_ty = yield_ty;
+ mir
} else {
// Get the revealed type of this const. This is *not* the adjusted
// type of its body, which may be a subtype of this type. For
var_indices: HirIdMap<LocalsForNode>,
local_decls: IndexVec<Local, LocalDecl<'tcx>>,
canonical_user_type_annotations: ty::CanonicalUserTypeAnnotations<'tcx>,
- __upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
upvar_mutbls: Vec<Mutability>,
unit_temp: Option<Place<'tcx>>,
+ var_debug_info: Vec<VarDebugInfo<'tcx>>,
+
/// Cached block with the `RESUME` terminator; this is created
/// when first set of cleanups are built.
cached_resume_block: Option<BasicBlock>,
safety: Safety,
abi: Abi,
return_ty: Ty<'tcx>,
- yield_ty: Option<Ty<'tcx>>,
return_ty_span: Span,
body: &'tcx hir::Body,
) -> Body<'tcx>
let tcx_hir = tcx.hir();
let span = tcx_hir.span(fn_id);
- let hir_tables = hir.tables();
let fn_def_id = tcx_hir.local_def_id(fn_id);
- // Gather the upvars of a closure, if any.
- let mut upvar_mutbls = vec![];
- // In analyze_closure() in upvar.rs we gathered a list of upvars used by a
- // closure and we stored in a map called upvar_list in TypeckTables indexed
- // with the closure's DefId. Here, we run through that vec of UpvarIds for
- // the given closure and use the necessary information to create UpvarDecl.
- let upvar_debuginfo: Vec<_> = hir_tables
- .upvar_list
- .get(&fn_def_id)
- .into_iter()
- .flatten()
- .map(|(&var_hir_id, &upvar_id)| {
- let capture = hir_tables.upvar_capture(upvar_id);
- let by_ref = match capture {
- ty::UpvarCapture::ByValue => false,
- ty::UpvarCapture::ByRef(..) => true,
- };
- let mut debuginfo = UpvarDebuginfo {
- debug_name: kw::Invalid,
- by_ref,
- };
- let mut mutability = Mutability::Not;
- if let Some(Node::Binding(pat)) = tcx_hir.find(var_hir_id) {
- if let hir::PatKind::Binding(_, _, ident, _) = pat.kind {
- debuginfo.debug_name = ident.name;
- if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) {
- if bm == ty::BindByValue(hir::Mutability::Mutable) {
- mutability = Mutability::Mut;
- } else {
- mutability = Mutability::Not;
- }
- } else {
- tcx.sess.delay_span_bug(pat.span, "missing binding mode");
- }
- }
- }
- upvar_mutbls.push(mutability);
- debuginfo
- })
- .collect();
-
let mut builder = Builder::new(hir,
span,
arguments.len(),
safety,
return_ty,
return_ty_span,
- upvar_debuginfo,
- upvar_mutbls,
body.generator_kind.is_some());
let call_site_scope = region::Scope {
Place::return_place(),
|builder| {
builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
- builder.args_and_body(block, &arguments, arg_scope, &body.value)
+ builder.args_and_body(block, fn_def_id, &arguments, arg_scope, &body.value)
})
},
));
info!("fn_id {:?} has attrs {:?}", fn_def_id,
tcx.get_attrs(fn_def_id));
- let mut body = builder.finish(yield_ty);
+ let mut body = builder.finish();
body.spread_arg = spread_arg;
body
}
Safety::Safe,
const_ty,
const_ty_span,
- vec![],
- vec![],
false,
);
TerminatorKind::Unreachable);
}
- builder.finish(None)
+ builder.finish()
}
fn construct_error<'a, 'tcx>(
let owner_id = hir.tcx().hir().body_owner(body_id);
let span = hir.tcx().hir().span(owner_id);
let ty = hir.tcx().types.err;
- let mut builder = Builder::new(hir, span, 0, Safety::Safe, ty, span, vec![], vec![], false);
+ let mut builder = Builder::new(hir, span, 0, Safety::Safe, ty, span, false);
let source_info = builder.source_info(span);
builder.cfg.terminate(START_BLOCK, source_info, TerminatorKind::Unreachable);
- builder.finish(None)
+ builder.finish()
}
impl<'a, 'tcx> Builder<'a, 'tcx> {
safety: Safety,
return_ty: Ty<'tcx>,
return_span: Span,
- __upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
- upvar_mutbls: Vec<Mutability>,
is_generator: bool)
-> Builder<'a, 'tcx> {
let lint_level = LintLevel::Explicit(hir.root_lint_level);
1,
),
canonical_user_type_annotations: IndexVec::new(),
- __upvar_debuginfo_codegen_only_do_not_use,
- upvar_mutbls,
+ upvar_mutbls: vec![],
var_indices: Default::default(),
unit_temp: None,
+ var_debug_info: vec![],
cached_resume_block: None,
cached_return_block: None,
cached_unreachable_block: None,
builder
}
- fn finish(self,
- yield_ty: Option<Ty<'tcx>>)
- -> Body<'tcx> {
+ fn finish(self) -> Body<'tcx> {
for (index, block) in self.cfg.basic_blocks.iter().enumerate() {
if block.terminator.is_none() {
span_bug!(self.fn_span, "no terminator on block {:?}", index);
self.cfg.basic_blocks,
self.source_scopes,
ClearCrossCrate::Set(self.source_scope_local_data),
- yield_ty,
self.local_decls,
self.canonical_user_type_annotations,
self.arg_count,
- self.__upvar_debuginfo_codegen_only_do_not_use,
+ self.var_debug_info,
self.fn_span,
self.hir.control_flow_destroyed(),
)
fn args_and_body(&mut self,
mut block: BasicBlock,
+ fn_def_id: DefId,
arguments: &[ArgInfo<'tcx>],
argument_scope: region::Scope,
ast_body: &'tcx hir::Expr)
{
// Allocate locals for the function arguments
for &ArgInfo(ty, _, arg_opt, _) in arguments.iter() {
- // If this is a simple binding pattern, give the local a name for
- // debuginfo and so that error reporting knows that this is a user
- // variable. For any other pattern the pattern introduces new
- // variables which will be named instead.
- let (name, span) = if let Some(arg) = arg_opt {
- (arg.pat.simple_ident().map(|ident| ident.name), arg.pat.span)
- } else {
- (None, self.fn_span)
+ let source_info = SourceInfo {
+ scope: OUTERMOST_SOURCE_SCOPE,
+ span: arg_opt.map_or(self.fn_span, |arg| arg.pat.span)
};
-
- let source_info = SourceInfo { scope: OUTERMOST_SOURCE_SCOPE, span, };
- self.local_decls.push(LocalDecl {
+ let arg_local = self.local_decls.push(LocalDecl {
mutability: Mutability::Mut,
ty,
user_ty: UserTypeProjections::none(),
source_info,
- visibility_scope: source_info.scope,
- name,
internal: false,
local_info: LocalInfo::Other,
is_block_tail: None,
});
+
+ // If this is a simple binding pattern, give debuginfo a nice name.
+ if let Some(arg) = arg_opt {
+ if let Some(ident) = arg.pat.simple_ident() {
+ self.var_debug_info.push(VarDebugInfo {
+ name: ident.name,
+ source_info,
+ place: arg_local.into(),
+ });
+ }
+ }
+ }
+
+ let tcx = self.hir.tcx();
+ let tcx_hir = tcx.hir();
+ let hir_tables = self.hir.tables();
+
+ // In analyze_closure() in upvar.rs we gathered a list of upvars used by a
+ // closure and we stored in a map called upvar_list in TypeckTables indexed
+ // with the closure's DefId. Here, we run through that vec of UpvarIds for
+ // the given closure and use the necessary information to create upvar
+ // debuginfo and to fill `self.upvar_mutbls`.
+ if let Some(upvars) = hir_tables.upvar_list.get(&fn_def_id) {
+ let closure_env_arg = Local::new(1);
+ let mut closure_env_projs = vec![];
+ let mut closure_ty = self.local_decls[closure_env_arg].ty;
+ if let ty::Ref(_, ty, _) = closure_ty.kind {
+ closure_env_projs.push(ProjectionElem::Deref);
+ closure_ty = ty;
+ }
+ let (def_id, upvar_substs) = match closure_ty.kind {
+ ty::Closure(def_id, substs) => (def_id, ty::UpvarSubsts::Closure(substs)),
+ ty::Generator(def_id, substs, _) => (def_id, ty::UpvarSubsts::Generator(substs)),
+ _ => span_bug!(self.fn_span, "upvars with non-closure env ty {:?}", closure_ty)
+ };
+ let upvar_tys = upvar_substs.upvar_tys(def_id, tcx);
+ let upvars_with_tys = upvars.iter().zip(upvar_tys);
+ self.upvar_mutbls = upvars_with_tys.enumerate().map(|(i, ((&var_id, &upvar_id), ty))| {
+ let capture = hir_tables.upvar_capture(upvar_id);
+
+ let mut mutability = Mutability::Not;
+ let mut name = kw::Invalid;
+ if let Some(Node::Binding(pat)) = tcx_hir.find(var_id) {
+ if let hir::PatKind::Binding(_, _, ident, _) = pat.kind {
+ name = ident.name;
+
+ if let Some(&bm) = hir_tables.pat_binding_modes().get(pat.hir_id) {
+ if bm == ty::BindByValue(hir::Mutability::Mutable) {
+ mutability = Mutability::Mut;
+ } else {
+ mutability = Mutability::Not;
+ }
+ } else {
+ tcx.sess.delay_span_bug(pat.span, "missing binding mode");
+ }
+ }
+ }
+
+ let mut projs = closure_env_projs.clone();
+ projs.push(ProjectionElem::Field(Field::new(i), ty));
+ match capture {
+ ty::UpvarCapture::ByValue => {}
+ ty::UpvarCapture::ByRef(..) => {
+ projs.push(ProjectionElem::Deref);
+ }
+ };
+
+ self.var_debug_info.push(VarDebugInfo {
+ name,
+ source_info: SourceInfo {
+ scope: OUTERMOST_SOURCE_SCOPE,
+ span: tcx_hir.span(var_id),
+ },
+ place: Place {
+ base: closure_env_arg.into(),
+ projection: tcx.intern_place_elems(&projs),
+ },
+ });
+
+ mutability
+ }).collect();
}
let mut scope = None;
mutability,
ty,
user_ty: UserTypeProjections::none(),
- name: None,
source_info,
- visibility_scope: source_info.scope,
internal: false,
local_info: LocalInfo::Other,
is_block_tail: None,
SourceScopeData { span: span, parent_scope: None }, 1
),
ClearCrossCrate::Clear,
- None,
local_decls_for_sig(&sig, span),
IndexVec::new(),
sig.inputs().len(),
SourceScopeData { span: self.span, parent_scope: None }, 1
),
ClearCrossCrate::Clear,
- None,
self.local_decls,
IndexVec::new(),
self.sig.inputs().len(),
SourceScopeData { span: span, parent_scope: None }, 1
),
ClearCrossCrate::Clear,
- None,
local_decls,
IndexVec::new(),
sig.inputs().len(),
SourceScopeData { span: span, parent_scope: None }, 1
),
ClearCrossCrate::Clear,
- None,
local_decls,
IndexVec::new(),
sig.inputs().len(),
body.basic_blocks().clone(),
Default::default(),
ClearCrossCrate::Clear,
- None,
body.local_decls.clone(),
Default::default(),
body.arg_count,
use rustc_index::bit_set::{BitSet, BitMatrix};
use std::borrow::Cow;
use std::iter;
-use std::mem;
use crate::transform::{MirPass, MirSource};
use crate::transform::simplify;
use crate::transform::no_landing_pads::no_landing_pads;
mutability: Mutability::Mut,
ty: ret_ty,
user_ty: UserTypeProjections::none(),
- name: None,
source_info,
- visibility_scope: source_info.scope,
internal: false,
is_block_tail: None,
local_info: LocalInfo::Other
}
}
- let dummy_local = LocalDecl::new_internal(tcx.mk_unit(), body.span);
-
- // Gather live locals and their indices replacing values in body.local_decls
- // with a dummy to avoid changing local indices.
+ // Gather live local types and their indices.
let mut locals = IndexVec::<GeneratorSavedLocal, _>::new();
let mut tys = IndexVec::<GeneratorSavedLocal, _>::new();
- let mut decls = IndexVec::<GeneratorSavedLocal, _>::new();
for (idx, local) in live_locals.iter().enumerate() {
- let var = mem::replace(&mut body.local_decls[local], dummy_local.clone());
locals.push(local);
- tys.push(var.ty);
- decls.push(var);
+ tys.push(body.local_decls[local].ty);
debug!("generator saved local {:?} => {:?}", GeneratorSavedLocal::from(idx), local);
}
field_tys: tys,
variant_fields,
storage_conflicts,
- __local_debuginfo_codegen_only_do_not_use: decls,
};
(remap, layout, storage_liveness)
mutability: Mutability::Mut,
ty: tcx.mk_unit(),
user_ty: UserTypeProjections::none(),
- name: None,
source_info,
- visibility_scope: source_info.scope,
internal: false,
is_block_tail: None,
local_info: LocalInfo::Other
mutbl: hir::Mutability::Mutable,
}),
user_ty: UserTypeProjections::none(),
- name: None,
source_info,
- visibility_scope: source_info.scope,
internal: false,
is_block_tail: None,
local_info: LocalInfo::Other
debug!("should_inline({:?})", callsite);
let tcx = self.tcx;
- // Don't inline closures that have capture debuginfo
- // FIXME: Handle closures better
- if callee_body.__upvar_debuginfo_codegen_only_do_not_use.len() > 0 {
- debug!(" upvar debuginfo present - not inlining");
- return false;
- }
-
// Cannot inline generators which haven't been transformed yet
if callee_body.yield_ty.is_some() {
debug!(" yield ty present - not inlining");
local.source_info.scope =
scope_map[local.source_info.scope];
local.source_info.span = callsite.location.span;
- local.visibility_scope = scope_map[local.visibility_scope];
let idx = caller_body.local_decls.push(local);
local_map.push(idx);
tcx: self.tcx,
};
+ for mut var_debug_info in callee_body.var_debug_info.drain(..) {
+ integrator.visit_var_debug_info(&mut var_debug_info);
+ caller_body.var_debug_info.push(var_debug_info);
+ }
for (bb, mut block) in callee_body.basic_blocks_mut().drain_enumerated(..) {
integrator.visit_basic_block_data(bb, &mut block);
// memory usage?
body.source_scopes.clone(),
body.source_scope_local_data.clone(),
- None,
initial_locals,
IndexVec::new(),
0,
use rustc::ty::TyCtxt;
use rustc::mir::*;
use rustc::mir::visit::{MutVisitor, Visitor, PlaceContext, MutatingUseContext};
-use rustc::session::config::DebugInfo;
use std::borrow::Cow;
use crate::transform::{MirPass, MirSource};
marker.locals.insert(arg);
}
- // We may need to keep dead user variables live for debuginfo.
- if tcx.sess.opts.debuginfo == DebugInfo::Full {
- for local in body.vars_iter() {
- marker.locals.insert(local);
- }
- }
-
marker.locals
};
match context {
PlaceContext::NonUse(NonUseContext::StorageLive) => local_use.alive = Some(location),
PlaceContext::NonUse(NonUseContext::StorageDead) => local_use.dead = Some(location),
+ PlaceContext::NonUse(NonUseContext::VarDebugInfo) => {}
_ => {
local_use.use_count += 1;
if local_use.first_use.is_none() {
//! Def-use analysis.
-use rustc::mir::{Body, Local, Location, PlaceElem};
+use rustc::mir::{Body, Local, Location, PlaceElem, VarDebugInfo};
use rustc::mir::visit::{PlaceContext, MutVisitor, Visitor};
use rustc::ty::TyCtxt;
use rustc_index::vec::IndexVec;
#[derive(Clone)]
pub struct Info {
+ // FIXME(eddyb) use smallvec where possible.
pub defs_and_uses: Vec<Use>,
+ var_debug_info_indices: Vec<usize>,
}
#[derive(Clone)]
let mut finder = DefUseFinder {
info: mem::take(&mut self.info),
+ var_debug_info_index: 0,
+ in_var_debug_info: false,
};
finder.visit_body(body);
self.info = finder.info
new_local: Local,
tcx: TyCtxt<'tcx>,
) {
- for place_use in &self.info[local].defs_and_uses {
- MutateUseVisitor::new(local, new_local, body, tcx)
- .visit_location(body, place_use.location)
+ let mut visitor = MutateUseVisitor::new(local, new_local, body, tcx);
+ let info = &self.info[local];
+ for place_use in &info.defs_and_uses {
+ visitor.visit_location(body, place_use.location)
+ }
+ // Update debuginfo as well, alongside defs/uses.
+ for &i in &info.var_debug_info_indices {
+ visitor.visit_var_debug_info(&mut body.var_debug_info[i]);
}
}
struct DefUseFinder {
info: IndexVec<Local, Info>,
+ var_debug_info_index: usize,
+ in_var_debug_info: bool,
}
impl Visitor<'_> for DefUseFinder {
&local: &Local,
context: PlaceContext,
location: Location) {
- self.info[local].defs_and_uses.push(Use {
- context,
- location,
- });
+ let info = &mut self.info[local];
+ if self.in_var_debug_info {
+ info.var_debug_info_indices.push(self.var_debug_info_index);
+ } else {
+ info.defs_and_uses.push(Use {
+ context,
+ location,
+ });
+ }
+ }
+ fn visit_var_debug_info(&mut self, var_debug_info: &VarDebugInfo<'tcx>) {
+ assert!(!self.in_var_debug_info);
+ self.in_var_debug_info = true;
+ self.super_var_debug_info(var_debug_info);
+ self.in_var_debug_info = false;
+ self.var_debug_info_index += 1;
}
}
fn new() -> Info {
Info {
defs_and_uses: vec![],
+ var_debug_info_indices: vec![],
}
}
fn clear(&mut self) {
self.defs_and_uses.clear();
+ self.var_debug_info_indices.clear();
}
pub fn def_count(&self) -> usize {
write!(w, "mut ")?;
}
- if let Some(name) = decl.name {
- write!(w, r#"{:?}: {}; // {}<br align="left"/>"#,
- Place::from(local), escape(&decl.ty), name)?;
- } else {
- write!(w, r#"{:?}: {};<br align="left"/>"#,
- Place::from(local), escape(&decl.ty))?;
- }
+ write!(w, r#"{:?}: {};<br align="left"/>"#,
+ Place::from(local), escape(&decl.ty))?;
+ }
+
+ for var_debug_info in &body.var_debug_info {
+ write!(w, r#"debug {} => {};<br align="left"/>"#,
+ var_debug_info.name, escape(&var_debug_info.place))?;
}
writeln!(w, ">;")
PlaceContext::MutatingUse(MutatingUseContext::Drop) =>
Some(DefUse::Drop),
+
+ // Debug info is neither def nor use.
+ PlaceContext::NonUse(NonUseContext::VarDebugInfo) => None,
}
}
) -> io::Result<()> {
let indent = depth * INDENT.len();
+ // Local variable debuginfo.
+ for var_debug_info in &body.var_debug_info {
+ if var_debug_info.source_info.scope != parent {
+ // Not declared in this scope.
+ continue;
+ }
+
+ let indented_debug_info = format!(
+ "{0:1$}debug {2} => {3:?};",
+ INDENT,
+ indent,
+ var_debug_info.name,
+ var_debug_info.place,
+ );
+
+ writeln!(
+ w,
+ "{0:1$} // in {2}",
+ indented_debug_info,
+ ALIGN,
+ comment(tcx, var_debug_info.source_info),
+ )?;
+ }
+
// Local variable types (including the user's name in a comment).
for (local, local_decl) in body.local_decls.iter_enumerated() {
if (1..body.arg_count+1).contains(&local.index()) {
let local_name = if local == RETURN_PLACE {
format!(" return place")
- } else if let Some(name) = local_decl.name {
- format!(" \"{}\"", name)
} else {
String::new()
};
use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
use crate::hir::def_id::DefId;
-use rustc::traits::{self, ObligationCauseCode};
+use rustc::traits::{self, ObligationCause, ObligationCauseCode};
use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable, ToPredicate};
use rustc::ty::subst::{Subst, InternalSubsts};
use rustc::util::nodemap::{FxHashSet, FxHashMap};
// The first type is `receiver_ty`, which we know its not equal to `self_ty`; skip it.
autoderef.next();
+ let receiver_trait_def_id = fcx.tcx.require_lang_item(
+ lang_items::ReceiverTraitLangItem,
+ None,
+ );
+
// Keep dereferencing `receiver_ty` until we get to `self_ty`.
loop {
if let Some((potential_self_ty, _)) = autoderef.next() {
}
break
+ } else {
+ // Without `feature(arbitrary_self_types)`, we require that each step in the
+ // deref chain implement `receiver`
+ if !arbitrary_self_types_enabled
+ && !receiver_is_implemented(
+ fcx,
+ receiver_trait_def_id,
+ cause.clone(),
+ potential_self_ty,
+ )
+ {
+ return false
+ }
}
} else {
debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`",
// unecessary errors (#58712).
return receiver_ty.references_error();
}
-
- // Without the `arbitrary_self_types` feature, `receiver_ty` must directly deref to
- // `self_ty`. Enforce this by only doing one iteration of the loop.
- if !arbitrary_self_types_enabled {
- return false
- }
}
// Without `feature(arbitrary_self_types)`, we require that `receiver_ty` implements `Receiver`.
- if !arbitrary_self_types_enabled {
- let trait_def_id = match fcx.tcx.lang_items().receiver_trait() {
- Some(did) => did,
- None => {
- debug!("receiver_is_valid: missing Receiver trait");
- return false
- }
- };
+ if !arbitrary_self_types_enabled
+ && !receiver_is_implemented(fcx, receiver_trait_def_id, cause.clone(), receiver_ty)
+ {
+ return false
+ }
- let trait_ref = ty::TraitRef{
- def_id: trait_def_id,
- substs: fcx.tcx.mk_substs_trait(receiver_ty, &[]),
- };
+ true
+}
+
+fn receiver_is_implemented(
+ fcx: &FnCtxt<'_, 'tcx>,
+ receiver_trait_def_id: DefId,
+ cause: ObligationCause<'tcx>,
+ receiver_ty: Ty<'tcx>,
+) -> bool {
+ let trait_ref = ty::TraitRef{
+ def_id: receiver_trait_def_id,
+ substs: fcx.tcx.mk_substs_trait(receiver_ty, &[]),
+ };
- let obligation = traits::Obligation::new(
- cause,
- fcx.param_env,
- trait_ref.to_predicate()
- );
+ let obligation = traits::Obligation::new(
+ cause,
+ fcx.param_env,
+ trait_ref.to_predicate()
+ );
- if !fcx.predicate_must_hold_modulo_regions(&obligation) {
- debug!("receiver_is_valid: type `{:?}` does not implement `Receiver` trait",
- receiver_ty);
- return false
- }
+ if fcx.predicate_must_hold_modulo_regions(&obligation) {
+ true
+ } else {
+ debug!("receiver_is_implemented: type `{:?}` does not implement `Receiver` trait",
+ receiver_ty);
+ false
}
-
- true
}
fn check_variances_for_type_defn<'tcx>(
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
#[rustc_clean(cfg="cfail3")]
pub fn change_loop_body() {
let mut _x = 0;
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
- except="HirBody,mir_built")]
+ except="HirBody,mir_built,optimized_mir")]
#[rustc_clean(cfg="cfail3")]
pub fn change_name() {
let _y = 2u64;
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
- except="HirBody,typeck_tables_of,mir_built")]
+ except="HirBody,typeck_tables_of,mir_built,optimized_mir")]
#[rustc_clean(cfg="cfail3")]
pub fn change_mutability_of_slot() {
let _x: u64 = 0;
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
- except="HirBody,typeck_tables_of,mir_built")]
+ except="HirBody,typeck_tables_of,mir_built,optimized_mir")]
#[rustc_clean(cfg="cfail3")]
pub fn add_initializer() {
let _x: i16 = 3i16;
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
- except="HirBody,mir_built")]
+ except="HirBody,mir_built,optimized_mir")]
#[rustc_clean(cfg="cfail3")]
pub fn change_initializer() {
let _x = 5u16;
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
#[rustc_clean(cfg="cfail3")]
pub fn change_loop_body() {
let mut _x = 0;
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
#[rustc_clean(cfg="cfail3")]
pub fn change_loop_body() {
let mut _x = 0;
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
#[rustc_clean(cfg="cfail3")]
pub fn change_loop_condition() {
let mut _x = 0;
// let _3: ();
// let mut _4: std::boxed::Box<S>;
// scope 1 {
+// debug x => _1;
// }
// bb0: {
// StorageLive(_1);
// ...
// let mut _9: Bar;
// scope 1 {
+// debug a => _2;
// let _3: Bar;
// scope 2 {
+// debug b => _3;
// }
// }
// bb0: {
// END RUST SOURCE
// START rustc.foo.Inline.after.mir
-// ...
-// bb0: {
-// ...
-// _3 = [closure@HirId { owner: DefIndex(4), local_id: 31 }];
-// ...
-// _4 = &_3;
-// ...
-// _6 = &(*_2);
-// ...
-// _7 = &(*_2);
-// _5 = (move _6, move _7);
-// _8 = move (_5.0: &i32);
-// _9 = move (_5.1: &i32);
-// ...
-// _0 = (*_8);
-// ...
-// return;
+// fn foo(_1: T, _2: &i32) -> i32{
+// debug _t => _1;
+// debug q => _2;
+// let mut _0: i32;
+// let _3: [closure@HirId { owner: DefIndex(4), local_id: 31 }];
+// let mut _4: &[closure@HirId { owner: DefIndex(4), local_id: 31 }];
+// let mut _5: (&i32, &i32);
+// let mut _6: &i32;
+// let mut _7: &i32;
+// let mut _8: &i32;
+// let mut _9: &i32;
+// scope 1 {
+// debug x => _3;
+// scope 2 {
+// debug r => _8;
+// debug _s => _9;
+// }
+// }
+// scope 3 {
+// debug variable => _8;
+// }
+// bb0: {
+// ...
+// _3 = [closure@HirId { owner: DefIndex(4), local_id: 31 }];
+// ...
+// _4 = &_3;
+// ...
+// _6 = &(*_2);
+// ...
+// _7 = &(*_2);
+// _5 = (move _6, move _7);
+// _8 = move (_5.0: &i32);
+// _9 = move (_5.1: &i32);
+// ...
+// _0 = (*_8);
+// ...
+// return;
+// }
// }
-// ...
// END rustc.foo.Inline.after.mir
--- /dev/null
+// compile-flags: -Z span_free_formats
+
+// Tests that MIR inliner can handle closure captures.
+
+fn main() {
+ println!("{:?}", foo(0, 14));
+}
+
+fn foo<T: Copy>(t: T, q: i32) -> (i32, T) {
+ let x = |_q| (q, t);
+ x(q)
+}
+
+// END RUST SOURCE
+// START rustc.foo.Inline.after.mir
+// fn foo(_1: T, _2: i32) -> (i32, T){
+// debug t => _1;
+// debug q => _2;
+// let mut _0: (i32, T);
+// let _3: [closure@HirId { owner: DefIndex(4), local_id: 15 } q:&i32, t:&T];
+// let mut _4: &i32;
+// let mut _5: &T;
+// let mut _6: &[closure@HirId { owner: DefIndex(4), local_id: 15 } q:&i32, t:&T];
+// let mut _7: (i32,);
+// let mut _8: i32;
+// let mut _11: i32;
+// scope 1 {
+// debug x => _3;
+// scope 2 {
+// debug _q => _11;
+// debug q => (*((*_6).0: &i32));
+// debug t => (*((*_6).1: &T));
+// let mut _9: i32;
+// let mut _10: T;
+// }
+// }
+// bb0: {
+// ...
+// _4 = &_2;
+// ...
+// _5 = &_1;
+// _3 = [closure@HirId { owner: DefIndex(4), local_id: 15 }] { q: move _4, t: move _5 };
+// ...
+// _6 = &_3;
+// ...
+// ...
+// _8 = _2;
+// _7 = (move _8,);
+// _11 = move (_7.0: i32);
+// ...
+// _9 = (*((*_6).0: &i32));
+// ...
+// _10 = (*((*_6).1: &T));
+// (_0.0: i32) = move _9;
+// (_0.1: T) = move _10;
+// ...
+// return;
+// }
+// }
+// END rustc.foo.Inline.after.mir
// END RUST SOURCE
// START rustc.foo.Inline.after.mir
-// ...
-// bb0: {
-// ...
-// _3 = [closure@HirId { owner: DefIndex(4), local_id: 15 }];
-// ...
-// _4 = &_3;
-// ...
-// _6 = _2;
-// ...
-// _7 = _2;
-// _5 = (move _6, move _7);
-// _8 = move (_5.0: i32);
-// _9 = move (_5.1: i32);
-// _0 = _8;
-// ...
-// return;
-// }
-// ...
+// fn foo(_1: T, _2: i32) -> i32{
+// debug _t => _1;
+// debug q => _2;
+// let mut _0: i32;
+// let _3: [closure@HirId { owner: DefIndex(4), local_id: 15 }];
+// let mut _4: &[closure@HirId { owner: DefIndex(4), local_id: 15 }];
+// let mut _5: (i32, i32);
+// let mut _6: i32;
+// let mut _7: i32;
+// let mut _8: i32;
+// let mut _9: i32;
+// scope 1 {
+// debug x => _3;
+// scope 2 {
+// debug _t => _8;
+// debug _q => _9;
+// }
+// }
+// bb0: {
+// ...
+// _3 = [closure@HirId { owner: DefIndex(4), local_id: 15 }];
+// ...
+// _4 = &_3;
+// ...
+// _6 = _2;
+// ...
+// _7 = _2;
+// _5 = (move _6, move _7);
+// _8 = move (_5.0: i32);
+// _9 = move (_5.1: i32);
+// _0 = _8;
+// ...
+// return;
+// }
// END rustc.foo.Inline.after.mir
// let mut _4: S;
// let mut _5: bool;
// scope 1 {
+// debug x => _1;
// }
// ...
// bb0: {
// let mut _5: S;
// let mut _6: bool;
// ...
+// debug u => _1;
+// ...
// let mut _2: S;
// ...
+// debug v => _2;
+// ...
// bb0: {
// END rustc.test.ElaborateDrops.after.mir
// fn main() -> () {
// let mut _0: ();
// scope 1 {
-// let _1: E; // `e`
+// let _1: E;
+// debug e => _1;
// scope 2 {
// let _6: K;
+// debug _k => _6;
// }
// }
// let mut _2: bool;
// let _5: ();
// let mut _6: &i32;
// scope 1 {
+// debug beacon => _2;
// }
// bb0: {
// goto -> bb1;
// let _15: bool; // `b`
// let _16: std::string::String; // `t`
// scope 1 {
+// debug a => _5;
+// debug a => _6;
+// debug s => _7;
+// debug s => _8;
// }
// scope 2 {
+// debug b => _15;
+// debug t => _16;
// }
// bb0: {
// FakeRead(ForMatchedPlace, _2);
// START rustc.main.nll.0.mir
// let _2: &'_#3r usize;
// ...
+// debug p => _2;
+// ...
// let _6: &'_#4r usize;
// ...
+// debug q => _6;
+// ...
// _2 = &'_#2r _1[_3];
// ...
// _6 = _2;
// let mut _5: Droppy;
// let mut _6: Aligned;
// scope 1 {
+// debug x => _1;
// }
//
// bb0: {
// END RUST SOURCE
// START rustc.try_identity.SimplifyArmIdentity.before.mir
// fn try_identity(_1: std::result::Result<u32, i32>) -> std::result::Result<u32, i32> {
+// debug x => _1;
// let mut _0: std::result::Result<u32, i32>;
// let _2: u32;
// let mut _3: std::result::Result<u32, i32>;
// let _10: u32;
// let mut _11: u32;
// scope 1 {
+// debug y => _10;
// }
// scope 2 {
+// debug err => _6;
// scope 3 {
// scope 7 {
+// debug t => _6;
// }
// scope 8 {
+// debug v => _6;
// let mut _12: i32;
// }
// }
// }
// scope 4 {
+// debug val => _10;
// scope 5 {
// }
// }
// scope 6 {
+// debug self => _1;
// }
// bb0: {
// _5 = discriminant(_1);
// START rustc.try_identity.SimplifyArmIdentity.after.mir
// fn try_identity(_1: std::result::Result<u32, i32>) -> std::result::Result<u32, i32> {
+// debug x => _1;
// let mut _0: std::result::Result<u32, i32>;
// let _2: u32;
// let mut _3: std::result::Result<u32, i32>;
// let _10: u32;
// let mut _11: u32;
// scope 1 {
+// debug y => _10;
// }
// scope 2 {
+// debug err => _6;
// scope 3 {
// scope 7 {
+// debug t => _6;
// }
// scope 8 {
+// debug v => _6;
// let mut _12: i32;
// }
// }
// }
// scope 4 {
+// debug val => _10;
// scope 5 {
// }
// }
// scope 6 {
+// debug self => _1;
// }
// bb0: {
// _5 = discriminant(_1);
// START rustc.try_identity.SimplifyBranchSame.after.mir
// fn try_identity(_1: std::result::Result<u32, i32>) -> std::result::Result<u32, i32> {
+// debug x => _1;
// let mut _0: std::result::Result<u32, i32>;
// let _2: u32;
// let mut _3: std::result::Result<u32, i32>;
// let _10: u32;
// let mut _11: u32;
// scope 1 {
+// debug y => _10;
// }
// scope 2 {
+// debug err => _6;
// scope 3 {
// scope 7 {
+// debug t => _6;
// }
// scope 8 {
+// debug v => _6;
// let mut _12: i32;
// }
// }
// }
// scope 4 {
+// debug val => _10;
// scope 5 {
// }
// }
// scope 6 {
+// debug self => _1;
// }
// bb0: {
// _5 = discriminant(_1);
// START rustc.try_identity.SimplifyLocals.after.mir
// fn try_identity(_1: std::result::Result<u32, i32>) -> std::result::Result<u32, i32> {
+// debug x => _1;
// let mut _0: std::result::Result<u32, i32>;
// let mut _2: isize;
+// let _3: i32;
+// let _4: u32;
// scope 1 {
+// debug y => _4;
// }
// scope 2 {
+// debug err => _3;
// scope 3 {
// scope 7 {
+// debug t => _3;
// }
// scope 8 {
+// debug v => _3;
// }
// }
// }
// scope 4 {
+// debug val => _4;
// scope 5 {
// }
// }
// scope 6 {
+// debug self => _1;
// }
// bb0: {
// _2 = discriminant(_1);
pub fn transparent_i128(p: TransparentI128); //~ ERROR: uses type `i128`
pub fn transparent_str(p: TransparentStr); //~ ERROR: uses type `str`
pub fn transparent_fn(p: TransparentBadFn); //~ ERROR: uses type `std::boxed::Box<u32>`
+ pub fn raw_array(arr: [u8; 8]); //~ ERROR: uses type `[u8; 8]`
+
+ pub static static_u128_type: u128; //~ ERROR: uses type `u128`
+ pub static static_u128_array_type: [u128; 16]; //~ ERROR: uses type `u128`
pub fn good3(fptr: Option<extern fn()>);
pub fn good4(aptr: &[u8; 4 as usize]);
pub fn good17(p: TransparentCustomZst);
#[allow(improper_ctypes)]
pub fn good18(_: &String);
+ pub fn good20(arr: *const [u8; 8]);
+ pub static good21: [u8; 8];
+
}
#[allow(improper_ctypes)]
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
= note: this struct has unspecified layout
-error: aborting due to 20 previous errors
+error: `extern` block uses type `[u8; 8]`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:68:27
+ |
+LL | pub fn raw_array(arr: [u8; 8]);
+ | ^^^^^^^ not FFI-safe
+ |
+ = help: consider passing a pointer to the array
+ = note: passing raw arrays by value is not FFI-safe
+
+error: `extern` block uses type `u128`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:70:34
+ |
+LL | pub static static_u128_type: u128;
+ | ^^^^ not FFI-safe
+ |
+ = note: 128-bit integers don't currently have a known stable ABI
+
+error: `extern` block uses type `u128`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:71:40
+ |
+LL | pub static static_u128_array_type: [u128; 16];
+ | ^^^^^^^^^^ not FFI-safe
+ |
+ = note: 128-bit integers don't currently have a known stable ABI
+
+error: aborting due to 23 previous errors
error: cannot find a built-in macro with name `line`
--> <::core::macros::builtin::line macros>:1:1
|
-LL | () => { }
- | ^^^^^^^^^
+LL | () => { } ;
+ | ^^^^^^^^^^^
error: aborting due to 2 previous errors
error[E0038]: the trait `Foo` cannot be made into an object
- --> $DIR/arbitrary-self-types-not-object-safe.rs:34:32
+ --> $DIR/arbitrary-self-types-not-object-safe.rs:33:32
|
LL | fn foo(self: &Rc<Self>) -> usize;
| --- method `foo`'s `self` parameter cannot be dispatched on
| ^^^^^^^^^^^ the trait `Foo` cannot be made into an object
error[E0038]: the trait `Foo` cannot be made into an object
- --> $DIR/arbitrary-self-types-not-object-safe.rs:34:13
+ --> $DIR/arbitrary-self-types-not-object-safe.rs:33:13
|
LL | fn foo(self: &Rc<Self>) -> usize;
| --- method `foo`'s `self` parameter cannot be dispatched on
error[E0038]: the trait `Foo` cannot be made into an object
- --> $DIR/arbitrary-self-types-not-object-safe.rs:34:13
+ --> $DIR/arbitrary-self-types-not-object-safe.rs:33:13
|
LL | fn foo(self: &Rc<Self>) -> usize;
| --- method `foo`'s `self` parameter cannot be dispatched on
// revisions: curr object_safe_for_dispatch
#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))]
-#![feature(arbitrary_self_types)]
use std::rc::Rc;
error[E0038]: the trait `Foo` cannot be made into an object
- --> $DIR/arbitrary-self-types-not-object-safe.rs:31:32
+ --> $DIR/arbitrary-self-types-not-object-safe.rs:29:32
|
LL | fn foo(self: &Rc<Self>) -> usize;
| --- method `foo`'s `self` parameter cannot be dispatched on
| ^^^^^^^^^^^ the trait `Foo` cannot be made into an object
error[E0038]: the trait `Foo` cannot be made into an object
- --> $DIR/arbitrary-self-types-not-object-safe.rs:31:13
+ --> $DIR/arbitrary-self-types-not-object-safe.rs:29:13
|
LL | fn foo(self: &Rc<Self>) -> usize;
| --- method `foo`'s `self` parameter cannot be dispatched on
--- /dev/null
+// run-pass
+
+use {
+ std::{
+ rc::Rc,
+ sync::Arc,
+ },
+};
+
+#[derive(Default)]
+struct Ty;
+
+trait Trait {
+ fn receive_trait(self: &Arc<Rc<Box<Self>>>) -> u32;
+}
+
+const TRAIT_MAGIC: u32 = 42;
+const INHERENT_MAGIC: u32 = 1995;
+
+impl Trait for Ty {
+ fn receive_trait(self: &Arc<Rc<Box<Self>>>) -> u32 {
+ TRAIT_MAGIC
+ }
+}
+
+impl Ty {
+ fn receive_inherent(self: &Arc<Rc<Box<Self>>>) -> u32 {
+ INHERENT_MAGIC
+ }
+}
+
+fn main() {
+ let ty = <Arc<Rc<Box<Ty>>>>::default();
+ assert_eq!(TRAIT_MAGIC, ty.receive_trait());
+ assert_eq!(INHERENT_MAGIC, ty.receive_inherent());
+}
// run-pass
-#![feature(arbitrary_self_types)]
use std::rc::Rc;
// run-pass
-#![feature(arbitrary_self_types)]
use std::rc::Rc;
// run-pass
-#![feature(arbitrary_self_types)]
use std::rc::Rc;
// check-pass
// edition:2018
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::rc::Rc;
// check-pass
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::rc::Rc;
// check-pass
// edition:2018
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::rc::Rc;
// check-pass
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::rc::Rc;
// check-pass
// edition:2018
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::rc::Rc;
// check-pass
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::rc::Rc;
// check-pass
// edition:2018
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::rc::Rc;
// check-pass
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::rc::Rc;
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/lt-ref-self-async.rs:13:42
+ --> $DIR/lt-ref-self-async.rs:12:42
|
LL | async fn ref_self(&self, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#23r
error: lifetime may not live long enough
- --> $DIR/lt-ref-self-async.rs:14:9
+ --> $DIR/lt-ref-self-async.rs:13:9
|
LL | async fn ref_self(&self, f: &u32) -> &u32 {
| -
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/lt-ref-self-async.rs:19:48
+ --> $DIR/lt-ref-self-async.rs:18:48
|
LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#23r
error: lifetime may not live long enough
- --> $DIR/lt-ref-self-async.rs:20:9
+ --> $DIR/lt-ref-self-async.rs:19:9
|
LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
| -
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/lt-ref-self-async.rs:23:57
+ --> $DIR/lt-ref-self-async.rs:22:57
|
LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#23r
error: lifetime may not live long enough
- --> $DIR/lt-ref-self-async.rs:24:9
+ --> $DIR/lt-ref-self-async.rs:23:9
|
LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
| -
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/lt-ref-self-async.rs:27:57
+ --> $DIR/lt-ref-self-async.rs:26:57
|
LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#23r
error: lifetime may not live long enough
- --> $DIR/lt-ref-self-async.rs:28:9
+ --> $DIR/lt-ref-self-async.rs:27:9
|
LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
| -
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/lt-ref-self-async.rs:31:66
+ --> $DIR/lt-ref-self-async.rs:30:66
|
LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#23r
error: lifetime may not live long enough
- --> $DIR/lt-ref-self-async.rs:32:9
+ --> $DIR/lt-ref-self-async.rs:31:9
|
LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
| -
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/lt-ref-self-async.rs:35:62
+ --> $DIR/lt-ref-self-async.rs:34:62
|
LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#23r
error: lifetime may not live long enough
- --> $DIR/lt-ref-self-async.rs:36:9
+ --> $DIR/lt-ref-self-async.rs:35:9
|
LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
| -
// edition:2018
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::pin::Pin;
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self-async.rs:14:9
+ --> $DIR/lt-ref-self-async.rs:13:9
|
LL | async fn ref_self(&self, f: &u32) -> &u32 {
| ----- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self-async.rs:20:9
+ --> $DIR/lt-ref-self-async.rs:19:9
|
LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
| ----- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self-async.rs:24:9
+ --> $DIR/lt-ref-self-async.rs:23:9
|
LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
| ----- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self-async.rs:28:9
+ --> $DIR/lt-ref-self-async.rs:27:9
|
LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
| ----- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self-async.rs:32:9
+ --> $DIR/lt-ref-self-async.rs:31:9
|
LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
| ----- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self-async.rs:36:9
+ --> $DIR/lt-ref-self-async.rs:35:9
|
LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
| ----- ----
error: lifetime may not live long enough
- --> $DIR/lt-ref-self.rs:12:9
+ --> $DIR/lt-ref-self.rs:11:9
|
LL | fn ref_self(&self, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/lt-ref-self.rs:18:9
+ --> $DIR/lt-ref-self.rs:17:9
|
LL | fn ref_Self(self: &Self, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/lt-ref-self.rs:22:9
+ --> $DIR/lt-ref-self.rs:21:9
|
LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/lt-ref-self.rs:26:9
+ --> $DIR/lt-ref-self.rs:25:9
|
LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/lt-ref-self.rs:30:9
+ --> $DIR/lt-ref-self.rs:29:9
|
LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/lt-ref-self.rs:34:9
+ --> $DIR/lt-ref-self.rs:33:9
|
LL | fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::pin::Pin;
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self.rs:12:9
+ --> $DIR/lt-ref-self.rs:11:9
|
LL | fn ref_self(&self, f: &u32) -> &u32 {
| ---- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self.rs:18:9
+ --> $DIR/lt-ref-self.rs:17:9
|
LL | fn ref_Self(self: &Self, f: &u32) -> &u32 {
| ---- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self.rs:22:9
+ --> $DIR/lt-ref-self.rs:21:9
|
LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
| ---- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self.rs:26:9
+ --> $DIR/lt-ref-self.rs:25:9
|
LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
| ---- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self.rs:30:9
+ --> $DIR/lt-ref-self.rs:29:9
|
LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
| ---- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self.rs:34:9
+ --> $DIR/lt-ref-self.rs:33:9
|
LL | fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
| ---- ----
// check-pass
// edition:2018
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::pin::Pin;
// check-pass
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::pin::Pin;
// check-pass
// edition:2018
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::rc::Rc;
// check-pass
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::rc::Rc;
// edition:2018
// check-pass
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::pin::Pin;
// check-pass
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::pin::Pin;
// edition:2018
// check-pass
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::pin::Pin;
// check-pass
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::pin::Pin;
// edition:2018
// check-pass
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::pin::Pin;
// check-pass
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::pin::Pin;
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-mut-self-async.rs:13:46
+ --> $DIR/ref-mut-self-async.rs:12:46
|
LL | async fn ref_self(&mut self, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#15r
error: lifetime may not live long enough
- --> $DIR/ref-mut-self-async.rs:14:9
+ --> $DIR/ref-mut-self-async.rs:13:9
|
LL | async fn ref_self(&mut self, f: &u32) -> &u32 {
| -
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-mut-self-async.rs:19:52
+ --> $DIR/ref-mut-self-async.rs:18:52
|
LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#15r
error: lifetime may not live long enough
- --> $DIR/ref-mut-self-async.rs:20:9
+ --> $DIR/ref-mut-self-async.rs:19:9
|
LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
| -
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-mut-self-async.rs:23:61
+ --> $DIR/ref-mut-self-async.rs:22:61
|
LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#15r
error: lifetime may not live long enough
- --> $DIR/ref-mut-self-async.rs:24:9
+ --> $DIR/ref-mut-self-async.rs:23:9
|
LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
| -
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-mut-self-async.rs:27:61
+ --> $DIR/ref-mut-self-async.rs:26:61
|
LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#15r
error: lifetime may not live long enough
- --> $DIR/ref-mut-self-async.rs:28:9
+ --> $DIR/ref-mut-self-async.rs:27:9
|
LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
| -
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-mut-self-async.rs:31:70
+ --> $DIR/ref-mut-self-async.rs:30:70
|
LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#15r
error: lifetime may not live long enough
- --> $DIR/ref-mut-self-async.rs:32:9
+ --> $DIR/ref-mut-self-async.rs:31:9
|
LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
| -
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-mut-self-async.rs:35:70
+ --> $DIR/ref-mut-self-async.rs:34:70
|
LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#15r
error: lifetime may not live long enough
- --> $DIR/ref-mut-self-async.rs:36:9
+ --> $DIR/ref-mut-self-async.rs:35:9
|
LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
| -
// edition:2018
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::pin::Pin;
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self-async.rs:14:9
+ --> $DIR/ref-mut-self-async.rs:13:9
|
LL | async fn ref_self(&mut self, f: &u32) -> &u32 {
| --------- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self-async.rs:20:9
+ --> $DIR/ref-mut-self-async.rs:19:9
|
LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
| --------- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self-async.rs:24:9
+ --> $DIR/ref-mut-self-async.rs:23:9
|
LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
| --------- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self-async.rs:28:9
+ --> $DIR/ref-mut-self-async.rs:27:9
|
LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
| --------- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self-async.rs:32:9
+ --> $DIR/ref-mut-self-async.rs:31:9
|
LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
| --------- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self-async.rs:36:9
+ --> $DIR/ref-mut-self-async.rs:35:9
|
LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
| --------- ----
error: lifetime may not live long enough
- --> $DIR/ref-mut-self.rs:12:9
+ --> $DIR/ref-mut-self.rs:11:9
|
LL | fn ref_self(&mut self, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-self.rs:18:9
+ --> $DIR/ref-mut-self.rs:17:9
|
LL | fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-self.rs:22:9
+ --> $DIR/ref-mut-self.rs:21:9
|
LL | fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-self.rs:26:9
+ --> $DIR/ref-mut-self.rs:25:9
|
LL | fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-self.rs:30:9
+ --> $DIR/ref-mut-self.rs:29:9
|
LL | fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-self.rs:34:9
+ --> $DIR/ref-mut-self.rs:33:9
|
LL | fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::pin::Pin;
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self.rs:12:9
+ --> $DIR/ref-mut-self.rs:11:9
|
LL | fn ref_self(&mut self, f: &u32) -> &u32 {
| ---- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self.rs:18:9
+ --> $DIR/ref-mut-self.rs:17:9
|
LL | fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
| ---- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self.rs:22:9
+ --> $DIR/ref-mut-self.rs:21:9
|
LL | fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
| ---- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self.rs:26:9
+ --> $DIR/ref-mut-self.rs:25:9
|
LL | fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
| ---- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self.rs:30:9
+ --> $DIR/ref-mut-self.rs:29:9
|
LL | fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
| ---- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self.rs:34:9
+ --> $DIR/ref-mut-self.rs:33:9
|
LL | fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
| ---- ----
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-mut-struct-async.rs:13:56
+ --> $DIR/ref-mut-struct-async.rs:12:56
|
LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#15r
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct-async.rs:14:9
+ --> $DIR/ref-mut-struct-async.rs:13:9
|
LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
| -
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-mut-struct-async.rs:17:65
+ --> $DIR/ref-mut-struct-async.rs:16:65
|
LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#15r
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct-async.rs:18:9
+ --> $DIR/ref-mut-struct-async.rs:17:9
|
LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
| -
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-mut-struct-async.rs:21:65
+ --> $DIR/ref-mut-struct-async.rs:20:65
|
LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#15r
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct-async.rs:22:9
+ --> $DIR/ref-mut-struct-async.rs:21:9
|
LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
| -
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-mut-struct-async.rs:25:74
+ --> $DIR/ref-mut-struct-async.rs:24:74
|
LL | async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#15r
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct-async.rs:26:9
+ --> $DIR/ref-mut-struct-async.rs:25:9
|
LL | async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
| -
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-mut-struct-async.rs:29:74
+ --> $DIR/ref-mut-struct-async.rs:28:74
|
LL | async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#15r
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct-async.rs:30:9
+ --> $DIR/ref-mut-struct-async.rs:29:9
|
LL | async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
| -
// edition:2018
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::pin::Pin;
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct-async.rs:14:9
+ --> $DIR/ref-mut-struct-async.rs:13:9
|
LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
| ----------- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct-async.rs:18:9
+ --> $DIR/ref-mut-struct-async.rs:17:9
|
LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
| ----------- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct-async.rs:22:9
+ --> $DIR/ref-mut-struct-async.rs:21:9
|
LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
| ----------- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct-async.rs:26:9
+ --> $DIR/ref-mut-struct-async.rs:25:9
|
LL | async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
| ----------- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct-async.rs:30:9
+ --> $DIR/ref-mut-struct-async.rs:29:9
|
LL | async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
| ----------- ----
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct.rs:12:9
+ --> $DIR/ref-mut-struct.rs:11:9
|
LL | fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct.rs:16:9
+ --> $DIR/ref-mut-struct.rs:15:9
|
LL | fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct.rs:20:9
+ --> $DIR/ref-mut-struct.rs:19:9
|
LL | fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct.rs:24:9
+ --> $DIR/ref-mut-struct.rs:23:9
|
LL | fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct.rs:28:9
+ --> $DIR/ref-mut-struct.rs:27:9
|
LL | fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::pin::Pin;
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct.rs:12:9
+ --> $DIR/ref-mut-struct.rs:11:9
|
LL | fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
| ---- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct.rs:16:9
+ --> $DIR/ref-mut-struct.rs:15:9
|
LL | fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
| ---- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct.rs:20:9
+ --> $DIR/ref-mut-struct.rs:19:9
|
LL | fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
| ---- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct.rs:24:9
+ --> $DIR/ref-mut-struct.rs:23:9
|
LL | fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
| ---- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct.rs:28:9
+ --> $DIR/ref-mut-struct.rs:27:9
|
LL | fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
| ---- ----
-error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-self-async.rs:22:42
- |
-LL | async fn ref_self(&self, f: &u32) -> &u32 {
- | ^^^^
- |
- = note: hidden type `impl std::future::Future` captures lifetime '_#15r
-
-error: lifetime may not live long enough
- --> $DIR/ref-self-async.rs:23:9
- |
-LL | async fn ref_self(&self, f: &u32) -> &u32 {
- | -
- | |
- | lifetime `'_` defined here
- | lifetime `'_` defined here
-LL | f
- | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
-
-error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-self-async.rs:28:48
- |
-LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
- | ^^^^
- |
- = note: hidden type `impl std::future::Future` captures lifetime '_#15r
-
-error: lifetime may not live long enough
- --> $DIR/ref-self-async.rs:29:9
- |
-LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
- | -
- | |
- | lifetime `'_` defined here
- | lifetime `'_` defined here
-LL | f
- | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
-
-error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-self-async.rs:32:57
- |
-LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
- | ^^^^
- |
- = note: hidden type `impl std::future::Future` captures lifetime '_#15r
-
-error: lifetime may not live long enough
- --> $DIR/ref-self-async.rs:33:9
- |
-LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
- | -
- | |
- | lifetime `'_` defined here
- | lifetime `'_` defined here
-LL | f
- | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
-
-error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-self-async.rs:36:57
- |
-LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
- | ^^^^
- |
- = note: hidden type `impl std::future::Future` captures lifetime '_#15r
-
-error: lifetime may not live long enough
- --> $DIR/ref-self-async.rs:37:9
- |
-LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
- | -
- | |
- | lifetime `'_` defined here
- | lifetime `'_` defined here
-LL | f
- | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
-
-error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-self-async.rs:40:66
- |
-LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
- | ^^^^
- |
- = note: hidden type `impl std::future::Future` captures lifetime '_#15r
-
-error: lifetime may not live long enough
- --> $DIR/ref-self-async.rs:41:9
- |
-LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
- | -
- | |
- | lifetime `'_` defined here
- | lifetime `'_` defined here
-LL | f
- | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
-
-error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-self-async.rs:44:66
- |
-LL | async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
- | ^^^^
- |
- = note: hidden type `impl std::future::Future` captures lifetime '_#15r
-
-error: lifetime may not live long enough
- --> $DIR/ref-self-async.rs:45:9
- |
-LL | async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
- | -
- | |
- | lifetime `'_` defined here
- | lifetime `'_` defined here
-LL | f
- | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
-
-error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-self-async.rs:48:69
+error[E0658]: `Wrap<&Struct, Struct>` cannot be used as the type of `self` without the `arbitrary_self_types` feature
+ --> $DIR/ref-self-async.rs:47:39
|
LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
- | ^^^
- |
- = note: hidden type `impl std::future::Future` captures lifetime '_#15r
-
-error: lifetime may not live long enough
- --> $DIR/ref-self-async.rs:49:9
+ | ^^^^^^^^^^^^^^^^^
|
-LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
- | -
- | |
- | lifetime `'_` defined here
- | lifetime `'_` defined here
-LL | f
- | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+ = note: for more information, see https://github.com/rust-lang/rust/issues/44874
+ = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
+ = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
-error: aborting due to 14 previous errors
+error: aborting due to previous error
-For more information about this error, try `rustc --explain E0700`.
+For more information about this error, try `rustc --explain E0658`.
// edition:2018
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::marker::PhantomData;
error[E0623]: lifetime mismatch
- --> $DIR/ref-self-async.rs:23:9
+ --> $DIR/ref-self-async.rs:22:9
|
LL | async fn ref_self(&self, f: &u32) -> &u32 {
| ----- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-self-async.rs:29:9
+ --> $DIR/ref-self-async.rs:28:9
|
LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
| ----- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-self-async.rs:33:9
+ --> $DIR/ref-self-async.rs:32:9
|
LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
| ----- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-self-async.rs:37:9
+ --> $DIR/ref-self-async.rs:36:9
|
LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
| ----- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-self-async.rs:41:9
+ --> $DIR/ref-self-async.rs:40:9
|
LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
| ----- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-self-async.rs:45:9
+ --> $DIR/ref-self-async.rs:44:9
|
LL | async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
| ----- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-self-async.rs:49:9
+ --> $DIR/ref-self-async.rs:48:9
|
LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
| ----- ---
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-struct-async.rs:13:52
+ --> $DIR/ref-struct-async.rs:12:52
|
LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#15r
error: lifetime may not live long enough
- --> $DIR/ref-struct-async.rs:14:9
+ --> $DIR/ref-struct-async.rs:13:9
|
LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
| -
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-struct-async.rs:17:61
+ --> $DIR/ref-struct-async.rs:16:61
|
LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#15r
error: lifetime may not live long enough
- --> $DIR/ref-struct-async.rs:18:9
+ --> $DIR/ref-struct-async.rs:17:9
|
LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
| -
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-struct-async.rs:21:61
+ --> $DIR/ref-struct-async.rs:20:61
|
LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#15r
error: lifetime may not live long enough
- --> $DIR/ref-struct-async.rs:22:9
+ --> $DIR/ref-struct-async.rs:21:9
|
LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
| -
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-struct-async.rs:25:70
+ --> $DIR/ref-struct-async.rs:24:70
|
LL | async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#15r
error: lifetime may not live long enough
- --> $DIR/ref-struct-async.rs:26:9
+ --> $DIR/ref-struct-async.rs:25:9
|
LL | async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
| -
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/ref-struct-async.rs:29:66
+ --> $DIR/ref-struct-async.rs:28:66
|
LL | async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
| ^^^^
= note: hidden type `impl std::future::Future` captures lifetime '_#15r
error: lifetime may not live long enough
- --> $DIR/ref-struct-async.rs:30:9
+ --> $DIR/ref-struct-async.rs:29:9
|
LL | async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
| -
// edition:2018
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::pin::Pin;
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct-async.rs:14:9
+ --> $DIR/ref-struct-async.rs:13:9
|
LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
| ------- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct-async.rs:18:9
+ --> $DIR/ref-struct-async.rs:17:9
|
LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
| ------- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct-async.rs:22:9
+ --> $DIR/ref-struct-async.rs:21:9
|
LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
| ------- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct-async.rs:26:9
+ --> $DIR/ref-struct-async.rs:25:9
|
LL | async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
| ------- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct-async.rs:30:9
+ --> $DIR/ref-struct-async.rs:29:9
|
LL | async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
| ------- ----
error: lifetime may not live long enough
- --> $DIR/ref-struct.rs:12:9
+ --> $DIR/ref-struct.rs:11:9
|
LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-struct.rs:16:9
+ --> $DIR/ref-struct.rs:15:9
|
LL | fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-struct.rs:20:9
+ --> $DIR/ref-struct.rs:19:9
|
LL | fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-struct.rs:24:9
+ --> $DIR/ref-struct.rs:23:9
|
LL | fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-struct.rs:28:9
+ --> $DIR/ref-struct.rs:27:9
|
LL | fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::pin::Pin;
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct.rs:12:9
+ --> $DIR/ref-struct.rs:11:9
|
LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
| ---- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct.rs:16:9
+ --> $DIR/ref-struct.rs:15:9
|
LL | fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
| ---- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct.rs:20:9
+ --> $DIR/ref-struct.rs:19:9
|
LL | fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
| ---- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct.rs:24:9
+ --> $DIR/ref-struct.rs:23:9
|
LL | fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
| ---- ----
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct.rs:28:9
+ --> $DIR/ref-struct.rs:27:9
|
LL | fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
| ---- ----
// check-pass
// edition:2018
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::rc::Rc;
// check-pass
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::rc::Rc;
// check-pass
// edition:2018
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::rc::Rc;
// check-pass
-#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
use std::rc::Rc;
--- /dev/null
+// Regression test for issue #63263.
+// Tests that we properly handle closures with an explicit return type
+// that return an opaque type.
+
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+pub type Closure = impl FnOnce();
+
+fn main() {
+ || -> Closure { || () };
+}