[[package]]
name = "stacker"
-version = "0.1.9"
+version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72dd941b456e1c006d6b9f27c526d5b69281288aeea8cba82c19d3843d8ccdd2"
+checksum = "a92bc346006ae78c539d6ab2cf1a1532bc657b8339c464877a990ec82073c66f"
dependencies = [
"cc",
"cfg-if",
[patch."https://github.com/rust-lang/cargo"]
cargo = { path = "src/tools/cargo" }
-[patch.crates-io]
+[patch."https://github.com/rust-lang/rustfmt"]
# Similar to Cargo above we want the RLS to use a vendored version of `rustfmt`
# that we're shipping as well (to ensure that the rustfmt in RLS and the
# `rustfmt` executable are the same exact version).
rustfmt-nightly = { path = "src/tools/rustfmt" }
+[patch.crates-io]
# See comments in `src/tools/rustc-workspace-hack/README.md` for what's going on
# here
rustc-workspace-hack = { path = 'src/tools/rustc-workspace-hack' }
);
// SAFETY: `new_size` must be non-zero, which is checked in the match expression.
+ // If `new_size` is zero, then `old_size` has to be zero as well.
// Other conditions must be upheld by the caller
unsafe {
match layout.size() {
- old_size if old_size == new_size => {
- Ok(NonNull::slice_from_raw_parts(ptr, new_size))
- }
0 => self.alloc(Layout::from_size_align_unchecked(new_size, layout.align())),
old_size => {
- // `realloc` probably checks for `new_size > size` or something similar.
- intrinsics::assume(new_size > old_size);
+ // `realloc` probably checks for `new_size >= size` or something similar.
+ intrinsics::assume(new_size >= old_size);
let raw_ptr = realloc(ptr.as_ptr(), layout, new_size);
let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
Ok(NonNull::slice_from_raw_parts(ptr, new_size))
);
// SAFETY: `new_size` must be non-zero, which is checked in the match expression.
+ // If `new_size` is zero, then `old_size` has to be zero as well.
// Other conditions must be upheld by the caller
unsafe {
match layout.size() {
- old_size if old_size == new_size => {
- Ok(NonNull::slice_from_raw_parts(ptr, new_size))
- }
0 => self.alloc_zeroed(Layout::from_size_align_unchecked(new_size, layout.align())),
old_size => {
- // `realloc` probably checks for `new_size > size` or something similar.
- intrinsics::assume(new_size > old_size);
+ // `realloc` probably checks for `new_size >= size` or something similar.
+ intrinsics::assume(new_size >= old_size);
let raw_ptr = realloc(ptr.as_ptr(), layout, new_size);
raw_ptr.add(old_size).write_bytes(0, new_size - old_size);
let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
"`new_size` must be smaller than or equal to `layout.size()`"
);
- let ptr = if new_size == old_size {
- ptr
- } else if new_size == 0 {
- // SAFETY: `layout` is non-zero in size as `old_size` != `new_size`
- // Other conditions must be upheld by the caller
+ let ptr = if new_size == 0 {
+ // SAFETY: conditions must be upheld by the caller
unsafe {
self.dealloc(ptr, layout);
}
// SAFETY: new_size is not zero,
// Other conditions must be upheld by the caller
let raw_ptr = unsafe {
- // `realloc` probably checks for `new_size < old_size` or something similar.
- intrinsics::assume(new_size < old_size);
+ // `realloc` probably checks for `new_size <= old_size` or something similar.
+ intrinsics::assume(new_size <= old_size);
realloc(ptr.as_ptr(), layout, new_size)
};
NonNull::new(raw_ptr).ok_or(AllocErr)?
/// * `new_size` must be greater than or equal to `layout.size()`, and
/// * `new_size`, when rounded up to the nearest multiple of `layout.align()`, must not overflow
/// (i.e., the rounded value must be less than or equal to `usize::MAX`).
- // Note: We can't require that `new_size` is strictly greater than `layout.size()` because of ZSTs.
- // alternative: `new_size` must be strictly greater than `layout.size()` or both are zero
///
/// [*currently allocated*]: #currently-allocated-memory
/// [*fit*]: #memory-fitting
"`new_size` must be greater than or equal to `layout.size()`"
);
- if size == new_size {
- return Ok(NonNull::slice_from_raw_parts(ptr, size));
- }
-
let new_layout =
// SAFETY: the caller must ensure that the `new_size` does not overflow.
// `layout.align()` comes from a `Layout` and is thus guaranteed to be valid for a Layout.
/// * `new_size` must be greater than or equal to `layout.size()`, and
/// * `new_size`, when rounded up to the nearest multiple of `layout.align()`, must not overflow
/// (i.e., the rounded value must be less than or equal to `usize::MAX`).
- // Note: We can't require that `new_size` is strictly greater than `layout.size()` because of ZSTs.
- // alternative: `new_size` must be strictly greater than `layout.size()` or both are zero
///
/// [*currently allocated*]: #currently-allocated-memory
/// [*fit*]: #memory-fitting
"`new_size` must be greater than or equal to `layout.size()`"
);
- if size == new_size {
- return Ok(NonNull::slice_from_raw_parts(ptr, size));
- }
-
let new_layout =
// SAFETY: the caller must ensure that the `new_size` does not overflow.
// `layout.align()` comes from a `Layout` and is thus guaranteed to be valid for a Layout.
/// * `ptr` must denote a block of memory [*currently allocated*] via this allocator,
/// * `layout` must [*fit*] that block of memory (The `new_size` argument need not fit it.), and
/// * `new_size` must be smaller than or equal to `layout.size()`.
- // Note: We can't require that `new_size` is strictly smaller than `layout.size()` because of ZSTs.
- // alternative: `new_size` must be smaller than `layout.size()` or both are zero
///
/// [*currently allocated*]: #currently-allocated-memory
/// [*fit*]: #memory-fitting
"`new_size` must be smaller than or equal to `layout.size()`"
);
- if size == new_size {
- return Ok(NonNull::slice_from_raw_parts(ptr, size));
- }
-
let new_layout =
// SAFETY: the caller must ensure that the `new_size` does not overflow.
// `layout.align()` comes from a `Layout` and is thus guaranteed to be valid for a Layout.
/// Most types implement `Any`. However, any type which contains a non-`'static` reference does not.
/// See the [module-level documentation][mod] for more details.
///
-/// [mod]: index.html
+/// [mod]: crate::any
// This trait is not unsafe, though we rely on the specifics of it's sole impl's
// `type_id` function in unsafe code (e.g., `downcast`). Normally, that would be
// a problem, but because the only impl of `Any` is a blanket implementation, no
))]
pub trait From<T>: Sized {
/// Performs the conversion.
+ #[cfg_attr(not(bootstrap), lang = "from")]
#[stable(feature = "rust1", since = "1.0.0")]
fn from(_: T) -> Self;
}
/// [`Context`]: ../task/struct.Context.html
/// [`Waker`]: ../task/struct.Waker.html
/// [`Waker::wake`]: ../task/struct.Waker.html#method.wake
+ #[cfg_attr(not(bootstrap), lang = "poll")]
#[stable(feature = "futures_api", since = "1.36.0")]
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}
/// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give
/// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`).
// This is `const` to avoid extra errors after we recover from `const async fn`
+#[cfg_attr(not(bootstrap), lang = "from_generator")]
#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
#[inline]
GenFuture(gen)
}
+#[cfg_attr(not(bootstrap), lang = "get_context")]
#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
#[inline]
/// Otherwise, consider using the [`unreachable!`] macro, which does not allow
/// optimizations but will panic when executed.
///
-/// [`unreachable!`]: ../macro.unreachable.html
///
/// # Example
///
/// **Note**: On platforms that do not support receiving spin-loop hints this function does not
/// do anything at all.
///
-/// [`core::sync::atomic::spin_loop_hint`]: ../sync/atomic/fn.spin_loop_hint.html
+/// [`core::sync::atomic::spin_loop_hint`]: crate::sync::atomic::spin_loop_hint
#[inline]
#[unstable(feature = "renamed_spin_loop", issue = "55002")]
pub fn spin_loop() {
/// assert_eq!(Some(3), iter.next());
/// assert_eq!(None, iter.next());
/// ```
+ #[cfg_attr(not(bootstrap), lang = "into_iter")]
#[stable(feature = "rust1", since = "1.0.0")]
fn into_iter(self) -> Self::IntoIter;
}
/// assert_eq!(None, iter.next());
/// assert_eq!(None, iter.next());
/// ```
+ #[cfg_attr(not(bootstrap), lang = "next")]
#[stable(feature = "rust1", since = "1.0.0")]
fn next(&mut self) -> Option<Self::Item>;
#![feature(optin_builtin_traits)]
#![feature(or_patterns)]
#![feature(prelude_import)]
+#![feature(ptr_as_uninit)]
#![feature(repr_simd, platform_intrinsics)]
#![feature(rustc_attrs)]
#![feature(simd_ffi)]
/// [`IntoIterator`]: ../iter/trait.Iterator.html
/// [`Iterator`]: ../iter/trait.IntoIterator.html
/// [slicing index]: ../slice/trait.SliceIndex.html
+#[cfg_attr(not(bootstrap), lang = "RangeFull")]
#[doc(alias = "..")]
#[derive(Copy, Clone, Default, PartialEq, Eq, Hash)]
#[stable(feature = "rust1", since = "1.0.0")]
/// assert_eq!(arr[1.. 3], [ 1,2 ]); // Range
/// assert_eq!(arr[1..=3], [ 1,2,3 ]);
/// ```
+#[cfg_attr(not(bootstrap), lang = "Range")]
#[doc(alias = "..")]
#[derive(Clone, Default, PartialEq, Eq, Hash)] // not Copy -- see #27186
#[stable(feature = "rust1", since = "1.0.0")]
/// ```
///
/// [`Iterator`]: ../iter/trait.IntoIterator.html
+#[cfg_attr(not(bootstrap), lang = "RangeFrom")]
#[doc(alias = "..")]
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
#[stable(feature = "rust1", since = "1.0.0")]
/// [`IntoIterator`]: ../iter/trait.Iterator.html
/// [`Iterator`]: ../iter/trait.IntoIterator.html
/// [slicing index]: ../slice/trait.SliceIndex.html
+#[cfg_attr(not(bootstrap), lang = "RangeTo")]
#[doc(alias = "..")]
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[stable(feature = "rust1", since = "1.0.0")]
/// assert_eq!(arr[1.. 3], [ 1,2 ]);
/// assert_eq!(arr[1..=3], [ 1,2,3 ]); // RangeInclusive
/// ```
+#[cfg_attr(not(bootstrap), lang = "RangeInclusive")]
#[doc(alias = "..=")]
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
#[stable(feature = "inclusive_range", since = "1.26.0")]
///
/// assert_eq!(3..=5, RangeInclusive::new(3, 5));
/// ```
+ #[cfg_attr(not(bootstrap), lang = "range_inclusive_new")]
#[stable(feature = "inclusive_range_methods", since = "1.27.0")]
#[inline]
#[rustc_promotable]
/// [`IntoIterator`]: ../iter/trait.Iterator.html
/// [`Iterator`]: ../iter/trait.IntoIterator.html
/// [slicing index]: ../slice/trait.SliceIndex.html
+#[cfg_attr(not(bootstrap), lang = "RangeToInclusive")]
#[doc(alias = "..=")]
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[stable(feature = "inclusive_range", since = "1.26.0")]
/// in the return type of the enclosing scope (which must itself implement
/// `Try`). Specifically, the value `X::from_error(From::from(e))`
/// is returned, where `X` is the return type of the enclosing function.
+ #[cfg_attr(not(bootstrap), lang = "into_result")]
#[unstable(feature = "try_trait", issue = "42327")]
fn into_result(self) -> Result<Self::Ok, Self::Error>;
/// Wrap an error value to construct the composite result. For example,
/// `Result::Err(x)` and `Result::from_error(x)` are equivalent.
+ #[cfg_attr(not(bootstrap), lang = "from_error")]
#[unstable(feature = "try_trait", issue = "42327")]
fn from_error(v: Self::Error) -> Self;
/// Wrap an OK value to construct the composite result. For example,
/// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent.
+ #[cfg_attr(not(bootstrap), lang = "from_ok")]
#[unstable(feature = "try_trait", issue = "42327")]
fn from_ok(v: Self::Ok) -> Self;
}
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Option<T> {
/// No value
+ #[cfg_attr(not(bootstrap), lang = "None")]
#[stable(feature = "rust1", since = "1.0.0")]
None,
/// Some value `T`
+ #[cfg_attr(not(bootstrap), lang = "Some")]
#[stable(feature = "rust1", since = "1.0.0")]
Some(#[stable(feature = "rust1", since = "1.0.0")] T),
}
//! as moving an object with pointers to itself will invalidate them, which could cause undefined
//! behavior.
//!
-//! A [`Pin<P>`] ensures that the pointee of any pointer type `P` has a stable location in memory,
-//! meaning it cannot be moved elsewhere and its memory cannot be deallocated
-//! until it gets dropped. We say that the pointee is "pinned".
+//! At a high level, a [`Pin<P>`] ensures that the pointee of any pointer type
+//! `P` has a stable location in memory, meaning it cannot be moved elsewhere
+//! and its memory cannot be deallocated until it gets dropped. We say that the
+//! pointee is "pinned". Things get more subtle when discussing types that
+//! combine pinned with non-pinned data; [see below](#projections-and-structural-pinning)
+//! for more details.
//!
//! By default, all types in Rust are movable. Rust allows passing all types by-value,
//! and common smart-pointer types such as [`Box<T>`] and `&mut T` allow replacing and
//!
//! # Example: self-referential struct
//!
+//! Before we go into more details to explain the guarantees and choices
+//! associated with `Pin<T>`, we discuss some examples for how it might be used.
+//! Feel free to [skip to where the theoretical discussion continues](#drop-guarantee).
+//!
//! ```rust
//! use std::pin::Pin;
//! use std::marker::PhantomPinned;
/// ```
///
/// [`mem::swap`]: ../../std/mem/fn.swap.html
+ #[cfg_attr(not(bootstrap), lang = "new_unchecked")]
#[stable(feature = "pin", since = "1.33.0")]
#[inline(always)]
pub unsafe fn new_unchecked(pointer: P) -> Pin<P> {
use crate::cmp::Ordering::{self, Equal, Greater, Less};
use crate::intrinsics;
use crate::mem;
-use crate::slice::SliceIndex;
+use crate::slice::{self, SliceIndex};
#[lang = "const_ptr"]
impl<T: ?Sized> *const T {
/// Therefore, two pointers that are null may still not compare equal to
/// each other.
///
+ /// ## Behavior during const evaluation
+ ///
+ /// When this function is used during const evaluation, it may return `false` for pointers
+ /// that turn out to be null at runtime. Specifically, when a pointer to some memory
+ /// is offset beyond its bounds in such a way that the resulting pointer is null,
+ /// the function will still return `false`. There is no way for CTFE to know
+ /// the absolute position of that memory, so we cannot tell if the pointer is
+ /// null or not.
+ ///
/// # Examples
///
/// Basic usage:
/// assert!(!ptr.is_null());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
#[inline]
- pub fn is_null(self) -> bool {
+ pub const fn is_null(self) -> bool {
// Compare via a cast to a thin pointer, so fat pointers are only
// considering their "data" part for null-ness.
- (self as *const u8) == null()
+ (self as *const u8).guaranteed_eq(null())
}
/// Casts to a pointer of another type.
self as _
}
- /// Returns `None` if the pointer is null, or else returns a reference to
- /// the value wrapped in `Some`.
+ /// Returns `None` if the pointer is null, or else returns a shared reference to
+ /// the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_ref`]
+ /// must be used instead.
///
- /// # Safety
+ /// [`as_uninit_ref`]: #method.as_uninit_ref
///
- /// While this method and its mutable counterpart are useful for
- /// null-safety, it is important to note that this is still an unsafe
- /// operation because the returned value could be pointing to invalid
- /// memory.
+ /// # Safety
///
/// When calling this method, you have to ensure that *either* the pointer is NULL *or*
/// all of the following is true:
- /// - it is properly aligned
- /// - it must point to an initialized instance of T; in particular, the pointer must be
- /// "dereferenceable" in the sense defined [here].
+ ///
+ /// * The pointer must be properly aligned.
+ ///
+ /// * It must be "dereferencable" in the sense defined in [the module documentation].
+ ///
+ /// * The pointer must point to an initialized instance of `T`.
+ ///
+ /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+ /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+ /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// not get mutated (except inside `UnsafeCell`).
///
/// This applies even if the result of this method is unused!
/// (The part about being initialized is not yet fully decided, but until
/// it is, the only safe approach is to ensure that they are indeed initialized.)
///
- /// Additionally, the lifetime `'a` returned is arbitrarily chosen and does
- /// not necessarily reflect the actual lifetime of the data. *You* must enforce
- /// Rust's aliasing rules. In particular, for the duration of this lifetime,
- /// the memory the pointer points to must not get mutated (except inside `UnsafeCell`).
- ///
- /// [here]: crate::ptr#safety
+ /// [the module documentation]: crate::ptr#safety
///
/// # Examples
///
if self.is_null() { None } else { unsafe { Some(&*self) } }
}
+ /// Returns `None` if the pointer is null, or else returns a shared reference to
+ /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
+ /// that the value has to be initialized.
+ ///
+ /// [`as_ref`]: #method.as_ref
+ ///
+ /// # Safety
+ ///
+ /// When calling this method, you have to ensure that *either* the pointer is NULL *or*
+ /// all of the following is true:
+ ///
+ /// * The pointer must be properly aligned.
+ ///
+ /// * It must be "dereferencable" in the sense defined in [the module documentation].
+ ///
+ /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+ /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+ /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// not get mutated (except inside `UnsafeCell`).
+ ///
+ /// This applies even if the result of this method is unused!
+ ///
+ /// [the module documentation]: crate::ptr#safety
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(ptr_as_uninit)]
+ ///
+ /// let ptr: *const u8 = &10u8 as *const u8;
+ ///
+ /// unsafe {
+ /// if let Some(val_back) = ptr.as_uninit_ref() {
+ /// println!("We got back the value: {}!", val_back.assume_init());
+ /// }
+ /// }
+ /// ```
+ #[inline]
+ #[unstable(feature = "ptr_as_uninit", issue = "75402")]
+ pub unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit<T>>
+ where
+ T: Sized,
+ {
+ // SAFETY: the caller must guarantee that `self` meets all the
+ // requirements for a reference.
+ if self.is_null() { None } else { Some(unsafe { &*(self as *const MaybeUninit<T>) }) }
+ }
+
/// Calculates the offset from a pointer.
///
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
// SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds.
unsafe { index.get_unchecked(self) }
}
+
+ /// Returns `None` if the pointer is null, or else returns a shared slice to
+ /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
+ /// that the value has to be initialized.
+ ///
+ /// [`as_ref`]: #method.as_ref
+ ///
+ /// # Safety
+ ///
+ /// When calling this method, you have to ensure that *either* the pointer is NULL *or*
+ /// all of the following is true:
+ ///
+ /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::<T>()` many bytes,
+ /// and it must be properly aligned. This means in particular:
+ ///
+ /// * The entire memory range of this slice must be contained within a single allocated object!
+ /// Slices can never span across multiple allocated objects.
+ ///
+ /// * The pointer must be aligned even for zero-length slices. One
+ /// reason for this is that enum layout optimizations may rely on references
+ /// (including slices of any length) being aligned and non-null to distinguish
+ /// them from other data. You can obtain a pointer that is usable as `data`
+ /// for zero-length slices using [`NonNull::dangling()`].
+ ///
+ /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+ /// See the safety documentation of [`pointer::offset`].
+ ///
+ /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+ /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+ /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// not get mutated (except inside `UnsafeCell`).
+ ///
+ /// This applies even if the result of this method is unused!
+ ///
+ /// See also [`slice::from_raw_parts`][].
+ ///
+ /// [valid]: crate::ptr#safety
+ /// [`NonNull::dangling()`]: NonNull::dangling
+ /// [`pointer::offset`]: ../std/primitive.pointer.html#method.offset
+ #[inline]
+ #[unstable(feature = "ptr_as_uninit", issue = "75402")]
+ pub unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit<T>]> {
+ if self.is_null() {
+ None
+ } else {
+ // SAFETY: the caller must uphold the safety contract for `as_uninit_slice`.
+ Some(unsafe { slice::from_raw_parts(self as *const MaybeUninit<T>, self.len()) })
+ }
+ }
}
// Equality for pointers
use super::*;
use crate::cmp::Ordering::{self, Equal, Greater, Less};
use crate::intrinsics;
-use crate::slice::SliceIndex;
+use crate::slice::{self, SliceIndex};
#[lang = "mut_ptr"]
impl<T: ?Sized> *mut T {
/// Therefore, two pointers that are null may still not compare equal to
/// each other.
///
+ /// ## Behavior during const evaluation
+ ///
+ /// When this function is used during const evaluation, it may return `false` for pointers
+ /// that turn out to be null at runtime. Specifically, when a pointer to some memory
+ /// is offset beyond its bounds in such a way that the resulting pointer is null,
+ /// the function will still return `false`. There is no way for CTFE to know
+ /// the absolute position of that memory, so we cannot tell if the pointer is
+ /// null or not.
+ ///
/// # Examples
///
/// Basic usage:
/// assert!(!ptr.is_null());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
#[inline]
- pub fn is_null(self) -> bool {
+ pub const fn is_null(self) -> bool {
// Compare via a cast to a thin pointer, so fat pointers are only
// considering their "data" part for null-ness.
- (self as *mut u8) == null_mut()
+ (self as *mut u8).guaranteed_eq(null_mut())
}
/// Casts to a pointer of another type.
self as _
}
- /// Returns `None` if the pointer is null, or else returns a reference to
- /// the value wrapped in `Some`.
+ /// Returns `None` if the pointer is null, or else returns a shared reference to
+ /// the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_ref`]
+ /// must be used instead.
///
- /// # Safety
+ /// For the mutable counterpart see [`as_mut`].
///
- /// While this method and its mutable counterpart are useful for
- /// null-safety, it is important to note that this is still an unsafe
- /// operation because the returned value could be pointing to invalid
- /// memory.
+ /// [`as_uninit_ref`]: #method.as_uninit_ref-1
+ /// [`as_mut`]: #method.as_mut
+ ///
+ /// # Safety
///
/// When calling this method, you have to ensure that *either* the pointer is NULL *or*
/// all of the following is true:
- /// - it is properly aligned
- /// - it must point to an initialized instance of T; in particular, the pointer must be
- /// "dereferencable" in the sense defined [here].
+ ///
+ /// * The pointer must be properly aligned.
+ ///
+ /// * It must be "dereferencable" in the sense defined in [the module documentation].
+ ///
+ /// * The pointer must point to an initialized instance of `T`.
+ ///
+ /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+ /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+ /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// not get mutated (except inside `UnsafeCell`).
///
/// This applies even if the result of this method is unused!
/// (The part about being initialized is not yet fully decided, but until
/// it is, the only safe approach is to ensure that they are indeed initialized.)
///
- /// Additionally, the lifetime `'a` returned is arbitrarily chosen and does
- /// not necessarily reflect the actual lifetime of the data. *You* must enforce
- /// Rust's aliasing rules. In particular, for the duration of this lifetime,
- /// the memory the pointer points to must not get mutated (except inside `UnsafeCell`).
- ///
- /// [here]: crate::ptr#safety
+ /// [the module documentation]: crate::ptr#safety
///
/// # Examples
///
if self.is_null() { None } else { unsafe { Some(&*self) } }
}
+ /// Returns `None` if the pointer is null, or else returns a shared reference to
+ /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
+ /// that the value has to be initialized.
+ ///
+ /// For the mutable counterpart see [`as_uninit_mut`].
+ ///
+ /// [`as_ref`]: #method.as_ref-1
+ /// [`as_uninit_mut`]: #method.as_uninit_mut
+ ///
+ /// # Safety
+ ///
+ /// When calling this method, you have to ensure that *either* the pointer is NULL *or*
+ /// all of the following is true:
+ ///
+ /// * The pointer must be properly aligned.
+ ///
+ /// * It must be "dereferencable" in the sense defined in [the module documentation].
+ ///
+ /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+ /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+ /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// not get mutated (except inside `UnsafeCell`).
+ ///
+ /// This applies even if the result of this method is unused!
+ ///
+ /// [the module documentation]: crate::ptr#safety
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(ptr_as_uninit)]
+ ///
+ /// let ptr: *mut u8 = &mut 10u8 as *mut u8;
+ ///
+ /// unsafe {
+ /// if let Some(val_back) = ptr.as_uninit_ref() {
+ /// println!("We got back the value: {}!", val_back.assume_init());
+ /// }
+ /// }
+ /// ```
+ #[inline]
+ #[unstable(feature = "ptr_as_uninit", issue = "75402")]
+ pub unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit<T>>
+ where
+ T: Sized,
+ {
+ // SAFETY: the caller must guarantee that `self` meets all the
+ // requirements for a reference.
+ if self.is_null() { None } else { Some(unsafe { &*(self as *const MaybeUninit<T>) }) }
+ }
+
/// Calculates the offset from a pointer.
///
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
unsafe { intrinsics::arith_offset(self, count) as *mut T }
}
- /// Returns `None` if the pointer is null, or else returns a mutable
- /// reference to the value wrapped in `Some`.
+ /// Returns `None` if the pointer is null, or else returns a unique reference to
+ /// the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_mut`]
+ /// must be used instead.
///
- /// # Safety
+ /// For the shared counterpart see [`as_ref`].
+ ///
+ /// [`as_uninit_mut`]: #method.as_uninit_mut
+ /// [`as_ref`]: #method.as_ref-1
///
- /// As with [`as_ref`], this is unsafe because it cannot verify the validity
- /// of the returned pointer, nor can it ensure that the lifetime `'a`
- /// returned is indeed a valid lifetime for the contained data.
+ /// # Safety
///
/// When calling this method, you have to ensure that *either* the pointer is NULL *or*
/// all of the following is true:
- /// - it is properly aligned
- /// - it must point to an initialized instance of T; in particular, the pointer must be
- /// "dereferenceable" in the sense defined [here].
+ ///
+ /// * The pointer must be properly aligned.
+ ///
+ /// * It must be "dereferencable" in the sense defined in [the module documentation].
+ ///
+ /// * The pointer must point to an initialized instance of `T`.
+ ///
+ /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+ /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+ /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// not get accessed (read or written) through any other pointer.
///
/// This applies even if the result of this method is unused!
/// (The part about being initialized is not yet fully decided, but until
- /// it is the only safe approach is to ensure that they are indeed initialized.)
- ///
- /// Additionally, the lifetime `'a` returned is arbitrarily chosen and does
- /// not necessarily reflect the actual lifetime of the data. *You* must enforce
- /// Rust's aliasing rules. In particular, for the duration of this lifetime,
- /// the memory this pointer points to must not get accessed (read or written)
- /// through any other pointer.
+ /// it is, the only safe approach is to ensure that they are indeed initialized.)
///
- /// [here]: crate::ptr#safety
- /// [`as_ref`]: #method.as_ref
+ /// [the module documentation]: crate::ptr#safety
///
/// # Examples
///
/// let ptr: *mut u32 = s.as_mut_ptr();
/// let first_value = unsafe { ptr.as_mut().unwrap() };
/// *first_value = 4;
+ /// # assert_eq!(s, [4, 2, 3]);
/// println!("{:?}", s); // It'll print: "[4, 2, 3]".
/// ```
///
/// let ptr: *mut u32 = s.as_mut_ptr();
/// let first_value = unsafe { &mut *ptr };
/// *first_value = 4;
+ /// # assert_eq!(s, [4, 2, 3]);
/// println!("{:?}", s); // It'll print: "[4, 2, 3]".
/// ```
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
if self.is_null() { None } else { unsafe { Some(&mut *self) } }
}
+ /// Returns `None` if the pointer is null, or else returns a unique reference to
+ /// the value wrapped in `Some`. In contrast to [`as_mut`], this does not require
+ /// that the value has to be initialized.
+ ///
+ /// For the shared counterpart see [`as_uninit_ref`].
+ ///
+ /// [`as_mut`]: #method.as_mut
+ /// [`as_uninit_ref`]: #method.as_uninit_ref-1
+ ///
+ /// # Safety
+ ///
+ /// When calling this method, you have to ensure that *either* the pointer is NULL *or*
+ /// all of the following is true:
+ ///
+ /// * The pointer must be properly aligned.
+ ///
+ /// * It must be "dereferencable" in the sense defined in [the module documentation].
+ ///
+ /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+ /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+ /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// not get accessed (read or written) through any other pointer.
+ ///
+ /// This applies even if the result of this method is unused!
+ ///
+ /// [the module documentation]: crate::ptr#safety
+ #[inline]
+ #[unstable(feature = "ptr_as_uninit", issue = "75402")]
+ pub unsafe fn as_uninit_mut<'a>(self) -> Option<&'a mut MaybeUninit<T>>
+ where
+ T: Sized,
+ {
+ // SAFETY: the caller must guarantee that `self` meets all the
+ // requirements for a reference.
+ if self.is_null() { None } else { Some(unsafe { &mut *(self as *mut MaybeUninit<T>) }) }
+ }
+
/// Returns whether two pointers are guaranteed to be equal.
///
/// At runtime this function behaves like `self == other`.
// SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds.
unsafe { index.get_unchecked_mut(self) }
}
+
+ /// Returns `None` if the pointer is null, or else returns a shared slice to
+ /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
+ /// that the value has to be initialized.
+ ///
+ /// For the mutable counterpart see [`as_uninit_slice_mut`].
+ ///
+ /// [`as_ref`]: #method.as_ref-1
+ /// [`as_uninit_slice_mut`]: #method.as_uninit_slice_mut
+ ///
+ /// # Safety
+ ///
+ /// When calling this method, you have to ensure that *either* the pointer is NULL *or*
+ /// all of the following is true:
+ ///
+ /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::<T>()` many bytes,
+ /// and it must be properly aligned. This means in particular:
+ ///
+ /// * The entire memory range of this slice must be contained within a single allocated object!
+ /// Slices can never span across multiple allocated objects.
+ ///
+ /// * The pointer must be aligned even for zero-length slices. One
+ /// reason for this is that enum layout optimizations may rely on references
+ /// (including slices of any length) being aligned and non-null to distinguish
+ /// them from other data. You can obtain a pointer that is usable as `data`
+ /// for zero-length slices using [`NonNull::dangling()`].
+ ///
+ /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+ /// See the safety documentation of [`pointer::offset`].
+ ///
+ /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+ /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+ /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// not get mutated (except inside `UnsafeCell`).
+ ///
+ /// This applies even if the result of this method is unused!
+ ///
+ /// See also [`slice::from_raw_parts`][].
+ ///
+ /// [valid]: crate::ptr#safety
+ /// [`NonNull::dangling()`]: NonNull::dangling
+ /// [`pointer::offset`]: ../std/primitive.pointer.html#method.offset
+ #[inline]
+ #[unstable(feature = "ptr_as_uninit", issue = "75402")]
+ pub unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit<T>]> {
+ if self.is_null() {
+ None
+ } else {
+ // SAFETY: the caller must uphold the safety contract for `as_uninit_slice`.
+ Some(unsafe { slice::from_raw_parts(self as *const MaybeUninit<T>, self.len()) })
+ }
+ }
+
+ /// Returns `None` if the pointer is null, or else returns a unique slice to
+ /// the value wrapped in `Some`. In contrast to [`as_mut`], this does not require
+ /// that the value has to be initialized.
+ ///
+ /// For the shared counterpart see [`as_uninit_slice`].
+ ///
+ /// [`as_mut`]: #method.as_mut
+ /// [`as_uninit_slice`]: #method.as_uninit_slice-1
+ ///
+ /// # Safety
+ ///
+ /// When calling this method, you have to ensure that *either* the pointer is NULL *or*
+ /// all of the following is true:
+ ///
+ /// * The pointer must be [valid] for reads and writes for `ptr.len() * mem::size_of::<T>()`
+ /// many bytes, and it must be properly aligned. This means in particular:
+ ///
+ /// * The entire memory range of this slice must be contained within a single allocated object!
+ /// Slices can never span across multiple allocated objects.
+ ///
+ /// * The pointer must be aligned even for zero-length slices. One
+ /// reason for this is that enum layout optimizations may rely on references
+ /// (including slices of any length) being aligned and non-null to distinguish
+ /// them from other data. You can obtain a pointer that is usable as `data`
+ /// for zero-length slices using [`NonNull::dangling()`].
+ ///
+ /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+ /// See the safety documentation of [`pointer::offset`].
+ ///
+ /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+ /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+ /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// not get accessed (read or written) through any other pointer.
+ ///
+ /// This applies even if the result of this method is unused!
+ ///
+ /// See also [`slice::from_raw_parts_mut`][].
+ ///
+ /// [valid]: crate::ptr#safety
+ /// [`NonNull::dangling()`]: NonNull::dangling
+ /// [`pointer::offset`]: ../std/primitive.pointer.html#method.offset
+ #[inline]
+ #[unstable(feature = "ptr_as_uninit", issue = "75402")]
+ pub unsafe fn as_uninit_slice_mut<'a>(self) -> Option<&'a mut [MaybeUninit<T>]> {
+ if self.is_null() {
+ None
+ } else {
+ // SAFETY: the caller must uphold the safety contract for `as_uninit_slice_mut`.
+ Some(unsafe { slice::from_raw_parts_mut(self as *mut MaybeUninit<T>, self.len()) })
+ }
+ }
}
// Equality for pointers
use crate::fmt;
use crate::hash;
use crate::marker::Unsize;
-use crate::mem;
+use crate::mem::{self, MaybeUninit};
use crate::ops::{CoerceUnsized, DispatchFromDyn};
use crate::ptr::Unique;
-use crate::slice::SliceIndex;
+use crate::slice::{self, SliceIndex};
/// `*mut T` but non-zero and covariant.
///
NonNull::new_unchecked(ptr)
}
}
+
+ /// Returns a shared references to the value. In contrast to [`as_ref`], this does not require
+ /// that the value has to be initialized.
+ ///
+ /// For the mutable counterpart see [`as_uninit_mut`].
+ ///
+ /// [`as_ref`]: #method.as_ref
+ /// [`as_uninit_mut`]: #method.as_uninit_mut
+ ///
+ /// # Safety
+ ///
+ /// When calling this method, you have to ensure that all of the following is true:
+ ///
+ /// * The pointer must be properly aligned.
+ ///
+ /// * It must be "dereferencable" in the sense defined in [the module documentation].
+ ///
+ /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+ /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+ /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// not get mutated (except inside `UnsafeCell`).
+ ///
+ /// This applies even if the result of this method is unused!
+ ///
+ /// [the module documentation]: crate::ptr#safety
+ #[inline]
+ #[unstable(feature = "ptr_as_uninit", issue = "75402")]
+ pub unsafe fn as_uninit_ref(&self) -> &MaybeUninit<T> {
+ // SAFETY: the caller must guarantee that `self` meets all the
+ // requirements for a reference.
+ unsafe { &*self.cast().as_ptr() }
+ }
+
+ /// Returns a unique references to the value. In contrast to [`as_mut`], this does not require
+ /// that the value has to be initialized.
+ ///
+ /// For the shared counterpart see [`as_uninit_ref`].
+ ///
+ /// [`as_mut`]: #method.as_mut
+ /// [`as_uninit_ref`]: #method.as_uninit_ref
+ ///
+ /// # Safety
+ ///
+ /// When calling this method, you have to ensure that all of the following is true:
+ ///
+ /// * The pointer must be properly aligned.
+ ///
+ /// * It must be "dereferencable" in the sense defined in [the module documentation].
+ ///
+ /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+ /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+ /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// not get accessed (read or written) through any other pointer.
+ ///
+ /// This applies even if the result of this method is unused!
+ ///
+ /// [the module documentation]: crate::ptr#safety
+ #[inline]
+ #[unstable(feature = "ptr_as_uninit", issue = "75402")]
+ pub unsafe fn as_uninit_mut(&mut self) -> &mut MaybeUninit<T> {
+ // SAFETY: the caller must guarantee that `self` meets all the
+ // requirements for a reference.
+ unsafe { &mut *self.cast().as_ptr() }
+ }
}
impl<T: ?Sized> NonNull<T> {
self.pointer as *mut T
}
- /// Dereferences the content.
+ /// Returns a shared reference to the value. If the value may be uninitialized, [`as_uninit_ref`]
+ /// must be used instead.
+ ///
+ /// For the mutable counterpart see [`as_mut`].
///
- /// The resulting lifetime is bound to self so this behaves "as if"
- /// it were actually an instance of T that is getting borrowed. If a longer
- /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
+ /// [`as_uninit_ref`]: #method.as_uninit_ref
+ /// [`as_mut`]: #method.as_mut
///
/// # Safety
///
/// When calling this method, you have to ensure that all of the following is true:
- /// - `self` is properly aligned
- /// - `self` must point to an initialized instance of T; in particular, the pointer must be
- /// "dereferencable" in the sense defined [here].
+ ///
+ /// * The pointer must be properly aligned.
+ ///
+ /// * It must be "dereferencable" in the sense defined in [the module documentation].
+ ///
+ /// * The pointer must point to an initialized instance of `T`.
+ ///
+ /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+ /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+ /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// not get mutated (except inside `UnsafeCell`).
///
/// This applies even if the result of this method is unused!
/// (The part about being initialized is not yet fully decided, but until
/// it is, the only safe approach is to ensure that they are indeed initialized.)
///
- /// Additionally, the lifetime of `self` does not necessarily reflect the actual
- /// lifetime of the data. *You* must enforce Rust's aliasing rules. In particular,
- /// for the duration of this lifetime, the memory the pointer points to must not
- /// get mutated (except inside `UnsafeCell`).
- ///
- /// [here]: crate::ptr#safety
+ /// [the module documentation]: crate::ptr#safety
#[stable(feature = "nonnull", since = "1.25.0")]
#[inline]
pub unsafe fn as_ref(&self) -> &T {
unsafe { &*self.as_ptr() }
}
- /// Mutably dereferences the content.
+ /// Returns a unique reference to the value. If the value may be uninitialized, [`as_uninit_mut`]
+ /// must be used instead.
+ ///
+ /// For the shared counterpart see [`as_ref`].
///
- /// The resulting lifetime is bound to self so this behaves "as if"
- /// it were actually an instance of T that is getting borrowed. If a longer
- /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
+ /// [`as_uninit_mut`]: #method.as_uninit_mut
+ /// [`as_ref`]: #method.as_ref
///
/// # Safety
///
/// When calling this method, you have to ensure that all of the following is true:
- /// - `self` is properly aligned
- /// - `self` must point to an initialized instance of T; in particular, the pointer must be
- /// "dereferenceable" in the sense defined [here].
+ ///
+ /// * The pointer must be properly aligned.
+ ///
+ /// * It must be "dereferencable" in the sense defined in [the module documentation].
+ ///
+ /// * The pointer must point to an initialized instance of `T`.
+ ///
+ /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+ /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+ /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// not get accessed (read or written) through any other pointer.
///
/// This applies even if the result of this method is unused!
/// (The part about being initialized is not yet fully decided, but until
- /// it is the only safe approach is to ensure that they are indeed initialized.)
- ///
- /// Additionally, the lifetime of `self` does not necessarily reflect the actual
- /// lifetime of the data. *You* must enforce Rust's aliasing rules. In particular,
- /// for the duration of this lifetime, the memory this pointer points to must not
- /// get accessed (read or written) through any other pointer.
+ /// it is, the only safe approach is to ensure that they are indeed initialized.)
///
- /// [here]: crate::ptr#safety
+ /// [the module documentation]: crate::ptr#safety
#[stable(feature = "nonnull", since = "1.25.0")]
#[inline]
pub unsafe fn as_mut(&mut self) -> &mut T {
self.as_non_null_ptr().as_ptr()
}
+ /// Returns a shared reference to a slice of possibly uninitialized values. In contrast to
+ /// [`as_ref`], this does not require that the value has to be initialized.
+ ///
+ /// For the mutable counterpart see [`as_uninit_slice_mut`].
+ ///
+ /// [`as_ref`]: #method.as_ref
+ /// [`as_uninit_slice_mut`]: #method.as_uninit_slice_mut
+ ///
+ /// # Safety
+ ///
+ /// When calling this method, you have to ensure that all of the following is true:
+ ///
+ /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::<T>()` many bytes,
+ /// and it must be properly aligned. This means in particular:
+ ///
+ /// * The entire memory range of this slice must be contained within a single allocated object!
+ /// Slices can never span across multiple allocated objects.
+ ///
+ /// * The pointer must be aligned even for zero-length slices. One
+ /// reason for this is that enum layout optimizations may rely on references
+ /// (including slices of any length) being aligned and non-null to distinguish
+ /// them from other data. You can obtain a pointer that is usable as `data`
+ /// for zero-length slices using [`NonNull::dangling()`].
+ ///
+ /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+ /// See the safety documentation of [`pointer::offset`].
+ ///
+ /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+ /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+ /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// not get mutated (except inside `UnsafeCell`).
+ ///
+ /// This applies even if the result of this method is unused!
+ ///
+ /// See also [`slice::from_raw_parts`][].
+ ///
+ /// [valid]: crate::ptr#safety
+ /// [`NonNull::dangling()`]: NonNull::dangling
+ /// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
+ #[inline]
+ #[unstable(feature = "ptr_as_uninit", issue = "75402")]
+ pub unsafe fn as_uninit_slice(&self) -> &[MaybeUninit<T>] {
+ // SAFETY: the caller must uphold the safety contract for `as_uninit_slice`.
+ unsafe { slice::from_raw_parts(self.cast().as_ptr(), self.len()) }
+ }
+
+ /// Returns a unique reference to a slice of possibly uninitialized values. In contrast to
+ /// [`as_mut`], this does not require that the value has to be initialized.
+ ///
+ /// For the shared counterpart see [`as_uninit_slice`].
+ ///
+ /// [`as_mut`]: #method.as_mut
+ /// [`as_uninit_slice`]: #method.as_uninit_slice
+ ///
+ /// # Safety
+ ///
+ /// When calling this method, you have to ensure that all of the following is true:
+ ///
+ /// * The pointer must be [valid] for reads and writes for `ptr.len() * mem::size_of::<T>()`
+ /// many bytes, and it must be properly aligned. This means in particular:
+ ///
+ /// * The entire memory range of this slice must be contained within a single allocated object!
+ /// Slices can never span across multiple allocated objects.
+ ///
+ /// * The pointer must be aligned even for zero-length slices. One
+ /// reason for this is that enum layout optimizations may rely on references
+ /// (including slices of any length) being aligned and non-null to distinguish
+ /// them from other data. You can obtain a pointer that is usable as `data`
+ /// for zero-length slices using [`NonNull::dangling()`].
+ ///
+ /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+ /// See the safety documentation of [`pointer::offset`].
+ ///
+ /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+ /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+ /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// not get accessed (read or written) through any other pointer.
+ ///
+ /// This applies even if the result of this method is unused!
+ ///
+ /// See also [`slice::from_raw_parts_mut`][].
+ ///
+ /// [valid]: crate::ptr#safety
+ /// [`NonNull::dangling()`]: NonNull::dangling
+ /// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// #![feature(allocator_api, ptr_as_uninit)]
+ ///
+ /// use std::alloc::{AllocRef, Layout, Global};
+ /// use std::mem::MaybeUninit;
+ /// use std::ptr::NonNull;
+ ///
+ /// let memory: NonNull<[u8]> = Global.alloc(Layout::new::<[u8; 32]>())?;
+ /// // This is safe as `memory` is valid for reads and writes for `memory.len()` many bytes.
+ /// // Note that calling `memory.as_mut()` is not allowed here as the content may be uninitialized.
+ /// # #[allow(unused_variables)]
+ /// let slice: &mut [MaybeUninit<u8>] = unsafe { memory.as_uninit_slice_mut() };
+ /// # Ok::<_, std::alloc::AllocErr>(())
+ /// ```
+ #[inline]
+ #[unstable(feature = "ptr_as_uninit", issue = "75402")]
+ pub unsafe fn as_uninit_slice_mut(&self) -> &mut [MaybeUninit<T>] {
+ // SAFETY: the caller must uphold the safety contract for `as_uninit_slice_mut`.
+ unsafe { slice::from_raw_parts_mut(self.cast().as_ptr(), self.len()) }
+ }
+
/// Returns a raw pointer to an element or subslice, without doing bounds
/// checking.
///
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Result<T, E> {
/// Contains the success value
+ #[cfg_attr(not(bootstrap), lang = "Ok")]
#[stable(feature = "rust1", since = "1.0.0")]
Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
/// Contains the error value
+ #[cfg_attr(not(bootstrap), lang = "Err")]
#[stable(feature = "rust1", since = "1.0.0")]
Err(#[stable(feature = "rust1", since = "1.0.0")] E),
}
///
/// - Read the first word with an unaligned load.
/// - Align the pointer, read subsequent words until end with aligned loads.
-/// - If there's a tail, the last `usize` from `s` with an unaligned load.
+/// - Read the last `usize` from `s` with an unaligned load.
///
/// If any of these loads produces something for which `contains_nonascii`
/// (above) returns true, then we know the answer is false.
// `align_offset` though.
debug_assert_eq!((word_ptr as usize) % mem::align_of::<usize>(), 0);
- while byte_pos <= len - USIZE_SIZE {
+ // Read subsequent words until the last aligned word, excluding the last
+ // aligned word by itself to be done in tail check later, to ensure that
+ // tail is always one `usize` at most to extra branch `byte_pos == len`.
+ while byte_pos < len - USIZE_SIZE {
debug_assert!(
// Sanity check that the read is in bounds
(word_ptr as usize + USIZE_SIZE) <= (start.wrapping_add(len) as usize) &&
word_ptr = unsafe { word_ptr.add(1) };
}
- // If we have anything left over, it should be at-most 1 usize worth of bytes,
- // which we check with a read_unaligned.
- if byte_pos == len {
- return true;
- }
-
// Sanity check to ensure there really is only one `usize` left. This should
// be guaranteed by our loop condition.
- debug_assert!(byte_pos < len && len - byte_pos < USIZE_SIZE);
+ debug_assert!(byte_pos <= len && len - byte_pos <= USIZE_SIZE);
// SAFETY: This relies on `len >= USIZE_SIZE`, which we check at the start.
let last_word = unsafe { (start.add(len - USIZE_SIZE) as *const usize).read_unaligned() };
#[stable(feature = "futures_api", since = "1.36.0")]
pub enum Poll<T> {
/// Represents that a value is immediately ready.
+ #[cfg_attr(not(bootstrap), lang = "Ready")]
#[stable(feature = "futures_api", since = "1.36.0")]
Ready(#[stable(feature = "futures_api", since = "1.36.0")] T),
/// When a function returns `Pending`, the function *must* also
/// ensure that the current task is scheduled to be awoken when
/// progress can be made.
+ #[cfg_attr(not(bootstrap), lang = "Pending")]
#[stable(feature = "futures_api", since = "1.36.0")]
Pending,
}
//! like `cdylib`s and `staticlib`s are guaranteed to use the [`System`] by
//! default.
//!
-//! [`System`]: struct.System.html
-//!
//! # The `#[global_allocator]` attribute
//!
//! This attribute allows configuring the choice of global allocator.
//! The attribute is used on a `static` item whose type implements the
//! [`GlobalAlloc`] trait. This type can be provided by an external library:
//!
-//! [`GlobalAlloc`]: ../../core/alloc/trait.GlobalAlloc.html
-//!
//! ```rust,ignore (demonstrates crates.io usage)
//! extern crate jemallocator;
//!
);
// SAFETY: `new_size` must be non-zero, which is checked in the match expression.
+ // If `new_size` is zero, then `old_size` has to be zero as well.
// Other conditions must be upheld by the caller
unsafe {
match layout.size() {
- old_size if old_size == new_size => {
- Ok(NonNull::slice_from_raw_parts(ptr, new_size))
- }
0 => self.alloc(Layout::from_size_align_unchecked(new_size, layout.align())),
old_size => {
- // `realloc` probably checks for `new_size > size` or something similar.
- intrinsics::assume(new_size > old_size);
+ // `realloc` probably checks for `new_size >= size` or something similar.
+ intrinsics::assume(new_size >= old_size);
let raw_ptr = GlobalAlloc::realloc(&System, ptr.as_ptr(), layout, new_size);
let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
Ok(NonNull::slice_from_raw_parts(ptr, new_size))
);
// SAFETY: `new_size` must be non-zero, which is checked in the match expression.
+ // If `new_size` is zero, then `old_size` has to be zero as well.
// Other conditions must be upheld by the caller
unsafe {
match layout.size() {
- old_size if old_size == new_size => {
- Ok(NonNull::slice_from_raw_parts(ptr, new_size))
- }
0 => self.alloc_zeroed(Layout::from_size_align_unchecked(new_size, layout.align())),
old_size => {
- // `realloc` probably checks for `new_size > size` or something similar.
- intrinsics::assume(new_size > old_size);
+ // `realloc` probably checks for `new_size >= size` or something similar.
+ intrinsics::assume(new_size >= old_size);
let raw_ptr = GlobalAlloc::realloc(&System, ptr.as_ptr(), layout, new_size);
raw_ptr.add(old_size).write_bytes(0, new_size - old_size);
let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
"`new_size` must be smaller than or equal to `layout.size()`"
);
- let ptr = if new_size == old_size {
- ptr
- } else if new_size == 0 {
- // SAFETY: `layout` is non-zero in size as `old_size` != `new_size`
- // Other conditions must be upheld by the caller
+ let ptr = if new_size == 0 {
+ // SAFETY: conditions must be upheld by the caller
unsafe {
self.dealloc(ptr, layout);
}
// SAFETY: new_size is not zero,
// Other conditions must be upheld by the caller
let raw_ptr = unsafe {
- // `realloc` probably checks for `new_size < old_size` or something similar.
- intrinsics::assume(new_size < old_size);
+ // `realloc` probably checks for `new_size <= old_size` or something similar.
+ intrinsics::assume(new_size <= old_size);
GlobalAlloc::realloc(&System, ptr.as_ptr(), layout, new_size)
};
NonNull::new(raw_ptr).ok_or(AllocErr)?
/// about the allocation that failed.
///
/// The allocation error hook is a global resource.
-///
-/// [`set_alloc_error_hook`]: fn.set_alloc_error_hook.html
-/// [`take_alloc_error_hook`]: fn.take_alloc_error_hook.html
#[unstable(feature = "alloc_error_hook", issue = "51245")]
pub fn set_alloc_error_hook(hook: fn(Layout)) {
HOOK.store(hook as *mut (), Ordering::SeqCst);
/// *See also the function [`set_alloc_error_hook`].*
///
/// If no custom hook is registered, the default hook will be returned.
-///
-/// [`set_alloc_error_hook`]: fn.set_alloc_error_hook.html
#[unstable(feature = "alloc_error_hook", issue = "51245")]
pub fn take_alloc_error_hook() -> fn(Layout) {
let hook = HOOK.swap(ptr::null_mut(), Ordering::SeqCst);
//!
//! The [`escape_default`] function provides an iterator over the bytes of an
//! escaped version of the character given.
-//!
-//! [`AsciiExt`]: trait.AsciiExt.html
-//! [`escape_default`]: fn.escape_default.html
#![stable(feature = "rust1", since = "1.0.0")]
///
/// # Note
///
- /// This method will be deprecated in favor of the identically-named
+ /// This method is deprecated in favor of the identically-named
/// inherent methods on `u8`, `char`, `[u8]` and `str`.
#[stable(feature = "rust1", since = "1.0.0")]
fn is_ascii(&self) -> bool;
///
/// # Note
///
- /// This method will be deprecated in favor of the identically-named
+ /// This method is deprecated in favor of the identically-named
/// inherent methods on `u8`, `char`, `[u8]` and `str`.
///
- /// [`make_ascii_uppercase`]: #tymethod.make_ascii_uppercase
+ /// [`make_ascii_uppercase`]: AsciiExt::make_ascii_uppercase
/// [`str::to_uppercase`]: ../primitive.str.html#method.to_uppercase
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
///
/// # Note
///
- /// This method will be deprecated in favor of the identically-named
+ /// This method is deprecated in favor of the identically-named
/// inherent methods on `u8`, `char`, `[u8]` and `str`.
///
- /// [`make_ascii_lowercase`]: #tymethod.make_ascii_lowercase
+ /// [`make_ascii_lowercase`]: AsciiExt::make_ascii_lowercase
/// [`str::to_lowercase`]: ../primitive.str.html#method.to_lowercase
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
///
/// # Note
///
- /// This method will be deprecated in favor of the identically-named
+ /// This method is deprecated in favor of the identically-named
/// inherent methods on `u8`, `char`, `[u8]` and `str`.
#[stable(feature = "rust1", since = "1.0.0")]
fn eq_ignore_ascii_case(&self, other: &Self) -> bool;
///
/// # Note
///
- /// This method will be deprecated in favor of the identically-named
+ /// This method is deprecated in favor of the identically-named
/// inherent methods on `u8`, `char`, `[u8]` and `str`.
///
- /// [`to_ascii_uppercase`]: #tymethod.to_ascii_uppercase
+ /// [`to_ascii_uppercase`]: AsciiExt::to_ascii_uppercase
#[stable(feature = "ascii", since = "1.9.0")]
fn make_ascii_uppercase(&mut self);
///
/// # Note
///
- /// This method will be deprecated in favor of the identically-named
+ /// This method is deprecated in favor of the identically-named
/// inherent methods on `u8`, `char`, `[u8]` and `str`.
///
- /// [`to_ascii_lowercase`]: #tymethod.to_ascii_lowercase
+ /// [`to_ascii_lowercase`]: AsciiExt::to_ascii_lowercase
#[stable(feature = "ascii", since = "1.9.0")]
fn make_ascii_lowercase(&mut self);
}
//! There are several functions and structs in this module that have a
//! counterpart ending in `os`. Those ending in `os` will return an [`OsString`]
//! and those without will return a [`String`].
-//!
-//! [`OsString`]: ../../std/ffi/struct.OsString.html
-//! [`String`]: ../string/struct.String.html
#![stable(feature = "env", since = "1.0.0")]
/// * Current directory does not exist.
/// * There are insufficient permissions to access the current directory.
///
-/// [`PathBuf`]: ../../std/path/struct.PathBuf.html
-/// [`Err`]: ../../std/result/enum.Result.html#method.err
-///
/// # Examples
///
/// ```
///
/// Returns an [`Err`] if the operation fails.
///
-/// [`Err`]: ../../std/result/enum.Result.html#method.err
-///
/// # Examples
///
/// ```
/// This structure is created by the [`std::env::vars`] function. See its
/// documentation for more.
///
-/// [`std::env::vars`]: fn.vars.html
+/// [`std::env::vars`]: vars
#[stable(feature = "env", since = "1.0.0")]
pub struct Vars {
inner: VarsOs,
/// This structure is created by the [`std::env::vars_os`] function. See
/// its documentation for more.
///
-/// [`std::env::vars_os`]: fn.vars_os.html
+/// [`std::env::vars_os`]: vars_os
#[stable(feature = "env", since = "1.0.0")]
pub struct VarsOs {
inner: os_imp::Env,
/// environment is not valid unicode. If this is not desired, consider using the
/// [`env::vars_os`] function.
///
-/// [`env::vars_os`]: fn.vars_os.html
+/// [`env::vars_os`]: vars_os
///
/// # Examples
///
/// Fetches the environment variable `key` from the current process, returning
/// [`None`] if the variable isn't set.
///
-/// [`None`]: ../option/enum.Option.html#variant.None
-///
/// # Panics
///
/// This function may panic if `key` is empty, contains an ASCII equals sign
/// The error type for operations interacting with environment variables.
/// Possibly returned from the [`env::var`] function.
///
-/// [`env::var`]: fn.var.html
+/// [`env::var`]: var
#[derive(Debug, PartialEq, Eq, Clone)]
#[stable(feature = "env", since = "1.0.0")]
pub enum VarError {
/// This structure is created by the [`std::env::split_paths`] function. See its
/// documentation for more.
///
-/// [`PathBuf`]: ../../std/path/struct.PathBuf.html
-/// [`std::env::split_paths`]: fn.split_paths.html
+/// [`std::env::split_paths`]: split_paths
#[stable(feature = "env", since = "1.0.0")]
pub struct SplitPaths<'a> {
inner: os_imp::SplitPaths<'a>,
/// None => println!("{} is not defined in the environment.", key)
/// }
/// ```
-///
-/// [`PathBuf`]: ../../std/path/struct.PathBuf.html
#[stable(feature = "env", since = "1.0.0")]
pub fn split_paths<T: AsRef<OsStr> + ?Sized>(unparsed: &T) -> SplitPaths<'_> {
SplitPaths { inner: os_imp::split_paths(unparsed.as_ref()) }
/// The error type for operations on the `PATH` variable. Possibly returned from
/// the [`env::join_paths`] function.
///
-/// [`env::join_paths`]: fn.join_paths.html
+/// [`env::join_paths`]: join_paths
#[derive(Debug)]
#[stable(feature = "env", since = "1.0.0")]
pub struct JoinPathsError {
///
/// # Errors
///
-/// Returns an [`Err`][err] (containing an error message) if one of the input
+/// Returns an [`Err`] (containing an error message) if one of the input
/// [`Path`]s contains an invalid character for constructing the `PATH`
/// variable (a double quote on Windows or a colon on Unix).
///
-/// [`Path`]: ../../std/path/struct.Path.html
-/// [`OsString`]: ../../std/ffi/struct.OsString.html
-/// [err]: ../../std/result/enum.Result.html#variant.Err
-///
/// # Examples
///
/// Joining paths on a Unix-like platform:
/// }
/// ```
///
-/// [`env::split_paths`]: fn.split_paths.html
+/// [`env::split_paths`]: split_paths
#[stable(feature = "env", since = "1.0.0")]
pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
where
/// set to arbitrary text, and may not even exist. This means this property
/// should not be relied upon for security purposes.
///
-/// [`String`]: ../string/struct.String.html
-/// [`std::env::args`]: ./fn.args.html
+/// [`std::env::args`]: args
#[stable(feature = "env", since = "1.0.0")]
pub struct Args {
inner: ArgsOs,
/// set to arbitrary text, and may not even exist. This means this property
/// should not be relied upon for security purposes.
///
-/// [`OsString`]: ../ffi/struct.OsString.html
-/// [`std::env::args_os`]: ./fn.args_os.html
+/// [`std::env::args_os`]: args_os
#[stable(feature = "env", since = "1.0.0")]
pub struct ArgsOs {
inner: sys::args::Args,
/// println!("{}", argument);
/// }
/// ```
-///
-/// [`args_os`]: ./fn.args_os.html
#[stable(feature = "env", since = "1.0.0")]
pub fn args() -> Args {
Args { inner: args_os() }
/// provide its own errors while also revealing some of the implementation for
/// debugging via [`source`] chains.
///
-/// [`Result<T, E>`]: ../result/enum.Result.html
-/// [`Display`]: ../fmt/trait.Display.html
-/// [`Debug`]: ../fmt/trait.Debug.html
-/// [`source`]: trait.Error.html#method.source
+/// [`Result<T, E>`]: Result
+/// [`source`]: Error::source
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Error: Debug + Display {
/// The lower-level source of this error, if any.
impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
/// Converts a type of [`Error`] into a box of dyn [`Error`].
///
- /// [`Error`]: ../error/trait.Error.html
- ///
/// # Examples
///
/// ```
/// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of
/// dyn [`Error`] + [`Send`] + [`Sync`].
///
- /// [`Error`]: ../error/trait.Error.html
- ///
/// # Examples
///
/// ```
impl From<String> for Box<dyn Error + Send + Sync> {
/// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
///
- /// [`Error`]: ../error/trait.Error.html
- ///
/// # Examples
///
/// ```
impl From<String> for Box<dyn Error> {
/// Converts a [`String`] into a box of dyn [`Error`].
///
- /// [`Error`]: ../error/trait.Error.html
- ///
/// # Examples
///
/// ```
impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
/// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
///
- /// [`Error`]: ../error/trait.Error.html
- ///
/// # Examples
///
/// ```
impl From<&str> for Box<dyn Error> {
/// Converts a [`str`] into a box of dyn [`Error`].
///
- /// [`Error`]: ../error/trait.Error.html
- ///
/// # Examples
///
/// ```
impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
/// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
///
- /// [`Cow`]: ../borrow/enum.Cow.html
- /// [`Error`]: ../error/trait.Error.html
- ///
/// # Examples
///
/// ```
impl<'a> From<Cow<'a, str>> for Box<dyn Error> {
/// Converts a [`Cow`] into a box of dyn [`Error`].
///
- /// [`Cow`]: ../borrow/enum.Cow.html
- /// [`Error`]: ../error/trait.Error.html
- ///
/// # Examples
///
/// ```
/// assert!(iter.next().is_none());
/// ```
///
- /// [`source`]: trait.Error.html#method.source
+ /// [`source`]: Error::source
#[unstable(feature = "error_iter", issue = "58520")]
#[inline]
pub fn chain(&self) -> Chain<'_> {
///
/// If you want to omit the initial error and only process
/// its sources, use `skip(1)`.
-///
-/// [`Error`]: trait.Error.html
#[unstable(feature = "error_iter", issue = "58520")]
#[derive(Clone, Debug)]
pub struct Chain<'a> {
///
/// # Examples
///
-/// Creates a new file and write bytes to it (you can also use [`write`]):
+/// Creates a new file and write bytes to it (you can also use [`write()`]):
///
/// ```no_run
/// use std::fs::File;
/// by different processes. Avoid assuming that holding a `&File` means that the
/// file will not change.
///
-/// [`Seek`]: ../io/trait.Seek.html
-/// [`String`]: ../string/struct.String.html
-/// [`Read`]: ../io/trait.Read.html
-/// [`Write`]: ../io/trait.Write.html
-/// [`BufReader<R>`]: ../io/struct.BufReader.html
-/// [`sync_all`]: struct.File.html#method.sync_all
-/// [`read`]: fn.read.html
-/// [`write`]: fn.write.html
+/// [`BufReader<R>`]: io::BufReader
+/// [`sync_all`]: File::sync_all
#[stable(feature = "rust1", since = "1.0.0")]
pub struct File {
inner: fs_imp::File,
/// [`symlink_metadata`] function or method and represents known
/// metadata about a file such as its permissions, size, modification
/// times, etc.
-///
-/// [`metadata`]: fn.metadata.html
-/// [`symlink_metadata`]: fn.symlink_metadata.html
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone)]
pub struct Metadata(fs_imp::FileAttr);
///
/// This [`io::Result`] will be an [`Err`] if there's some sort of intermittent
/// IO error during iteration.
-///
-/// [`read_dir`]: fn.read_dir.html
-/// [`DirEntry`]: struct.DirEntry.html
-/// [`io::Result`]: ../io/type.Result.html
-/// [`Err`]: ../result/enum.Result.html#variant.Err
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Debug)]
pub struct ReadDir(fs_imp::ReadDir);
/// Entries returned by the [`ReadDir`] iterator.
///
-/// [`ReadDir`]: struct.ReadDir.html
-///
/// An instance of `DirEntry` represents an entry inside of a directory on the
/// filesystem. Each entry can be inspected via methods to learn about the full
/// path or possibly other metadata through per-platform extension traits.
/// [`File::create`] methods are aliases for commonly used options using this
/// builder.
///
-/// [`File`]: struct.File.html
-/// [`File::open`]: struct.File.html#method.open
-/// [`File::create`]: struct.File.html#method.create
-///
-/// Generally speaking, when using `OpenOptions`, you'll first call [`new`],
-/// then chain calls to methods to set each option, then call [`open`],
-/// passing the path of the file you're trying to open. This will give you a
-/// [`io::Result`][result] with a [`File`][file] inside that you can further
-/// operate on.
-///
-/// [`new`]: struct.OpenOptions.html#method.new
-/// [`open`]: struct.OpenOptions.html#method.open
-/// [result]: ../io/type.Result.html
-/// [file]: struct.File.html
+/// Generally speaking, when using `OpenOptions`, you'll first call
+/// [`OpenOptions::new`], then chain calls to methods to set each option, then
+/// call [`OpenOptions::open`], passing the path of the file you're trying to
+/// open. This will give you a [`io::Result`] with a [`File`] inside that you
+/// can further operate on.
///
/// # Examples
///
/// Representation of the various permissions on a file.
///
-/// This module only currently provides one bit of information, [`readonly`],
-/// which is exposed on all currently supported platforms. Unix-specific
-/// functionality, such as mode bits, is available through the
-/// [`PermissionsExt`] trait.
+/// This module only currently provides one bit of information,
+/// [`Permissions::readonly`], which is exposed on all currently supported
+/// platforms. Unix-specific functionality, such as mode bits, is available
+/// through the [`PermissionsExt`] trait.
///
-/// [`readonly`]: struct.Permissions.html#method.readonly
-/// [`PermissionsExt`]: ../os/unix/fs/trait.PermissionsExt.html
+/// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt
#[derive(Clone, PartialEq, Eq, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Permissions(fs_imp::FilePermissions);
/// A structure representing a type of file with accessors for each file type.
/// It is returned by [`Metadata::file_type`] method.
-///
-/// [`Metadata::file_type`]: struct.Metadata.html#method.file_type
#[stable(feature = "file_type", since = "1.1.0")]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct FileType(fs_imp::FileType);
/// This is a convenience function for using [`File::open`] and [`read_to_end`]
/// with fewer imports and without an intermediate variable. It pre-allocates a
/// buffer based on the file size when available, so it is generally faster than
-/// reading into a vector created with `Vec::new()`.
+/// reading into a vector created with [`Vec::new()`].
///
-/// [`File::open`]: struct.File.html#method.open
-/// [`read_to_end`]: ../io/trait.Read.html#method.read_to_end
+/// [`read_to_end`]: Read::read_to_end
///
/// # Errors
///
/// This function will return an error if `path` does not already exist.
/// Other errors may also be returned according to [`OpenOptions::open`].
///
-/// [`OpenOptions::open`]: struct.OpenOptions.html#method.open
-///
/// It will also return an error if it encounters while reading an error
-/// of a kind other than [`ErrorKind::Interrupted`].
-///
-/// [`ErrorKind::Interrupted`]: ../../std/io/enum.ErrorKind.html#variant.Interrupted
+/// of a kind other than [`io::ErrorKind::Interrupted`].
///
/// # Examples
///
/// This is a convenience function for using [`File::open`] and [`read_to_string`]
/// with fewer imports and without an intermediate variable. It pre-allocates a
/// buffer based on the file size when available, so it is generally faster than
-/// reading into a string created with `String::new()`.
+/// reading into a string created with [`String::new()`].
///
-/// [`File::open`]: struct.File.html#method.open
-/// [`read_to_string`]: ../io/trait.Read.html#method.read_to_string
+/// [`read_to_string`]: Read::read_to_string
///
/// # Errors
///
/// This function will return an error if `path` does not already exist.
/// Other errors may also be returned according to [`OpenOptions::open`].
///
-/// [`OpenOptions::open`]: struct.OpenOptions.html#method.open
-///
/// It will also return an error if it encounters while reading an error
-/// of a kind other than [`ErrorKind::Interrupted`],
+/// of a kind other than [`io::ErrorKind::Interrupted`],
/// or if the contents of the file are not valid UTF-8.
///
-/// [`ErrorKind::Interrupted`]: ../../std/io/enum.ErrorKind.html#variant.Interrupted
-///
/// # Examples
///
/// ```no_run
/// This is a convenience function for using [`File::create`] and [`write_all`]
/// with fewer imports.
///
-/// [`File::create`]: struct.File.html#method.create
-/// [`write_all`]: ../io/trait.Write.html#method.write_all
+/// [`write_all`]: Write::write_all
///
/// # Examples
///
/// This function will return an error if `path` does not already exist.
/// Other errors may also be returned according to [`OpenOptions::open`].
///
- /// [`OpenOptions::open`]: struct.OpenOptions.html#method.open
- ///
/// # Examples
///
/// ```no_run
///
/// See the [`OpenOptions::open`] function for more details.
///
- /// [`OpenOptions::open`]: struct.OpenOptions.html#method.open
- ///
/// # Examples
///
/// ```no_run
///
/// See the [`OpenOptions::new`] function for more details.
///
- /// [`OpenOptions::new`]: struct.OpenOptions.html#method.new
- ///
/// # Examples
///
/// ```no_run
/// Note that some platforms may simply implement this in terms of
/// [`sync_all`].
///
- /// [`sync_all`]: struct.File.html#method.sync_all
+ /// [`sync_all`]: File::sync_all
///
/// # Examples
///
///
/// ## Note
///
- /// This function doesn't create the file if it doesn't exist. Use the [`create`]
- /// method to do so.
+ /// This function doesn't create the file if it doesn't exist. Use the
+ /// [`OpenOptions::create`] method to do so.
///
- /// [`write()`]: ../../std/fs/struct.File.html#method.write
- /// [`flush()`]: ../../std/fs/struct.File.html#method.flush
- /// [`seek`]: ../../std/fs/struct.File.html#method.seek
- /// [`SeekFrom`]: ../../std/io/enum.SeekFrom.html
- /// [`Current`]: ../../std/io/enum.SeekFrom.html#variant.Current
- /// [`create`]: #method.create
+ /// [`write()`]: Write::write
+ /// [`flush()`]: Write::flush
+ /// [`seek`]: Seek::seek
+ /// [`Current`]: SeekFrom::Current
///
/// # Examples
///
/// Sets the option to create a new file, or open it if it already exists.
///
- /// In order for the file to be created, [`write`] or [`append`] access must
- /// be used.
- ///
- /// [`write`]: #method.write
- /// [`append`]: #method.append
+ /// In order for the file to be created, [`OpenOptions::write`] or
+ /// [`OpenOptions::append`] access must be used.
///
/// # Examples
///
/// The file must be opened with write or append access in order to create
/// a new file.
///
- /// [`.create()`]: #method.create
- /// [`.truncate()`]: #method.truncate
+ /// [`.create()`]: OpenOptions::create
+ /// [`.truncate()`]: OpenOptions::truncate
///
/// # Examples
///
///
/// This function will return an error under a number of different
/// circumstances. Some of these error conditions are listed here, together
- /// with their [`ErrorKind`]. The mapping to [`ErrorKind`]s is not part of
- /// the compatibility contract of the function, especially the `Other` kind
- /// might change to more specific kinds in the future.
+ /// with their [`io::ErrorKind`]. The mapping to [`io::ErrorKind`]s is not
+ /// part of the compatibility contract of the function, especially the
+ /// [`Other`] kind might change to more specific kinds in the future.
///
/// * [`NotFound`]: The specified file does not exist and neither `create`
/// or `create_new` is set.
/// let file = OpenOptions::new().read(true).open("foo.txt");
/// ```
///
- /// [`ErrorKind`]: ../io/enum.ErrorKind.html
- /// [`AlreadyExists`]: ../io/enum.ErrorKind.html#variant.AlreadyExists
- /// [`InvalidInput`]: ../io/enum.ErrorKind.html#variant.InvalidInput
- /// [`NotFound`]: ../io/enum.ErrorKind.html#variant.NotFound
- /// [`Other`]: ../io/enum.ErrorKind.html#variant.Other
- /// [`PermissionDenied`]: ../io/enum.ErrorKind.html#variant.PermissionDenied
+ /// [`AlreadyExists`]: io::ErrorKind::AlreadyExists
+ /// [`InvalidInput`]: io::ErrorKind::InvalidInput
+ /// [`NotFound`]: io::ErrorKind::NotFound
+ /// [`Other`]: io::ErrorKind::Other
+ /// [`PermissionDenied`]: io::ErrorKind::PermissionDenied
#[stable(feature = "rust1", since = "1.0.0")]
pub fn open<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {
self._open(path.as_ref())
/// Returns `true` if this metadata is for a directory. The
/// result is mutually exclusive to the result of
- /// [`is_file`], and will be false for symlink metadata
+ /// [`Metadata::is_file`], and will be false for symlink metadata
/// obtained from [`symlink_metadata`].
///
- /// [`is_file`]: struct.Metadata.html#method.is_file
- /// [`symlink_metadata`]: fn.symlink_metadata.html
- ///
/// # Examples
///
/// ```no_run
/// Returns `true` if this metadata is for a regular file. The
/// result is mutually exclusive to the result of
- /// [`is_dir`], and will be false for symlink metadata
+ /// [`Metadata::is_dir`], and will be false for symlink metadata
/// obtained from [`symlink_metadata`].
///
/// When the goal is simply to read from (or write to) the source, the most
/// a Unix-like system for example. See [`File::open`] or
/// [`OpenOptions::open`] for more information.
///
- /// [`is_dir`]: struct.Metadata.html#method.is_dir
- /// [`symlink_metadata`]: fn.symlink_metadata.html
- /// [`File::open`]: struct.File.html#method.open
- /// [`OpenOptions::open`]: struct.OpenOptions.html#method.open
- ///
/// # Examples
///
/// ```no_run
/// writing.
///
/// This operation does **not** modify the filesystem. To modify the
- /// filesystem use the [`fs::set_permissions`] function.
- ///
- /// [`fs::set_permissions`]: fn.set_permissions.html
+ /// filesystem use the [`set_permissions`] function.
///
/// # Examples
///
/// [`is_file`] and [`is_symlink`]; only zero or one of these
/// tests may pass.
///
- /// [`is_file`]: struct.FileType.html#method.is_file
- /// [`is_symlink`]: struct.FileType.html#method.is_symlink
+ /// [`is_file`]: FileType::is_file
+ /// [`is_symlink`]: FileType::is_symlink
///
/// # Examples
///
/// a Unix-like system for example. See [`File::open`] or
/// [`OpenOptions::open`] for more information.
///
- /// [`is_dir`]: struct.FileType.html#method.is_dir
- /// [`is_symlink`]: struct.FileType.html#method.is_symlink
- /// [`File::open`]: struct.File.html#method.open
- /// [`OpenOptions::open`]: struct.OpenOptions.html#method.open
+ /// [`is_dir`]: FileType::is_dir
+ /// [`is_symlink`]: FileType::is_symlink
///
/// # Examples
///
/// follows symbolic links, so [`is_symlink`] would always
/// return `false` for the target file.
///
- /// [`Metadata`]: struct.Metadata.html
- /// [`fs::metadata`]: fn.metadata.html
- /// [`fs::symlink_metadata`]: fn.symlink_metadata.html
- /// [`is_dir`]: struct.FileType.html#method.is_dir
- /// [`is_file`]: struct.FileType.html#method.is_file
- /// [`is_symlink`]: struct.FileType.html#method.is_symlink
+ /// [`fs::metadata`]: metadata
+ /// [`fs::symlink_metadata`]: symlink_metadata
+ /// [`is_dir`]: FileType::is_dir
+ /// [`is_file`]: FileType::is_file
+ /// [`is_symlink`]: FileType::is_symlink
///
/// # Examples
///
/// This function will not traverse symlinks if this entry points at a
/// symlink. To traverse symlinks use [`fs::metadata`] or [`fs::File::metadata`].
///
- /// [`fs::metadata`]: fn.metadata.html
- /// [`fs::File::metadata`]: struct.File.html#method.metadata
+ /// [`fs::metadata`]: metadata
+ /// [`fs::File::metadata`]: File::metadata
///
/// # Platform-specific behavior
///
/// If you’re wanting to copy the contents of one file to another and you’re
/// working with [`File`]s, see the [`io::copy`] function.
///
-/// [`io::copy`]: ../io/fn.copy.html
-/// [`File`]: ./struct.File.html
-///
/// # Platform-specific behavior
///
/// This function currently corresponds to the `open` function in Unix
/// and [`std::os::windows::fs::symlink_file`] or [`symlink_dir`] should be
/// used instead to make the intent explicit.
///
-/// [`std::os::unix::fs::symlink`]: ../os/unix/fs/fn.symlink.html
-/// [`std::os::windows::fs::symlink_file`]: ../os/windows/fs/fn.symlink_file.html
-/// [`symlink_dir`]: ../os/windows/fs/fn.symlink_dir.html
-///
+/// [`std::os::unix::fs::symlink`]: crate::os::unix::fs::symlink
+/// [`std::os::windows::fs::symlink_file`]: crate::os::windows::fs::symlink_file
+/// [`symlink_dir`]: crate::os::windows::fs::symlink_dir
///
/// # Examples
///
/// function.)
/// * `path` already exists.
///
-/// [`create_dir_all`]: fn.create_dir_all.html
-///
/// # Examples
///
/// ```no_run
/// concurrently from multiple threads or processes is guaranteed not to fail
/// due to a race condition with itself.
///
-/// [`fs::create_dir`]: fn.create_dir.html
+/// [`fs::create_dir`]: create_dir
///
/// # Examples
///
///
/// See [`fs::remove_file`] and [`fs::remove_dir`].
///
-/// [`fs::remove_file`]: fn.remove_file.html
-/// [`fs::remove_dir`]: fn.remove_dir.html
+/// [`fs::remove_file`]: remove_file
+/// [`fs::remove_dir`]: remove_dir
///
/// # Examples
///
/// The iterator will yield instances of [`io::Result`]`<`[`DirEntry`]`>`.
/// New errors may be encountered after an iterator is initially constructed.
///
-/// [`io::Result`]: ../io/type.Result.html
-/// [`DirEntry`]: struct.DirEntry.html
-///
/// # Platform-specific behavior
///
/// This function currently corresponds to the `opendir` function on Unix
/// purpose of this trait is to encode what types are safe to cross a [`catch_unwind`]
/// boundary with no fear of unwind safety.
///
-/// [`Send`]: ../marker/trait.Send.html
-/// [`Sync`]: ../marker/trait.Sync.html
-/// [`catch_unwind`]: ./fn.catch_unwind.html
-///
/// ## What is unwind safety?
///
/// In Rust a function can "return" early if it either panics or calls a
/// above, the lack of `unsafe` means it is mostly an advisory. The
/// [`AssertUnwindSafe`] wrapper struct can be used to force this trait to be
/// implemented for any closed over variables passed to `catch_unwind`.
-///
-/// [`AssertUnwindSafe`]: ./struct.AssertUnwindSafe.html
#[stable(feature = "catch_unwind", since = "1.9.0")]
#[rustc_on_unimplemented(
message = "the type `{Self}` may not be safely transferred across an unwind boundary",
///
/// This is a "helper marker trait" used to provide impl blocks for the
/// [`UnwindSafe`] trait, for more information see that documentation.
-///
-/// [`UnsafeCell`]: ../cell/struct.UnsafeCell.html
-/// [`UnwindSafe`]: ./trait.UnwindSafe.html
#[stable(feature = "catch_unwind", since = "1.9.0")]
#[rustc_on_unimplemented(
message = "the type `{Self}` may contain interior mutability and a reference may not be safely \
/// account. This wrapper struct is useful for a quick and lightweight
/// annotation that a variable is indeed unwind safe.
///
-/// [`catch_unwind`]: ./fn.catch_unwind.html
/// # Examples
///
/// One way to use `AssertUnwindSafe` is to assert that the entire closure
/// can fail on a regular basis. Additionally, this function is not guaranteed
/// to catch all panics, see the "Notes" section below.
///
-/// [`Result`]: ../result/enum.Result.html
-///
/// The closure provided is required to adhere to the [`UnwindSafe`] trait to ensure
/// that all captured variables are safe to cross this boundary. The purpose of
/// this bound is to encode the concept of [exception safety][rfc] in the type
/// becomes a problem the [`AssertUnwindSafe`] wrapper struct can be used to quickly
/// assert that the usage here is indeed unwind safe.
///
-/// [`AssertUnwindSafe`]: ./struct.AssertUnwindSafe.html
-/// [`UnwindSafe`]: ./trait.UnwindSafe.html
-///
/// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md
///
/// # Notes
/// This is designed to be used in conjunction with [`catch_unwind`] to, for
/// example, carry a panic across a layer of C code.
///
-/// [`catch_unwind`]: ./fn.catch_unwind.html
-///
/// # Notes
///
/// Note that panics in Rust are not always implemented via unwinding, but they
//! [`OsString`] is the Rust wrapper for owned strings in the
//! preferred representation of the operating system. On Windows,
//! this struct gets augmented with an implementation of the
-//! [`OsStringExt`] trait, which has a [`from_wide`] method. This
+//! [`OsStringExt`] trait, which has a [`OsStringExt::from_wide`] method. This
//! lets you create an [`OsString`] from a `&[u16]` slice; presumably
//! you get such a slice out of a `WCHAR` Windows API.
//!
//! Similarly, [`OsStr`] is the Rust wrapper for borrowed strings from
//! preferred representation of the operating system. On Windows, the
-//! [`OsStrExt`] trait provides the [`encode_wide`] method, which
+//! [`OsStrExt`] trait provides the [`OsStrExt::encode_wide`] method, which
//! outputs an [`EncodeWide`] iterator. You can [`collect`] this
//! iterator, for example, to obtain a `Vec<u16>`; you can later get a
//! pointer to this vector's contents and feed it to Windows APIs.
//! ill-formed UTF-16.
//!
//! [ill-formed-utf-16]: https://simonsapin.github.io/wtf-8/#ill-formed-utf-16
-//! [`OsString`]: ../../../ffi/struct.OsString.html
-//! [`OsStr`]: ../../../ffi/struct.OsStr.html
-//! [`OsStringExt`]: trait.OsStringExt.html
-//! [`OsStrExt`]: trait.OsStrExt.html
-//! [`EncodeWide`]: struct.EncodeWide.html
-//! [`from_wide`]: trait.OsStringExt.html#tymethod.from_wide
-//! [`encode_wide`]: trait.OsStrExt.html#tymethod.encode_wide
-//! [`collect`]: ../../../iter/trait.Iterator.html#method.collect
-//! [U+FFFD]: ../../../char/constant.REPLACEMENT_CHARACTER.html
+//! [`collect`]: crate::iter::Iterator::collect
+//! [U+FFFD]: crate::char::REPLACEMENT_CHARACTER
#![stable(feature = "rust1", since = "1.0.0")]
pub use crate::sys_common::wtf8::EncodeWide;
/// Windows-specific extensions to [`OsString`].
-///
-/// [`OsString`]: ../../../../std/ffi/struct.OsString.html
#[stable(feature = "rust1", since = "1.0.0")]
pub trait OsStringExt {
/// Creates an `OsString` from a potentially ill-formed UTF-16 slice of
/// 16-bit code units.
///
- /// This is lossless: calling [`encode_wide`] on the resulting string
+ /// This is lossless: calling [`OsStrExt::encode_wide`] on the resulting string
/// will always return the original code units.
///
/// # Examples
///
/// let string = OsString::from_wide(&source[..]);
/// ```
- ///
- /// [`encode_wide`]: ./trait.OsStrExt.html#tymethod.encode_wide
#[stable(feature = "rust1", since = "1.0.0")]
fn from_wide(wide: &[u16]) -> Self;
}
}
/// Windows-specific extensions to [`OsStr`].
-///
-/// [`OsStr`]: ../../../../std/ffi/struct.OsStr.html
#[stable(feature = "rust1", since = "1.0.0")]
pub trait OsStrExt {
/// Re-encodes an `OsStr` as a wide character sequence, i.e., potentially
/// ill-formed UTF-16.
///
- /// This is lossless: calling [`OsString::from_wide`] and then
+ /// This is lossless: calling [`OsStringExt::from_wide`] and then
/// `encode_wide` on the result will yield the original code units.
/// Note that the encoding does not add a final null terminator.
///
/// let result: Vec<u16> = string.encode_wide().collect();
/// assert_eq!(&source[..], &result[..]);
/// ```
- ///
- /// [`OsString::from_wide`]: ./trait.OsStringExt.html#tymethod.from_wide
#[stable(feature = "rust1", since = "1.0.0")]
fn encode_wide(&self) -> EncodeWide<'_>;
}
use crate::sys;
use crate::sys_common::{AsInner, AsInnerMut};
-/// Windows-specific extensions to [`File`].
-///
-/// [`File`]: ../../../fs/struct.File.html
+/// Windows-specific extensions to [`fs::File`].
#[stable(feature = "file_offset", since = "1.15.0")]
pub trait FileExt {
/// Seeks to a given position and reads a number of bytes.
}
/// Windows-specific extensions to [`fs::OpenOptions`].
-///
-/// [`fs::OpenOptions`]: ../../../../std/fs/struct.OpenOptions.html
#[stable(feature = "open_options_ext", since = "1.10.0")]
pub trait OpenOptionsExt {
/// Overrides the `dwDesiredAccess` argument to the call to [`CreateFile`]
/// The data members that this trait exposes correspond to the members
/// of the [`BY_HANDLE_FILE_INFORMATION`] structure.
///
-/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
/// [`BY_HANDLE_FILE_INFORMATION`]:
/// https://docs.microsoft.com/en-us/windows/win32/api/fileapi/ns-fileapi-by_handle_file_information
#[stable(feature = "metadata_ext", since = "1.1.0")]
}
}
-/// Windows-specific extensions to [`FileType`].
+/// Windows-specific extensions to [`fs::FileType`].
///
/// On Windows, a symbolic link knows whether it is a file or directory.
-///
-/// [`FileType`]: ../../../../std/fs/struct.FileType.html
#[unstable(feature = "windows_file_type_ext", issue = "none")]
pub trait FileTypeExt {
/// Returns `true` if this file type is a symbolic link that is also a directory.
}
/// Windows-specific extensions to [`process::ExitStatus`].
-///
-/// [`process::ExitStatus`]: ../../../../std/process/struct.ExitStatus.html
#[stable(feature = "exit_status_from", since = "1.12.0")]
pub trait ExitStatusExt {
/// Creates a new `ExitStatus` from the raw underlying `u32` return value of
}
/// Windows-specific extensions to the [`process::Command`] builder.
-///
-/// [`process::Command`]: ../../../../std/process/struct.Command.html
#[stable(feature = "windows_process_extensions", since = "1.16.0")]
pub trait CommandExt {
/// Sets the [process creation flags][1] to be passed to `CreateProcess`.
WORKDIR /tmp
COPY host-x86_64/dist-various-2/shared.sh /tmp/
-COPY host-x86_64/dist-various-2/build-cloudabi-toolchain.sh /tmp/
-RUN /tmp/build-cloudabi-toolchain.sh x86_64-unknown-cloudabi
COPY host-x86_64/dist-various-2/build-fuchsia-toolchain.sh /tmp/
RUN /tmp/build-fuchsia-toolchain.sh
COPY host-x86_64/dist-various-2/build-solaris-toolchain.sh /tmp/
ENV TARGETS=$TARGETS,sparcv9-sun-solaris
ENV TARGETS=$TARGETS,x86_64-sun-solaris
ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32
-ENV TARGETS=$TARGETS,x86_64-unknown-cloudabi
ENV TARGETS=$TARGETS,x86_64-fortanix-unknown-sgx
ENV TARGETS=$TARGETS,nvptx64-nvidia-cuda
ENV TARGETS=$TARGETS,armv7-unknown-linux-gnueabi
install_prereq() {
curl https://apt.llvm.org/llvm-snapshot.gpg.key|apt-key add -
- add-apt-repository -y 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic main'
+ add-apt-repository -y 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-11 main'
apt-get update
apt-get install -y --no-install-recommends \
build-essential \
git clone https://github.com/emscripten-core/emsdk.git /emsdk-portable
cd /emsdk-portable
-hide_output ./emsdk install 1.38.46-upstream
-./emsdk activate 1.38.46-upstream
+hide_output ./emsdk install 1.38.47-upstream
+./emsdk activate 1.38.47-upstream
`x86_64-linux-android` | ✓ | | 64-bit x86 Android
`x86_64-rumprun-netbsd` | ✓ | | 64-bit NetBSD Rump Kernel
`x86_64-sun-solaris` | ✓ | | 64-bit Solaris 10/11, illumos
-`x86_64-unknown-cloudabi` | ✓ | | 64-bit CloudABI
`x86_64-unknown-freebsd` | ✓ | ✓ | 64-bit FreeBSD
`x86_64-unknown-illumos` | ✓ | ✓ | illumos
`x86_64-unknown-linux-gnux32` | ✓ | | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27)
`thumbv4t-none-eabi` | * | | ARMv4T T32
`x86_64-apple-ios-macabi` | ✓[^apple] | | Apple Catalyst
`x86_64-apple-tvos` | *[^apple] | | x86 64-bit tvOS
-`x86_64-linux-kernel` | ? | | Linux kernel modules
+`x86_64-linux-kernel` | * | | Linux kernel modules
`x86_64-pc-solaris` | ? | |
`x86_64-pc-windows-msvc` | ✓ | | 64-bit Windows XP support
+`x86_64-unknown-cloudabi` | ✓ | | 64-bit CloudABI
`x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD
`x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku
`x86_64-unknown-hermit` | ? | |
pub mod tokenstream;
pub mod visit;
+pub use self::ast::*;
+
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
/// Requirements for a `StableHashingContext` to be used in this crate.
use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
-use rustc_ast::ast::*;
use rustc_ast::attr;
use rustc_ast::ptr::P as AstP;
+use rustc_ast::*;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::thin_vec::ThinVec;
// `::std::ops::Try::from_ok($tail_expr)`
block.expr = Some(this.wrap_in_try_constructor(
- sym::from_ok,
+ hir::LangItem::TryFromOk,
try_span,
tail_expr,
ok_wrapped_span,
fn wrap_in_try_constructor(
&mut self,
- method: Symbol,
+ lang_item: hir::LangItem,
method_span: Span,
expr: &'hir hir::Expr<'hir>,
overall_span: Span,
) -> &'hir hir::Expr<'hir> {
- let path = &[sym::ops, sym::Try, method];
let constructor =
- self.arena.alloc(self.expr_std_path(method_span, path, None, ThinVec::new()));
+ self.arena.alloc(self.expr_lang_item_path(method_span, lang_item, ThinVec::new()));
self.expr_call(overall_span, constructor, std::slice::from_ref(expr))
}
// `future::from_generator`:
let unstable_span =
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
- let gen_future = self.expr_std_path(
- unstable_span,
- &[sym::future, sym::from_generator],
- None,
- ThinVec::new(),
- );
+ let gen_future =
+ self.expr_lang_item_path(unstable_span, hir::LangItem::FromGenerator, ThinVec::new());
// `future::from_generator(generator)`:
hir::ExprKind::Call(self.arena.alloc(gen_future), arena_vec![self; generator])
// Use of `await` outside of an async context, we cannot use `task_context` here.
self.expr_err(span)
};
- let pin_ty_id = self.next_id();
- let new_unchecked_expr_kind = self.expr_call_std_assoc_fn(
- pin_ty_id,
+ let new_unchecked = self.expr_call_lang_item_fn_mut(
span,
- &[sym::pin, sym::Pin],
- "new_unchecked",
+ hir::LangItem::PinNewUnchecked,
arena_vec![self; ref_mut_pinned],
);
- let new_unchecked = self.expr(span, new_unchecked_expr_kind, ThinVec::new());
- let get_context = self.expr_call_std_path_mut(
+ let get_context = self.expr_call_lang_item_fn_mut(
gen_future_span,
- &[sym::future, sym::get_context],
+ hir::LangItem::GetContext,
arena_vec![self; task_context],
);
- let call = self.expr_call_std_path(
+ let call = self.expr_call_lang_item_fn(
span,
- &[sym::future, sym::Future, sym::poll],
+ hir::LangItem::FuturePoll,
arena_vec![self; new_unchecked, get_context],
);
self.arena.alloc(self.expr_unsafe(call))
let x_ident = Ident::with_dummy_span(sym::result);
let (x_pat, x_pat_hid) = self.pat_ident(span, x_ident);
let x_expr = self.expr_ident(span, x_ident, x_pat_hid);
- let ready_pat = self.pat_std_enum(
- span,
- &[sym::task, sym::Poll, sym::Ready],
- arena_vec![self; x_pat],
- );
+ let ready_field = self.single_pat_field(span, x_pat);
+ let ready_pat = self.pat_lang_item_variant(span, hir::LangItem::PollReady, ready_field);
let break_x = self.with_loop_scope(loop_node_id, move |this| {
let expr_break =
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
// `::std::task::Poll::Pending => {}`
let pending_arm = {
- let pending_pat = self.pat_std_enum(span, &[sym::task, sym::Poll, sym::Pending], &[]);
+ let pending_pat = self.pat_lang_item_variant(span, hir::LangItem::PollPending, &[]);
let empty_block = self.expr_block_empty(span);
self.arm(pending_pat, empty_block)
};
/// Desugar `<start>..=<end>` into `std::ops::RangeInclusive::new(<start>, <end>)`.
fn lower_expr_range_closed(&mut self, span: Span, e1: &Expr, e2: &Expr) -> hir::ExprKind<'hir> {
- let id = self.next_id();
let e1 = self.lower_expr_mut(e1);
let e2 = self.lower_expr_mut(e2);
- self.expr_call_std_assoc_fn(
- id,
- span,
- &[sym::ops, sym::RangeInclusive],
- "new",
- arena_vec![self; e1, e2],
- )
+ let fn_path = hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, span);
+ let fn_expr =
+ self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new()));
+ hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
}
fn lower_expr_range(
e2: Option<&Expr>,
lims: RangeLimits,
) -> hir::ExprKind<'hir> {
- use rustc_ast::ast::RangeLimits::*;
-
- let path = match (e1, e2, lims) {
- (None, None, HalfOpen) => sym::RangeFull,
- (Some(..), None, HalfOpen) => sym::RangeFrom,
- (None, Some(..), HalfOpen) => sym::RangeTo,
- (Some(..), Some(..), HalfOpen) => sym::Range,
- (None, Some(..), Closed) => sym::RangeToInclusive,
+ use rustc_ast::RangeLimits::*;
+
+ let lang_item = match (e1, e2, lims) {
+ (None, None, HalfOpen) => hir::LangItem::RangeFull,
+ (Some(..), None, HalfOpen) => hir::LangItem::RangeFrom,
+ (None, Some(..), HalfOpen) => hir::LangItem::RangeTo,
+ (Some(..), Some(..), HalfOpen) => hir::LangItem::Range,
+ (None, Some(..), Closed) => hir::LangItem::RangeToInclusive,
(Some(..), Some(..), Closed) => unreachable!(),
(_, None, Closed) => {
self.diagnostic().span_fatal(span, "inclusive range with no end").raise()
}),
);
- let is_unit = fields.is_empty();
- let struct_path = [sym::ops, path];
- let struct_path = self.std_path(span, &struct_path, None, is_unit);
- let struct_path = hir::QPath::Resolved(None, struct_path);
-
- if is_unit {
- hir::ExprKind::Path(struct_path)
- } else {
- hir::ExprKind::Struct(self.arena.alloc(struct_path), fields, None)
- }
+ hir::ExprKind::Struct(self.arena.alloc(hir::QPath::LangItem(lang_item, span)), fields, None)
}
fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hir::Destination {
let match_expr = {
let iter = self.expr_ident(desugared_span, iter, iter_pat_nid);
let ref_mut_iter = self.expr_mut_addr_of(desugared_span, iter);
- let next_path = &[sym::iter, sym::Iterator, sym::next];
- let next_expr =
- self.expr_call_std_path(desugared_span, next_path, arena_vec![self; ref_mut_iter]);
+ let next_expr = self.expr_call_lang_item_fn(
+ desugared_span,
+ hir::LangItem::IteratorNext,
+ arena_vec![self; ref_mut_iter],
+ );
let arms = arena_vec![self; pat_arm, break_arm];
self.expr_match(desugared_span, next_expr, arms, hir::MatchSource::ForLoopDesugar)
// `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
let into_iter_expr = {
- let into_iter_path = &[sym::iter, sym::IntoIterator, sym::into_iter];
- self.expr_call_std_path(into_iter_span, into_iter_path, arena_vec![self; head])
+ self.expr_call_lang_item_fn(
+ into_iter_span,
+ hir::LangItem::IntoIterIntoIter,
+ arena_vec![self; head],
+ )
};
let match_expr = self.arena.alloc(self.expr_match(
// expand <expr>
let sub_expr = self.lower_expr_mut(sub_expr);
- let path = &[sym::ops, sym::Try, sym::into_result];
- self.expr_call_std_path(unstable_span, path, arena_vec![self; sub_expr])
+ self.expr_call_lang_item_fn(
+ unstable_span,
+ hir::LangItem::TryIntoResult,
+ arena_vec![self; sub_expr],
+ )
};
// `#[allow(unreachable_code)]`
let err_ident = Ident::with_dummy_span(sym::err);
let (err_local, err_local_nid) = self.pat_ident(try_span, err_ident);
let from_expr = {
- let from_path = &[sym::convert, sym::From, sym::from];
let err_expr = self.expr_ident_mut(try_span, err_ident, err_local_nid);
- self.expr_call_std_path(try_span, from_path, arena_vec![self; err_expr])
+ self.expr_call_lang_item_fn(
+ try_span,
+ hir::LangItem::FromFrom,
+ arena_vec![self; err_expr],
+ )
};
- let from_err_expr =
- self.wrap_in_try_constructor(sym::from_error, unstable_span, from_expr, try_span);
+ let from_err_expr = self.wrap_in_try_constructor(
+ hir::LangItem::TryFromError,
+ unstable_span,
+ from_expr,
+ try_span,
+ );
let thin_attrs = ThinVec::from(attrs);
let catch_scope = self.catch_scopes.last().copied();
let ret_expr = if let Some(catch_node) = catch_scope {
self.arena.alloc(self.expr_call_mut(span, e, args))
}
- // Note: associated functions must use `expr_call_std_path`.
- fn expr_call_std_path_mut(
+ fn expr_call_lang_item_fn_mut(
&mut self,
span: Span,
- path_components: &[Symbol],
+ lang_item: hir::LangItem,
args: &'hir [hir::Expr<'hir>],
) -> hir::Expr<'hir> {
- let path =
- self.arena.alloc(self.expr_std_path(span, path_components, None, ThinVec::new()));
+ let path = self.arena.alloc(self.expr_lang_item_path(span, lang_item, ThinVec::new()));
self.expr_call_mut(span, path, args)
}
- fn expr_call_std_path(
+ fn expr_call_lang_item_fn(
&mut self,
span: Span,
- path_components: &[Symbol],
+ lang_item: hir::LangItem,
args: &'hir [hir::Expr<'hir>],
) -> &'hir hir::Expr<'hir> {
- self.arena.alloc(self.expr_call_std_path_mut(span, path_components, args))
- }
-
- // Create an expression calling an associated function of an std type.
- //
- // Associated functions cannot be resolved through the normal `std_path` function,
- // as they are resolved differently and so cannot use `expr_call_std_path`.
- //
- // This function accepts the path component (`ty_path_components`) separately from
- // the name of the associated function (`assoc_fn_name`) in order to facilitate
- // separate resolution of the type and creation of a path referring to its associated
- // function.
- fn expr_call_std_assoc_fn(
- &mut self,
- ty_path_id: hir::HirId,
- span: Span,
- ty_path_components: &[Symbol],
- assoc_fn_name: &str,
- args: &'hir [hir::Expr<'hir>],
- ) -> hir::ExprKind<'hir> {
- let ty_path = self.std_path(span, ty_path_components, None, false);
- let ty =
- self.arena.alloc(self.ty_path(ty_path_id, span, hir::QPath::Resolved(None, ty_path)));
- let fn_seg = self.arena.alloc(hir::PathSegment::from_ident(Ident::from_str(assoc_fn_name)));
- let fn_path = hir::QPath::TypeRelative(ty, fn_seg);
- let fn_expr =
- self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new()));
- hir::ExprKind::Call(fn_expr, args)
+ self.arena.alloc(self.expr_call_lang_item_fn_mut(span, lang_item, args))
}
- fn expr_std_path(
+ fn expr_lang_item_path(
&mut self,
span: Span,
- components: &[Symbol],
- params: Option<&'hir hir::GenericArgs<'hir>>,
+ lang_item: hir::LangItem,
attrs: AttrVec,
) -> hir::Expr<'hir> {
- let path = self.std_path(span, components, params, true);
- self.expr(span, hir::ExprKind::Path(hir::QPath::Resolved(None, path)), attrs)
+ self.expr(span, hir::ExprKind::Path(hir::QPath::LangItem(lang_item, span)), attrs)
}
pub(super) fn expr_ident(
use super::{ImplTraitContext, ImplTraitPosition};
use crate::Arena;
-use rustc_ast::ast::*;
use rustc_ast::node_id::NodeMap;
use rustc_ast::ptr::P;
-use rustc_ast::visit::{self, AssocCtxt, Visitor};
+use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
+use rustc_ast::*;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
}
}
+ fn visit_fn(&mut self, fk: FnKind<'a>, sp: Span, _: NodeId) {
+ match fk {
+ FnKind::Fn(FnCtxt::Foreign, _, sig, _, _) => {
+ self.visit_fn_header(&sig.header);
+ visit::walk_fn_decl(self, &sig.decl);
+ // Don't visit the foreign function body even if it has one, since lowering the
+ // body would have no meaning and will have already been caught as a parse error.
+ }
+ _ => visit::walk_fn(self, fk, sp),
+ }
+ }
+
fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
self.lctx.with_hir_id_owner(item.id, |lctx| match ctxt {
AssocCtxt::Trait => {
#![feature(or_patterns)]
#![recursion_limit = "256"]
-use rustc_ast::ast;
-use rustc_ast::ast::*;
use rustc_ast::node_id::NodeMap;
use rustc_ast::token::{self, DelimToken, Nonterminal, Token};
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
use rustc_ast::visit::{self, AssocCtxt, Visitor};
use rustc_ast::walk_list;
+use rustc_ast::{self as ast, *};
use rustc_ast_pretty::pprust;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashSet;
rustc_hir::arena_types!(rustc_arena::declare_arena, [], 'tcx);
struct LoweringContext<'a, 'hir: 'a> {
- crate_root: Option<Symbol>,
-
/// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
sess: &'a Session,
/// This should only return `None` during testing.
fn definitions(&mut self) -> &mut Definitions;
- /// Given suffix `["b", "c", "d"]`, creates an AST path for `[::crate_root]::b::c::d` and
- /// resolves it based on `is_value`.
- fn resolve_str_path(
- &mut self,
- span: Span,
- crate_root: Option<Symbol>,
- components: &[Symbol],
- ns: Namespace,
- ) -> (ast::Path, Res<NodeId>);
-
fn lint_buffer(&mut self) -> &mut LintBuffer;
fn next_node_id(&mut self) -> NodeId;
let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering");
LoweringContext {
- crate_root: sess.parse_sess.injected_crate_name.get().copied(),
sess,
resolver,
nt_to_tokenstream,
};
// "<Output = T>"
- let future_params = self.arena.alloc(hir::GenericArgs {
+ let future_args = self.arena.alloc(hir::GenericArgs {
args: &[],
bindings: arena_vec![self; self.output_ty_binding(span, output_ty)],
parenthesized: false,
});
- // ::std::future::Future<future_params>
- let future_path =
- self.std_path(span, &[sym::future, sym::Future], Some(future_params), false);
-
- hir::GenericBound::Trait(
- hir::PolyTraitRef {
- trait_ref: hir::TraitRef { path: future_path, hir_ref_id: self.next_id() },
- bound_generic_params: &[],
- span,
- },
- hir::TraitBoundModifier::None,
+ hir::GenericBound::LangItemTrait(
+ // ::std::future::Future<future_params>
+ hir::LangItem::FutureTraitLangItem,
+ span,
+ self.next_id(),
+ future_args,
)
}
}
fn pat_ok(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
- self.pat_std_enum(span, &[sym::result, sym::Result, sym::Ok], arena_vec![self; pat])
+ let field = self.single_pat_field(span, pat);
+ self.pat_lang_item_variant(span, hir::LangItem::ResultOk, field)
}
fn pat_err(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
- self.pat_std_enum(span, &[sym::result, sym::Result, sym::Err], arena_vec![self; pat])
+ let field = self.single_pat_field(span, pat);
+ self.pat_lang_item_variant(span, hir::LangItem::ResultErr, field)
}
fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
- self.pat_std_enum(span, &[sym::option, sym::Option, sym::Some], arena_vec![self; pat])
+ let field = self.single_pat_field(span, pat);
+ self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
}
fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
- self.pat_std_enum(span, &[sym::option, sym::Option, sym::None], &[])
+ self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
}
- fn pat_std_enum(
+ fn single_pat_field(
&mut self,
span: Span,
- components: &[Symbol],
- subpats: &'hir [&'hir hir::Pat<'hir>],
- ) -> &'hir hir::Pat<'hir> {
- let path = self.std_path(span, components, None, true);
- let qpath = hir::QPath::Resolved(None, path);
- let pt = if subpats.is_empty() {
- hir::PatKind::Path(qpath)
- } else {
- hir::PatKind::TupleStruct(qpath, subpats, None)
+ pat: &'hir hir::Pat<'hir>,
+ ) -> &'hir [hir::FieldPat<'hir>] {
+ let field = hir::FieldPat {
+ hir_id: self.next_id(),
+ ident: Ident::new(sym::integer(0), span),
+ is_shorthand: false,
+ pat,
+ span,
};
- self.pat(span, pt)
+ arena_vec![self; field]
+ }
+
+ fn pat_lang_item_variant(
+ &mut self,
+ span: Span,
+ lang_item: hir::LangItem,
+ fields: &'hir [hir::FieldPat<'hir>],
+ ) -> &'hir hir::Pat<'hir> {
+ let qpath = hir::QPath::LangItem(lang_item, span);
+ self.pat(span, hir::PatKind::Struct(qpath, fields, false))
}
fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, hir::HirId) {
self.arena.alloc(hir::Pat { hir_id: self.next_id(), kind, span })
}
- /// Given a suffix `["b", "c", "d"]`, returns path `::std::b::c::d` when
- /// `fld.cx.use_std`, and `::core::b::c::d` otherwise.
- /// The path is also resolved according to `is_value`.
- fn std_path(
- &mut self,
- span: Span,
- components: &[Symbol],
- params: Option<&'hir hir::GenericArgs<'hir>>,
- is_value: bool,
- ) -> &'hir hir::Path<'hir> {
- let ns = if is_value { Namespace::ValueNS } else { Namespace::TypeNS };
- let (path, res) = self.resolver.resolve_str_path(span, self.crate_root, components, ns);
-
- let mut segments: Vec<_> = path
- .segments
- .iter()
- .map(|segment| {
- let res = self.expect_full_res(segment.id);
- hir::PathSegment {
- ident: segment.ident,
- hir_id: Some(self.lower_node_id(segment.id)),
- res: Some(self.lower_res(res)),
- infer_args: true,
- args: None,
- }
- })
- .collect();
- segments.last_mut().unwrap().args = params;
-
- self.arena.alloc(hir::Path {
- span,
- res: res.map_id(|_| panic!("unexpected `NodeId`")),
- segments: self.arena.alloc_from_iter(segments),
- })
- }
-
fn ty_path(
&mut self,
mut hir_id: hir::HirId,
use super::{ImplTraitContext, LoweringContext, ParamMode};
-use rustc_ast::ast::*;
use rustc_ast::ptr::P;
+use rustc_ast::*;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::Applicability;
use rustc_hir as hir;
use super::{AnonymousLifetimeMode, ImplTraitContext, LoweringContext, ParamMode};
use super::{GenericArgsCtor, ParenthesizedGenericArgs};
-use rustc_ast::ast::{self, *};
+use rustc_ast::{self as ast, *};
use rustc_errors::{struct_span_err, Applicability};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, PartialRes, Res};
// or type checking or some other kind of complex analysis.
use itertools::{Either, Itertools};
-use rustc_ast::ast::*;
use rustc_ast::ptr::P;
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
use rustc_ast::walk_list;
+use rustc_ast::*;
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{error_code, pluralize, struct_span_err, Applicability};
-use rustc_ast::ast::{self, AssocTyConstraint, AssocTyConstraintKind, NodeId};
-use rustc_ast::ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData};
+use rustc_ast as ast;
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
+use rustc_ast::{AssocTyConstraint, AssocTyConstraintKind, NodeId};
+use rustc_ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData};
use rustc_errors::struct_span_err;
use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
use rustc_feature::{Features, GateIssue};
// Simply gives a rough count of the number of nodes in an AST.
-use rustc_ast::ast::*;
use rustc_ast::visit::*;
+use rustc_ast::*;
use rustc_span::symbol::Ident;
use rustc_span::Span;
use std::str::FromStr;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::visit;
use rustc_ast::visit::Visitor;
use crate::pp::Breaks::{Consistent, Inconsistent};
use crate::pp::{self, Breaks};
-use rustc_ast::ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
-use rustc_ast::ast::{Attribute, GenericArg, MacArgs};
-use rustc_ast::ast::{GenericBound, SelfKind, TraitBoundModifier};
-use rustc_ast::ast::{InlineAsmOperand, InlineAsmRegOrRegClass};
-use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_ast::attr;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, BinOpToken, CommentKind, DelimToken, Nonterminal, Token, TokenKind};
use rustc_ast::util::classify;
use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle};
use rustc_ast::util::parser::{self, AssocOp, Fixity};
+use rustc_ast::{self as ast, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
+use rustc_ast::{GenericArg, MacArgs};
+use rustc_ast::{GenericBound, SelfKind, TraitBoundModifier};
+use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass};
+use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_span::edition::Edition;
use rustc_span::source_map::{SourceMap, Spanned};
use rustc_span::symbol::{kw, sym, Ident, IdentPrinter, Symbol};
}
}
- crate fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod, attrs: &[Attribute]) {
+ crate fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod, attrs: &[ast::Attribute]) {
self.print_inner_attributes(attrs);
for item in &nmod.items {
self.print_foreign_item(item);
}
}
- fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>], attrs: &[Attribute]) {
+ fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>], attrs: &[ast::Attribute]) {
self.ibox(INDENT_UNIT);
self.s.word("[");
self.print_inner_attributes_inline(attrs);
&mut self,
element: &ast::Expr,
count: &ast::AnonConst,
- attrs: &[Attribute],
+ attrs: &[ast::Attribute],
) {
self.ibox(INDENT_UNIT);
self.s.word("[");
path: &ast::Path,
fields: &[ast::Field],
wth: &Option<P<ast::Expr>>,
- attrs: &[Attribute],
+ attrs: &[ast::Attribute],
) {
self.print_path(path, true, 0);
self.s.word("{");
self.s.word("}");
}
- fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>], attrs: &[Attribute]) {
+ fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>], attrs: &[ast::Attribute]) {
self.popen();
self.print_inner_attributes_inline(attrs);
self.commasep_exprs(Inconsistent, &exprs[..]);
use super::*;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_span::source_map::respan;
use rustc_span::symbol::Ident;
use rustc_span::with_default_session_globals;
//! Parsing and validation of builtin attributes
-use rustc_ast::ast::{self, Attribute, Lit, LitKind, MetaItem, MetaItemKind, NestedMetaItem};
+use rustc_ast::{self as ast, Attribute, Lit, LitKind, MetaItem, MetaItemKind, NestedMetaItem};
use rustc_ast_pretty::pprust;
use rustc_errors::{struct_span_err, Applicability};
use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg};
[dependencies]
rustc_parse_format = { path = "../librustc_parse_format" }
-log = { package = "tracing", version = "0.1" }
+tracing = "0.1"
rustc_ast_pretty = { path = "../librustc_ast_pretty" }
rustc_attr = { path = "../librustc_attr" }
rustc_data_structures = { path = "../librustc_data_structures" }
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
use rustc_errors::{Applicability, DiagnosticBuilder};
-use rustc_ast::ast::{self, *};
use rustc_ast::ptr::P;
use rustc_ast::token::{self, TokenKind};
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
+use rustc_ast::{self as ast, *};
use rustc_ast_pretty::pprust;
use rustc_expand::base::*;
use rustc_parse::parser::Parser;
//! a literal `true` or `false` based on whether the given cfg matches the
//! current compilation environment.
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
use rustc_attr as attr;
//! Implementation of the `#[cfg_accessible(path)]` attribute macro.
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier};
use rustc_feature::AttributeTemplate;
use rustc_parse::validate_attr;
//! Attributes injected into the crate root from command line using `-Z crate-attr`.
-use rustc_ast::ast::{self, AttrItem, AttrStyle};
use rustc_ast::attr::mk_attr;
use rustc_ast::token;
+use rustc_ast::{self as ast, AttrItem, AttrStyle};
use rustc_session::parse::ParseSess;
use rustc_span::FileName;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::tokenstream::TokenStream;
use rustc_expand::base::{self, DummyResult};
use rustc_span::symbol::Symbol;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Token};
use rustc_ast::tokenstream::{TokenStream, TokenTree};
use crate::deriving::generic::*;
use crate::deriving::path_std;
-use rustc_ast::ast::MetaItem;
+use rustc_ast::MetaItem;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::Span;
use crate::deriving::generic::*;
use crate::deriving::path_std;
-use rustc_ast::ast::{self, Expr, GenericArg, Generics, ItemKind, MetaItem, VariantData};
use rustc_ast::ptr::P;
+use rustc_ast::{self as ast, Expr, GenericArg, Generics, ItemKind, MetaItem, VariantData};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span;
use crate::deriving::generic::*;
use crate::deriving::path_std;
-use rustc_ast::ast::{self, Expr, GenericArg, MetaItem};
use rustc_ast::ptr::P;
+use rustc_ast::{self as ast, Expr, GenericArg, MetaItem};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
use crate::deriving::generic::*;
use crate::deriving::path_std;
-use rustc_ast::ast::{self, Expr, MetaItem};
use rustc_ast::ptr::P;
+use rustc_ast::{self as ast, Expr, MetaItem};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
use crate::deriving::generic::*;
use crate::deriving::{path_local, path_std};
-use rustc_ast::ast::{BinOpKind, Expr, MetaItem};
use rustc_ast::ptr::P;
+use rustc_ast::{BinOpKind, Expr, MetaItem};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::sym;
use rustc_span::Span;
use crate::deriving::generic::*;
use crate::deriving::{path_local, path_std, pathvec_std};
-use rustc_ast::ast::{self, BinOpKind, Expr, MetaItem};
use rustc_ast::ptr::P;
+use rustc_ast::{self as ast, BinOpKind, Expr, MetaItem};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
use crate::deriving::generic::*;
use crate::deriving::path_std;
-use rustc_ast::ast;
-use rustc_ast::ast::{Expr, MetaItem};
use rustc_ast::ptr::P;
+use rustc_ast::{self as ast, Expr, MetaItem};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident};
use rustc_span::{Span, DUMMY_SP};
use crate::deriving::generic::*;
use crate::deriving::pathvec_std;
-use rustc_ast::ast;
-use rustc_ast::ast::{Expr, MetaItem, Mutability};
use rustc_ast::ptr::P;
+use rustc_ast::{self as ast, Expr, MetaItem, Mutability};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
-use rustc_ast::ast::{Expr, MetaItem};
use rustc_ast::ptr::P;
+use rustc_ast::{Expr, MetaItem};
use rustc_errors::struct_span_err;
use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt};
use rustc_span::symbol::{kw, sym};
use crate::deriving::generic::*;
use crate::deriving::pathvec_std;
-use rustc_ast::ast::{Expr, ExprKind, MetaItem, Mutability};
use rustc_ast::ptr::P;
+use rustc_ast::{Expr, ExprKind, MetaItem, Mutability};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
use std::iter;
use std::vec;
-use rustc_ast::ast::{self, BinOpKind, EnumDef, Expr, Generics, PatKind};
-use rustc_ast::ast::{GenericArg, GenericParamKind, VariantData};
use rustc_ast::ptr::P;
+use rustc_ast::{self as ast, BinOpKind, EnumDef, Expr, Generics, PatKind};
+use rustc_ast::{GenericArg, GenericParamKind, VariantData};
use rustc_attr as attr;
use rustc_data_structures::map_in_place::MapInPlace;
use rustc_expand::base::{Annotatable, ExtCtxt};
pub use PtrTy::*;
pub use Ty::*;
-use rustc_ast::ast::{self, Expr, GenericArg, GenericParamKind, Generics, SelfKind};
use rustc_ast::ptr::P;
+use rustc_ast::{self as ast, Expr, GenericArg, GenericParamKind, Generics, SelfKind};
use rustc_expand::base::ExtCtxt;
use rustc_span::source_map::{respan, DUMMY_SP};
use rustc_span::symbol::{kw, Ident, Symbol};
use crate::deriving::generic::*;
use crate::deriving::{self, path_std, pathvec_std};
-use rustc_ast::ast::{Expr, MetaItem, Mutability};
use rustc_ast::ptr::P;
+use rustc_ast::{Expr, MetaItem, Mutability};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::sym;
use rustc_span::Span;
//! The compiler code necessary to implement the `#[derive]` extensions.
-use rustc_ast::ast::{self, ItemKind, MetaItem};
+use rustc_ast as ast;
use rustc_ast::ptr::P;
+use rustc_ast::{ItemKind, MetaItem};
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier};
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
// interface.
//
-use rustc_ast::ast::{self, GenericArg};
use rustc_ast::tokenstream::TokenStream;
+use rustc_ast::{self as ast, GenericArg};
use rustc_expand::base::{self, *};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span;
use ArgumentType::*;
use Position::*;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
use crate::util::check_builtin_macro_attribute;
-use rustc_ast::ast::{self, Attribute, Expr, FnHeader, FnSig, Generics, Param};
-use rustc_ast::ast::{ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe};
use rustc_ast::expand::allocator::{
AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS,
};
use rustc_ast::ptr::P;
+use rustc_ast::{self as ast, Attribute, Expr, FnHeader, FnSig, Generics, Param};
+use rustc_ast::{ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span;
//! LLVM's `module asm "some assembly here"`. All of LLVM's caveats
//! therefore apply.
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
//
use State::*;
-use rustc_ast::ast::{self, LlvmAsmDialect};
+use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Token};
use rustc_ast::tokenstream::{self, TokenStream};
+use rustc_ast::LlvmAsmDialect;
use rustc_errors::{struct_span_err, DiagnosticBuilder, PResult};
use rustc_expand::base::*;
use rustc_parse::parser::Parser;
use std::mem;
-use rustc_ast::ast::{self, NodeId};
use rustc_ast::attr;
use rustc_ast::ptr::P;
use rustc_ast::visit::{self, Visitor};
+use rustc_ast::{self as ast, NodeId};
use rustc_ast_pretty::pprust;
use rustc_expand::base::{ExtCtxt, ResolverExpand};
use rustc_expand::expand::{AstFragment, ExpansionConfig};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_expand::base::{ExtCtxt, ResolverExpand};
use rustc_expand::expand::ExpansionConfig;
/// Ideally, this code would be in libtest but for efficiency and error messages it lives here.
use crate::util::check_builtin_macro_attribute;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::attr;
use rustc_ast_pretty::pprust;
use rustc_expand::base::*;
// extern crate test
let test_extern = cx.item(sp, test_id, vec![], ast::ItemKind::ExternCrate(None));
- log::debug!("synthetic test item:\n{}\n", pprust::item_to_string(&test_const));
+ tracing::debug!("synthetic test item:\n{}\n", pprust::item_to_string(&test_const));
vec![
// Access to libtest under a hygienic name
// Code that generates a test runner to run all the tests in a crate
-use log::debug;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::attr;
use rustc_ast::entry::EntryPointType;
use rustc_ast::mut_visit::{ExpectOne, *};
use rustc_span::{Span, DUMMY_SP};
use rustc_target::spec::PanicStrategy;
use smallvec::{smallvec, SmallVec};
+use tracing::debug;
use std::{iter, mem};
-use rustc_ast::ast::MetaItem;
+use rustc_ast::MetaItem;
use rustc_expand::base::ExtCtxt;
use rustc_feature::AttributeTemplate;
use rustc_parse::validate_attr;
flate2 = "1.0"
libc = "0.2"
measureme = "0.7.1"
-log = { package = "tracing", version = "0.1" }
+tracing = "0.1"
rustc_middle = { path = "../librustc_middle" }
rustc-demangle = "0.1"
rustc_attr = { path = "../librustc_attr" }
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
-use rustc_ast::ast::LlvmAsmDialect;
-use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
+use rustc_ast::LlvmAsmDialect;
+use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_codegen_ssa::mir::operand::OperandValue;
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::*;
use rustc_target::asm::*;
use libc::{c_char, c_uint};
-use log::debug;
+use tracing::debug;
impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
fn codegen_llvm_inline_asm(
for (idx, op) in operands.iter().enumerate() {
match *op {
InlineAsmOperandRef::Out { reg, late, place } => {
- let ty = if let Some(place) = place {
+ let mut layout = None;
+ let ty = if let Some(ref place) = place {
+ layout = Some(&place.layout);
llvm_fixup_output_type(self.cx, reg.reg_class(), &place.layout)
} else {
// If the output is discarded, we don't really care what
output_types.push(ty);
op_idx.insert(idx, constraints.len());
let prefix = if late { "=" } else { "=&" };
- constraints.push(format!("{}{}", prefix, reg_to_llvm(reg)));
+ constraints.push(format!("{}{}", prefix, reg_to_llvm(reg, layout)));
}
InlineAsmOperandRef::InOut { reg, late, in_value, out_place } => {
- let ty = if let Some(ref out_place) = out_place {
- llvm_fixup_output_type(self.cx, reg.reg_class(), &out_place.layout)
+ let layout = if let Some(ref out_place) = out_place {
+ &out_place.layout
} else {
// LLVM required tied operands to have the same type,
// so we just use the type of the input.
- llvm_fixup_output_type(self.cx, reg.reg_class(), &in_value.layout)
+ &in_value.layout
};
+ let ty = llvm_fixup_output_type(self.cx, reg.reg_class(), layout);
output_types.push(ty);
op_idx.insert(idx, constraints.len());
let prefix = if late { "=" } else { "=&" };
- constraints.push(format!("{}{}", prefix, reg_to_llvm(reg)));
+ constraints.push(format!("{}{}", prefix, reg_to_llvm(reg, Some(layout))));
}
_ => {}
}
for (idx, op) in operands.iter().enumerate() {
match *op {
InlineAsmOperandRef::In { reg, value } => {
- let value =
+ let llval =
llvm_fixup_input(self, value.immediate(), reg.reg_class(), &value.layout);
- inputs.push(value);
+ inputs.push(llval);
op_idx.insert(idx, constraints.len());
- constraints.push(reg_to_llvm(reg));
+ constraints.push(reg_to_llvm(reg, Some(&value.layout)));
}
InlineAsmOperandRef::InOut { reg, late: _, in_value, out_place: _ } => {
let value = llvm_fixup_input(
}
}
+/// If the register is an xmm/ymm/zmm register then return its index.
+fn xmm_reg_index(reg: InlineAsmReg) -> Option<u32> {
+ match reg {
+ InlineAsmReg::X86(reg)
+ if reg as u32 >= X86InlineAsmReg::xmm0 as u32
+ && reg as u32 <= X86InlineAsmReg::xmm15 as u32 =>
+ {
+ Some(reg as u32 - X86InlineAsmReg::xmm0 as u32)
+ }
+ InlineAsmReg::X86(reg)
+ if reg as u32 >= X86InlineAsmReg::ymm0 as u32
+ && reg as u32 <= X86InlineAsmReg::ymm15 as u32 =>
+ {
+ Some(reg as u32 - X86InlineAsmReg::ymm0 as u32)
+ }
+ InlineAsmReg::X86(reg)
+ if reg as u32 >= X86InlineAsmReg::zmm0 as u32
+ && reg as u32 <= X86InlineAsmReg::zmm31 as u32 =>
+ {
+ Some(reg as u32 - X86InlineAsmReg::zmm0 as u32)
+ }
+ _ => None,
+ }
+}
+
+/// If the register is an AArch64 vector register then return its index.
+fn a64_vreg_index(reg: InlineAsmReg) -> Option<u32> {
+ match reg {
+ InlineAsmReg::AArch64(reg)
+ if reg as u32 >= AArch64InlineAsmReg::v0 as u32
+ && reg as u32 <= AArch64InlineAsmReg::v31 as u32 =>
+ {
+ Some(reg as u32 - AArch64InlineAsmReg::v0 as u32)
+ }
+ _ => None,
+ }
+}
+
/// Converts a register class to an LLVM constraint code.
-fn reg_to_llvm(reg: InlineAsmRegOrRegClass) -> String {
+fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'tcx>>) -> String {
match reg {
- InlineAsmRegOrRegClass::Reg(reg) => format!("{{{}}}", reg.name()),
+ // For vector registers LLVM wants the register name to match the type size.
+ InlineAsmRegOrRegClass::Reg(reg) => {
+ if let Some(idx) = xmm_reg_index(reg) {
+ let class = if let Some(layout) = layout {
+ match layout.size.bytes() {
+ 64 => 'z',
+ 32 => 'y',
+ _ => 'x',
+ }
+ } else {
+ // We use f32 as the type for discarded outputs
+ 'x'
+ };
+ format!("{{{}mm{}}}", class, idx)
+ } else if let Some(idx) = a64_vreg_index(reg) {
+ let class = if let Some(layout) = layout {
+ match layout.size.bytes() {
+ 16 => 'q',
+ 8 => 'd',
+ 4 => 's',
+ 2 => 'h',
+ 1 => 'd', // We fixup i8 to i8x8
+ _ => unreachable!(),
+ }
+ } else {
+ // We use i32 as the type for discarded outputs
+ 's'
+ };
+ format!("{{{}{}}}", class, idx)
+ } else {
+ format!("{{{}}}", reg.name())
+ }
+ }
InlineAsmRegOrRegClass::RegClass(reg) => match reg {
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => "r",
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) => "w",
InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg),
Abi::Vector { .. },
) if layout.size.bytes() == 64 => bx.bitcast(value, bx.cx.type_vector(bx.cx.type_f64(), 8)),
+ (
+ InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16),
+ Abi::Scalar(s),
+ ) => {
+ if let Primitive::Int(Integer::I32, _) = s.value {
+ bx.bitcast(value, bx.cx.type_f32())
+ } else {
+ value
+ }
+ }
(
InlineAsmRegClass::Arm(
- ArmInlineAsmRegClass::sreg_low16
+ ArmInlineAsmRegClass::dreg
| ArmInlineAsmRegClass::dreg_low8
- | ArmInlineAsmRegClass::qreg_low4
- | ArmInlineAsmRegClass::dreg
- | ArmInlineAsmRegClass::qreg,
+ | ArmInlineAsmRegClass::dreg_low16,
),
Abi::Scalar(s),
) => {
- if let Primitive::Int(Integer::I32, _) = s.value {
- bx.bitcast(value, bx.cx.type_f32())
+ if let Primitive::Int(Integer::I64, _) = s.value {
+ bx.bitcast(value, bx.cx.type_f64())
} else {
value
}
InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg),
Abi::Vector { .. },
) if layout.size.bytes() == 64 => bx.bitcast(value, layout.llvm_type(bx.cx)),
+ (
+ InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16),
+ Abi::Scalar(s),
+ ) => {
+ if let Primitive::Int(Integer::I32, _) = s.value {
+ bx.bitcast(value, bx.cx.type_i32())
+ } else {
+ value
+ }
+ }
(
InlineAsmRegClass::Arm(
- ArmInlineAsmRegClass::sreg_low16
+ ArmInlineAsmRegClass::dreg
| ArmInlineAsmRegClass::dreg_low8
- | ArmInlineAsmRegClass::qreg_low4
- | ArmInlineAsmRegClass::dreg
- | ArmInlineAsmRegClass::qreg,
+ | ArmInlineAsmRegClass::dreg_low16,
),
Abi::Scalar(s),
) => {
- if let Primitive::Int(Integer::I32, _) = s.value {
- bx.bitcast(value, bx.cx.type_i32())
+ if let Primitive::Int(Integer::I64, _) = s.value {
+ bx.bitcast(value, bx.cx.type_i64())
} else {
value
}
InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg),
Abi::Vector { .. },
) if layout.size.bytes() == 64 => cx.type_vector(cx.type_f64(), 8),
+ (
+ InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16),
+ Abi::Scalar(s),
+ ) => {
+ if let Primitive::Int(Integer::I32, _) = s.value {
+ cx.type_f32()
+ } else {
+ layout.llvm_type(cx)
+ }
+ }
(
InlineAsmRegClass::Arm(
- ArmInlineAsmRegClass::sreg_low16
+ ArmInlineAsmRegClass::dreg
| ArmInlineAsmRegClass::dreg_low8
- | ArmInlineAsmRegClass::qreg_low4
- | ArmInlineAsmRegClass::dreg
- | ArmInlineAsmRegClass::qreg,
+ | ArmInlineAsmRegClass::dreg_low16,
),
Abi::Scalar(s),
) => {
- if let Primitive::Int(Integer::I32, _) = s.value {
- cx.type_f32()
+ if let Primitive::Int(Integer::I64, _) = s.value {
+ cx.type_f64()
} else {
layout.llvm_type(cx)
}
use crate::llvm::archive_ro::ArchiveRO;
use crate::llvm::{self, False, True};
use crate::{LlvmCodegenBackend, ModuleLlvm};
-use log::{debug, info};
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared};
use rustc_codegen_ssa::back::symbol_export;
use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig};
use rustc_middle::middle::exported_symbols::SymbolExportLevel;
use rustc_session::cgu_reuse_tracker::CguReuse;
use rustc_session::config::{self, CrateType, Lto};
+use tracing::{debug, info};
use std::ffi::{CStr, CString};
use std::fs::File;
use crate::type_::Type;
use crate::LlvmCodegenBackend;
use crate::ModuleLlvm;
-use log::debug;
use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig};
use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
use rustc_span::symbol::sym;
use rustc_span::InnerSpan;
use rustc_target::spec::{CodeModel, RelocModel};
+use tracing::debug;
use libc::{c_char, c_int, c_uint, c_void, size_t};
use std::ffi::CString;
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
use libc::{c_char, c_uint};
-use log::debug;
use rustc_codegen_ssa::base::to_immediate;
use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, TypeKind};
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
use std::iter::TrustedLen;
use std::ops::{Deref, Range};
use std::ptr;
+use tracing::debug;
// All Builders must have an llfn associated with them
#[must_use]
lhs: Self::Value,
rhs: Self::Value,
) -> (Self::Value, Self::Value) {
- use rustc_ast::ast::IntTy::*;
- use rustc_ast::ast::UintTy::*;
+ use rustc_ast::IntTy::*;
+ use rustc_ast::UintTy::*;
use rustc_middle::ty::{Int, Uint};
let new_kind = match ty.kind {
use crate::context::CodegenCx;
use crate::llvm;
use crate::value::Value;
-use log::debug;
use rustc_codegen_ssa::traits::*;
+use tracing::debug;
use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt};
use rustc_middle::ty::{self, Instance, TypeFoldable};
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
-use rustc_ast::ast::Mutability;
+use rustc_ast::Mutability;
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::*;
use rustc_middle::bug;
use rustc_target::abi::{self, AddressSpace, HasDataLayout, LayoutOf, Pointer, Size};
use libc::{c_char, c_uint};
-use log::debug;
+use tracing::debug;
/*
* A note on nomenclature of linking: "extern", "foreign", and "upcall".
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
use libc::c_uint;
-use log::debug;
use rustc_codegen_ssa::traits::*;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_target::abi::{AddressSpace, Align, HasDataLayout, LayoutOf, Primitive, Scalar, Size};
+use tracing::debug;
use std::ffi::CStr;
use crate::llvm;
use llvm::coverageinfo::CounterMappingRegion;
-use log::debug;
use rustc_codegen_ssa::coverageinfo::map::{Counter, CounterExpression, Region};
use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods};
use rustc_data_structures::fx::FxIndexSet;
use rustc_llvm::RustString;
+use tracing::debug;
use std::ffi::CString;
use libc::c_uint;
use llvm::coverageinfo::CounterMappingRegion;
-use log::debug;
use rustc_codegen_ssa::coverageinfo::map::{CounterExpression, ExprKind, FunctionCoverage, Region};
use rustc_codegen_ssa::traits::{
BaseTypeMethods, CoverageInfoBuilderMethods, CoverageInfoMethods, MiscMethods, StaticMethods,
use rustc_data_structures::fx::FxHashMap;
use rustc_llvm::RustString;
use rustc_middle::ty::Instance;
+use tracing::debug;
use std::cell::RefCell;
use std::ffi::CString;
};
use crate::value::Value;
-use log::debug;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::const_cstr;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_target::abi::{Abi, Align, HasDataLayout, Integer, LayoutOf, TagEncoding};
use rustc_target::abi::{Int, Pointer, F32, F64};
use rustc_target::abi::{Primitive, Size, VariantIdx, Variants};
+use tracing::debug;
use libc::{c_longlong, c_uint};
use std::collections::hash_map::Entry;
use rustc_target::abi::{LayoutOf, Primitive, Size};
use libc::c_uint;
-use log::debug;
use smallvec::SmallVec;
use std::cell::RefCell;
+use tracing::debug;
mod create_scope_map;
pub mod gdb;
use crate::llvm::AttributePlace::Function;
use crate::type_::Type;
use crate::value::Value;
-use log::debug;
use rustc_codegen_ssa::traits::*;
use rustc_middle::ty::Ty;
+use tracing::debug;
/// Declare a function.
///
use crate::va_arg::emit_va_arg;
use crate::value::Value;
-use log::debug;
-
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_codegen_ssa::base::{compare_simd_types, to_immediate, wants_msvc_seh};
use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
use rustc_span::{sym, symbol::kw, Span, Symbol};
use rustc_target::abi::{self, HasDataLayout, LayoutOf, Primitive};
use rustc_target::spec::PanicStrategy;
+use tracing::debug;
use std::cmp::Ordering;
use std::iter;
}
impl AsmDialect {
- pub fn from_generic(asm: rustc_ast::ast::LlvmAsmDialect) -> Self {
+ pub fn from_generic(asm: rustc_ast::LlvmAsmDialect) -> Self {
match asm {
- rustc_ast::ast::LlvmAsmDialect::Att => AsmDialect::Att,
- rustc_ast::ast::LlvmAsmDialect::Intel => AsmDialect::Intel,
+ rustc_ast::LlvmAsmDialect::Att => AsmDialect::Att,
+ rustc_ast::LlvmAsmDialect::Intel => AsmDialect::Intel,
}
}
}
use rustc_middle::middle::cstore::MetadataLoader;
use rustc_target::spec::Target;
-use log::debug;
use rustc_codegen_ssa::METADATA_FILENAME;
use rustc_data_structures::owning_ref::OwningRef;
use rustc_data_structures::rustc_erase_owner;
+use tracing::debug;
use rustc_fs_util::path_to_c_string;
use std::path::Path;
use crate::context::CodegenCx;
use crate::llvm;
use crate::type_of::LayoutLlvmExt;
-use log::debug;
use rustc_codegen_ssa::traits::*;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
pub use rustc_middle::mir::mono::MonoItem;
use rustc_middle::ty::layout::FnAbiExt;
use rustc_middle::ty::{self, Instance, TypeFoldable};
use rustc_target::abi::LayoutOf;
+use tracing::debug;
impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn predefine_static(
use crate::llvm::{Bool, False, True};
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_codegen_ssa::common::TypeKind;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::small_c_str::SmallCStr;
use crate::abi::FnAbi;
use crate::common::*;
use crate::type_::Type;
-use log::debug;
use rustc_codegen_ssa::traits::*;
use rustc_middle::bug;
use rustc_middle::ty::layout::{FnAbiExt, TyAndLayout};
use rustc_target::abi::{Abi, AddressSpace, Align, FieldsShape};
use rustc_target::abi::{Int, Pointer, F32, F64};
use rustc_target::abi::{LayoutOf, PointeeInfo, Scalar, Size, TyAndLayoutMethods, Variants};
+use tracing::debug;
use std::fmt::Write;
cc = "1.0.1"
num_cpus = "1.0"
memmap = "0.7"
-log = { package = "tracing", version = "0.1" }
+tracing = "0.1"
libc = "0.2.50"
jobserver = "0.1.11"
tempfile = "3.1"
if let Some(implib_name) = implib_name {
let implib = out_filename.parent().map(|dir| dir.join(&implib_name));
if let Some(implib) = implib {
- self.linker_arg(&format!("--out-implib,{}", (*implib).to_str().unwrap()));
+ self.linker_arg(&format!("--out-implib={}", (*implib).to_str().unwrap()));
}
}
}
let mut reachable_non_generics: DefIdMap<_> = tcx
.reachable_set(LOCAL_CRATE)
.iter()
- .filter_map(|&hir_id| {
+ .filter_map(|&def_id| {
// We want to ignore some FFI functions that are not exposed from
// this crate. Reachable FFI functions can be lumped into two
// categories:
//
// As a result, if this id is an FFI item (foreign item) then we only
// let it through if it's included statically.
- match tcx.hir().get(hir_id) {
+ match tcx.hir().get(tcx.hir().local_def_id_to_hir_id(def_id)) {
Node::ForeignItem(..) => {
- let def_id = tcx.hir().local_def_id(hir_id);
tcx.is_statically_included_foreign_item(def_id).then_some(def_id)
}
..
})
| Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) => {
- let def_id = tcx.hir().local_def_id(hir_id);
let generics = tcx.generics_of(def_id);
if !generics.requires_monomorphization(tcx)
// Functions marked with #[inline] are codegened with "internal"
fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
if let Some(def_id) = def_id.as_local() {
- !tcx.reachable_set(LOCAL_CRATE).contains(&tcx.hir().local_def_id_to_hir_id(def_id))
+ !tcx.reachable_set(LOCAL_CRATE).contains(&def_id)
} else {
bug!("is_unreachable_local_definition called with non-local DefId: {:?}", def_id)
}
#[macro_use]
extern crate rustc_macros;
#[macro_use]
-extern crate log;
+extern crate tracing;
#[macro_use]
extern crate rustc_middle;
use crate::traits::*;
use crate::MemFlags;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_hir::lang_items;
use rustc_index::vec::Idx;
use rustc_middle::mir;
use super::BackendTypes;
use crate::mir::operand::OperandRef;
use crate::mir::place::PlaceRef;
-use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
+use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir::def_id::DefId;
use rustc_hir::{GlobalAsm, LlvmInlineAsmInner};
use rustc_middle::ty::Instance;
[dependencies]
ena = "0.14"
indexmap = "1.5.1"
-log = { package = "tracing", version = "0.1" }
+tracing = "0.1"
jobserver_crate = { version = "0.1.13", package = "jobserver" }
lazy_static = "1"
once_cell = { version = "1", features = ["parking_lot"] }
bitflags = "1.2.1"
measureme = "0.7.1"
libc = "0.2"
-stacker = "0.1.9"
+stacker = "0.1.11"
tempfile = "3.0.5"
[dependencies.parking_lot]
#![allow(rustc::default_hash_types)]
#[macro_use]
-extern crate log;
+extern crate tracing;
#[macro_use]
extern crate cfg_if;
#[macro_use]
pub extern crate rustc_plugin_impl as plugin;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_codegen_ssa::{traits::CodegenBackend, CodegenResults};
use rustc_data_structures::profiling::print_time_passes_entry;
use rustc_data_structures::sync::SeqCst;
//! The various pretty-printing routines.
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast_pretty::pprust;
use rustc_errors::ErrorReported;
use rustc_hir as hir;
An non-ascii identifier was used in an invalid context.
-Erroneous code example:
+Erroneous code examples:
```compile_fail,E0754
# #![feature(non_ascii_idents)]
-mod řųśť;
-// ^ error!
-fn main() {}
-```
-
-```compile_fail,E0754
-# #![feature(non_ascii_idents)]
+mod řųśť; // error!
#[no_mangle]
-fn řųśť() {}
-// ^ error!
+fn řųśť() {} // error!
+
fn main() {}
```
-Non-ascii can be used as module names if it is inline
-or a #\[path\] attribute is specified. For example:
+Non-ascii can be used as module names if it is inlined or if a `#[path]`
+attribute is specified. For example:
```
# #![feature(non_ascii_idents)]
-mod řųśť {
+mod řųśť { // ok!
const IS_GREAT: bool = true;
}
}
/// Adds a span/label to be included in the resulting snippet.
- /// This label will be shown together with the original span/label used when creating the
- /// diagnostic, *not* a span added by one of the `span_*` methods.
///
- /// This is pushed onto the `MultiSpan` that was created when the
- /// diagnostic was first built. If you don't call this function at
- /// all, and you just supplied a `Span` to create the diagnostic,
- /// then the snippet will just include that `Span`, which is
- /// called the primary span.
+ /// This is pushed onto the [`MultiSpan`] that was created when the diagnostic
+ /// was first built. That means it will be shown together with the original
+ /// span/label, *not* a span added by one of the `span_{note,warn,help,suggestions}` methods.
+ ///
+ /// This span is *not* considered a ["primary span"][`MultiSpan`]; only
+ /// the `Span` supplied when creating the diagnostic is primary.
+ ///
+ /// [`MultiSpan`]: ../rustc_span/struct.MultiSpan.html
pub fn span_label<T: Into<String>>(&mut self, span: Span, label: T) -> &mut Self {
self.span.push_span_label(span, label.into());
self
}
/// Adds a span/label to be included in the resulting snippet.
- /// This is pushed onto the `MultiSpan` that was created when the
- /// diagnostic was first built. If you don't call this function at
- /// all, and you just supplied a `Span` to create the diagnostic,
- /// then the snippet will just include that `Span`, which is
- /// called the primary span.
+ ///
+ /// This is pushed onto the [`MultiSpan`] that was created when the diagnostic
+ /// was first built. That means it will be shown together with the original
+ /// span/label, *not* a span added by one of the `span_{note,warn,help,suggestions}` methods.
+ ///
+ /// This span is *not* considered a ["primary span"][`MultiSpan`]; only
+ /// the `Span` supplied when creating the diagnostic is primary.
+ ///
+ /// [`MultiSpan`]: ../rustc_span/struct.MultiSpan.html
pub fn span_label(&mut self, span: Span, label: impl Into<String>) -> &mut Self {
self.0.diagnostic.span_label(span, label);
self
use crate::expand::{self, AstFragment, Invocation};
use crate::module::DirectoryOwnership;
-use rustc_ast::ast::{self, Attribute, NodeId, PatKind};
use rustc_ast::mut_visit::{self, MutVisitor};
use rustc_ast::ptr::P;
use rustc_ast::token;
use rustc_ast::tokenstream::{self, TokenStream};
use rustc_ast::visit::{AssocCtxt, Visitor};
+use rustc_ast::{self as ast, Attribute, NodeId, PatKind};
use rustc_attr::{self as attr, Deprecation, HasAttrs, Stability};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::{self, Lrc};
use crate::base::ExtCtxt;
-use rustc_ast::ast::{self, AttrVec, BlockCheckMode, Expr, PatKind, UnOp};
use rustc_ast::attr;
use rustc_ast::ptr::P;
+use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Expr, PatKind, UnOp};
use rustc_span::source_map::{respan, Spanned};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
//! Conditional compilation stripping.
-use rustc_ast::ast::{self, AttrItem, Attribute, MetaItem};
use rustc_ast::attr::HasAttrs;
use rustc_ast::mut_visit::*;
use rustc_ast::ptr::P;
+use rustc_ast::{self as ast, AttrItem, Attribute, MetaItem};
use rustc_attr as attr;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::map_in_place::MapInPlace;
use crate::placeholders::{placeholder, PlaceholderExpander};
use crate::proc_macro::collect_derives;
-use rustc_ast::ast::{self, AttrItem, Block, LitKind, NodeId, PatKind, Path};
-use rustc_ast::ast::{ItemKind, MacArgs, MacStmtStyle, StmtKind};
use rustc_ast::mut_visit::*;
use rustc_ast::ptr::P;
use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::visit::{self, AssocCtxt, Visitor};
+use rustc_ast::{self as ast, AttrItem, Block, LitKind, NodeId, PatKind, Path};
+use rustc_ast::{ItemKind, MacArgs, MacStmtStyle, StmtKind};
use rustc_ast_pretty::pprust;
use rustc_attr::{self as attr, is_builtin_attr, HasAttrs};
use rustc_data_structures::map_in_place::MapInPlace;
//! bound.
use crate::mbe::{KleeneToken, TokenTree};
-use rustc_ast::ast::{NodeId, DUMMY_NODE_ID};
use rustc_ast::token::{DelimToken, Token, TokenKind};
+use rustc_ast::{NodeId, DUMMY_NODE_ID};
use rustc_data_structures::fx::FxHashMap;
use rustc_session::lint::builtin::META_VARIABLE_MISUSE;
use rustc_session::parse::ParseSess;
use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq};
use crate::mbe::transcribe::transcribe;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::token::{self, NonterminalKind, NtTT, Token, TokenKind::*};
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
use rustc_ast_pretty::pprust;
use crate::mbe::macro_parser;
use crate::mbe::{Delimited, KleeneOp, KleeneToken, SequenceRepetition, TokenTree};
-use rustc_ast::ast::{NodeId, DUMMY_NODE_ID};
use rustc_ast::token::{self, Token};
use rustc_ast::tokenstream;
+use rustc_ast::{NodeId, DUMMY_NODE_ID};
use rustc_ast_pretty::pprust;
use rustc_session::parse::ParseSess;
use rustc_span::symbol::{kw, Ident};
use crate::mbe;
use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedMatch};
-use rustc_ast::ast::MacCall;
use rustc_ast::mut_visit::{self, MutVisitor};
use rustc_ast::token::{self, NtTT, Token};
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
+use rustc_ast::MacCall;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lrc;
use rustc_errors::{pluralize, PResult};
-use rustc_ast::ast::{Attribute, Mod};
-use rustc_ast::token;
+use rustc_ast::{token, Attribute, Mod};
use rustc_errors::{struct_span_err, PResult};
use rustc_parse::new_parser_from_file;
use rustc_session::parse::ParseSess;
use crate::tests::{matches_codepattern, string_to_crate};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::mut_visit::{self, MutVisitor};
use rustc_ast_pretty::pprust;
use rustc_span::symbol::Ident;
use crate::tests::{matches_codepattern, string_to_stream, with_error_checking_parse};
-use rustc_ast::ast::{self, PatKind};
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Token};
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
use rustc_ast::visit;
+use rustc_ast::{self as ast, PatKind};
use rustc_ast_pretty::pprust::item_to_string;
use rustc_errors::PResult;
use rustc_parse::new_parser_from_source_str;
use crate::base::ExtCtxt;
use crate::expand::{AstFragment, AstFragmentKind};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::mut_visit::*;
use rustc_ast::ptr::P;
use rustc_span::source_map::{dummy_spanned, DUMMY_SP};
use crate::base::{self, *};
use crate::proc_macro_server;
-use rustc_ast::ast::{self, ItemKind, MetaItemKind, NestedMetaItem};
use rustc_ast::token;
use rustc_ast::tokenstream::{TokenStream, TokenTree};
+use rustc_ast::{self as ast, *};
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, ErrorReported};
use rustc_parse::nt_to_tokenstream;
use crate::base::ExtCtxt;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::token;
use rustc_ast::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint};
use rustc_ast_pretty::pprust;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::tokenstream::TokenStream;
use rustc_parse::{new_parser_from_source_str, parser::Parser, source_file_to_stream};
use rustc_session::parse::ParseSess;
[few] hir_krate: rustc_hir::Crate<$tcx>,
[] arm: rustc_hir::Arm<$tcx>,
[] asm_operand: rustc_hir::InlineAsmOperand<$tcx>,
- [] asm_template: rustc_ast::ast::InlineAsmTemplatePiece,
- [] attribute: rustc_ast::ast::Attribute,
+ [] asm_template: rustc_ast::InlineAsmTemplatePiece,
+ [] attribute: rustc_ast::Attribute,
[] block: rustc_hir::Block<$tcx>,
[] bare_fn_ty: rustc_hir::BareFnTy<$tcx>,
[few] global_asm: rustc_hir::GlobalAsm,
use crate::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use crate::hir;
-use rustc_ast::ast;
-use rustc_ast::ast::NodeId;
+use rustc_ast as ast;
+use rustc_ast::NodeId;
use rustc_macros::HashStable_Generic;
use rustc_span::hygiene::MacroKind;
use crate::def::{DefKind, Namespace, Res};
use crate::def_id::DefId;
crate use crate::hir_id::HirId;
-use crate::itemlikevisit;
+use crate::{itemlikevisit, LangItem};
-use rustc_ast::ast::{self, CrateSugar, LlvmAsmDialect};
-use rustc_ast::ast::{AttrVec, Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, UintTy};
-pub use rustc_ast::ast::{BorrowKind, ImplPolarity, IsAuto};
-pub use rustc_ast::ast::{CaptureBy, Movability, Mutability};
-use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_ast::node_id::NodeMap;
use rustc_ast::util::parser::ExprPrecedence;
+use rustc_ast::{self as ast, CrateSugar, LlvmAsmDialect};
+use rustc_ast::{AttrVec, Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, UintTy};
+pub use rustc_ast::{BorrowKind, ImplPolarity, IsAuto};
+pub use rustc_ast::{CaptureBy, Movability, Mutability};
+use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
use rustc_macros::HashStable_Generic;
use rustc_span::def_id::LocalDefId;
-use rustc_span::source_map::{SourceMap, Spanned};
+use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{MultiSpan, Span, DUMMY_SP};
use rustc_target::asm::InlineAsmRegOrRegClass;
#[derive(Debug, HashStable_Generic)]
pub enum GenericBound<'hir> {
Trait(PolyTraitRef<'hir>, TraitBoundModifier),
+ // FIXME(davidtwco): Introduce `PolyTraitRef::LangItem`
+ LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>),
Outlives(Lifetime),
}
pub fn span(&self) -> Span {
match self {
&GenericBound::Trait(ref t, ..) => t.span,
+ &GenericBound::LangItemTrait(_, span, ..) => span,
&GenericBound::Outlives(ref l) => l.span,
}
}
self.is_place_expr(|_| true)
}
- // Whether this is a place expression.
- // `allow_projections_from` should return `true` if indexing a field or
- // index expression based on the given expression should be considered a
- // place expression.
+ /// Whether this is a place expression.
+ ///
+ /// `allow_projections_from` should return `true` if indexing a field or index expression based
+ /// on the given expression should be considered a place expression.
pub fn is_place_expr(&self, mut allow_projections_from: impl FnMut(&Self) -> bool) -> bool {
match self.kind {
ExprKind::Path(QPath::Resolved(_, ref path)) => match path.res {
allow_projections_from(base) || base.is_place_expr(allow_projections_from)
}
+ // Lang item paths cannot currently be local variables or statics.
+ ExprKind::Path(QPath::LangItem(..)) => false,
+
// Partially qualified paths in expressions can only legally
// refer to associated items which are always rvalues.
ExprKind::Path(QPath::TypeRelative(..))
/// Checks if the specified expression is a built-in range literal.
/// (See: `LoweringContext::lower_expr()`).
-///
-/// FIXME(#60607): This function is a hack. If and when we have `QPath::Lang(...)`,
-/// we can use that instead as simpler, more reliable mechanism, as opposed to using `SourceMap`.
-pub fn is_range_literal(sm: &SourceMap, expr: &Expr<'_>) -> bool {
- // Returns whether the given path represents a (desugared) range,
- // either in std or core, i.e. has either a `::std::ops::Range` or
- // `::core::ops::Range` prefix.
- fn is_range_path(path: &Path<'_>) -> bool {
- let segs: Vec<_> = path.segments.iter().map(|seg| seg.ident.to_string()).collect();
- let segs: Vec<_> = segs.iter().map(|seg| &**seg).collect();
-
- // "{{root}}" is the equivalent of `::` prefix in `Path`.
- if let ["{{root}}", std_core, "ops", range] = segs.as_slice() {
- (*std_core == "std" || *std_core == "core") && range.starts_with("Range")
- } else {
- false
- }
- };
-
- // Check whether a span corresponding to a range expression is a
- // range literal, rather than an explicit struct or `new()` call.
- fn is_lit(sm: &SourceMap, span: &Span) -> bool {
- sm.span_to_snippet(*span).map(|range_src| range_src.contains("..")).unwrap_or(false)
- };
-
+pub fn is_range_literal(expr: &Expr<'_>) -> bool {
match expr.kind {
// All built-in range literals but `..=` and `..` desugar to `Struct`s.
- ExprKind::Struct(ref qpath, _, _) => {
- if let QPath::Resolved(None, ref path) = **qpath {
- return is_range_path(&path) && is_lit(sm, &expr.span);
- }
- }
-
- // `..` desugars to its struct path.
- ExprKind::Path(QPath::Resolved(None, ref path)) => {
- return is_range_path(&path) && is_lit(sm, &expr.span);
- }
+ ExprKind::Struct(ref qpath, _, _) => matches!(
+ **qpath,
+ QPath::LangItem(
+ LangItem::Range
+ | LangItem::RangeTo
+ | LangItem::RangeFrom
+ | LangItem::RangeFull
+ | LangItem::RangeToInclusive,
+ _,
+ )
+ ),
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
ExprKind::Call(ref func, _) => {
- if let ExprKind::Path(QPath::TypeRelative(ref ty, ref segment)) = func.kind {
- if let TyKind::Path(QPath::Resolved(None, ref path)) = ty.kind {
- let new_call = segment.ident.name == sym::new;
- return is_range_path(&path) && is_lit(sm, &expr.span) && new_call;
- }
- }
+ matches!(func.kind, ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, _)))
}
- _ => {}
+ _ => false,
}
-
- false
}
#[derive(Debug, HashStable_Generic)]
/// `<Vec>::new`, and `T::X::Y::method` into `<<<T>::X>::Y>::method`,
/// the `X` and `Y` nodes each being a `TyKind::Path(QPath::TypeRelative(..))`.
TypeRelative(&'hir Ty<'hir>, &'hir PathSegment<'hir>),
+
+ /// Reference to a `#[lang = "foo"]` item.
+ LangItem(LangItem, Span),
+}
+
+impl<'hir> QPath<'hir> {
+ /// Returns the span of this `QPath`.
+ pub fn span(&self) -> Span {
+ match *self {
+ QPath::Resolved(_, path) => path.span,
+ QPath::TypeRelative(_, ps) => ps.ident.span,
+ QPath::LangItem(_, span) => span,
+ }
+ }
+
+ /// Returns the span of the qself of this `QPath`. For example, `()` in
+ /// `<() as Trait>::method`.
+ pub fn qself_span(&self) -> Span {
+ match *self {
+ QPath::Resolved(_, path) => path.span,
+ QPath::TypeRelative(qself, _) => qself.span,
+ QPath::LangItem(_, span) => span,
+ }
+ }
+
+ /// Returns the span of the last segment of this `QPath`. For example, `method` in
+ /// `<() as Trait>::method`.
+ pub fn last_segment_span(&self) -> Span {
+ match *self {
+ QPath::Resolved(_, path) => path.segments.last().unwrap().ident.span,
+ QPath::TypeRelative(_, segment) => segment.ident.span,
+ QPath::LangItem(_, span) => span,
+ }
+ }
}
/// Hints at the original code for a let statement.
use crate::hir::*;
use crate::hir_id::CRATE_HIR_ID;
use crate::itemlikevisit::{ItemLikeVisitor, ParItemLikeVisitor};
-use rustc_ast::ast::{Attribute, Label};
use rustc_ast::walk_list;
+use rustc_ast::{Attribute, Label};
use rustc_span::symbol::{Ident, Symbol};
use rustc_span::Span;
visitor.visit_ty(qself);
visitor.visit_path_segment(span, segment);
}
+ QPath::LangItem(..) => {}
}
}
GenericBound::Trait(ref typ, modifier) => {
visitor.visit_poly_trait_ref(typ, modifier);
}
+ GenericBound::LangItemTrait(_, span, hir_id, args) => {
+ visitor.visit_id(hir_id);
+ visitor.visit_generic_args(span, args);
+ }
GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
}
}
pub use self::LangItem::*;
use crate::def_id::DefId;
-use crate::Target;
+use crate::{MethodKind, Target};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_macros::HashStable_Generic;
CountCodeRegionFnLangItem, sym::count_code_region, count_code_region_fn, Target::Fn;
CoverageCounterAddFnLangItem, sym::coverage_counter_add, coverage_counter_add_fn, Target::Fn;
CoverageCounterSubtractFnLangItem, sym::coverage_counter_subtract, coverage_counter_subtract_fn, Target::Fn;
+
+ // Language items from AST lowering
+ TryFromError, sym::from_error, from_error_fn, Target::Method(MethodKind::Trait { body: false });
+ TryFromOk, sym::from_ok, from_ok_fn, Target::Method(MethodKind::Trait { body: false });
+ TryIntoResult, sym::into_result, into_result_fn, Target::Method(MethodKind::Trait { body: false });
+
+ PollReady, sym::Ready, poll_ready_variant, Target::Variant;
+ PollPending, sym::Pending, poll_pending_variant, Target::Variant;
+
+ FromGenerator, sym::from_generator, from_generator_fn, Target::Fn;
+ GetContext, sym::get_context, get_context_fn, Target::Fn;
+
+ FuturePoll, sym::poll, future_poll_fn, Target::Method(MethodKind::Trait { body: false });
+
+ FromFrom, sym::from, from_fn, Target::Method(MethodKind::Trait { body: false });
+
+ OptionSome, sym::Some, option_some_variant, Target::Variant;
+ OptionNone, sym::None, option_none_variant, Target::Variant;
+
+ ResultOk, sym::Ok, result_ok_variant, Target::Variant;
+ ResultErr, sym::Err, result_err_variant, Target::Variant;
+
+ IntoIterIntoIter, sym::into_iter, into_iter_fn, Target::Method(MethodKind::Trait { body: false });
+ IteratorNext, sym::next, next_fn, Target::Method(MethodKind::Trait { body: false});
+
+ PinNewUnchecked, sym::new_unchecked, new_unchecked_fn, Target::Method(MethodKind::Inherent);
+
+ RangeFrom, sym::RangeFrom, range_from_struct, Target::Struct;
+ RangeFull, sym::RangeFull, range_full_struct, Target::Struct;
+ RangeInclusiveStruct, sym::RangeInclusive, range_inclusive_struct, Target::Struct;
+ RangeInclusiveNew, sym::range_inclusive_new, range_inclusive_new_method, Target::Method(MethodKind::Inherent);
+ Range, sym::Range, range_struct, Target::Struct;
+ RangeToInclusive, sym::RangeToInclusive, range_to_inclusive_struct, Target::Struct;
+ RangeTo, sym::RangeTo, range_to_struct, Target::Struct;
}
TyAlias,
OpaqueTy,
Enum,
+ Variant,
Struct,
Union,
Trait,
Target::TyAlias => "type alias",
Target::OpaqueTy => "opaque type",
Target::Enum => "enum",
+ Target::Variant => "enum variant",
Target::Struct => "struct",
Target::Union => "union",
Target::Trait => "trait",
use crate::def_id::DefId;
use crate::{lang_items, LangItem, LanguageItems};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_data_structures::fx::FxHashMap;
use rustc_span::symbol::{sym, Symbol};
#![feature(or_patterns)]
#![recursion_limit = "256"]
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::util::parser::{self, AssocOp, Fixity};
use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent};
use rustc_ast_pretty::pp::{self, Breaks};
colons_before_params,
)
}
+ hir::QPath::LangItem(lang_item, span) => {
+ self.s.word("#[lang = \"");
+ self.print_ident(Ident::new(lang_item.name(), span));
+ self.s.word("\"]");
+ }
}
}
}
self.print_poly_trait_ref(tref);
}
+ GenericBound::LangItemTrait(lang_item, span, ..) => {
+ self.s.word("#[lang = \"");
+ self.print_ident(Ident::new(lang_item.name(), *span));
+ self.s.word("\"]");
+ }
GenericBound::Outlives(lt) => {
self.print_lifetime(lt);
}
//! fn baz() { foo(); }
//! ```
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::graph::implementation::{Direction, NodeIndex, INCOMING, OUTGOING};
use rustc_graphviz as dot;
//! allows for doing a more fine-grained check to see if pre- or post-lto data
//! was re-used.
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::mir::mono::CodegenUnitNameBuilder;
use rustc_middle::ty::TyCtxt;
//! Errors are reported if we are in the suitable configuration but
//! the required condition is not met.
-use rustc_ast::ast::{self, Attribute, NestedMetaItem};
+use rustc_ast::{self as ast, Attribute, NestedMetaItem};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use crate::traits::{Obligation, PredicateObligations};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_hir::def_id::DefId;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::error::TypeError;
pub use crate::passes::BoxedResolver;
use crate::util;
-use rustc_ast::ast::{self, MetaItemKind};
use rustc_ast::token;
+use rustc_ast::{self as ast, MetaItemKind};
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::Lrc;
use once_cell::sync::Lazy;
use rustc_ast::mut_visit::MutVisitor;
-use rustc_ast::{self, ast, visit};
+use rustc_ast::{self as ast, visit};
use rustc_codegen_ssa::back::link::emit_metadata;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::sync::{par_iter, Lrc, OnceCell, ParallelIterator, WorkerLocal};
use crate::interface::{Compiler, Result};
use crate::passes::{self, BoxedResolver, QueryContext};
-use rustc_ast::{self, ast};
+use rustc_ast as ast;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
use rustc_errors::ErrorReported;
-use rustc_ast::ast::{AttrVec, BlockCheckMode};
use rustc_ast::mut_visit::{visit_clobber, MutVisitor, *};
use rustc_ast::ptr::P;
use rustc_ast::util::lev_distance::find_best_match_for_name;
-use rustc_ast::{self, ast};
+use rustc_ast::{self as ast, AttrVec, BlockCheckMode};
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use crate::{
types::CItemKind, EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext,
};
-use rustc_ast::ast::{self, Expr};
use rustc_ast::attr::{self, HasAttrs};
use rustc_ast::tokenstream::{TokenStream, TokenTree};
use rustc_ast::visit::{FnCtxt, FnKind};
+use rustc_ast::{self as ast, *};
use rustc_ast_pretty::pprust::{self, expr_to_string};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
_ => false,
}
}
- hir::QPath::Resolved(..) => false,
+ hir::QPath::Resolved(..) | hir::QPath::LangItem(..) => false,
}
}
return;
}
- use self::ast::{PatKind, RangeEnd, RangeSyntax::DotDotDot};
+ use self::ast::{PatKind, RangeSyntax::DotDotDot};
/// If `pat` is a `...` pattern, return the start and end of the range, as well as the span
/// corresponding to the ellipsis.
/// Test if this constant is all-0.
fn is_zero(expr: &hir::Expr<'_>) -> bool {
use hir::ExprKind::*;
- use rustc_ast::ast::LitKind::*;
+ use rustc_ast::LitKind::*;
match &expr.kind {
Lit(lit) => {
if let Int(i, _) = lit.node {
use crate::levels::LintLevelsBuilder;
use crate::passes::{EarlyLintPassObject, LateLintPassObject};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::util::lev_distance::find_best_match_for_name;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync;
pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res {
match *qpath {
hir::QPath::Resolved(_, ref path) => path.res,
- hir::QPath::TypeRelative(..) => self
+ hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self
.maybe_typeck_results()
.and_then(|typeck_results| typeck_results.type_dependent_def(id))
.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),
use crate::context::{EarlyContext, LintContext, LintStore};
use crate::passes::{EarlyLintPass, EarlyLintPassObject};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::visit as ast_visit;
use rustc_session::lint::{BufferedEarlyLint, LintBuffer, LintPass};
use rustc_session::Session;
//! Clippy.
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
-use rustc_ast::ast::{Item, ItemKind};
+use rustc_ast::{Item, ItemKind};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::Applicability;
use rustc_hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind};
//! for all lint attributes.
use crate::{passes::LateLintPassObject, LateContext, LateLintPass, LintStore};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::walk_list;
use rustc_data_structures::sync::{join, par_iter, ParallelIterator};
use rustc_hir as hir;
use crate::context::{CheckLintNameResult, LintStore};
use crate::late::unerased_lint_store;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::attr;
use rustc_ast::unwrap_or;
use rustc_ast_pretty::pprust;
mod types;
mod unused;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_middle::ty::query::Providers;
use crate::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_data_structures::fx::FxHashMap;
use rustc_span::symbol::Symbol;
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_attr as attr;
use rustc_errors::Applicability;
use rustc_hir as hir;
use crate::context::{EarlyContext, LateContext};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_data_structures::sync;
use rustc_hir as hir;
use rustc_session::lint::builtin::HardwiredLints;
use crate::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_ast::ast::{Block, StmtKind};
+use rustc_ast::{Block, StmtKind};
use rustc_errors::Applicability;
use rustc_span::Span;
#![allow(non_snake_case)]
use crate::{LateContext, LateLintPass, LintContext};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_attr as attr;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
//
// No suggestion for: `isize`, `usize`.
fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<&'static str> {
- use rustc_ast::ast::IntTy::*;
- use rustc_ast::ast::UintTy::*;
+ use rustc_ast::IntTy::*;
+ use rustc_ast::UintTy::*;
macro_rules! find_fit {
($ty:expr, $val:expr, $negative:expr,
$($type:ident => [$($utypes:expr),*] => [$($itypes:expr),*]),+) => {
let par_id = cx.tcx.hir().get_parent_node(e.hir_id);
if let Node::Expr(par_e) = cx.tcx.hir().get(par_id) {
if let hir::ExprKind::Struct(..) = par_e.kind {
- if is_range_literal(cx.sess().source_map(), par_e)
+ if is_range_literal(par_e)
&& lint_overflowing_range_endpoint(cx, lit, v, max, e, par_e, t.name_str())
{
// The overflowing literal lint was overridden.
return;
}
}
- hir::ExprKind::Struct(..) if is_range_literal(cx.sess().source_map(), par_e) => {
+ hir::ExprKind::Struct(..) if is_range_literal(par_e) => {
let t = t.name_str();
if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, par_e, t) {
// The overflowing literal lint was overridden.
use crate::Lint;
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
-use rustc_ast::ast;
-use rustc_ast::ast::{ExprKind, StmtKind};
+use rustc_ast as ast;
use rustc_ast::util::parser;
+use rustc_ast::{ExprKind, StmtKind};
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{pluralize, Applicability};
}
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
- use rustc_ast::ast::ExprKind::*;
+ use rustc_ast::ExprKind::*;
let (value, ctx, followed_by_block, left_pos, right_pos) = match e.kind {
// Do not lint `unused_braces` in `if let` expressions.
If(ref cond, ref block, ..)
use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob};
use rustc_ast::expand::allocator::AllocatorKind;
-use rustc_ast::{ast, visit};
+use rustc_ast::{self as ast, *};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::Lrc;
&& file.ends_with(&self.target.options.dll_suffix)
{
// Make sure there's at most one rlib and at most one dylib.
- let loc = fs::canonicalize(&loc).unwrap_or_else(|_| loc.clone());
+ // Note to take care and match against the non-canonicalized name:
+ // some systems save build artifacts into content-addressed stores
+ // that do not preserve extensions, and then link to them using
+ // e.g. symbolic links. If we canonicalize too early, we resolve
+ // the symlink, the file type is lost and we might treat rlibs and
+ // rmetas as dylibs.
+ let loc_canon = fs::canonicalize(&loc).unwrap_or_else(|_| loc.clone());
if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") {
- rlibs.insert(loc, PathKind::ExternFlag);
+ rlibs.insert(loc_canon, PathKind::ExternFlag);
} else if loc.file_name().unwrap().to_str().unwrap().ends_with(".rmeta") {
- rmetas.insert(loc, PathKind::ExternFlag);
+ rmetas.insert(loc_canon, PathKind::ExternFlag);
} else {
- dylibs.insert(loc, PathKind::ExternFlag);
+ dylibs.insert(loc_canon, PathKind::ExternFlag);
}
} else {
self.rejected_via_filename
use crate::rmeta::table::{FixedSizeEncoding, Table};
use crate::rmeta::*;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_attr as attr;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fingerprint::{Fingerprint, FingerprintDecoder};
use crate::native_libs;
use crate::rmeta::{self, encoder};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_data_structures::svh::Svh;
use rustc_hir as hir;
use crate::rmeta::table::{FixedSizeEncoding, TableBuilder};
use crate::rmeta::*;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_data_structures::fingerprint::{Fingerprint, FingerprintEncoder};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_data_structures::stable_hasher::StableHasher;
use decoder::Metadata;
use table::{Table, TableBuilder};
-use rustc_ast::ast::{self, MacroDef};
+use rustc_ast::{self as ast, MacroDef};
use rustc_attr as attr;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::MetadataRef;
[] upvars_mentioned: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>,
[] object_safety_violations: rustc_middle::traits::ObjectSafetyViolation,
[] codegen_unit: rustc_middle::mir::mono::CodegenUnit<$tcx>,
- [] attribute: rustc_ast::ast::Attribute,
+ [] attribute: rustc_ast::Attribute,
[] name_set: rustc_data_structures::fx::FxHashSet<rustc_span::symbol::Symbol>,
[] hir_id_set: rustc_hir::HirIdSet,
// Note that this deliberately duplicates items in the `rustc_hir::arena`,
// since we need to allocate this type on both the `rustc_hir` arena
// (during lowering) and the `librustc_middle` arena (for decoding MIR)
- [decode] asm_template: rustc_ast::ast::InlineAsmTemplatePiece,
+ [decode] asm_template: rustc_ast::InlineAsmTemplatePiece,
// This is used to decode the &'tcx [Span] for InlineAsm's line_spans.
[decode] span: rustc_span::Span,
//! for the `Code` associated with a particular NodeId.
use crate::hir::map::Map;
-use rustc_ast::ast::Attribute;
+use rustc_ast::Attribute;
use rustc_hir as hir;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{Expr, FnDecl, Node};
use crate::hir::{Owner, OwnerNodes};
use crate::ty::query::Providers;
use crate::ty::TyCtxt;
-use rustc_ast::ast::{self};
+use rustc_ast as ast;
use rustc_data_structures::svh::Svh;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use crate::middle::cstore::CrateStore;
use crate::ty::{fast_reject, TyCtxt};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc;
use crate::ich::StableHashingContext;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_span::SourceFile;
use crate::ty::TyCtxt;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::{self, MetadataRef};
//! just peeks and looks for that attribute.
use crate::bug;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_data_structures::sync::OnceCell;
use rustc_session::{Limit, Session};
use rustc_span::symbol::{sym, Symbol};
pub use self::StabilityLevel::*;
use crate::ty::{self, TyCtxt};
-use rustc_ast::ast::CRATE_NODE_ID;
+use rustc_ast::CRATE_NODE_ID;
use rustc_attr::{self as attr, ConstStability, Deprecation, Stability};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{Applicability, DiagnosticBuilder};
use std::iter;
use std::ops::{Deref, DerefMut, Range};
-use rustc_ast::ast::Mutability;
+use rustc_ast::Mutability;
use rustc_data_structures::sorted_map::SortedMap;
use rustc_target::abi::{Align, HasDataLayout, Size};
use std::sync::atomic::{AtomicU32, Ordering};
use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
-use rustc_ast::ast::LitKind;
+use rustc_ast::LitKind;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::{HashMapExt, Lock};
use rustc_data_structures::tiny_list::TinyList;
use rustc_target::abi::VariantIdx;
use polonius_engine::Atom;
-pub use rustc_ast::ast::Mutability;
+pub use rustc_ast::Mutability;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::graph::dominators::{dominators, Dominators};
use rustc_data_structures::graph::{self, GraphSuccessors};
use crate::mir::interpret::Scalar;
use crate::ty::{self, Ty, TyCtxt};
-use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
+use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use super::{
AssertMessage, BasicBlock, InlineAsmOperand, Operand, Place, SourceInfo, Successors,
SuccessorsMut,
};
-pub use rustc_ast::ast::Mutability;
+pub use rustc_ast::Mutability;
use rustc_macros::HashStable;
use rustc_span::Span;
use std::borrow::Cow;
}
Other {
- query reachable_set(_: CrateNum) -> &'tcx HirIdSet {
+ query reachable_set(_: CrateNum) -> FxHashSet<LocalDefId> {
+ storage(ArenaCacheSelector<'tcx>)
desc { "reachability" }
}
use crate::ty::{self, Ty};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_macros::HashStable;
/// Types that are represented as ints.
/// A placeholder for a const which could not be computed; this is
/// propagated to avoid useless error messages.
- Error(ty::sty::DelaySpanBugEmitted),
+ Error(ty::DelaySpanBugEmitted),
}
#[cfg(target_arch = "x86_64")]
ProjectionTy, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar,
TyVid, TypeAndMut,
};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_attr as attr;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use std::ops::{Bound, Deref};
use std::sync::Arc;
+/// A type that is not publicly constructable. This prevents people from making `TyKind::Error`
+/// except through `tcx.err*()`, which are in this module.
+#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
+#[derive(TyEncodable, TyDecodable, HashStable)]
+pub struct DelaySpanBugEmitted(());
+
type InternedSet<'tcx, T> = ShardedHashMap<Interned<'tcx, T>, ()>;
pub struct CtxtInterners<'tcx> {
pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res {
match *qpath {
hir::QPath::Resolved(_, ref path) => path.res,
- hir::QPath::TypeRelative(..) => self
+ hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self
.type_dependent_def(id)
.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),
}
#[track_caller]
pub fn ty_error_with_message<S: Into<MultiSpan>>(self, span: S, msg: &str) -> Ty<'tcx> {
self.sess.delay_span_bug(span, msg);
- self.mk_ty(Error(super::sty::DelaySpanBugEmitted(())))
+ self.mk_ty(Error(DelaySpanBugEmitted(())))
}
/// Like `err` but for constants.
pub fn const_error(self, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
self.sess
.delay_span_bug(DUMMY_SP, "ty::ConstKind::Error constructed but no error reported.");
- self.mk_const(ty::Const {
- val: ty::ConstKind::Error(super::sty::DelaySpanBugEmitted(())),
- ty,
- })
+ self.mk_const(ty::Const { val: ty::ConstKind::Error(DelaySpanBugEmitted(())), ty })
}
pub fn consider_optimizing<T: Fn() -> String>(&self, msg: T) -> bool {
use crate::traits::{ObligationCause, ObligationCauseCode};
use crate::ty::diagnostics::suggest_constraining_type_param;
use crate::ty::{self, BoundRegion, Region, Ty, TyCtxt};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect};
use rustc_errors::{pluralize, DiagnosticBuilder};
use rustc_hir as hir;
use crate::ich::StableHashingContext;
use crate::ty::{self, Ty, TyCtxt};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_hir::def_id::DefId;
use std::fmt::Debug;
use crate::ty::subst::Subst;
use crate::ty::{self, subst::SubstsRef, ReprOptions, Ty, TyCtxt, TypeFoldable};
-use rustc_ast::ast::{self, IntTy, UintTy};
+use rustc_ast::{self as ast, IntTy, UintTy};
use rustc_attr as attr;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_hir as hir;
use crate::ty;
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
use crate::ty::util::{Discr, IntTypeExt};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_attr as attr;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fingerprint::Fingerprint;
pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
pub use self::sty::{CanonicalPolyFnSig, FnSig, GenSig, PolyFnSig, PolyGenSig};
pub use self::sty::{ClosureSubsts, GeneratorSubsts, TypeAndMut, UpvarSubsts};
+pub use self::sty::{ClosureSubstsParts, GeneratorSubstsParts};
pub use self::sty::{ConstVid, FloatVid, IntVid, RegionVid, TyVid};
pub use self::sty::{ExistentialPredicate, InferTy, ParamConst, ParamTy, ProjectionTy};
pub use self::sty::{ExistentialProjection, PolyExistentialProjection};
pub use self::context::{tls, FreeRegionInfo, TyCtxt};
pub use self::context::{
- CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, ResolvedOpaqueTy,
- UserType, UserTypeAnnotationIndex,
+ CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations,
+ DelaySpanBugEmitted, ResolvedOpaqueTy, UserType, UserTypeAnnotationIndex,
};
pub use self::context::{
CtxtInterners, GeneratorInteriorTypeCause, GlobalCtxt, Lift, TypeckResults,
use crate::ty::{self, ConstInt, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable};
use rustc_apfloat::ieee::{Double, Single};
use rustc_apfloat::Float;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_attr::{SignedInt, UnsignedInt};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Namespace};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
use rustc_hir::lang_items::{LangItem, LanguageItems};
-use rustc_hir::{Crate, HirIdSet, ItemLocalId, TraitCandidate};
+use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
use rustc_session::utils::NativeLibKind;
use rustc_session::CrateDisambiguator;
use rustc_target::spec::PanicStrategy;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_attr as attr;
use rustc_span::symbol::Symbol;
use rustc_span::{Span, DUMMY_SP};
}
}
-impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
- for &'tcx [rustc_ast::ast::InlineAsmTemplatePiece]
-{
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [rustc_ast::InlineAsmTemplatePiece] {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
RefDecodable::decode(d)
}
u64,
String,
crate::middle::region::Scope,
- ::rustc_ast::ast::FloatTy,
- ::rustc_ast::ast::InlineAsmOptions,
- ::rustc_ast::ast::InlineAsmTemplatePiece,
- ::rustc_ast::ast::NodeId,
+ ::rustc_ast::FloatTy,
+ ::rustc_ast::InlineAsmOptions,
+ ::rustc_ast::InlineAsmTemplatePiece,
+ ::rustc_ast::NodeId,
::rustc_span::symbol::Symbol,
::rustc_hir::def::Res,
::rustc_hir::def_id::DefId,
use crate::ty::{
self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable, WithConstness,
};
-use crate::ty::{List, ParamEnv, TyS};
+use crate::ty::{DelaySpanBugEmitted, List, ParamEnv, TyS};
use polonius_engine::Atom;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_data_structures::captures::Captures;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
}
}
-/// A type that is not publicly constructable. This prevents people from making `TyKind::Error`
-/// except through `tcx.err*()`.
-#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
-#[derive(TyEncodable, TyDecodable, HashStable)]
-pub struct DelaySpanBugEmitted(pub(super) ());
-
// `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
static_assert_size!(TyKind<'_>, 24);
pub substs: SubstsRef<'tcx>,
}
-/// Struct returned by `split()`. Note that these are subslices of the
-/// parent slice and not canonical substs themselves.
-struct SplitClosureSubsts<'tcx> {
- parent: &'tcx [GenericArg<'tcx>],
- closure_kind_ty: GenericArg<'tcx>,
- closure_sig_as_fn_ptr_ty: GenericArg<'tcx>,
- tupled_upvars_ty: GenericArg<'tcx>,
+/// Struct returned by `split()`.
+pub struct ClosureSubstsParts<'tcx, T> {
+ pub parent_substs: &'tcx [GenericArg<'tcx>],
+ pub closure_kind_ty: T,
+ pub closure_sig_as_fn_ptr_ty: T,
+ pub tupled_upvars_ty: T,
}
impl<'tcx> ClosureSubsts<'tcx> {
- /// Divides the closure substs into their respective
- /// components. Single source of truth with respect to the
- /// ordering.
- fn split(self) -> SplitClosureSubsts<'tcx> {
+ /// Construct `ClosureSubsts` from `ClosureSubstsParts`, containing `Substs`
+ /// for the closure parent, alongside additional closure-specific components.
+ pub fn new(
+ tcx: TyCtxt<'tcx>,
+ parts: ClosureSubstsParts<'tcx, Ty<'tcx>>,
+ ) -> ClosureSubsts<'tcx> {
+ ClosureSubsts {
+ substs: tcx.mk_substs(
+ parts.parent_substs.iter().copied().chain(
+ [parts.closure_kind_ty, parts.closure_sig_as_fn_ptr_ty, parts.tupled_upvars_ty]
+ .iter()
+ .map(|&ty| ty.into()),
+ ),
+ ),
+ }
+ }
+
+ /// Divides the closure substs into their respective components.
+ /// The ordering assumed here must match that used by `ClosureSubsts::new` above.
+ fn split(self) -> ClosureSubstsParts<'tcx, GenericArg<'tcx>> {
match self.substs[..] {
- [ref parent @ .., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => {
- SplitClosureSubsts {
- parent,
+ [ref parent_substs @ .., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => {
+ ClosureSubstsParts {
+ parent_substs,
closure_kind_ty,
closure_sig_as_fn_ptr_ty,
tupled_upvars_ty,
/// Returns the substitutions of the closure's parent.
pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] {
- self.split().parent
+ self.split().parent_substs
}
#[inline]
pub substs: SubstsRef<'tcx>,
}
-struct SplitGeneratorSubsts<'tcx> {
- parent: &'tcx [GenericArg<'tcx>],
- resume_ty: GenericArg<'tcx>,
- yield_ty: GenericArg<'tcx>,
- return_ty: GenericArg<'tcx>,
- witness: GenericArg<'tcx>,
- tupled_upvars_ty: GenericArg<'tcx>,
+pub struct GeneratorSubstsParts<'tcx, T> {
+ pub parent_substs: &'tcx [GenericArg<'tcx>],
+ pub resume_ty: T,
+ pub yield_ty: T,
+ pub return_ty: T,
+ pub witness: T,
+ pub tupled_upvars_ty: T,
}
impl<'tcx> GeneratorSubsts<'tcx> {
- fn split(self) -> SplitGeneratorSubsts<'tcx> {
+ /// Construct `GeneratorSubsts` from `GeneratorSubstsParts`, containing `Substs`
+ /// for the generator parent, alongside additional generator-specific components.
+ pub fn new(
+ tcx: TyCtxt<'tcx>,
+ parts: GeneratorSubstsParts<'tcx, Ty<'tcx>>,
+ ) -> GeneratorSubsts<'tcx> {
+ GeneratorSubsts {
+ substs: tcx.mk_substs(
+ parts.parent_substs.iter().copied().chain(
+ [
+ parts.resume_ty,
+ parts.yield_ty,
+ parts.return_ty,
+ parts.witness,
+ parts.tupled_upvars_ty,
+ ]
+ .iter()
+ .map(|&ty| ty.into()),
+ ),
+ ),
+ }
+ }
+
+ /// Divides the generator substs into their respective components.
+ /// The ordering assumed here must match that used by `GeneratorSubsts::new` above.
+ fn split(self) -> GeneratorSubstsParts<'tcx, GenericArg<'tcx>> {
match self.substs[..] {
- [ref parent @ .., resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty] => {
- SplitGeneratorSubsts {
- parent,
+ [ref parent_substs @ .., resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty] => {
+ GeneratorSubstsParts {
+ parent_substs,
resume_ty,
yield_ty,
return_ty,
/// Returns the substitutions of the generator's parent.
pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] {
- self.split().parent
+ self.split().parent_substs
}
/// This describes the types that can be contained in a generator.
use crate::ty::TyKind::*;
use crate::ty::{self, DefIdTree, GenericParamDefKind, List, Ty, TyCtxt, TypeFoldable};
use rustc_apfloat::Float as _;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_attr::{self as attr, SignedInt, UnsignedInt};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::fx::FxHashMap;
-use rustc_ast::ast::Mutability;
+use rustc_ast::Mutability;
use rustc_hir::def_id::DefId;
use rustc_middle::mir::AssertMessage;
use rustc_session::Limit;
use std::fs;
use std::path::PathBuf;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_data_structures::work_queue::WorkQueue;
use rustc_graphviz as dot;
use rustc_hir::def_id::DefId;
-use rustc_ast::ast::{self, MetaItem};
+use rustc_ast::{self as ast, MetaItem};
use rustc_middle::ty;
use rustc_session::Session;
use rustc_span::symbol::{sym, Symbol};
use rustc_apfloat::ieee::{Double, Single};
use rustc_apfloat::{Float, FloatConvert};
-use rustc_ast::ast::FloatTy;
+use rustc_ast::FloatTy;
use rustc_attr as attr;
use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar};
use rustc_middle::mir::CastKind;
use rustc_middle::mir::interpret::InterpResult;
use rustc_middle::ty::{self, query::TyCtxtAt, Ty};
-use rustc_ast::ast::Mutability;
+use rustc_ast::Mutability;
use super::{AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind, Scalar, ValueVisitor};
self.write_scalar(offset_ptr, dest)?;
}
sym::ptr_guaranteed_eq | sym::ptr_guaranteed_ne => {
- // FIXME: return `true` for at least some comparisons where we can reliably
- // determine the result of runtime (in)equality tests at compile-time.
- self.write_scalar(Scalar::from_bool(false), dest)?;
+ let a = self.read_immediate(args[0])?.to_scalar()?;
+ let b = self.read_immediate(args[1])?.to_scalar()?;
+ let cmp = if intrinsic_name == sym::ptr_guaranteed_eq {
+ self.guaranteed_eq(a, b)
+ } else {
+ self.guaranteed_ne(a, b)
+ };
+ self.write_scalar(Scalar::from_bool(cmp), dest)?;
}
sym::ptr_offset_from => {
let a = self.read_immediate(args[0])?.to_scalar()?;
Ok(true)
}
+ fn guaranteed_eq(&mut self, a: Scalar<M::PointerTag>, b: Scalar<M::PointerTag>) -> bool {
+ match (a, b) {
+ // Comparisons between integers are always known.
+ (Scalar::Raw { .. }, Scalar::Raw { .. }) => a == b,
+ // Equality with integers can never be known for sure.
+ (Scalar::Raw { .. }, Scalar::Ptr(_)) | (Scalar::Ptr(_), Scalar::Raw { .. }) => false,
+ // FIXME: return `true` for when both sides are the same pointer, *except* that
+ // some things (like functions and vtables) do not have stable addresses
+ // so we need to be careful around them.
+ (Scalar::Ptr(_), Scalar::Ptr(_)) => false,
+ }
+ }
+
+ fn guaranteed_ne(&mut self, a: Scalar<M::PointerTag>, b: Scalar<M::PointerTag>) -> bool {
+ match (a, b) {
+ // Comparisons between integers are always known.
+ (Scalar::Raw { .. }, Scalar::Raw { .. }) => a != b,
+ // Comparisons of abstract pointers with null pointers are known if the pointer
+ // is in bounds, because if they are in bounds, the pointer can't be null.
+ (Scalar::Raw { data: 0, .. }, Scalar::Ptr(ptr))
+ | (Scalar::Ptr(ptr), Scalar::Raw { data: 0, .. }) => !self.memory.ptr_may_be_null(ptr),
+ // Inequality with integers other than null can never be known for sure.
+ (Scalar::Raw { .. }, Scalar::Ptr(_)) | (Scalar::Ptr(_), Scalar::Raw { .. }) => false,
+ // FIXME: return `true` for at least some comparisons where we can reliably
+ // determine the result of runtime inequality tests at compile-time.
+ // Examples include comparison of addresses in static items, for these we can
+ // give reliable results.
+ (Scalar::Ptr(_), Scalar::Ptr(_)) => false,
+ }
+ }
+
pub fn exact_div(
&mut self,
a: ImmTy<'tcx, M::PointerTag>,
/// Whether memory accesses should be alignment-checked.
fn enforce_alignment(memory_extra: &Self::MemoryExtra) -> bool;
+ /// Whether, when checking alignment, we should `force_int` and thus support
+ /// custom alignment logic based on whatever the integer address happens to be.
+ fn force_int_for_alignment_check(memory_extra: &Self::MemoryExtra) -> bool;
+
/// Whether to enforce the validity invariant
fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
false
}
+ #[inline(always)]
+ fn force_int_for_alignment_check(_memory_extra: &Self::MemoryExtra) -> bool {
+ // We do not support `force_int`.
+ false
+ }
+
#[inline(always)]
fn enforce_validity(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
false // for now, we don't enforce validity
use std::borrow::Cow;
use std::collections::VecDeque;
-use std::convert::TryFrom;
+use std::convert::{TryFrom, TryInto};
use std::fmt;
use std::ptr;
-use rustc_ast::ast::Mutability;
+use rustc_ast::Mutability;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_middle::ty::{Instance, ParamEnv, TyCtxt};
use rustc_target::abi::{Align, HasDataLayout, Size, TargetDataLayout};
// if this is already a `Pointer` we want to do the bounds checks!
sptr
} else {
- // A "real" access, we must get a pointer.
+ // A "real" access, we must get a pointer to be able to check the bounds.
Scalar::from(self.force_ptr(sptr)?)
};
Ok(match normalized.to_bits_or_ptr(self.pointer_size(), self) {
// Test align. Check this last; if both bounds and alignment are violated
// we want the error to be about the bounds.
if let Some(align) = align {
- if alloc_align.bytes() < align.bytes() {
- // The allocation itself is not aligned enough.
- // FIXME: Alignment check is too strict, depending on the base address that
- // got picked we might be aligned even if this check fails.
- // We instead have to fall back to converting to an integer and checking
- // the "real" alignment.
- throw_ub!(AlignmentCheckFailed { has: alloc_align, required: align });
+ if M::force_int_for_alignment_check(&self.extra) {
+ let bits = self
+ .force_bits(ptr.into(), self.pointer_size())
+ .expect("ptr-to-int cast for align check should never fail");
+ check_offset_align(bits.try_into().unwrap(), align)?;
+ } else {
+ // Check allocation alignment and offset alignment.
+ if alloc_align.bytes() < align.bytes() {
+ throw_ub!(AlignmentCheckFailed { has: alloc_align, required: align });
+ }
+ check_offset_align(ptr.offset.bytes(), align)?;
}
- check_offset_align(ptr.offset.bytes(), align)?;
}
// We can still be zero-sized in this branch, in which case we have to
use std::convert::TryFrom;
use rustc_apfloat::Float;
-use rustc_ast::ast::FloatTy;
+use rustc_ast::FloatTy;
use rustc_middle::mir;
use rustc_middle::mir::interpret::{InterpResult, Scalar};
use rustc_middle::ty::{self, layout::TyAndLayout, Ty};
let base_ty = Place::ty_from(place.local, proj_base, self.body, self.tcx).ty;
match base_ty.kind {
ty::RawPtr(..) => self.require_unsafe(
- UnsafetyViolationKind::General,
+ UnsafetyViolationKind::GeneralAndConstFn,
UnsafetyViolationDetails::DerefOfRawPointer,
),
ty::Adt(adt, _) => {
use std::cell::Cell;
-use rustc_ast::ast::Mutability;
+use rustc_ast::Mutability;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def::DefKind;
use rustc_hir::HirId;
//! initialization and can otherwise silence errors, if
//! move analysis runs after promotion on broken MIR.
-use rustc_ast::ast::LitKind;
+use rustc_ast::LitKind;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_middle::mir::traversal::ReversePostorder;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_target::spec::abi::Abi;
use rustc_index::{bit_set::BitSet, vec::IndexVec};
use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor};
use rustc_middle::mir::*;
-use rustc_middle::ty::{List, Ty, TyCtxt};
+use rustc_middle::ty::{self, List, Ty, TyCtxt};
use rustc_target::abi::VariantIdx;
use std::iter::{Enumerate, Peekable};
use std::slice::Iter;
pub struct SimplifyBranchSame;
impl<'tcx> MirPass<'tcx> for SimplifyBranchSame {
- fn run_pass(&self, _: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) {
- let mut did_remove_blocks = false;
- let bbs = body.basic_blocks_mut();
- for bb_idx in bbs.indices() {
- let targets = match &bbs[bb_idx].terminator().kind {
- TerminatorKind::SwitchInt { targets, .. } => targets,
- _ => continue,
- };
+ fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) {
+ trace!("Running SimplifyBranchSame on {:?}", source);
+ let finder = SimplifyBranchSameOptimizationFinder { body, tcx };
+ let opts = finder.find();
+
+ let did_remove_blocks = opts.len() > 0;
+ for opt in opts.iter() {
+ trace!("SUCCESS: Applying optimization {:?}", opt);
+ // Replace `SwitchInt(..) -> [bb_first, ..];` with a `goto -> bb_first;`.
+ body.basic_blocks_mut()[opt.bb_to_opt_terminator].terminator_mut().kind =
+ TerminatorKind::Goto { target: opt.bb_to_goto };
+ }
+
+ if did_remove_blocks {
+ // We have dead blocks now, so remove those.
+ simplify::remove_dead_blocks(body);
+ }
+ }
+}
+
+#[derive(Debug)]
+struct SimplifyBranchSameOptimization {
+ /// All basic blocks are equal so go to this one
+ bb_to_goto: BasicBlock,
+ /// Basic block where the terminator can be simplified to a goto
+ bb_to_opt_terminator: BasicBlock,
+}
+
+struct SimplifyBranchSameOptimizationFinder<'a, 'tcx> {
+ body: &'a Body<'tcx>,
+ tcx: TyCtxt<'tcx>,
+}
- let mut iter_bbs_reachable = targets
- .iter()
- .map(|idx| (*idx, &bbs[*idx]))
- .filter(|(_, bb)| {
- // Reaching `unreachable` is UB so assume it doesn't happen.
- bb.terminator().kind != TerminatorKind::Unreachable
+impl<'a, 'tcx> SimplifyBranchSameOptimizationFinder<'a, 'tcx> {
+ fn find(&self) -> Vec<SimplifyBranchSameOptimization> {
+ self.body
+ .basic_blocks()
+ .iter_enumerated()
+ .filter_map(|(bb_idx, bb)| {
+ let (discr_switched_on, targets) = match &bb.terminator().kind {
+ TerminatorKind::SwitchInt { targets, discr, .. } => (discr, targets),
+ _ => return None,
+ };
+
+ // find the adt that has its discriminant read
+ // assuming this must be the last statement of the block
+ let adt_matched_on = match &bb.statements.last()?.kind {
+ StatementKind::Assign(box (place, rhs))
+ if Some(*place) == discr_switched_on.place() =>
+ {
+ match rhs {
+ Rvalue::Discriminant(adt_place) if adt_place.ty(self.body, self.tcx).ty.is_enum() => adt_place,
+ _ => {
+ trace!("NO: expected a discriminant read of an enum instead of: {:?}", rhs);
+ return None;
+ }
+ }
+ }
+ other => {
+ trace!("NO: expected an assignment of a discriminant read to a place. Found: {:?}", other);
+ return None
+ },
+ };
+
+ let mut iter_bbs_reachable = targets
+ .iter()
+ .map(|idx| (*idx, &self.body.basic_blocks()[*idx]))
+ .filter(|(_, bb)| {
+ // Reaching `unreachable` is UB so assume it doesn't happen.
+ bb.terminator().kind != TerminatorKind::Unreachable
// But `asm!(...)` could abort the program,
// so we cannot assume that the `unreachable` terminator itself is reachable.
// FIXME(Centril): use a normalization pass instead of a check.
StatementKind::LlvmInlineAsm(..) => true,
_ => false,
})
- })
- .peekable();
-
- // We want to `goto -> bb_first`.
- let bb_first = iter_bbs_reachable.peek().map(|(idx, _)| *idx).unwrap_or(targets[0]);
-
- // All successor basic blocks should have the exact same form.
- let all_successors_equivalent =
- iter_bbs_reachable.map(|(_, bb)| bb).tuple_windows().all(|(bb_l, bb_r)| {
- bb_l.is_cleanup == bb_r.is_cleanup
- && bb_l.terminator().kind == bb_r.terminator().kind
- && bb_l.statements.iter().eq_by(&bb_r.statements, |x, y| x.kind == y.kind)
- });
-
- if all_successors_equivalent {
- // Replace `SwitchInt(..) -> [bb_first, ..];` with a `goto -> bb_first;`.
- bbs[bb_idx].terminator_mut().kind = TerminatorKind::Goto { target: bb_first };
- did_remove_blocks = true;
+ })
+ .peekable();
+
+ let bb_first = iter_bbs_reachable.peek().map(|(idx, _)| *idx).unwrap_or(targets[0]);
+ let mut all_successors_equivalent = StatementEquality::TrivialEqual;
+
+ // All successor basic blocks must be equal or contain statements that are pairwise considered equal.
+ for ((bb_l_idx,bb_l), (bb_r_idx,bb_r)) in iter_bbs_reachable.tuple_windows() {
+ let trivial_checks = bb_l.is_cleanup == bb_r.is_cleanup
+ && bb_l.terminator().kind == bb_r.terminator().kind;
+ let statement_check = || {
+ bb_l.statements.iter().zip(&bb_r.statements).try_fold(StatementEquality::TrivialEqual, |acc,(l,r)| {
+ let stmt_equality = self.statement_equality(*adt_matched_on, &l, bb_l_idx, &r, bb_r_idx);
+ if matches!(stmt_equality, StatementEquality::NotEqual) {
+ // short circuit
+ None
+ } else {
+ Some(acc.combine(&stmt_equality))
+ }
+ })
+ .unwrap_or(StatementEquality::NotEqual)
+ };
+ if !trivial_checks {
+ all_successors_equivalent = StatementEquality::NotEqual;
+ break;
+ }
+ all_successors_equivalent = all_successors_equivalent.combine(&statement_check());
+ };
+
+ match all_successors_equivalent{
+ StatementEquality::TrivialEqual => {
+ // statements are trivially equal, so just take first
+ trace!("Statements are trivially equal");
+ Some(SimplifyBranchSameOptimization {
+ bb_to_goto: bb_first,
+ bb_to_opt_terminator: bb_idx,
+ })
+ }
+ StatementEquality::ConsideredEqual(bb_to_choose) => {
+ trace!("Statements are considered equal");
+ Some(SimplifyBranchSameOptimization {
+ bb_to_goto: bb_to_choose,
+ bb_to_opt_terminator: bb_idx,
+ })
+ }
+ StatementEquality::NotEqual => {
+ trace!("NO: not all successors of basic block {:?} were equivalent", bb_idx);
+ None
+ }
+ }
+ })
+ .collect()
+ }
+
+ /// Tests if two statements can be considered equal
+ ///
+ /// Statements can be trivially equal if the kinds match.
+ /// But they can also be considered equal in the following case A:
+ /// ```
+ /// discriminant(_0) = 0; // bb1
+ /// _0 = move _1; // bb2
+ /// ```
+ /// In this case the two statements are equal iff
+ /// 1: _0 is an enum where the variant index 0 is fieldless, and
+ /// 2: bb1 was targeted by a switch where the discriminant of _1 was switched on
+ fn statement_equality(
+ &self,
+ adt_matched_on: Place<'tcx>,
+ x: &Statement<'tcx>,
+ x_bb_idx: BasicBlock,
+ y: &Statement<'tcx>,
+ y_bb_idx: BasicBlock,
+ ) -> StatementEquality {
+ let helper = |rhs: &Rvalue<'tcx>,
+ place: &Box<Place<'tcx>>,
+ variant_index: &VariantIdx,
+ side_to_choose| {
+ let place_type = place.ty(self.body, self.tcx).ty;
+ let adt = match place_type.kind {
+ ty::Adt(adt, _) if adt.is_enum() => adt,
+ _ => return StatementEquality::NotEqual,
+ };
+ let variant_is_fieldless = adt.variants[*variant_index].fields.is_empty();
+ if !variant_is_fieldless {
+ trace!("NO: variant {:?} was not fieldless", variant_index);
+ return StatementEquality::NotEqual;
+ }
+
+ match rhs {
+ Rvalue::Use(operand) if operand.place() == Some(adt_matched_on) => {
+ StatementEquality::ConsideredEqual(side_to_choose)
+ }
+ _ => {
+ trace!(
+ "NO: RHS of assignment was {:?}, but expected it to match the adt being matched on in the switch, which is {:?}",
+ rhs,
+ adt_matched_on
+ );
+ StatementEquality::NotEqual
+ }
+ }
+ };
+ match (&x.kind, &y.kind) {
+ // trivial case
+ (x, y) if x == y => StatementEquality::TrivialEqual,
+
+ // check for case A
+ (
+ StatementKind::Assign(box (_, rhs)),
+ StatementKind::SetDiscriminant { place, variant_index },
+ ) => {
+ // choose basic block of x, as that has the assign
+ helper(rhs, place, variant_index, x_bb_idx)
+ }
+ (
+ StatementKind::SetDiscriminant { place, variant_index },
+ StatementKind::Assign(box (_, rhs)),
+ ) => {
+ // choose basic block of y, as that has the assign
+ helper(rhs, place, variant_index, y_bb_idx)
+ }
+ _ => {
+ trace!("NO: statements `{:?}` and `{:?}` not considered equal", x, y);
+ StatementEquality::NotEqual
}
}
+ }
+}
- if did_remove_blocks {
- // We have dead blocks now, so remove those.
- simplify::remove_dead_blocks(body);
+#[derive(Copy, Clone, Eq, PartialEq)]
+enum StatementEquality {
+ /// The two statements are trivially equal; same kind
+ TrivialEqual,
+ /// The two statements are considered equal, but may be of different kinds. The BasicBlock field is the basic block to jump to when performing the branch-same optimization.
+ /// For example, `_0 = _1` and `discriminant(_0) = discriminant(0)` are considered equal if 0 is a fieldless variant of an enum. But we don't want to jump to the basic block with the SetDiscriminant, as that is not legal if _1 is not the 0 variant index
+ ConsideredEqual(BasicBlock),
+ /// The two statements are not equal
+ NotEqual,
+}
+
+impl StatementEquality {
+ fn combine(&self, other: &StatementEquality) -> StatementEquality {
+ use StatementEquality::*;
+ match (self, other) {
+ (TrivialEqual, TrivialEqual) => TrivialEqual,
+ (TrivialEqual, ConsideredEqual(b)) | (ConsideredEqual(b), TrivialEqual) => {
+ ConsideredEqual(*b)
+ }
+ (ConsideredEqual(b1), ConsideredEqual(b2)) => {
+ if b1 == b2 {
+ ConsideredEqual(*b1)
+ } else {
+ NotEqual
+ }
+ }
+ (_, NotEqual) | (NotEqual, _) => NotEqual,
}
}
}
fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
self.super_constant(constant, location);
let Constant { span, user_ty, literal } = constant;
- self.push("mir::Constant");
- self.push(&format!("+ span: {}", self.tcx.sess.source_map().span_to_string(*span)));
- if let Some(user_ty) = user_ty {
- self.push(&format!("+ user_ty: {:?}", user_ty));
+ match literal.ty.kind {
+ ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char => {}
+ _ => {
+ self.push("mir::Constant");
+ self.push(&format!("+ span: {}", self.tcx.sess.source_map().span_to_string(*span)));
+ if let Some(user_ty) = user_ty {
+ self.push(&format!("+ user_ty: {:?}", user_ty));
+ }
+ self.push(&format!("+ literal: {:?}", literal));
+ }
}
- self.push(&format!("+ literal: {:?}", literal));
}
fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, _: Location) {
self.super_const(constant);
let ty::Const { ty, val, .. } = constant;
- self.push("ty::Const");
- self.push(&format!("+ ty: {:?}", ty));
- self.push(&format!("+ val: {:?}", val));
+ match ty.kind {
+ ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char => {}
+ _ => {
+ self.push("ty::Const");
+ self.push(&format!("+ ty: {:?}", ty));
+ self.push(&format!("+ val: {:?}", val));
+ }
+ }
}
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
use crate::build::expr::category::{Category, RvalueFunc};
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
use crate::thir::*;
-use rustc_ast::ast::InlineAsmOptions;
+use rustc_ast::InlineAsmOptions;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir as hir;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_middle::mir::interpret::{
truncate, Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar,
};
use crate::thir::util::UserAnnotatedTyHelpers;
use crate::thir::*;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::Node;
//! structures.
use self::cx::Cx;
-use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
+use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_middle::infer::canonical::Canonical;
use super::{PatCtxt, PatKind, PatternError};
use rustc_arena::TypedArena;
-use rustc_ast::ast::Mutability;
+use rustc_ast::Mutability;
use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::def::*;
use crate::thir::util::UserAnnotatedTyHelpers;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
#![feature(try_blocks)]
#![feature(or_patterns)]
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::token::{self, DelimToken, Nonterminal, Token};
use rustc_ast::tokenstream::{self, TokenStream, TokenTree};
use rustc_ast_pretty::pprust;
use super::{Parser, PathStyle};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::attr;
use rustc_ast::token::{self, Nonterminal};
use rustc_ast_pretty::pprust;
use super::ty::AllowPlus;
use super::{BlockMode, Parser, PathStyle, SemiColonMode, SeqSep, TokenExpectType, TokenType};
-use rustc_ast::ast::{
- self, AngleBracketedArgs, AttrVec, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind,
- Item, ItemKind, Mutability, Param, Pat, PatKind, PathSegment, QSelf, Ty, TyKind,
-};
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Lit, LitKind, TokenKind};
use rustc_ast::util::parser::AssocOp;
+use rustc_ast::{
+ self as ast, AngleBracketedArgs, AttrVec, BinOpKind, BindingMode, BlockCheckMode, Expr,
+ ExprKind, Item, ItemKind, Mutability, Param, Pat, PatKind, PathSegment, QSelf, Ty, TyKind,
+};
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{pluralize, struct_span_err};
use super::{SemiColonMode, SeqSep, TokenExpectType};
use crate::maybe_recover_from_interpolated_ty_qpath;
-use rustc_ast::ast::{self, AttrStyle, AttrVec, CaptureBy, Field, Lit, UnOp, DUMMY_NODE_ID};
-use rustc_ast::ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty, TyKind};
-use rustc_ast::ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits};
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Token, TokenKind};
use rustc_ast::util::classify;
use rustc_ast::util::literal::LitError;
use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity};
+use rustc_ast::{self as ast, AttrStyle, AttrVec, CaptureBy, Field, Lit, UnOp, DUMMY_NODE_ID};
+use rustc_ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty, TyKind};
+use rustc_ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits};
use rustc_ast_pretty::pprust;
use rustc_errors::{Applicability, DiagnosticBuilder, PResult};
use rustc_span::source_map::{self, Span, Spanned};
use super::Parser;
-use rustc_ast::ast::{self, Attribute, GenericBounds, GenericParam, GenericParamKind, WhereClause};
use rustc_ast::token;
+use rustc_ast::{
+ self as ast, Attribute, GenericBounds, GenericParam, GenericParamKind, WhereClause,
+};
use rustc_errors::PResult;
use rustc_span::symbol::{kw, sym};
use crate::maybe_whole;
-use rustc_ast::ast::{self, AttrStyle, AttrVec, Attribute, DUMMY_NODE_ID};
-use rustc_ast::ast::{AssocItem, AssocItemKind, ForeignItemKind, Item, ItemKind, Mod};
-use rustc_ast::ast::{Async, Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree, UseTreeKind};
-use rustc_ast::ast::{BindingMode, Block, FnDecl, FnSig, Param, SelfKind};
-use rustc_ast::ast::{EnumDef, Generics, StructField, TraitRef, Ty, TyKind, Variant, VariantData};
-use rustc_ast::ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
-use rustc_ast::ast::{MacArgs, MacCall, MacDelimiter};
use rustc_ast::ptr::P;
use rustc_ast::token::{self, TokenKind};
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
+use rustc_ast::{self as ast, AttrStyle, AttrVec, Attribute, DUMMY_NODE_ID};
+use rustc_ast::{AssocItem, AssocItemKind, ForeignItemKind, Item, ItemKind, Mod};
+use rustc_ast::{Async, Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree, UseTreeKind};
+use rustc_ast::{BindingMode, Block, FnDecl, FnSig, Param, SelfKind};
+use rustc_ast::{EnumDef, Generics, StructField, TraitRef, Ty, TyKind, Variant, VariantData};
+use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
+use rustc_ast::{MacArgs, MacCall, MacDelimiter};
use rustc_ast_pretty::pprust;
use rustc_errors::{struct_span_err, Applicability, PResult, StashKey};
use rustc_span::edition::Edition;
use diagnostics::Error;
pub use path::PathStyle;
-use rustc_ast::ast::DUMMY_NODE_ID;
-use rustc_ast::ast::{self, AttrStyle, AttrVec, Const, CrateSugar, Extern, Unsafe};
-use rustc_ast::ast::{
- Async, MacArgs, MacDelimiter, Mutability, StrLit, Visibility, VisibilityKind,
-};
use rustc_ast::ptr::P;
use rustc_ast::token::{self, DelimToken, Token, TokenKind};
use rustc_ast::tokenstream::{self, DelimSpan, TokenStream, TokenTree, TreeAndJoint};
+use rustc_ast::DUMMY_NODE_ID;
+use rustc_ast::{self as ast, AttrStyle, AttrVec, Const, CrateSugar, Extern, Unsafe};
+use rustc_ast::{Async, MacArgs, MacDelimiter, Mutability, StrLit, Visibility, VisibilityKind};
use rustc_ast_pretty::pprust;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, FatalError, PResult};
use rustc_session::parse::ParseSess;
use super::{Parser, PathStyle};
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
-use rustc_ast::ast::{self, AttrVec, Attribute, FieldPat, MacCall, Pat, PatKind, RangeEnd};
-use rustc_ast::ast::{BindingMode, Expr, ExprKind, Mutability, Path, QSelf, RangeSyntax};
use rustc_ast::mut_visit::{noop_visit_mac, noop_visit_pat, MutVisitor};
use rustc_ast::ptr::P;
use rustc_ast::token;
+use rustc_ast::{self as ast, AttrVec, Attribute, FieldPat, MacCall, Pat, PatKind, RangeEnd};
+use rustc_ast::{BindingMode, Expr, ExprKind, Mutability, Path, QSelf, RangeSyntax};
use rustc_ast_pretty::pprust;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, PResult};
use rustc_span::source_map::{respan, Span, Spanned};
use super::ty::{AllowPlus, RecoverQPath};
use super::{Parser, TokenType};
use crate::maybe_whole;
-use rustc_ast::ast::{self, AngleBracketedArg, AngleBracketedArgs, GenericArg, ParenthesizedArgs};
-use rustc_ast::ast::{AnonConst, AssocTyConstraint, AssocTyConstraintKind, BlockCheckMode};
-use rustc_ast::ast::{Path, PathSegment, QSelf};
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Token};
+use rustc_ast::{
+ self as ast, AngleBracketedArg, AngleBracketedArgs, GenericArg, ParenthesizedArgs,
+};
+use rustc_ast::{AnonConst, AssocTyConstraint, AssocTyConstraintKind, BlockCheckMode};
+use rustc_ast::{Path, PathSegment, QSelf};
use rustc_errors::{pluralize, Applicability, PResult};
use rustc_span::source_map::{BytePos, Span};
use rustc_span::symbol::{kw, sym, Ident};
use super::{BlockMode, Parser, Restrictions, SemiColonMode};
use crate::maybe_whole;
-use rustc_ast::ast;
-use rustc_ast::ast::{AttrStyle, AttrVec, Attribute, MacCall, MacStmtStyle};
-use rustc_ast::ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt, StmtKind, DUMMY_NODE_ID};
+use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, TokenKind};
use rustc_ast::util::classify;
+use rustc_ast::{AttrStyle, AttrVec, Attribute, MacCall, MacStmtStyle};
+use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt, StmtKind, DUMMY_NODE_ID};
use rustc_errors::{Applicability, PResult};
use rustc_span::source_map::{BytePos, Span};
use rustc_span::symbol::{kw, sym};
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
-use rustc_ast::ast::{self, BareFnTy, FnRetTy, GenericParam, Lifetime, MutTy, Ty, TyKind};
-use rustc_ast::ast::{GenericBound, GenericBounds, MacCall, Mutability};
-use rustc_ast::ast::{PolyTraitRef, TraitBoundModifier, TraitObjectSyntax};
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Token, TokenKind};
+use rustc_ast::{self as ast, BareFnTy, FnRetTy, GenericParam, Lifetime, MutTy, Ty, TyKind};
+use rustc_ast::{GenericBound, GenericBounds, MacCall, Mutability};
+use rustc_ast::{PolyTraitRef, TraitBoundModifier, TraitObjectSyntax};
use rustc_errors::{pluralize, struct_span_err, Applicability, PResult};
use rustc_span::source_map::Span;
use rustc_span::symbol::{kw, sym};
use crate::parse_in;
-use rustc_ast::ast::{self, Attribute, MacArgs, MacDelimiter, MetaItem, MetaItemKind};
use rustc_ast::tokenstream::DelimSpan;
+use rustc_ast::{self as ast, Attribute, MacArgs, MacDelimiter, MetaItem, MetaItemKind};
use rustc_errors::{Applicability, PResult};
use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP};
use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
-use rustc_ast::ast::{Attribute, NestedMetaItem};
+use rustc_ast::{Attribute, NestedMetaItem};
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_middle::ty::{self, DefIdTree, TyCtxt};
use rustc_session::lint;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_span::symbol::{sym, Symbol};
// Any local node that may call something in its body block should be
//!
//! * Compiler internal types like `Ty` and `TyCtxt`
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
// pieces of AST and HIR. The resulting numbers are good approximations but not
// completely accurate (some things might be counted twice, others missed).
-use rustc_ast::ast::{self, AttrId, NodeId};
use rustc_ast::visit as ast_visit;
+use rustc_ast::{self as ast, AttrId, NodeId};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir as hir;
use rustc_hir::intravisit as hir_visit;
-use rustc_ast::ast::{FloatTy, InlineAsmTemplatePiece, IntTy, UintTy};
+use rustc_ast::{FloatTy, InlineAsmTemplatePiece, IntTy, UintTy};
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_middle::middle::cstore::ExternCrate;
use rustc_middle::ty::TyCtxt;
-use rustc_ast::ast::Attribute;
+use rustc_ast::Attribute;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
impl ItemLikeVisitor<'v> for LanguageItemCollector<'tcx> {
fn visit_item(&mut self, item: &hir::Item<'_>) {
- self.check_for_lang(Target::from_item(item), item.hir_id, item.attrs)
+ self.check_for_lang(Target::from_item(item), item.hir_id, item.attrs);
+
+ if let hir::ItemKind::Enum(def, ..) = &item.kind {
+ for variant in def.variants {
+ self.check_for_lang(Target::Variant, variant.id, variant.attrs);
+ }
+ }
}
fn visit_trait_item(&mut self, trait_item: &hir::TraitItem<'_>) {
-use rustc_ast::ast::Attribute;
+use rustc_ast::Attribute;
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::itemlikevisit::ItemLikeVisitor;
// and `#[unstable (..)]`), but are not declared in one single location
// (unlike lang features), which means we need to collect them instead.
-use rustc_ast::ast::{Attribute, MetaItem, MetaItemKind};
+use rustc_ast::{Attribute, MetaItem, MetaItemKind};
use rustc_errors::struct_span_err;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use self::LiveNodeKind::*;
use self::VarKind::*;
-use rustc_ast::ast::InlineAsmOptions;
+use rustc_ast::InlineAsmOptions;
use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::Applicability;
use rustc_hir as hir;
| hir::ExprKind::Yield(..)
| hir::ExprKind::Type(..)
| hir::ExprKind::Err
- | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => {
+ | hir::ExprKind::Path(hir::QPath::TypeRelative(..))
+ | hir::ExprKind::Path(hir::QPath::LangItem(..)) => {
intravisit::walk_expr(ir, expr);
}
}
hir::ExprKind::Lit(..)
| hir::ExprKind::Err
- | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => succ,
+ | hir::ExprKind::Path(hir::QPath::TypeRelative(..))
+ | hir::ExprKind::Path(hir::QPath::LangItem(..)) => succ,
// Note that labels have been resolved, so we don't need to look
// at the label ident
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::itemlikevisit::ItemLikeVisitor;
-use rustc_hir::{HirIdSet, Node};
+use rustc_hir::Node;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::middle::privacy;
use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::ty::{self, DefIdTree, TyCtxt};
use rustc_session::config::CrateType;
use rustc_target::spec::abi::Abi;
tcx: TyCtxt<'tcx>,
maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
// The set of items which must be exported in the linkage sense.
- reachable_symbols: HirIdSet,
+ reachable_symbols: FxHashSet<LocalDefId>,
// A worklist of item IDs. Each item ID in this worklist will be inlined
// and will be scanned for further references.
- worklist: Vec<hir::HirId>,
+ // FIXME(eddyb) benchmark if this would be faster as a `VecDeque`.
+ worklist: Vec<LocalDefId>,
// Whether any output of this compilation is a library
any_library: bool,
}
_ => None,
};
- match res {
- Some(Res::Local(hir_id)) => {
- self.reachable_symbols.insert(hir_id);
- }
- Some(res) => {
- if let Some((hir_id, def_id)) = res.opt_def_id().and_then(|def_id| {
- def_id
- .as_local()
- .map(|def_id| (self.tcx.hir().local_def_id_to_hir_id(def_id), def_id))
- }) {
- if self.def_id_represents_local_inlined_item(def_id.to_def_id()) {
- self.worklist.push(hir_id);
- } else {
- match res {
- // If this path leads to a constant, then we need to
- // recurse into the constant to continue finding
- // items that are reachable.
- Res::Def(DefKind::Const | DefKind::AssocConst, _) => {
- self.worklist.push(hir_id);
- }
+ if let Some(res) = res {
+ if let Some(def_id) = res.opt_def_id().and_then(|def_id| def_id.as_local()) {
+ if self.def_id_represents_local_inlined_item(def_id.to_def_id()) {
+ self.worklist.push(def_id);
+ } else {
+ match res {
+ // If this path leads to a constant, then we need to
+ // recurse into the constant to continue finding
+ // items that are reachable.
+ Res::Def(DefKind::Const | DefKind::AssocConst, _) => {
+ self.worklist.push(def_id);
+ }
- // If this wasn't a static, then the destination is
- // surely reachable.
- _ => {
- self.reachable_symbols.insert(hir_id);
- }
+ // If this wasn't a static, then the destination is
+ // surely reachable.
+ _ => {
+ self.reachable_symbols.insert(def_id);
}
}
}
}
- _ => {}
}
intravisit::walk_expr(self, expr)
continue;
}
- if let Some(ref item) = self.tcx.hir().find(search_item) {
+ if let Some(ref item) =
+ self.tcx.hir().find(self.tcx.hir().local_def_id_to_hir_id(search_item))
+ {
self.propagate_node(item, search_item);
}
}
}
- fn propagate_node(&mut self, node: &Node<'tcx>, search_item: hir::HirId) {
+ fn propagate_node(&mut self, node: &Node<'tcx>, search_item: LocalDefId) {
if !self.any_library {
// If we are building an executable, only explicitly extern
// types need to be exported.
self.visit_nested_body(body);
}
hir::ImplItemKind::Fn(_, body) => {
- let did = self.tcx.hir().get_parent_did(search_item);
- if method_might_be_inlined(self.tcx, impl_item, did) {
+ let impl_def_id =
+ self.tcx.parent(search_item.to_def_id()).unwrap().expect_local();
+ if method_might_be_inlined(self.tcx, impl_item, impl_def_id) {
self.visit_nested_body(body)
}
}
_ => {
bug!(
"found unexpected node kind in worklist: {} ({:?})",
- self.tcx.hir().node_to_string(search_item),
+ self.tcx
+ .hir()
+ .node_to_string(self.tcx.hir().local_def_id_to_hir_id(search_item)),
node,
);
}
struct CollectPrivateImplItemsVisitor<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
access_levels: &'a privacy::AccessLevels,
- worklist: &'a mut Vec<hir::HirId>,
+ worklist: &'a mut Vec<LocalDefId>,
}
impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx> {
if codegen_attrs.contains_extern_indicator()
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
{
- self.worklist.push(item.hir_id);
+ self.worklist.push(def_id);
}
// We need only trait impls here, not inherent impls, and only non-exported ones
if let hir::ItemKind::Impl { of_trait: Some(ref trait_ref), ref items, .. } = item.kind {
if !self.access_levels.is_reachable(item.hir_id) {
- self.worklist.extend(items.iter().map(|ii_ref| ii_ref.id.hir_id));
+ // FIXME(#53488) remove `let`
+ let tcx = self.tcx;
+ self.worklist
+ .extend(items.iter().map(|ii_ref| tcx.hir().local_def_id(ii_ref.id.hir_id)));
let trait_def_id = match trait_ref.path.res {
Res::Def(DefKind::Trait, def_id) => def_id,
return;
}
- // FIXME(#53488) remove `let`
- let tcx = self.tcx;
- self.worklist
- .extend(tcx.provided_trait_methods(trait_def_id).map(|assoc| {
- tcx.hir().local_def_id_to_hir_id(assoc.def_id.expect_local())
- }));
+ self.worklist.extend(
+ tcx.provided_trait_methods(trait_def_id)
+ .map(|assoc| assoc.def_id.expect_local()),
+ );
}
}
}
}
}
-fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx HirIdSet {
+fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> FxHashSet<LocalDefId> {
debug_assert!(crate_num == LOCAL_CRATE);
let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
// If other crates link to us, they're going to expect to be able to
// use the lang items, so we need to be sure to mark them as
// exported.
- reachable_context.worklist.extend(access_levels.map.iter().map(|(id, _)| *id));
+ reachable_context
+ .worklist
+ .extend(access_levels.map.iter().map(|(id, _)| tcx.hir().local_def_id(*id)));
for item in tcx.lang_items().items().iter() {
- if let Some(did) = *item {
- if let Some(hir_id) = did.as_local().map(|did| tcx.hir().local_def_id_to_hir_id(did)) {
- reachable_context.worklist.push(hir_id);
+ if let Some(def_id) = *item {
+ if let Some(def_id) = def_id.as_local() {
+ reachable_context.worklist.push(def_id);
}
}
}
debug!("Inline reachability shows: {:?}", reachable_context.reachable_symbols);
// Return the set of reachable symbols.
- tcx.arena.alloc(reachable_context.reachable_symbols)
+ reachable_context.reachable_symbols
}
pub fn provide(providers: &mut Providers) {
//! A pass that annotates every item and method with its stability level,
//! propagating default levels lexically from parent to children ast nodes.
-use rustc_ast::ast::Attribute;
+use rustc_ast::Attribute;
use rustc_attr::{self as attr, ConstStability, Stability};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::struct_span_err;
//! Used by `rustc` when loading a plugin.
use crate::Registry;
-use rustc_ast::ast::Crate;
+use rustc_ast::Crate;
use rustc_errors::struct_span_err;
use rustc_metadata::locator;
use rustc_middle::middle::cstore::MetadataLoader;
Res::Def(kind, def_id) => Some((kind, def_id)),
_ => None,
},
- hir::QPath::TypeRelative(..) => self
+ hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self
.maybe_typeck_results
.and_then(|typeck_results| typeck_results.type_dependent_def(id)),
};
let sess = self.tcx.sess;
let sm = sess.source_map();
let name = match qpath {
- hir::QPath::Resolved(_, path) => sm.span_to_snippet(path.span).ok(),
+ hir::QPath::Resolved(..) | hir::QPath::LangItem(..) => {
+ sm.span_to_snippet(qpath.span()).ok()
+ }
hir::QPath::TypeRelative(_, segment) => Some(segment.ident.to_string()),
};
let kind = kind.descr(def_id);
};
use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding};
-use rustc_ast::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId};
-use rustc_ast::ast::{AssocItem, AssocItemKind, MetaItemKind, StmtKind};
use rustc_ast::token::{self, Token};
use rustc_ast::visit::{self, AssocCtxt, Visitor};
+use rustc_ast::{self as ast, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId};
+use rustc_ast::{AssocItem, AssocItemKind, MetaItemKind, StmtKind};
use rustc_ast_lowering::ResolverAstLowering;
use rustc_attr as attr;
use rustc_data_structures::sync::Lrc;
use crate::imports::ImportKind;
use crate::Resolver;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::node_id::NodeMap;
use rustc_ast::visit::{self, Visitor};
use rustc_ast_lowering::ResolverAstLowering;
use crate::Resolver;
-use rustc_ast::ast::*;
use rustc_ast::token::{self, Token};
use rustc_ast::visit::{self, FnKind};
use rustc_ast::walk_list;
+use rustc_ast::*;
use rustc_ast_lowering::ResolverAstLowering;
use rustc_expand::expand::AstFragment;
use rustc_hir::def_id::LocalDefId;
use std::cmp::Reverse;
use std::ptr;
-use rustc_ast::ast::{self, Path};
use rustc_ast::util::lev_distance::find_best_match_for_name;
+use rustc_ast::{self as ast, Path};
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use crate::{CrateLint, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet, Weak};
use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBinding};
-use rustc_ast::ast::NodeId;
use rustc_ast::unwrap_or;
use rustc_ast::util::lev_distance::find_best_match_for_name;
+use rustc_ast::NodeId;
use rustc_ast_lowering::ResolverAstLowering;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::ptr_key::PtrKey;
use crate::{Module, ModuleOrUniformRoot, NameBindingKind, ParentScope, PathResult};
use crate::{ResolutionError, Resolver, Segment, UseError};
-use rustc_ast::ast::*;
use rustc_ast::ptr::P;
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
+use rustc_ast::*;
use rustc_ast::{unwrap_or, walk_list};
use rustc_ast_lowering::ResolverAstLowering;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use crate::{CrateLint, Module, ModuleKind, ModuleOrUniformRoot};
use crate::{PathResult, PathSource, Segment};
-use rustc_ast::ast::{self, Expr, ExprKind, Item, ItemKind, NodeId, Path, Ty, TyKind};
use rustc_ast::util::lev_distance::find_best_match_for_name;
use rustc_ast::visit::FnKind;
+use rustc_ast::{self as ast, Expr, ExprKind, Item, ItemKind, NodeId, Path, Ty, TyKind};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir;
}
}
+ fn visit_param_bound(&mut self, bound: &'tcx hir::GenericBound<'tcx>) {
+ match bound {
+ hir::GenericBound::LangItemTrait { .. } if !self.trait_ref_hack => {
+ let scope = Scope::Binder {
+ lifetimes: FxHashMap::default(),
+ s: self.scope,
+ next_early_index: self.next_early_index(),
+ track_lifetime_uses: true,
+ opaque_type_parent: false,
+ };
+ self.with(scope, |_, this| {
+ intravisit::walk_param_bound(this, bound);
+ });
+ }
+ _ => intravisit::walk_param_bound(self, bound),
+ }
+ }
+
fn visit_poly_trait_ref(
&mut self,
trait_ref: &'tcx hir::PolyTraitRef<'tcx>,
self.outer_index.shift_out(1);
}
+ fn visit_param_bound(&mut self, bound: &hir::GenericBound<'_>) {
+ if let hir::GenericBound::LangItemTrait { .. } = bound {
+ self.outer_index.shift_in(1);
+ intravisit::walk_param_bound(self, bound);
+ self.outer_index.shift_out(1);
+ } else {
+ intravisit::walk_param_bound(self, bound);
+ }
+ }
+
fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) {
if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.hir_id) {
match lifetime {
use Determinacy::*;
use rustc_arena::TypedArena;
-use rustc_ast::ast::{self, FloatTy, IntTy, NodeId, UintTy};
-use rustc_ast::ast::{Crate, CRATE_NODE_ID};
-use rustc_ast::ast::{ItemKind, Path};
use rustc_ast::node_id::NodeMap;
use rustc_ast::unwrap_or;
use rustc_ast::visit::{self, Visitor};
+use rustc_ast::{self as ast, FloatTy, IntTy, NodeId, UintTy};
+use rustc_ast::{Crate, CRATE_NODE_ID};
+use rustc_ast::{ItemKind, Path};
use rustc_ast_lowering::ResolverAstLowering;
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
self.cstore().item_generics_num_lifetimes(def_id, sess)
}
- fn resolve_str_path(
- &mut self,
- span: Span,
- crate_root: Option<Symbol>,
- components: &[Symbol],
- ns: Namespace,
- ) -> (ast::Path, Res) {
- let root = if crate_root.is_some() { kw::PathRoot } else { kw::Crate };
- let segments = iter::once(Ident::with_dummy_span(root))
- .chain(
- crate_root
- .into_iter()
- .chain(components.iter().cloned())
- .map(Ident::with_dummy_span),
- )
- .map(|i| self.new_ast_path_segment(i))
- .collect::<Vec<_>>();
-
- let path = ast::Path { span, segments };
-
- let parent_scope = &ParentScope::module(self.graph_root);
- let res = match self.resolve_ast_path(&path, ns, parent_scope) {
- Ok(res) => res,
- Err((span, error)) => {
- self.report_error(span, error);
- Res::Err
- }
- };
- (path, res)
- }
-
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes> {
self.partial_res_map.get(&id).cloned()
}
use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy};
use crate::{CrateLint, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Weak};
use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding};
-use rustc_ast::ast::{self, NodeId};
+use rustc_ast::{self as ast, NodeId};
use rustc_ast_lowering::ResolverAstLowering;
use rustc_ast_pretty::pprust;
use rustc_attr::StabilityLevel;
//! DumpVisitor walks the AST and processes it, and Dumper is used for
//! recording the output.
-use rustc_ast::ast::{self};
+use rustc_ast as ast;
use rustc_ast::{token, walk_list};
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
// super-traits
for super_bound in trait_refs.iter() {
- let trait_ref = match *super_bound {
- hir::GenericBound::Trait(ref trait_ref, _) => trait_ref,
+ let (def_id, sub_span) = match *super_bound {
+ hir::GenericBound::Trait(ref trait_ref, _) => (
+ self.lookup_def_id(trait_ref.trait_ref.hir_ref_id),
+ trait_ref.trait_ref.path.segments.last().unwrap().ident.span,
+ ),
+ hir::GenericBound::LangItemTrait(lang_item, span, _, _) => {
+ (Some(self.tcx.require_lang_item(lang_item, Some(span))), span)
+ }
hir::GenericBound::Outlives(..) => continue,
};
- let trait_ref = &trait_ref.trait_ref;
- if let Some(id) = self.lookup_def_id(trait_ref.hir_ref_id) {
- let sub_span = trait_ref.path.segments.last().unwrap().ident.span;
+ if let Some(id) = def_id {
if !self.span.filter_generated(sub_span) {
let span = self.span_from_span(sub_span);
self.dumper.dump_ref(Ref {
}
fn process_path(&mut self, id: hir::HirId, path: &hir::QPath<'tcx>) {
- let span = match path {
- hir::QPath::Resolved(_, path) => path.span,
- hir::QPath::TypeRelative(_, segment) => segment.ident.span,
- };
- if self.span.filter_generated(span) {
+ if self.span.filter_generated(path.span()) {
return;
}
self.dump_path_ref(id, path);
self.visit_ty(ty);
std::slice::from_ref(*segment)
}
+ hir::QPath::LangItem(..) => return,
};
for seg in segments {
if let Some(ref generic_args) = seg.args {
}
if let Some(id) = self.lookup_def_id(t.hir_id) {
- let sub_span = match path {
- hir::QPath::Resolved(_, path) => path.segments.last().unwrap().ident.span,
- hir::QPath::TypeRelative(_, segment) => segment.ident.span,
- };
+ let sub_span = path.last_segment_span();
let span = self.span_from_span(sub_span);
self.dumper.dump_ref(Ref {
kind: RefKind::Type,
mod span_utils;
mod sig;
-use rustc_ast::ast::{self};
+use rustc_ast as ast;
use rustc_ast::util::comments::beautify_doc_string;
use rustc_ast_pretty::pprust::attribute_to_string;
use rustc_hir as hir;
}
}
}
- hir::ExprKind::Struct(qpath, ..) => {
- let segment = match qpath {
- hir::QPath::Resolved(_, path) => path.segments.last().unwrap(),
- hir::QPath::TypeRelative(_, segment) => segment,
- };
- match ty.kind {
- ty::Adt(def, _) => {
- let sub_span = segment.ident.span;
- filter!(self.span_utils, sub_span);
- let span = self.span_from_span(sub_span);
- Some(Data::RefData(Ref {
- kind: RefKind::Type,
- span,
- ref_id: id_from_def_id(def.did),
- }))
- }
- _ => {
- debug!("expected adt, found {:?}", ty);
- None
- }
+ hir::ExprKind::Struct(qpath, ..) => match ty.kind {
+ ty::Adt(def, _) => {
+ let sub_span = qpath.last_segment_span();
+ filter!(self.span_utils, sub_span);
+ let span = self.span_from_span(sub_span);
+ Some(Data::RefData(Ref {
+ kind: RefKind::Type,
+ span,
+ ref_id: id_from_def_id(def.did),
+ }))
}
- }
+ _ => {
+ debug!("expected adt, found {:?}", ty);
+ None
+ }
+ },
hir::ExprKind::MethodCall(ref seg, ..) => {
let method_id = match self.typeck_results().type_dependent_def_id(expr.hir_id) {
Some(id) => id,
})
| Node::Ty(&hir::Ty { kind: hir::TyKind::Path(ref qpath), .. }) => match qpath {
hir::QPath::Resolved(_, path) => path.res,
- hir::QPath::TypeRelative(..) => self
+ hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self
.maybe_typeck_results
.map_or(Res::Err, |typeck_results| typeck_results.qpath_res(qpath, hir_id)),
},
let segment = match path {
hir::QPath::Resolved(_, path) => path.segments.last(),
hir::QPath::TypeRelative(_, segment) => Some(*segment),
+ hir::QPath::LangItem(..) => None,
};
segment.and_then(|seg| {
self.get_path_segment_data(seg).or_else(|| self.get_path_segment_data_with_id(seg, id))
use rls_data::{SigElement, Signature};
-use rustc_ast::ast::Mutability;
+use rustc_ast::Mutability;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir_pretty::id_to_string;
refs: vec![SigElement { id, start, end }],
})
}
+ hir::TyKind::Path(hir::QPath::LangItem(lang_item, _)) => {
+ Ok(text_sig(format!("#[lang = \"{}\"]", lang_item.name())))
+ }
hir::TyKind::TraitObject(bounds, ..) => {
// FIXME recurse into bounds
let bounds: Vec<hir::GenericBound<'_>> = bounds
//! Related to out filenames of compilation (e.g. save analysis, binaries).
use crate::config::{CrateType, Input, OutputFilenames, OutputType};
use crate::Session;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_span::symbol::sym;
use rustc_span::Span;
use std::path::{Path, PathBuf};
use crate::parse::ParseSess;
use crate::search_paths::{PathKind, SearchPath};
-pub use rustc_ast::ast::Attribute;
pub use rustc_ast::attr::MarkedAttrs;
pub use rustc_ast::crate_disambiguator::CrateDisambiguator;
+pub use rustc_ast::Attribute;
use rustc_data_structures::flock;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::jobserver::{self, Client};
}
}
/// Delay a span_bug() call until abort_if_errors()
+ #[track_caller]
pub fn delay_span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
self.diagnostic().delay_span_bug(sp, msg)
}
never_type,
never_type_fallback,
new,
+ new_unchecked,
next,
nll,
no,
quad_precision_float,
question_mark,
quote,
+ range_inclusive_new,
raw_dylib,
raw_identifiers,
raw_ref_op,
-use rustc_ast::ast::{FloatTy, IntTy, UintTy};
+use rustc_ast::{FloatTy, IntTy, UintTy};
use rustc_data_structures::base_n;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir as hir;
-use rustc_ast::ast::{MetaItem, NestedMetaItem};
+use rustc_ast::{MetaItem, NestedMetaItem};
use rustc_attr as attr;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{struct_span_err, ErrorReported};
impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::Ty<RustInterner<'tcx>> {
use chalk_ir::TyData;
- use rustc_ast::ast;
+ use rustc_ast as ast;
use TyKind::*;
let empty = || chalk_ir::Substitution::empty(interner);
match _data {
chalk_ir::GenericArgData::Ty(_t) => {
use chalk_ir::TyData;
- use rustc_ast::ast;
+ use rustc_ast as ast;
let _data = _t.data(&interner);
let kind = match _data {
use crate::collect::PlaceholderHirTyCollector;
use crate::middle::resolve_lifetime as rl;
use crate::require_c_abi_if_c_variadic;
-use rustc_ast::{ast::ParamKindOrd, util::lev_distance::find_best_match_for_name};
+use rustc_ast::{util::lev_distance::find_best_match_for_name, ParamKindOrd};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::ErrorReported;
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, FatalError};
)
}
+ pub fn instantiate_lang_item_trait_ref(
+ &self,
+ lang_item: hir::LangItem,
+ span: Span,
+ hir_id: hir::HirId,
+ args: &GenericArgs<'_>,
+ self_ty: Ty<'tcx>,
+ bounds: &mut Bounds<'tcx>,
+ ) {
+ let trait_def_id = self.tcx().require_lang_item(lang_item, Some(span));
+
+ let (substs, assoc_bindings, _) =
+ self.create_substs_for_ast_path(span, trait_def_id, &[], args, false, Some(self_ty));
+ let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs));
+ bounds.trait_bounds.push((poly_trait_ref, span, Constness::NotConst));
+
+ let mut dup_bindings = FxHashMap::default();
+ for binding in assoc_bindings {
+ let _: Result<_, ErrorReported> = self.add_predicates_for_ast_type_binding(
+ hir_id,
+ poly_trait_ref,
+ &binding,
+ bounds,
+ false,
+ &mut dup_bindings,
+ span,
+ );
+ }
+ }
+
fn ast_path_to_mono_trait_ref(
&self,
span: Span,
trait_bounds.push((b, Constness::NotConst))
}
hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => {}
+ hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => self
+ .instantiate_lang_item_trait_ref(
+ lang_item, span, hir_id, args, param_ty, bounds,
+ ),
hir::GenericBound::Outlives(ref l) => region_bounds.push(l),
}
}
.map(|(ty, _, _)| ty)
.unwrap_or_else(|_| tcx.ty_error())
}
+ hir::TyKind::Path(hir::QPath::LangItem(lang_item, span)) => {
+ let def_id = tcx.require_lang_item(lang_item, Some(span));
+ let (substs, _, _) = self.create_substs_for_ast_path(
+ span,
+ def_id,
+ &[],
+ &GenericArgs::none(),
+ true,
+ None,
+ );
+ self.normalize_ty(span, tcx.at(span).type_of(def_id).subst(tcx, substs))
+ }
hir::TyKind::Array(ref ty, ref length) => {
let length_def_id = tcx.hir().local_def_id(length.hir_id);
let length = ty::Const::from_anon_const(tcx, length_def_id);
use crate::hir::def_id::DefId;
use crate::type_error_struct;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
use rustc_hir as hir;
use rustc_hir::lang_items;
use rustc_infer::infer::{InferOk, InferResult};
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::subst::InternalSubsts;
-use rustc_middle::ty::{self, GenericParamDefKind, Ty};
+use rustc_middle::ty::{self, Ty};
use rustc_span::source_map::Span;
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits::error_reporting::ArgKind;
let generator_types =
check_fn(self, self.param_env, liberated_sig, decl, expr.hir_id, body, gen).1;
- let base_substs = InternalSubsts::identity_for_item(
+ let parent_substs = InternalSubsts::identity_for_item(
self.tcx,
self.tcx.closure_base_def_id(expr_def_id.to_def_id()),
);
- // HACK(eddyb) this hardcodes indices into substs but it should rely on
- // `ClosureSubsts` and `GeneratorSubsts` providing constructors, instead.
- // That would also remove the need for most of the inference variables,
- // as they immediately unified with the actual type below, including
- // the `InferCtxt::closure_sig` and `ClosureSubsts::sig_ty` methods.
- let tupled_upvars_idx = base_substs.len() + if generator_types.is_some() { 4 } else { 2 };
- let substs =
- base_substs.extend_to(self.tcx, expr_def_id.to_def_id(), |param, _| match param.kind {
- GenericParamDefKind::Lifetime => span_bug!(expr.span, "closure has lifetime param"),
- GenericParamDefKind::Type { .. } => if param.index as usize == tupled_upvars_idx {
- self.tcx.mk_tup(self.tcx.upvars_mentioned(expr_def_id).iter().flat_map(
- |upvars| {
- upvars.iter().map(|(&var_hir_id, _)| {
- // Create type variables (for now) to represent the transformed
- // types of upvars. These will be unified during the upvar
- // inference phase (`upvar.rs`).
- self.infcx.next_ty_var(TypeVariableOrigin {
- // FIXME(eddyb) distinguish upvar inference variables from the rest.
- kind: TypeVariableOriginKind::ClosureSynthetic,
- span: self.tcx.hir().span(var_hir_id),
- })
- })
- },
- ))
- } else {
- // Create type variables (for now) to represent the various
- // pieces of information kept in `{Closure,Generic}Substs`.
- // They will either be unified below, or later during the upvar
- // inference phase (`upvar.rs`)
+
+ let tupled_upvars_ty =
+ self.tcx.mk_tup(self.tcx.upvars_mentioned(expr_def_id).iter().flat_map(|upvars| {
+ upvars.iter().map(|(&var_hir_id, _)| {
+ // Create type variables (for now) to represent the transformed
+ // types of upvars. These will be unified during the upvar
+ // inference phase (`upvar.rs`).
self.infcx.next_ty_var(TypeVariableOrigin {
+ // FIXME(eddyb) distinguish upvar inference variables from the rest.
kind: TypeVariableOriginKind::ClosureSynthetic,
- span: expr.span,
+ span: self.tcx.hir().span(var_hir_id),
})
- }
- .into(),
- GenericParamDefKind::Const => span_bug!(expr.span, "closure has const param"),
- });
+ })
+ }));
+
if let Some(GeneratorTypes { resume_ty, yield_ty, interior, movability }) = generator_types
{
- let generator_substs = substs.as_generator();
- self.demand_eqtype(expr.span, resume_ty, generator_substs.resume_ty());
- self.demand_eqtype(expr.span, yield_ty, generator_substs.yield_ty());
- self.demand_eqtype(expr.span, liberated_sig.output(), generator_substs.return_ty());
- self.demand_eqtype(expr.span, interior, generator_substs.witness());
-
- // HACK(eddyb) this forces the types equated above into `substs` but
- // it should rely on `GeneratorSubsts` providing a constructor, instead.
- let substs = self.resolve_vars_if_possible(&substs);
+ let generator_substs = ty::GeneratorSubsts::new(
+ self.tcx,
+ ty::GeneratorSubstsParts {
+ parent_substs,
+ resume_ty,
+ yield_ty,
+ return_ty: liberated_sig.output(),
+ witness: interior,
+ tupled_upvars_ty,
+ },
+ );
- return self.tcx.mk_generator(expr_def_id.to_def_id(), substs, movability);
+ return self.tcx.mk_generator(
+ expr_def_id.to_def_id(),
+ generator_substs.substs,
+ movability,
+ );
}
// Tuple up the arguments and insert the resulting function type into
expr_def_id, sig, opt_kind
);
- let sig_fn_ptr_ty = self.tcx.mk_fn_ptr(sig);
- self.demand_eqtype(expr.span, sig_fn_ptr_ty, substs.as_closure().sig_as_fn_ptr_ty());
+ let closure_kind_ty = match opt_kind {
+ Some(kind) => kind.to_ty(self.tcx),
- if let Some(kind) = opt_kind {
- self.demand_eqtype(expr.span, kind.to_ty(self.tcx), substs.as_closure().kind_ty());
- }
+ // Create a type variable (for now) to represent the closure kind.
+ // It will be unified during the upvar inference phase (`upvar.rs`)
+ None => self.infcx.next_ty_var(TypeVariableOrigin {
+ // FIXME(eddyb) distinguish closure kind inference variables from the rest.
+ kind: TypeVariableOriginKind::ClosureSynthetic,
+ span: expr.span,
+ }),
+ };
- // HACK(eddyb) this forces the types equated above into `substs` but
- // it should rely on `ClosureSubsts` providing a constructor, instead.
- let substs = self.resolve_vars_if_possible(&substs);
+ let closure_substs = ty::ClosureSubsts::new(
+ self.tcx,
+ ty::ClosureSubstsParts {
+ parent_substs,
+ closure_kind_ty,
+ closure_sig_as_fn_ptr_ty: self.tcx.mk_fn_ptr(sig),
+ tupled_upvars_ty,
+ },
+ );
- let closure_type = self.tcx.mk_closure(expr_def_id.to_def_id(), substs);
+ let closure_type = self.tcx.mk_closure(expr_def_id.to_def_id(), closure_substs.substs);
debug!("check_closure: expr.hir_id={:?} closure_type={:?}", expr.hir_id, closure_type);
self.suggest_missing_await(err, expr, expected, expr_ty);
self.suggest_missing_parentheses(err, expr);
self.note_need_for_fn_pointer(err, expected, expr_ty);
+ self.note_internal_mutation_in_method(err, expr, expected, expr_ty);
}
// Requires that the two types unify, and prints an error message if
// parenthesize if needed (Issue #46756)
hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
// parenthesize borrows of range literals (Issue #54505)
- _ if is_range_literal(self.tcx.sess.source_map(), expr) => true,
+ _ if is_range_literal(expr) => true,
_ => false,
};
let sugg_expr = if needs_parens { format!("({})", src) } else { src };
use crate::check::TupleArgumentsFlag::DontTupleArguments;
use crate::type_error_struct;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::util::lev_distance::find_best_match_for_name;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
ExprKind::AddrOf(kind, mutbl, ref oprnd) => {
self.check_expr_addr_of(kind, mutbl, oprnd, expected, expr)
}
+ ExprKind::Path(QPath::LangItem(lang_item, _)) => {
+ self.check_lang_item_path(lang_item, expr)
+ }
ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr),
ExprKind::InlineAsm(asm) => self.check_expr_asm(asm),
ExprKind::LlvmInlineAsm(ref asm) => {
}
}
+ fn check_lang_item_path(
+ &self,
+ lang_item: hir::LangItem,
+ expr: &'tcx hir::Expr<'tcx>,
+ ) -> Ty<'tcx> {
+ self.resolve_lang_item_path(lang_item, expr.span, expr.hir_id).1
+ }
+
fn check_expr_path(&self, qpath: &hir::QPath<'_>, expr: &'tcx hir::Expr<'tcx>) -> Ty<'tcx> {
let tcx = self.tcx;
let (res, opt_ty, segs) = self.resolve_ty_and_res_ufcs(qpath, expr.hir_id, expr.span);
return self.tcx.ty_error();
};
- let path_span = match *qpath {
- QPath::Resolved(_, ref path) => path.span,
- QPath::TypeRelative(ref qself, _) => qself.span,
- };
-
// Prohibit struct expressions when non-exhaustive flag is set.
let adt = adt_ty.ty_adt_def().expect("`check_struct_path` returned non-ADT type");
if !adt.did.is_local() && variant.is_field_list_non_exhaustive() {
adt_ty,
expected,
expr.hir_id,
- path_span,
+ qpath.span(),
variant,
fields,
base_expr.is_none(),
use crate::hir::def::DefKind;
use crate::hir::def_id::DefId;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::util::lev_distance::{find_best_match_for_name, lev_distance};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sync::Lrc;
use crate::astconv::{
AstConv, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, PathSeg,
};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::util::parser::ExprPrecedence;
use rustc_attr as attr;
use rustc_data_structures::captures::Captures;
use rustc_middle::ty::subst::{self, InternalSubsts, Subst, SubstsRef};
use rustc_middle::ty::subst::{GenericArgKind, UserSelfTy, UserSubsts};
use rustc_middle::ty::util::{Discr, IntTypeExt, Representability};
-use rustc_middle::ty::{
- self, AdtKind, CanonicalUserType, Const, GenericParamDefKind, RegionKind, ToPolyTraitRef,
- ToPredicate, Ty, TyCtxt, UserType, WithConstness,
-};
+use rustc_middle::ty::WithConstness;
+use rustc_middle::ty::{self, AdtKind, CanonicalUserType, Const, DefIdTree, GenericParamDefKind};
+use rustc_middle::ty::{RegionKind, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, UserType};
use rustc_session::config::{self, EntryFnType};
use rustc_session::lint;
use rustc_session::parse::feature_err;
qpath: &QPath<'_>,
hir_id: hir::HirId,
) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
- let path_span = match *qpath {
- QPath::Resolved(_, ref path) => path.span,
- QPath::TypeRelative(ref qself, _) => qself.span,
- };
+ let path_span = qpath.qself_span();
let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
let variant = match def {
Res::Err => {
(result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
}
+ QPath::LangItem(lang_item, span) => {
+ self.resolve_lang_item_path(lang_item, span, hir_id)
+ }
}
}
+ fn resolve_lang_item_path(
+ &self,
+ lang_item: hir::LangItem,
+ span: Span,
+ hir_id: hir::HirId,
+ ) -> (Res, Ty<'tcx>) {
+ let def_id = self.tcx.require_lang_item(lang_item, Some(span));
+ let def_kind = self.tcx.def_kind(def_id);
+
+ let item_ty = if let DefKind::Variant = def_kind {
+ self.tcx.type_of(self.tcx.parent(def_id).expect("variant w/out parent"))
+ } else {
+ self.tcx.type_of(def_id)
+ };
+ let substs = self.infcx.fresh_substs_for_item(span, def_id);
+ let ty = item_ty.subst(self.tcx, substs);
+
+ self.write_resolution(hir_id, Ok((def_kind, def_id)));
+ self.add_required_obligations(span, def_id, &substs);
+ (Res::Def(def_kind, def_id), ty)
+ }
+
/// Resolves an associated value path into a base type and associated constant, or method
/// resolution. The newly resolved definition is written into `type_dependent_defs`.
pub fn resolve_ty_and_res_ufcs<'b>(
);
}
QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
+ QPath::LangItem(..) => bug!("`resolve_ty_and_res_ufcs` called on `LangItem`"),
};
if let Some(&cached_result) = self.typeck_results.borrow().type_dependent_defs().get(hir_id)
{
}
}
+ fn note_internal_mutation_in_method(
+ &self,
+ err: &mut DiagnosticBuilder<'_>,
+ expr: &hir::Expr<'_>,
+ expected: Ty<'tcx>,
+ found: Ty<'tcx>,
+ ) {
+ if found != self.tcx.types.unit {
+ return;
+ }
+ if let ExprKind::MethodCall(path_segment, _, [rcvr, ..], _) = expr.kind {
+ if self
+ .typeck_results
+ .borrow()
+ .expr_ty_adjusted_opt(rcvr)
+ .map_or(true, |ty| expected.peel_refs() != ty.peel_refs())
+ {
+ return;
+ }
+ let mut sp = MultiSpan::from_span(path_segment.ident.span);
+ sp.push_span_label(
+ path_segment.ident.span,
+ format!(
+ "this call modifies {} in-place",
+ match rcvr.kind {
+ ExprKind::Path(QPath::Resolved(
+ None,
+ hir::Path { segments: [segment], .. },
+ )) => format!("`{}`", segment.ident),
+ _ => "its receiver".to_string(),
+ }
+ ),
+ );
+ sp.push_span_label(
+ rcvr.span,
+ "you probably want to use this value after calling the method...".to_string(),
+ );
+ err.span_note(
+ sp,
+ &format!("method `{}` modifies its receiver in-place", path_segment.ident),
+ );
+ err.note(&format!("...instead of the `()` output of method `{}`", path_segment.ident));
+ }
+ }
+
/// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
fn suggest_calling_boxed_future_when_appropriate(
&self,
use crate::check::FnCtxt;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_ast::util::lev_distance::find_best_match_for_name;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
// |
// L | let A(()) = A(());
// | ^ ^
- [] => {
- let qpath_span = match qpath {
- hir::QPath::Resolved(_, path) => path.span,
- hir::QPath::TypeRelative(_, ps) => ps.ident.span,
- };
- (qpath_span.shrink_to_hi(), pat_span)
- }
+ [] => (qpath.span().shrink_to_hi(), pat_span),
// Easy case. Just take the "lo" of the first sub-pattern and the "hi" of the
// last sub-pattern. In the case of `A(x)` the first and last may coincide.
// This looks like:
use crate::check::{FnCtxt, Inherited};
use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_middle::ty::{self, CrateInherentImpls, TyCtxt};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_span::Span;
/// On-demand query: yields a map containing all types mapped to their inherent impls.
use crate::check::intrinsic::intrinsic_operation_unsafety;
use crate::constrained_generic_params as cgp;
use crate::middle::resolve_lifetime as rl;
-use rustc_ast::ast;
-use rustc_ast::ast::MetaItemKind;
+use rustc_ast as ast;
+use rustc_ast::MetaItemKind;
use rustc_attr::{list_contains_name, InlineAttr, OptimizeAttr};
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
predicates.extend(bounds.predicates(tcx, ty));
}
+ &hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => {
+ let mut bounds = Bounds::default();
+ AstConv::instantiate_lang_item_trait_ref(
+ &icx,
+ lang_item,
+ span,
+ hir_id,
+ args,
+ ty,
+ &mut bounds,
+ );
+ predicates.extend(bounds.predicates(tcx, ty));
+ }
+
&hir::GenericBound::Outlives(ref lifetime) => {
let region = AstConv::ast_region_to_region(&icx, lifetime, None);
predicates.push((
let _ = astconv.instantiate_poly_trait_ref(tr, constness, param_ty, &mut bounds);
bounds.predicates(astconv.tcx(), param_ty)
}
+ hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => {
+ let mut bounds = Bounds::default();
+ astconv.instantiate_lang_item_trait_ref(
+ lang_item,
+ span,
+ hir_id,
+ args,
+ param_ty,
+ &mut bounds,
+ );
+ bounds.predicates(astconv.tcx(), param_ty)
+ }
hir::GenericBound::Outlives(ref lifetime) => {
let region = astconv.ast_region_to_region(lifetime, None);
let pred = ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(param_ty, region))
}
fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<usize> {
- use rustc_ast::ast::{Lit, LitIntType, LitKind};
+ use rustc_ast::{Lit, LitIntType, LitKind};
let meta_item_list = attr.meta_item_list();
let meta_item_list: Option<&[ast::NestedMetaItem]> = meta_item_list.as_ref().map(Vec::as_ref);
let sole_meta_list = match meta_item_list {
use std::mem;
use std::ops;
-use rustc_ast::ast::{LitKind, MetaItem, MetaItemKind, NestedMetaItem};
+use rustc_ast::{LitKind, MetaItem, MetaItemKind, NestedMetaItem};
use rustc_feature::Features;
use rustc_session::parse::ParseSess;
use rustc_span::symbol::{sym, Symbol};
use super::*;
-use rustc_ast::ast::*;
use rustc_ast::attr;
+use rustc_ast::Path;
use rustc_span::symbol::{Ident, Symbol};
use rustc_span::with_default_session_globals;
use rustc_span::DUMMY_SP;
use std::iter::once;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
pub mod types;
pub mod utils;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_attr as attr;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
use rustc_index::vec::{Idx, IndexVec};
use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
+use rustc_middle::bug;
use rustc_middle::middle::resolve_lifetime as rl;
use rustc_middle::middle::stability;
use rustc_middle::ty::fold::TypeFolder;
fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
match *self {
hir::GenericBound::Outlives(lt) => GenericBound::Outlives(lt.clean(cx)),
+ hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => {
+ let def_id = cx.tcx.require_lang_item(lang_item, Some(span));
+
+ let trait_ref = ty::TraitRef::identity(cx.tcx, def_id);
+
+ let generic_args = generic_args.clean(cx);
+ let bindings = match generic_args {
+ GenericArgs::AngleBracketed { bindings, .. } => bindings,
+ _ => bug!("clean: parenthesized `GenericBound::LangItemTrait`"),
+ };
+
+ GenericBound::TraitBound(
+ PolyTrait { trait_: (trait_ref, &*bindings).clean(cx), generic_params: vec![] },
+ hir::TraitBoundModifier::None,
+ )
+ }
hir::GenericBound::Trait(ref t, modifier) => {
GenericBound::TraitBound(t.clean(cx), modifier)
}
trait_: box resolve_type(cx, trait_path.clean(cx), self.hir_id),
}
}
+ TyKind::Path(hir::QPath::LangItem(..)) => {
+ bug!("clean: requiring documentation of lang item")
+ }
TyKind::TraitObject(ref bounds, ref lifetime) => {
match bounds[0].clean(cx).trait_ {
ResolvedPath { path, param_names: None, did, is_generic } => {
use std::sync::Arc;
use std::{slice, vec};
-use rustc_ast::ast::{self, AttrStyle};
use rustc_ast::attr;
use rustc_ast::util::comments::beautify_doc_string;
+use rustc_ast::{self as ast, AttrStyle};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir as hir;
use rustc_hir::def::Res;
impl Attributes {
/// Extracts the content from an attribute `#[doc(cfg(content))]`.
pub fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> {
- use rustc_ast::ast::NestedMetaItem::MetaItem;
+ use rustc_ast::NestedMetaItem::MetaItem;
if let ast::MetaItemKind::List(ref nmis) = mi.kind {
if nmis.len() == 1 {
let segments = match *p {
hir::QPath::Resolved(_, ref path) => &path.segments,
hir::QPath::TypeRelative(_, ref segment) => return segment.ident.to_string(),
+ hir::QPath::LangItem(lang_item, ..) => return lang_item.name().to_string(),
};
let mut s = String::new();
//! manner (and with prettier names) before cleaning.
pub use self::StructType::*;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_span::hygiene::MacroKind;
use rustc_span::{self, Span, Symbol};
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_expand::base::SyntaxExtensionKind;
use rustc_feature::UnstableFeatures;
}
const PRIMITIVES: &[(&str, Res)] = &[
- ("u8", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::ast::UintTy::U8))),
- ("u16", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::ast::UintTy::U16))),
- ("u32", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::ast::UintTy::U32))),
- ("u64", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::ast::UintTy::U64))),
- ("u128", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::ast::UintTy::U128))),
- ("usize", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::ast::UintTy::Usize))),
- ("i8", Res::PrimTy(hir::PrimTy::Int(rustc_ast::ast::IntTy::I8))),
- ("i16", Res::PrimTy(hir::PrimTy::Int(rustc_ast::ast::IntTy::I16))),
- ("i32", Res::PrimTy(hir::PrimTy::Int(rustc_ast::ast::IntTy::I32))),
- ("i64", Res::PrimTy(hir::PrimTy::Int(rustc_ast::ast::IntTy::I64))),
- ("i128", Res::PrimTy(hir::PrimTy::Int(rustc_ast::ast::IntTy::I128))),
- ("isize", Res::PrimTy(hir::PrimTy::Int(rustc_ast::ast::IntTy::Isize))),
- ("f32", Res::PrimTy(hir::PrimTy::Float(rustc_ast::ast::FloatTy::F32))),
- ("f64", Res::PrimTy(hir::PrimTy::Float(rustc_ast::ast::FloatTy::F64))),
+ ("u8", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U8))),
+ ("u16", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U16))),
+ ("u32", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U32))),
+ ("u64", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U64))),
+ ("u128", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U128))),
+ ("usize", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::Usize))),
+ ("i8", Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I8))),
+ ("i16", Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I16))),
+ ("i32", Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I32))),
+ ("i64", Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I64))),
+ ("i128", Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I128))),
+ ("isize", Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::Isize))),
+ ("f32", Res::PrimTy(hir::PrimTy::Float(rustc_ast::FloatTy::F32))),
+ ("f64", Res::PrimTy(hir::PrimTy::Float(rustc_ast::FloatTy::F64))),
("str", Res::PrimTy(hir::PrimTy::Str)),
("bool", Res::PrimTy(hir::PrimTy::Bool)),
("char", Res::PrimTy(hir::PrimTy::Char)),
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_data_structures::sync::Lrc;
use rustc_errors::ErrorReported;
use rustc_feature::UnstableFeatures;
//! The Rust AST Visitor. Extracts useful information and massages it into a form
//! usable for `clean`.
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
};
}
+macro_rules! check_reg {
+ ($func:ident $ty:ident $reg:tt $mov:literal) => {
+ #[no_mangle]
+ pub unsafe fn $func(x: $ty) -> $ty {
+ // Hack to avoid function merging
+ extern "Rust" {
+ fn dont_merge(s: &str);
+ }
+ dont_merge(stringify!($func));
+
+ let y;
+ asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
+ y
+ }
+ };
+}
+
// CHECK-LABEL: reg_i8:
// CHECK: //APP
// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_f64x2 f64x2 vreg_low16 "fmov" "s");
+
+// CHECK-LABEL: x0_i8:
+// CHECK: //APP
+// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
+// CHECK: //NO_APP
+check_reg!(x0_i8 i8 "x0" "mov");
+
+// CHECK-LABEL: x0_i16:
+// CHECK: //APP
+// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
+// CHECK: //NO_APP
+check_reg!(x0_i16 i16 "x0" "mov");
+
+// CHECK-LABEL: x0_i32:
+// CHECK: //APP
+// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
+// CHECK: //NO_APP
+check_reg!(x0_i32 i32 "x0" "mov");
+
+// CHECK-LABEL: x0_f32:
+// CHECK: //APP
+// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
+// CHECK: //NO_APP
+check_reg!(x0_f32 f32 "x0" "mov");
+
+// CHECK-LABEL: x0_i64:
+// CHECK: //APP
+// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
+// CHECK: //NO_APP
+check_reg!(x0_i64 i64 "x0" "mov");
+
+// CHECK-LABEL: x0_f64:
+// CHECK: //APP
+// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
+// CHECK: //NO_APP
+check_reg!(x0_f64 f64 "x0" "mov");
+
+// CHECK-LABEL: x0_ptr:
+// CHECK: //APP
+// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
+// CHECK: //NO_APP
+check_reg!(x0_ptr ptr "x0" "mov");
+
+// CHECK-LABEL: v0_i8:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_i8 i8 "s0" "fmov");
+
+// CHECK-LABEL: v0_i16:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_i16 i16 "s0" "fmov");
+
+// CHECK-LABEL: v0_i32:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_i32 i32 "s0" "fmov");
+
+// CHECK-LABEL: v0_f32:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_f32 f32 "s0" "fmov");
+
+// CHECK-LABEL: v0_i64:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_i64 i64 "s0" "fmov");
+
+// CHECK-LABEL: v0_f64:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_f64 f64 "s0" "fmov");
+
+// CHECK-LABEL: v0_ptr:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_ptr ptr "s0" "fmov");
+
+// CHECK-LABEL: v0_i8x8:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_i8x8 i8x8 "s0" "fmov");
+
+// CHECK-LABEL: v0_i16x4:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_i16x4 i16x4 "s0" "fmov");
+
+// CHECK-LABEL: v0_i32x2:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_i32x2 i32x2 "s0" "fmov");
+
+// CHECK-LABEL: v0_i64x1:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_i64x1 i64x1 "s0" "fmov");
+
+// CHECK-LABEL: v0_f32x2:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_f32x2 f32x2 "s0" "fmov");
+
+// CHECK-LABEL: v0_f64x1:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_f64x1 f64x1 "s0" "fmov");
+
+// CHECK-LABEL: v0_i8x16:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_i8x16 i8x16 "s0" "fmov");
+
+// CHECK-LABEL: v0_i16x8:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_i16x8 i16x8 "s0" "fmov");
+
+// CHECK-LABEL: v0_i32x4:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_i32x4 i32x4 "s0" "fmov");
+
+// CHECK-LABEL: v0_i64x2:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_i64x2 i64x2 "s0" "fmov");
+
+// CHECK-LABEL: v0_f32x4:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_f32x4 f32x4 "s0" "fmov");
+
+// CHECK-LABEL: v0_f64x2:
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_f64x2 f64x2 "s0" "fmov");
};
}
+macro_rules! check_reg {
+ ($func:ident $ty:ident $reg:tt $mov:literal) => {
+ #[no_mangle]
+ pub unsafe fn $func(x: $ty) -> $ty {
+ // Hack to avoid function merging
+ extern "Rust" {
+ fn dont_merge(s: &str);
+ }
+ dont_merge(stringify!($func));
+
+ let y;
+ asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
+ y
+ }
+ };
+}
+
// CHECK-LABEL: reg_i8:
// CHECK: @APP
// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}}
// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
// CHECK: @NO_APP
check!(qreg_low4_f32x4 f32x4 qreg_low4 "vmov");
+
+// CHECK-LABEL: r0_i8:
+// CHECK: @APP
+// CHECK: mov r0, r0
+// CHECK: @NO_APP
+check_reg!(r0_i8 i8 "r0" "mov");
+
+// CHECK-LABEL: r0_i16:
+// CHECK: @APP
+// CHECK: mov r0, r0
+// CHECK: @NO_APP
+check_reg!(r0_i16 i16 "r0" "mov");
+
+// CHECK-LABEL: r0_i32:
+// CHECK: @APP
+// CHECK: mov r0, r0
+// CHECK: @NO_APP
+check_reg!(r0_i32 i32 "r0" "mov");
+
+// CHECK-LABEL: r0_f32:
+// CHECK: @APP
+// CHECK: mov r0, r0
+// CHECK: @NO_APP
+check_reg!(r0_f32 f32 "r0" "mov");
+
+// CHECK-LABEL: r0_ptr:
+// CHECK: @APP
+// CHECK: mov r0, r0
+// CHECK: @NO_APP
+check_reg!(r0_ptr ptr "r0" "mov");
+
+// CHECK-LABEL: s0_i32:
+// CHECK: @APP
+// CHECK: vmov.f32 s0, s0
+// CHECK: @NO_APP
+check_reg!(s0_i32 i32 "s0" "vmov.f32");
+
+// CHECK-LABEL: s0_f32:
+// CHECK: @APP
+// CHECK: vmov.f32 s0, s0
+// CHECK: @NO_APP
+check_reg!(s0_f32 f32 "s0" "vmov.f32");
+
+// CHECK-LABEL: s0_ptr:
+// CHECK: @APP
+// CHECK: vmov.f32 s0, s0
+// CHECK: @NO_APP
+check_reg!(s0_ptr ptr "s0" "vmov.f32");
+
+// CHECK-LABEL: d0_i64:
+// CHECK: @APP
+// CHECK: vmov.f64 d0, d0
+// CHECK: @NO_APP
+check_reg!(d0_i64 i64 "d0" "vmov.f64");
+
+// CHECK-LABEL: d0_f64:
+// CHECK: @APP
+// CHECK: vmov.f64 d0, d0
+// CHECK: @NO_APP
+check_reg!(d0_f64 f64 "d0" "vmov.f64");
+
+// CHECK-LABEL: d0_i8x8:
+// CHECK: @APP
+// CHECK: vmov.f64 d0, d0
+// CHECK: @NO_APP
+check_reg!(d0_i8x8 i8x8 "d0" "vmov.f64");
+
+// CHECK-LABEL: d0_i16x4:
+// CHECK: @APP
+// CHECK: vmov.f64 d0, d0
+// CHECK: @NO_APP
+check_reg!(d0_i16x4 i16x4 "d0" "vmov.f64");
+
+// CHECK-LABEL: d0_i32x2:
+// CHECK: @APP
+// CHECK: vmov.f64 d0, d0
+// CHECK: @NO_APP
+check_reg!(d0_i32x2 i32x2 "d0" "vmov.f64");
+
+// CHECK-LABEL: d0_i64x1:
+// CHECK: @APP
+// CHECK: vmov.f64 d0, d0
+// CHECK: @NO_APP
+check_reg!(d0_i64x1 i64x1 "d0" "vmov.f64");
+
+// CHECK-LABEL: d0_f32x2:
+// CHECK: @APP
+// CHECK: vmov.f64 d0, d0
+// CHECK: @NO_APP
+check_reg!(d0_f32x2 f32x2 "d0" "vmov.f64");
+
+// CHECK-LABEL: q0_i8x16:
+// CHECK: @APP
+// CHECK: vorr q0, q0, q0
+// CHECK: @NO_APP
+check_reg!(q0_i8x16 i8x16 "q0" "vmov");
+
+// CHECK-LABEL: q0_i16x8:
+// CHECK: @APP
+// CHECK: vorr q0, q0, q0
+// CHECK: @NO_APP
+check_reg!(q0_i16x8 i16x8 "q0" "vmov");
+
+// CHECK-LABEL: q0_i32x4:
+// CHECK: @APP
+// CHECK: vorr q0, q0, q0
+// CHECK: @NO_APP
+check_reg!(q0_i32x4 i32x4 "q0" "vmov");
+
+// CHECK-LABEL: q0_i64x2:
+// CHECK: @APP
+// CHECK: vorr q0, q0, q0
+// CHECK: @NO_APP
+check_reg!(q0_i64x2 i64x2 "q0" "vmov");
+
+// CHECK-LABEL: q0_f32x4:
+// CHECK: @APP
+// CHECK: vorr q0, q0, q0
+// CHECK: @NO_APP
+check_reg!(q0_f32x4 f32x4 "q0" "vmov");
() => {};
}
#[rustc_builtin_macro]
+macro_rules! concat {
+ () => {};
+}
+#[rustc_builtin_macro]
macro_rules! stringify {
() => {};
}
};
}
+macro_rules! check_reg {
+ ($func:ident $ty:ident $reg:tt) => {
+ #[no_mangle]
+ pub unsafe fn $func(x: $ty) -> $ty {
+ // Hack to avoid function merging
+ extern "Rust" {
+ fn dont_merge(s: &str);
+ }
+ dont_merge(stringify!($func));
+
+ let y;
+ asm!(concat!($reg, " = ", $reg), lateout($reg) y, in($reg) x);
+ y
+ }
+ };
+}
+
// CHECK-LABEL: sym_static:
// CHECK: InlineAsm Start
// CHECK: r0 = #extern_static
}}", out(reg) _, in(reg) &val);
}
-// CHECK-LABEL: ptr:
+// CHECK-LABEL: reg_ptr:
// CHECK: InlineAsm Start
// CHECK: r{{[0-9]+}} = r{{[0-9]+}}
// CHECK: InlineAsm End
// CHECK: r{{[0-9]+}} = r{{[0-9]+}}
// CHECK: InlineAsm End
check!(reg_i16 i16 reg);
+
+// CHECK-LABEL: r0_ptr:
+// CHECK: InlineAsm Start
+// CHECK: r0 = r0
+// CHECK: InlineAsm End
+check_reg!(r0_ptr ptr "r0");
+
+// CHECK-LABEL: r0_f32:
+// CHECK: InlineAsm Start
+// CHECK: r0 = r0
+// CHECK: InlineAsm End
+check_reg!(r0_f32 f32 "r0");
+
+// CHECK-LABEL: r0_i32:
+// CHECK: InlineAsm Start
+// CHECK: r0 = r0
+// CHECK: InlineAsm End
+check_reg!(r0_i32 i32 "r0");
+
+// CHECK-LABEL: r0_i8:
+// CHECK: InlineAsm Start
+// CHECK: r0 = r0
+// CHECK: InlineAsm End
+check_reg!(r0_i8 i8 "r0");
+
+// CHECK-LABEL: r0_i16:
+// CHECK: InlineAsm Start
+// CHECK: r0 = r0
+// CHECK: InlineAsm End
+check_reg!(r0_i16 i16 "r0");
+++ /dev/null
-// no-system-llvm
-// assembly-output: emit-asm
-// compile-flags: -O
-// compile-flags: --target riscv64gc-unknown-linux-gnu
-// compile-flags: -C target-feature=+f
-// needs-llvm-components: riscv
-
-#![feature(no_core, lang_items, rustc_attrs)]
-#![crate_type = "rlib"]
-#![no_core]
-
-#[rustc_builtin_macro]
-macro_rules! asm {
- () => {};
-}
-#[rustc_builtin_macro]
-macro_rules! concat {
- () => {};
-}
-#[rustc_builtin_macro]
-macro_rules! stringify {
- () => {};
-}
-
-#[lang = "sized"]
-trait Sized {}
-#[lang = "copy"]
-trait Copy {}
-
-impl Copy for f32 {}
-
-macro_rules! check {
- ($func:ident $modifier:literal $reg:ident $mov:literal) => {
- // -O and extern "C" guarantee that the selected register is always r0/s0/d0/q0
- #[no_mangle]
- pub unsafe extern "C" fn $func() -> f32 {
- // Hack to avoid function merging
- extern "Rust" {
- fn dont_merge(s: &str);
- }
- dont_merge(stringify!($func));
-
- let y;
- asm!(concat!($mov, " {0:", $modifier, "}, {0:", $modifier, "}"), out($reg) y);
- y
- }
- };
-}
-
-// CHECK-LABEL: reg:
-// CHECK: #APP
-// CHECK: mv a0, a0
-// CHECK: #NO_APP
-check!(reg "" reg "mv");
-
-// CHECK-LABEL: freg:
-// CHECK: #APP
-// CHECK: fmv.s fa0, fa0
-// CHECK: #NO_APP
-check!(freg "" freg "fmv.s");
};
}
+macro_rules! check_reg {
+ ($func:ident $ty:ident $reg:tt $mov:literal) => {
+ #[no_mangle]
+ pub unsafe fn $func(x: $ty) -> $ty {
+ // Hack to avoid function merging
+ extern "Rust" {
+ fn dont_merge(s: &str);
+ }
+ dont_merge(stringify!($func));
+
+ let y;
+ asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
+ y
+ }
+ };
+}
+
// CHECK-LABEL: reg_i8:
// CHECK: #APP
// CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
// CHECK: fmv.d f{{[a-z0-9]+}}, f{{[a-z0-9]+}}
// CHECK: #NO_APP
check!(freg_f64 f64 freg "fmv.d");
+
+// CHECK-LABEL: a0_i8:
+// CHECK: #APP
+// CHECK: mv a0, a0
+// CHECK: #NO_APP
+check_reg!(a0_i8 i8 "a0" "mv");
+
+// CHECK-LABEL: a0_i16:
+// CHECK: #APP
+// CHECK: mv a0, a0
+// CHECK: #NO_APP
+check_reg!(a0_i16 i16 "a0" "mv");
+
+// CHECK-LABEL: a0_i32:
+// CHECK: #APP
+// CHECK: mv a0, a0
+// CHECK: #NO_APP
+check_reg!(a0_i32 i32 "a0" "mv");
+
+// CHECK-LABEL: a0_f32:
+// CHECK: #APP
+// CHECK: mv a0, a0
+// CHECK: #NO_APP
+check_reg!(a0_f32 f32 "a0" "mv");
+
+// riscv64-LABEL: a0_i64:
+// riscv64: #APP
+// riscv64: mv a0, a0
+// riscv64: #NO_APP
+#[cfg(riscv64)]
+check_reg!(a0_i64 i64 "a0" "mv");
+
+// riscv64-LABEL: a0_f64:
+// riscv64: #APP
+// riscv64: mv a0, a0
+// riscv64: #NO_APP
+#[cfg(riscv64)]
+check_reg!(a0_f64 f64 "a0" "mv");
+
+// CHECK-LABEL: a0_ptr:
+// CHECK: #APP
+// CHECK: mv a0, a0
+// CHECK: #NO_APP
+check_reg!(a0_ptr ptr "a0" "mv");
+
+// CHECK-LABEL: fa0_f32:
+// CHECK: #APP
+// CHECK: fmv.s fa0, fa0
+// CHECK: #NO_APP
+check_reg!(fa0_f32 f32 "fa0" "fmv.s");
+
+// CHECK-LABEL: fa0_f64:
+// CHECK: #APP
+// CHECK: fmv.d fa0, fa0
+// CHECK: #NO_APP
+check_reg!(fa0_f64 f64 "fa0" "fmv.d");
dont_merge(stringify!($func));
let y;
- asm!(concat!($mov, " {}, {}"), out($class) y, in($class) x);
+ asm!(concat!($mov, " {}, {}"), lateout($class) y, in($class) x);
+ y
+ }
+ };
+}
+
+macro_rules! check_reg {
+ ($func:ident $ty:ident $reg:tt $mov:literal) => {
+ #[no_mangle]
+ pub unsafe fn $func(x: $ty) -> $ty {
+ // Hack to avoid function merging
+ extern "Rust" {
+ fn dont_merge(s: &str);
+ }
+ dont_merge(stringify!($func));
+
+ let y;
+ asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
y
}
};
// CHECK: kmovq k{{[0-9]+}}, k{{[0-9]+}}
// CHECK: #NO_APP
check!(kreg_ptr ptr kreg "kmovq");
+
+// CHECK-LABEL: eax_i16:
+// CHECK: #APP
+// CHECK: mov eax, eax
+// CHECK: #NO_APP
+check_reg!(eax_i16 i16 "eax" "mov");
+
+// CHECK-LABEL: eax_i32:
+// CHECK: #APP
+// CHECK: mov eax, eax
+// CHECK: #NO_APP
+check_reg!(eax_i32 i32 "eax" "mov");
+
+// CHECK-LABEL: eax_f32:
+// CHECK: #APP
+// CHECK: mov eax, eax
+// CHECK: #NO_APP
+check_reg!(eax_f32 f32 "eax" "mov");
+
+// x86_64-LABEL: eax_i64:
+// x86_64: #APP
+// x86_64: mov eax, eax
+// x86_64: #NO_APP
+#[cfg(x86_64)]
+check_reg!(eax_i64 i64 "eax" "mov");
+
+// x86_64-LABEL: eax_f64:
+// x86_64: #APP
+// x86_64: mov eax, eax
+// x86_64: #NO_APP
+#[cfg(x86_64)]
+check_reg!(eax_f64 f64 "eax" "mov");
+
+// CHECK-LABEL: eax_ptr:
+// CHECK: #APP
+// CHECK: mov eax, eax
+// CHECK: #NO_APP
+check_reg!(eax_ptr ptr "eax" "mov");
+
+// CHECK-LABEL: ah_byte:
+// CHECK: #APP
+// CHECK: mov ah, ah
+// CHECK: #NO_APP
+check_reg!(ah_byte i8 "ah" "mov");
+
+// CHECK-LABEL: xmm0_i32:
+// CHECK: #APP
+// CHECK: movaps xmm0, xmm0
+// CHECK: #NO_APP
+check_reg!(xmm0_i32 i32 "xmm0" "movaps");
+
+// CHECK-LABEL: xmm0_f32:
+// CHECK: #APP
+// CHECK: movaps xmm0, xmm0
+// CHECK: #NO_APP
+check_reg!(xmm0_f32 f32 "xmm0" "movaps");
+
+// CHECK-LABEL: xmm0_i64:
+// CHECK: #APP
+// CHECK: movaps xmm0, xmm0
+// CHECK: #NO_APP
+check_reg!(xmm0_i64 i64 "xmm0" "movaps");
+
+// CHECK-LABEL: xmm0_f64:
+// CHECK: #APP
+// CHECK: movaps xmm0, xmm0
+// CHECK: #NO_APP
+check_reg!(xmm0_f64 f64 "xmm0" "movaps");
+
+// CHECK-LABEL: xmm0_ptr:
+// CHECK: #APP
+// CHECK: movaps xmm0, xmm0
+// CHECK: #NO_APP
+check_reg!(xmm0_ptr ptr "xmm0" "movaps");
+
+// CHECK-LABEL: xmm0_i8x16:
+// CHECK: #APP
+// CHECK: movaps xmm0, xmm0
+// CHECK: #NO_APP
+check_reg!(xmm0_i8x16 i8x16 "xmm0" "movaps");
+
+// CHECK-LABEL: xmm0_i16x8:
+// CHECK: #APP
+// CHECK: movaps xmm0, xmm0
+// CHECK: #NO_APP
+check_reg!(xmm0_i16x8 i16x8 "xmm0" "movaps");
+
+// CHECK-LABEL: xmm0_i32x4:
+// CHECK: #APP
+// CHECK: movaps xmm0, xmm0
+// CHECK: #NO_APP
+check_reg!(xmm0_i32x4 i32x4 "xmm0" "movaps");
+
+// CHECK-LABEL: xmm0_i64x2:
+// CHECK: #APP
+// CHECK: movaps xmm0, xmm0
+// CHECK: #NO_APP
+check_reg!(xmm0_i64x2 i64x2 "xmm0" "movaps");
+
+// CHECK-LABEL: xmm0_f32x4:
+// CHECK: #APP
+// CHECK: movaps xmm0, xmm0
+// CHECK: #NO_APP
+check_reg!(xmm0_f32x4 f32x4 "xmm0" "movaps");
+
+// CHECK-LABEL: xmm0_f64x2:
+// CHECK: #APP
+// CHECK: movaps xmm0, xmm0
+// CHECK: #NO_APP
+check_reg!(xmm0_f64x2 f64x2 "xmm0" "movaps");
+
+// CHECK-LABEL: ymm0_i32:
+// CHECK: #APP
+// CHECK: vmovaps ymm0, ymm0
+// CHECK: #NO_APP
+check_reg!(ymm0_i32 i32 "ymm0" "vmovaps");
+
+// CHECK-LABEL: ymm0_f32:
+// CHECK: #APP
+// CHECK: vmovaps ymm0, ymm0
+// CHECK: #NO_APP
+check_reg!(ymm0_f32 f32 "ymm0" "vmovaps");
+
+// CHECK-LABEL: ymm0_i64:
+// CHECK: #APP
+// CHECK: vmovaps ymm0, ymm0
+// CHECK: #NO_APP
+check_reg!(ymm0_i64 i64 "ymm0" "vmovaps");
+
+// CHECK-LABEL: ymm0_f64:
+// CHECK: #APP
+// CHECK: vmovaps ymm0, ymm0
+// CHECK: #NO_APP
+check_reg!(ymm0_f64 f64 "ymm0" "vmovaps");
+
+// CHECK-LABEL: ymm0_ptr:
+// CHECK: #APP
+// CHECK: vmovaps ymm0, ymm0
+// CHECK: #NO_APP
+check_reg!(ymm0_ptr ptr "ymm0" "vmovaps");
+
+// CHECK-LABEL: ymm0_i8x16:
+// CHECK: #APP
+// CHECK: vmovaps ymm0, ymm0
+// CHECK: #NO_APP
+check_reg!(ymm0_i8x16 i8x16 "ymm0" "vmovaps");
+
+// CHECK-LABEL: ymm0_i16x8:
+// CHECK: #APP
+// CHECK: vmovaps ymm0, ymm0
+// CHECK: #NO_APP
+check_reg!(ymm0_i16x8 i16x8 "ymm0" "vmovaps");
+
+// CHECK-LABEL: ymm0_i32x4:
+// CHECK: #APP
+// CHECK: vmovaps ymm0, ymm0
+// CHECK: #NO_APP
+check_reg!(ymm0_i32x4 i32x4 "ymm0" "vmovaps");
+
+// CHECK-LABEL: ymm0_i64x2:
+// CHECK: #APP
+// CHECK: vmovaps ymm0, ymm0
+// CHECK: #NO_APP
+check_reg!(ymm0_i64x2 i64x2 "ymm0" "vmovaps");
+
+// CHECK-LABEL: ymm0_f32x4:
+// CHECK: #APP
+// CHECK: vmovaps ymm0, ymm0
+// CHECK: #NO_APP
+check_reg!(ymm0_f32x4 f32x4 "ymm0" "vmovaps");
+
+// CHECK-LABEL: ymm0_f64x2:
+// CHECK: #APP
+// CHECK: vmovaps ymm0, ymm0
+// CHECK: #NO_APP
+check_reg!(ymm0_f64x2 f64x2 "ymm0" "vmovaps");
+
+// CHECK-LABEL: ymm0_i8x32:
+// CHECK: #APP
+// CHECK: vmovaps ymm0, ymm0
+// CHECK: #NO_APP
+check_reg!(ymm0_i8x32 i8x32 "ymm0" "vmovaps");
+
+// CHECK-LABEL: ymm0_i16x16:
+// CHECK: #APP
+// CHECK: vmovaps ymm0, ymm0
+// CHECK: #NO_APP
+check_reg!(ymm0_i16x16 i16x16 "ymm0" "vmovaps");
+
+// CHECK-LABEL: ymm0_i32x8:
+// CHECK: #APP
+// CHECK: vmovaps ymm0, ymm0
+// CHECK: #NO_APP
+check_reg!(ymm0_i32x8 i32x8 "ymm0" "vmovaps");
+
+// CHECK-LABEL: ymm0_i64x4:
+// CHECK: #APP
+// CHECK: vmovaps ymm0, ymm0
+// CHECK: #NO_APP
+check_reg!(ymm0_i64x4 i64x4 "ymm0" "vmovaps");
+
+// CHECK-LABEL: ymm0_f32x8:
+// CHECK: #APP
+// CHECK: vmovaps ymm0, ymm0
+// CHECK: #NO_APP
+check_reg!(ymm0_f32x8 f32x8 "ymm0" "vmovaps");
+
+// CHECK-LABEL: ymm0_f64x4:
+// CHECK: #APP
+// CHECK: vmovaps ymm0, ymm0
+// CHECK: #NO_APP
+check_reg!(ymm0_f64x4 f64x4 "ymm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_i32:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_i32 i32 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_f32:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_f32 f32 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_i64:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_i64 i64 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_f64:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_f64 f64 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_ptr:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_ptr ptr "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_i8x16:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_i8x16 i8x16 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_i16x8:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_i16x8 i16x8 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_i32x4:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_i32x4 i32x4 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_i64x2:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_i64x2 i64x2 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_f32x4:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_f32x4 f32x4 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_f64x2:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_f64x2 f64x2 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_i8x32:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_i8x32 i8x32 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_i16x16:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_i16x16 i16x16 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_i32x8:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_i32x8 i32x8 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_i64x4:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_i64x4 i64x4 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_f32x8:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_f32x8 f32x8 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_f64x4:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_f64x4 f64x4 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_i8x64:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_i8x64 i8x64 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_i16x32:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_i16x32 i16x32 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_i32x16:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_i32x16 i32x16 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_i64x8:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_i64x8 i64x8 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_f32x16:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_f32x16 f32x16 "zmm0" "vmovaps");
+
+// CHECK-LABEL: zmm0_f64x8:
+// CHECK: #APP
+// CHECK: vmovaps zmm0, zmm0
+// CHECK: #NO_APP
+check_reg!(zmm0_f64x8 f64x8 "zmm0" "vmovaps");
+
+// CHECK-LABEL: k1_i8:
+// CHECK: #APP
+// CHECK: kmovb k1, k1
+// CHECK: #NO_APP
+check_reg!(k1_i8 i8 "k1" "kmovb");
+
+// CHECK-LABEL: k1_i16:
+// CHECK: #APP
+// CHECK: kmovw k1, k1
+// CHECK: #NO_APP
+check_reg!(k1_i16 i16 "k1" "kmovw");
+
+// CHECK-LABEL: k1_i32:
+// CHECK: #APP
+// CHECK: kmovd k1, k1
+// CHECK: #NO_APP
+check_reg!(k1_i32 i32 "k1" "kmovd");
+
+// CHECK-LABEL: k1_i64:
+// CHECK: #APP
+// CHECK: kmovq k1, k1
+// CHECK: #NO_APP
+check_reg!(k1_i64 i64 "k1" "kmovq");
+
+// CHECK-LABEL: k1_ptr:
+// CHECK: #APP
+// CHECK: kmovq k1, k1
+// CHECK: #NO_APP
+check_reg!(k1_ptr ptr "k1" "kmovq");
StorageLive(_1); // scope 0 at $DIR/address-of.rs:4:9: 4:10
StorageLive(_2); // scope 0 at $DIR/address-of.rs:4:14: 4:21
_2 = [const 0_i32; 10]; // scope 0 at $DIR/address-of.rs:4:14: 4:21
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/address-of.rs:4:15: 4:16
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
_1 = &_2; // scope 0 at $DIR/address-of.rs:4:13: 4:21
FakeRead(ForLet, _1); // scope 0 at $DIR/address-of.rs:4:9: 4:10
StorageLive(_3); // scope 1 at $DIR/address-of.rs:5:9: 5:14
StorageLive(_4); // scope 1 at $DIR/address-of.rs:5:22: 5:29
_4 = [const 0_i32; 10]; // scope 1 at $DIR/address-of.rs:5:22: 5:29
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/address-of.rs:5:23: 5:24
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
_3 = &mut _4; // scope 1 at $DIR/address-of.rs:5:17: 5:29
FakeRead(ForLet, _3); // scope 1 at $DIR/address-of.rs:5:9: 5:14
StorageLive(_5); // scope 2 at $DIR/address-of.rs:7:5: 7:18
bb0: {
StorageLive(_1); // scope 0 at $DIR/array-index-is-temporary.rs:13:9: 13:14
_1 = [const 42_u32, const 43_u32, const 44_u32]; // scope 0 at $DIR/array-index-is-temporary.rs:13:17: 13:29
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/array-index-is-temporary.rs:13:18: 13:20
- // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x0000002b))
- // mir::Constant
- // + span: $DIR/array-index-is-temporary.rs:13:22: 13:24
- // + literal: Const { ty: u32, val: Value(Scalar(0x0000002b)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x0000002c))
- // mir::Constant
- // + span: $DIR/array-index-is-temporary.rs:13:26: 13:28
- // + literal: Const { ty: u32, val: Value(Scalar(0x0000002c)) }
StorageLive(_2); // scope 1 at $DIR/array-index-is-temporary.rs:14:9: 14:14
_2 = const 1_usize; // scope 1 at $DIR/array-index-is-temporary.rs:14:17: 14:18
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/array-index-is-temporary.rs:14:17: 14:18
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000001)) }
StorageLive(_3); // scope 2 at $DIR/array-index-is-temporary.rs:15:9: 15:10
StorageLive(_4); // scope 2 at $DIR/array-index-is-temporary.rs:15:25: 15:31
_4 = &mut _2; // scope 2 at $DIR/array-index-is-temporary.rs:15:25: 15:31
bb0: {
StorageLive(_1); // scope 0 at $DIR/array-index-is-temporary.rs:13:9: 13:14
_1 = [const 42_u32, const 43_u32, const 44_u32]; // scope 0 at $DIR/array-index-is-temporary.rs:13:17: 13:29
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/array-index-is-temporary.rs:13:18: 13:20
- // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x0000002b))
- // mir::Constant
- // + span: $DIR/array-index-is-temporary.rs:13:22: 13:24
- // + literal: Const { ty: u32, val: Value(Scalar(0x0000002b)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x0000002c))
- // mir::Constant
- // + span: $DIR/array-index-is-temporary.rs:13:26: 13:28
- // + literal: Const { ty: u32, val: Value(Scalar(0x0000002c)) }
StorageLive(_2); // scope 1 at $DIR/array-index-is-temporary.rs:14:9: 14:14
_2 = const 1_usize; // scope 1 at $DIR/array-index-is-temporary.rs:14:17: 14:18
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000001))
- // mir::Constant
- // + span: $DIR/array-index-is-temporary.rs:14:17: 14:18
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000001)) }
StorageLive(_3); // scope 2 at $DIR/array-index-is-temporary.rs:15:9: 15:10
StorageLive(_4); // scope 2 at $DIR/array-index-is-temporary.rs:15:25: 15:31
_4 = &mut _2; // scope 2 at $DIR/array-index-is-temporary.rs:15:25: 15:31
bb0: {
StorageLive(_1); // scope 0 at $DIR/basic_assignment.rs:11:9: 11:17
_1 = const false; // scope 0 at $DIR/basic_assignment.rs:11:20: 11:25
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/basic_assignment.rs:11:20: 11:25
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
FakeRead(ForLet, _1); // scope 0 at $DIR/basic_assignment.rs:11:9: 11:17
StorageLive(_2); // scope 1 at $DIR/basic_assignment.rs:12:9: 12:17
StorageLive(_3); // scope 2 at $DIR/basic_assignment.rs:16:16: 16:24
// + literal: Const { ty: &[u8; 3], val: Value(Scalar(alloc0)) }
StorageLive(_2); // scope 1 at $DIR/byte_slice.rs:6:9: 6:10
_2 = [const 5_u8, const 120_u8]; // scope 1 at $DIR/byte_slice.rs:6:13: 6:24
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x05))
- // mir::Constant
- // + span: $DIR/byte_slice.rs:6:14: 6:17
- // + literal: Const { ty: u8, val: Value(Scalar(0x05)) }
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x78))
- // mir::Constant
- // + span: $DIR/byte_slice.rs:6:19: 6:23
- // + literal: Const { ty: u8, val: Value(Scalar(0x78)) }
_0 = const (); // scope 0 at $DIR/byte_slice.rs:4:11: 7:2
// ty::Const
// + ty: ()
StorageLive(_2); // scope 0 at $DIR/combine_array_len.rs:5:9: 5:10
StorageLive(_3); // scope 0 at $DIR/combine_array_len.rs:5:15: 5:16
_3 = const 0_usize; // scope 0 at $DIR/combine_array_len.rs:5:15: 5:16
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/combine_array_len.rs:5:15: 5:16
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000000)) }
- _4 = Len(_1); // scope 0 at $DIR/combine_array_len.rs:5:13: 5:17
+ _4 = const 2_usize; // scope 0 at $DIR/combine_array_len.rs:5:13: 5:17
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x00000002))
-+ // mir::Constant
-+ // + span: $DIR/combine_array_len.rs:5:13: 5:17
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x00000002)) }
_5 = Lt(_3, _4); // scope 0 at $DIR/combine_array_len.rs:5:13: 5:17
assert(move _5, "index out of bounds: the len is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/combine_array_len.rs:5:13: 5:17
}
StorageLive(_6); // scope 1 at $DIR/combine_array_len.rs:6:9: 6:10
StorageLive(_7); // scope 1 at $DIR/combine_array_len.rs:6:15: 6:16
_7 = const 1_usize; // scope 1 at $DIR/combine_array_len.rs:6:15: 6:16
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/combine_array_len.rs:6:15: 6:16
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000001)) }
- _8 = Len(_1); // scope 1 at $DIR/combine_array_len.rs:6:13: 6:17
+ _8 = const 2_usize; // scope 1 at $DIR/combine_array_len.rs:6:13: 6:17
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x00000002))
-+ // mir::Constant
-+ // + span: $DIR/combine_array_len.rs:6:13: 6:17
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x00000002)) }
_9 = Lt(_7, _8); // scope 1 at $DIR/combine_array_len.rs:6:13: 6:17
assert(move _9, "index out of bounds: the len is {} but the index is {}", move _8, _7) -> bb2; // scope 1 at $DIR/combine_array_len.rs:6:13: 6:17
}
StorageLive(_2); // scope 0 at $DIR/combine_array_len.rs:5:9: 5:10
StorageLive(_3); // scope 0 at $DIR/combine_array_len.rs:5:15: 5:16
_3 = const 0_usize; // scope 0 at $DIR/combine_array_len.rs:5:15: 5:16
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000000))
- // mir::Constant
- // + span: $DIR/combine_array_len.rs:5:15: 5:16
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) }
- _4 = Len(_1); // scope 0 at $DIR/combine_array_len.rs:5:13: 5:17
+ _4 = const 2_usize; // scope 0 at $DIR/combine_array_len.rs:5:13: 5:17
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x0000000000000002))
-+ // mir::Constant
-+ // + span: $DIR/combine_array_len.rs:5:13: 5:17
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000002)) }
_5 = Lt(_3, _4); // scope 0 at $DIR/combine_array_len.rs:5:13: 5:17
assert(move _5, "index out of bounds: the len is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/combine_array_len.rs:5:13: 5:17
}
StorageLive(_6); // scope 1 at $DIR/combine_array_len.rs:6:9: 6:10
StorageLive(_7); // scope 1 at $DIR/combine_array_len.rs:6:15: 6:16
_7 = const 1_usize; // scope 1 at $DIR/combine_array_len.rs:6:15: 6:16
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000001))
- // mir::Constant
- // + span: $DIR/combine_array_len.rs:6:15: 6:16
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000001)) }
- _8 = Len(_1); // scope 1 at $DIR/combine_array_len.rs:6:13: 6:17
+ _8 = const 2_usize; // scope 1 at $DIR/combine_array_len.rs:6:13: 6:17
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x0000000000000002))
-+ // mir::Constant
-+ // + span: $DIR/combine_array_len.rs:6:13: 6:17
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000002)) }
_9 = Lt(_7, _8); // scope 1 at $DIR/combine_array_len.rs:6:13: 6:17
assert(move _9, "index out of bounds: the len is {} but the index is {}", move _8, _7) -> bb2; // scope 1 at $DIR/combine_array_len.rs:6:13: 6:17
}
StorageLive(_2); // scope 0 at $DIR/aggregate.rs:5:13: 5:24
StorageLive(_3); // scope 0 at $DIR/aggregate.rs:5:13: 5:22
(_3.0: i32) = const 0_i32; // scope 0 at $DIR/aggregate.rs:5:13: 5:22
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/aggregate.rs:5:14: 5:15
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
(_3.1: i32) = const 1_i32; // scope 0 at $DIR/aggregate.rs:5:13: 5:22
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/aggregate.rs:5:17: 5:18
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
(_3.2: i32) = const 2_i32; // scope 0 at $DIR/aggregate.rs:5:13: 5:22
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/aggregate.rs:5:20: 5:21
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
- _2 = (_3.1: i32); // scope 0 at $DIR/aggregate.rs:5:13: 5:24
- _1 = Add(move _2, const 0_i32); // scope 0 at $DIR/aggregate.rs:5:13: 5:28
+ _2 = const 1_i32; // scope 0 at $DIR/aggregate.rs:5:13: 5:24
- // ty::Const
- // + ty: i32
-- // + val: Value(Scalar(0x00000000))
-+ // + val: Value(Scalar(0x00000001))
- // mir::Constant
-- // + span: $DIR/aggregate.rs:5:27: 5:28
-- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
-+ // + span: $DIR/aggregate.rs:5:13: 5:24
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
+ _1 = const 1_i32; // scope 0 at $DIR/aggregate.rs:5:13: 5:28
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x00000001))
-+ // mir::Constant
-+ // + span: $DIR/aggregate.rs:5:13: 5:28
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
StorageDead(_2); // scope 0 at $DIR/aggregate.rs:5:27: 5:28
StorageDead(_3); // scope 0 at $DIR/aggregate.rs:5:28: 5:29
_0 = const (); // scope 0 at $DIR/aggregate.rs:4:11: 6:2
StorageLive(_1); // scope 0 at $DIR/array_index.rs:5:9: 5:10
StorageLive(_2); // scope 0 at $DIR/array_index.rs:5:18: 5:30
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; // scope 0 at $DIR/array_index.rs:5:18: 5:30
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/array_index.rs:5:19: 5:20
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/array_index.rs:5:22: 5:23
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/array_index.rs:5:25: 5:26
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/array_index.rs:5:28: 5:29
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000003)) }
StorageLive(_3); // scope 0 at $DIR/array_index.rs:5:31: 5:32
_3 = const 2_usize; // scope 0 at $DIR/array_index.rs:5:31: 5:32
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/array_index.rs:5:31: 5:32
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000002)) }
_4 = const 4_usize; // scope 0 at $DIR/array_index.rs:5:18: 5:33
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000004))
- // mir::Constant
- // + span: $DIR/array_index.rs:5:18: 5:33
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000004)) }
- _5 = Lt(_3, _4); // scope 0 at $DIR/array_index.rs:5:18: 5:33
- assert(move _5, "index out of bounds: the len is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/array_index.rs:5:18: 5:33
+ _5 = const true; // scope 0 at $DIR/array_index.rs:5:18: 5:33
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/array_index.rs:5:18: 5:33
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
+ assert(const true, "index out of bounds: the len is {} but the index is {}", const 4_usize, const 2_usize) -> bb1; // scope 0 at $DIR/array_index.rs:5:18: 5:33
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/array_index.rs:5:18: 5:33
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x00000004))
-+ // mir::Constant
-+ // + span: $DIR/array_index.rs:5:18: 5:33
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x00000004)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x00000002))
-+ // mir::Constant
-+ // + span: $DIR/array_index.rs:5:18: 5:33
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x00000002)) }
}
bb1: {
- _1 = _2[_3]; // scope 0 at $DIR/array_index.rs:5:18: 5:33
+ _1 = const 2_u32; // scope 0 at $DIR/array_index.rs:5:18: 5:33
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x00000002))
-+ // mir::Constant
-+ // + span: $DIR/array_index.rs:5:18: 5:33
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageDead(_3); // scope 0 at $DIR/array_index.rs:5:33: 5:34
StorageDead(_2); // scope 0 at $DIR/array_index.rs:5:33: 5:34
_0 = const (); // scope 0 at $DIR/array_index.rs:4:11: 6:2
StorageLive(_1); // scope 0 at $DIR/array_index.rs:5:9: 5:10
StorageLive(_2); // scope 0 at $DIR/array_index.rs:5:18: 5:30
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; // scope 0 at $DIR/array_index.rs:5:18: 5:30
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/array_index.rs:5:19: 5:20
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/array_index.rs:5:22: 5:23
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/array_index.rs:5:25: 5:26
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/array_index.rs:5:28: 5:29
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000003)) }
StorageLive(_3); // scope 0 at $DIR/array_index.rs:5:31: 5:32
_3 = const 2_usize; // scope 0 at $DIR/array_index.rs:5:31: 5:32
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000002))
- // mir::Constant
- // + span: $DIR/array_index.rs:5:31: 5:32
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000002)) }
_4 = const 4_usize; // scope 0 at $DIR/array_index.rs:5:18: 5:33
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000004))
- // mir::Constant
- // + span: $DIR/array_index.rs:5:18: 5:33
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000004)) }
- _5 = Lt(_3, _4); // scope 0 at $DIR/array_index.rs:5:18: 5:33
- assert(move _5, "index out of bounds: the len is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/array_index.rs:5:18: 5:33
+ _5 = const true; // scope 0 at $DIR/array_index.rs:5:18: 5:33
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/array_index.rs:5:18: 5:33
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
+ assert(const true, "index out of bounds: the len is {} but the index is {}", const 4_usize, const 2_usize) -> bb1; // scope 0 at $DIR/array_index.rs:5:18: 5:33
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/array_index.rs:5:18: 5:33
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x0000000000000004))
-+ // mir::Constant
-+ // + span: $DIR/array_index.rs:5:18: 5:33
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000004)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x0000000000000002))
-+ // mir::Constant
-+ // + span: $DIR/array_index.rs:5:18: 5:33
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000002)) }
}
bb1: {
- _1 = _2[_3]; // scope 0 at $DIR/array_index.rs:5:18: 5:33
+ _1 = const 2_u32; // scope 0 at $DIR/array_index.rs:5:18: 5:33
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x00000002))
-+ // mir::Constant
-+ // + span: $DIR/array_index.rs:5:18: 5:33
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageDead(_3); // scope 0 at $DIR/array_index.rs:5:33: 5:34
StorageDead(_2); // scope 0 at $DIR/array_index.rs:5:33: 5:34
_0 = const (); // scope 0 at $DIR/array_index.rs:4:11: 6:2
bb0: {
StorageLive(_1); // scope 0 at $DIR/bad_op_div_by_zero.rs:4:9: 4:10
_1 = const 0_i32; // scope 0 at $DIR/bad_op_div_by_zero.rs:4:13: 4:14
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/bad_op_div_by_zero.rs:4:13: 4:14
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
StorageLive(_2); // scope 1 at $DIR/bad_op_div_by_zero.rs:5:9: 5:11
StorageLive(_3); // scope 1 at $DIR/bad_op_div_by_zero.rs:5:18: 5:19
- _3 = _1; // scope 1 at $DIR/bad_op_div_by_zero.rs:5:18: 5:19
- _4 = Eq(_3, const 0_i32); // scope 1 at $DIR/bad_op_div_by_zero.rs:5:14: 5:19
-+ _3 = const 0_i32; // scope 1 at $DIR/bad_op_div_by_zero.rs:5:18: 5:19
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
-- // + span: $DIR/bad_op_div_by_zero.rs:5:14: 5:19
-+ // + span: $DIR/bad_op_div_by_zero.rs:5:18: 5:19
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
- assert(!move _4, "attempt to divide {} by zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_div_by_zero.rs:5:14: 5:19
++ _3 = const 0_i32; // scope 1 at $DIR/bad_op_div_by_zero.rs:5:18: 5:19
+ _4 = const true; // scope 1 at $DIR/bad_op_div_by_zero.rs:5:14: 5:19
- // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/bad_op_div_by_zero.rs:5:14: 5:19
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
+ assert(!const true, "attempt to divide {} by zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_div_by_zero.rs:5:14: 5:19
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/bad_op_div_by_zero.rs:5:14: 5:19
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
-+ // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/bad_op_div_by_zero.rs:5:14: 5:15
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
}
bb1: {
- _5 = Eq(_3, const -1_i32); // scope 1 at $DIR/bad_op_div_by_zero.rs:5:14: 5:19
-+ _5 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:5:14: 5:19
- // ty::Const
-- // + ty: i32
-- // + val: Value(Scalar(0xffffffff))
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/bad_op_div_by_zero.rs:5:14: 5:19
-- // + literal: Const { ty: i32, val: Value(Scalar(0xffffffff)) }
- _6 = Eq(const 1_i32, const i32::MIN); // scope 1 at $DIR/bad_op_div_by_zero.rs:5:14: 5:19
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
-+ _6 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:5:14: 5:19
- // ty::Const
-- // + ty: i32
-- // + val: Value(Scalar(0x00000001))
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
- // mir::Constant
-- // + span: $DIR/bad_op_div_by_zero.rs:5:14: 5:15
-- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
-+ // + span: $DIR/bad_op_div_by_zero.rs:5:14: 5:19
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
-+ _7 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:5:14: 5:19
- // ty::Const
-- // + ty: i32
-- // + val: Value(Scalar(0x80000000))
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/bad_op_div_by_zero.rs:5:14: 5:19
-- // + literal: Const { ty: i32, val: Value(Scalar(0x80000000)) }
- _7 = BitAnd(move _5, move _6); // scope 1 at $DIR/bad_op_div_by_zero.rs:5:14: 5:19
- assert(!move _7, "attempt to compute `{} / {}` which would overflow", const 1_i32, _3) -> bb2; // scope 1 at $DIR/bad_op_div_by_zero.rs:5:14: 5:19
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
++ _5 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:5:14: 5:19
++ _6 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:5:14: 5:19
++ _7 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:5:14: 5:19
+ assert(!const false, "attempt to compute `{} / {}` which would overflow", const 1_i32, const 0_i32) -> bb2; // scope 1 at $DIR/bad_op_div_by_zero.rs:5:14: 5:19
- // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
-+ // mir::Constant
-+ // + span: $DIR/bad_op_div_by_zero.rs:5:14: 5:19
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
-+ // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/bad_op_div_by_zero.rs:5:14: 5:15
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x00000000))
-+ // mir::Constant
-+ // + span: $DIR/bad_op_div_by_zero.rs:5:14: 5:19
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
}
bb2: {
- _2 = Div(const 1_i32, move _3); // scope 1 at $DIR/bad_op_div_by_zero.rs:5:14: 5:19
+ _2 = Div(const 1_i32, const 0_i32); // scope 1 at $DIR/bad_op_div_by_zero.rs:5:14: 5:19
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/bad_op_div_by_zero.rs:5:14: 5:15
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x00000000))
-+ // mir::Constant
-+ // + span: $DIR/bad_op_div_by_zero.rs:5:14: 5:19
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
StorageDead(_3); // scope 1 at $DIR/bad_op_div_by_zero.rs:5:18: 5:19
_0 = const (); // scope 0 at $DIR/bad_op_div_by_zero.rs:3:11: 6:2
// ty::Const
bb0: {
StorageLive(_1); // scope 0 at $DIR/bad_op_mod_by_zero.rs:4:9: 4:10
_1 = const 0_i32; // scope 0 at $DIR/bad_op_mod_by_zero.rs:4:13: 4:14
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/bad_op_mod_by_zero.rs:4:13: 4:14
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
StorageLive(_2); // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:9: 5:11
StorageLive(_3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:18: 5:19
- _3 = _1; // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:18: 5:19
- _4 = Eq(_3, const 0_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
-+ _3 = const 0_i32; // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:18: 5:19
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
-- // + span: $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
-+ // + span: $DIR/bad_op_mod_by_zero.rs:5:18: 5:19
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
- assert(!move _4, "attempt to calculate the remainder of {} with a divisor of zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
++ _3 = const 0_i32; // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:18: 5:19
+ _4 = const true; // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
- // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
+ assert(!const true, "attempt to calculate the remainder of {} with a divisor of zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
-+ // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/bad_op_mod_by_zero.rs:5:14: 5:15
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
}
bb1: {
- _5 = Eq(_3, const -1_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
-+ _5 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
- // ty::Const
-- // + ty: i32
-- // + val: Value(Scalar(0xffffffff))
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
-- // + literal: Const { ty: i32, val: Value(Scalar(0xffffffff)) }
- _6 = Eq(const 1_i32, const i32::MIN); // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
-+ _6 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
- // ty::Const
-- // + ty: i32
-- // + val: Value(Scalar(0x00000001))
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
- // mir::Constant
-- // + span: $DIR/bad_op_mod_by_zero.rs:5:14: 5:15
-- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
-+ // + span: $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
-+ _7 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
- // ty::Const
-- // + ty: i32
-- // + val: Value(Scalar(0x80000000))
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
-- // + literal: Const { ty: i32, val: Value(Scalar(0x80000000)) }
- _7 = BitAnd(move _5, move _6); // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
- assert(!move _7, "attempt to compute the remainder of `{} % {}` which would overflow", const 1_i32, _3) -> bb2; // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
++ _5 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
++ _6 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
++ _7 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
+ assert(!const false, "attempt to compute the remainder of `{} % {}` which would overflow", const 1_i32, const 0_i32) -> bb2; // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
- // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
-+ // mir::Constant
-+ // + span: $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
-+ // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/bad_op_mod_by_zero.rs:5:14: 5:15
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x00000000))
-+ // mir::Constant
-+ // + span: $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
}
bb2: {
- _2 = Rem(const 1_i32, move _3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
+ _2 = Rem(const 1_i32, const 0_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/bad_op_mod_by_zero.rs:5:14: 5:15
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x00000000))
-+ // mir::Constant
-+ // + span: $DIR/bad_op_mod_by_zero.rs:5:14: 5:19
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
StorageDead(_3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:5:18: 5:19
_0 = const (); // scope 0 at $DIR/bad_op_mod_by_zero.rs:3:11: 6:2
// ty::Const
StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:7:13: 7:15
StorageLive(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:7:23: 7:24
_6 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:7:23: 7:24
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:7:23: 7:24
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000003)) }
_7 = Len((*_1)); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:7:18: 7:25
- _8 = Lt(_6, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:7:18: 7:25
- assert(move _8, "index out of bounds: the len is {} but the index is {}", move _7, _6) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:7:18: 7:25
+ _8 = Lt(const 3_usize, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:7:18: 7:25
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x00000003))
-+ // mir::Constant
-+ // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:7:18: 7:25
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x00000003)) }
+ assert(move _8, "index out of bounds: the len is {} but the index is {}", move _7, const 3_usize) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:7:18: 7:25
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x00000003))
-+ // mir::Constant
-+ // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:7:18: 7:25
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x00000003)) }
}
bb1: {
StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:7:13: 7:15
StorageLive(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:7:23: 7:24
_6 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:7:23: 7:24
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000003))
- // mir::Constant
- // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:7:23: 7:24
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000003)) }
_7 = Len((*_1)); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:7:18: 7:25
- _8 = Lt(_6, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:7:18: 7:25
- assert(move _8, "index out of bounds: the len is {} but the index is {}", move _7, _6) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:7:18: 7:25
+ _8 = Lt(const 3_usize, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:7:18: 7:25
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x0000000000000003))
-+ // mir::Constant
-+ // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:7:18: 7:25
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000003)) }
+ assert(move _8, "index out of bounds: the len is {} but the index is {}", move _7, const 3_usize) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:7:18: 7:25
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x0000000000000003))
-+ // mir::Constant
-+ // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:7:18: 7:25
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000003)) }
}
bb1: {
_4 = _2; // scope 0 at $DIR/boolean_identities.rs:5:6: 5:7
- _3 = BitOr(move _4, const true); // scope 0 at $DIR/boolean_identities.rs:5:5: 5:15
+ _3 = const true; // scope 0 at $DIR/boolean_identities.rs:5:5: 5:15
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
-- // + span: $DIR/boolean_identities.rs:5:10: 5:14
-+ // + span: $DIR/boolean_identities.rs:5:5: 5:15
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
StorageDead(_4); // scope 0 at $DIR/boolean_identities.rs:5:14: 5:15
StorageLive(_5); // scope 0 at $DIR/boolean_identities.rs:5:18: 5:29
StorageLive(_6); // scope 0 at $DIR/boolean_identities.rs:5:19: 5:20
_6 = _1; // scope 0 at $DIR/boolean_identities.rs:5:19: 5:20
- _5 = BitAnd(move _6, const false); // scope 0 at $DIR/boolean_identities.rs:5:18: 5:29
+ _5 = const false; // scope 0 at $DIR/boolean_identities.rs:5:18: 5:29
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
-- // + span: $DIR/boolean_identities.rs:5:23: 5:28
-+ // + span: $DIR/boolean_identities.rs:5:18: 5:29
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
StorageDead(_6); // scope 0 at $DIR/boolean_identities.rs:5:28: 5:29
- _0 = BitAnd(move _3, move _5); // scope 0 at $DIR/boolean_identities.rs:5:5: 5:29
+ _0 = const false; // scope 0 at $DIR/boolean_identities.rs:5:5: 5:29
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
-+ // mir::Constant
-+ // + span: $DIR/boolean_identities.rs:5:5: 5:29
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
StorageDead(_5); // scope 0 at $DIR/boolean_identities.rs:5:28: 5:29
StorageDead(_3); // scope 0 at $DIR/boolean_identities.rs:5:28: 5:29
return; // scope 0 at $DIR/boolean_identities.rs:6:2: 6:2
StorageLive(_4); // scope 0 at $DIR/boxes.rs:12:14: 12:22
_4 = Box(i32); // scope 0 at $DIR/boxes.rs:12:14: 12:22
(*_4) = const 42_i32; // scope 0 at $DIR/boxes.rs:12:19: 12:21
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/boxes.rs:12:19: 12:21
- // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
_3 = move _4; // scope 0 at $DIR/boxes.rs:12:14: 12:22
StorageDead(_4); // scope 0 at $DIR/boxes.rs:12:21: 12:22
_2 = (*_3); // scope 0 at $DIR/boxes.rs:12:13: 12:22
_1 = Add(move _2, const 0_i32); // scope 0 at $DIR/boxes.rs:12:13: 12:26
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/boxes.rs:12:25: 12:26
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
StorageDead(_2); // scope 0 at $DIR/boxes.rs:12:25: 12:26
drop(_3) -> [return: bb2, unwind: bb1]; // scope 0 at $DIR/boxes.rs:12:26: 12:27
}
StorageLive(_1); // scope 0 at $DIR/cast.rs:4:9: 4:10
- _1 = const 42_u8 as u32 (Misc); // scope 0 at $DIR/cast.rs:4:13: 4:24
+ _1 = const 42_u32; // scope 0 at $DIR/cast.rs:4:13: 4:24
- // ty::Const
-- // + ty: u8
-- // + val: Value(Scalar(0x2a))
-- // mir::Constant
-- // + span: $DIR/cast.rs:4:13: 4:17
-- // + literal: Const { ty: u8, val: Value(Scalar(0x2a)) }
-- StorageLive(_2); // scope 1 at $DIR/cast.rs:6:9: 6:10
+ StorageLive(_2); // scope 1 at $DIR/cast.rs:6:9: 6:10
- _2 = const 42_u32 as u8 (Misc); // scope 1 at $DIR/cast.rs:6:13: 6:24
-- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
-- // + span: $DIR/cast.rs:6:13: 6:18
-+ // + span: $DIR/cast.rs:4:13: 4:24
- // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
-+ StorageLive(_2); // scope 1 at $DIR/cast.rs:6:9: 6:10
+ _2 = const 42_u8; // scope 1 at $DIR/cast.rs:6:13: 6:24
-+ // ty::Const
-+ // + ty: u8
-+ // + val: Value(Scalar(0x2a))
-+ // mir::Constant
-+ // + span: $DIR/cast.rs:6:13: 6:24
-+ // + literal: Const { ty: u8, val: Value(Scalar(0x2a)) }
_0 = const (); // scope 0 at $DIR/cast.rs:3:11: 7:2
// ty::Const
// + ty: ()
bb0: {
StorageLive(_1); // scope 0 at $DIR/checked_add.rs:5:9: 5:10
- _2 = CheckedAdd(const 1_u32, const 1_u32); // scope 0 at $DIR/checked_add.rs:5:18: 5:23
-+ _2 = (const 2_u32, const false); // scope 0 at $DIR/checked_add.rs:5:18: 5:23
- // ty::Const
- // + ty: u32
-- // + val: Value(Scalar(0x00000001))
-+ // + val: Value(Scalar(0x00000002))
- // mir::Constant
-- // + span: $DIR/checked_add.rs:5:18: 5:19
-- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
-+ // + span: $DIR/checked_add.rs:5:18: 5:23
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
- // ty::Const
-- // + ty: u32
-- // + val: Value(Scalar(0x00000001))
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
- // mir::Constant
-- // + span: $DIR/checked_add.rs:5:22: 5:23
-- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
- assert(!move (_2.1: bool), "attempt to compute `{} + {}` which would overflow", const 1_u32, const 1_u32) -> bb1; // scope 0 at $DIR/checked_add.rs:5:18: 5:23
-+ // + span: $DIR/checked_add.rs:5:18: 5:23
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
++ _2 = (const 2_u32, const false); // scope 0 at $DIR/checked_add.rs:5:18: 5:23
+ assert(!const false, "attempt to compute `{} + {}` which would overflow", const 1_u32, const 1_u32) -> bb1; // scope 0 at $DIR/checked_add.rs:5:18: 5:23
- // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
-+ // mir::Constant
-+ // + span: $DIR/checked_add.rs:5:18: 5:23
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
-+ // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/checked_add.rs:5:18: 5:19
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/checked_add.rs:5:22: 5:23
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
}
bb1: {
- _1 = move (_2.0: u32); // scope 0 at $DIR/checked_add.rs:5:18: 5:23
+ _1 = const 2_u32; // scope 0 at $DIR/checked_add.rs:5:18: 5:23
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x00000002))
-+ // mir::Constant
-+ // + span: $DIR/checked_add.rs:5:18: 5:23
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
_0 = const (); // scope 0 at $DIR/checked_add.rs:4:11: 6:2
// ty::Const
// + ty: ()
bb0: {
StorageLive(_1); // scope 0 at $DIR/control-flow-simplification.rs:12:8: 12:21
- _1 = const <bool as NeedsDrop>::NEEDS; // scope 0 at $DIR/control-flow-simplification.rs:12:8: 12:21
-+ _1 = const false; // scope 0 at $DIR/control-flow-simplification.rs:12:8: 12:21
- // ty::Const
- // + ty: bool
-- // + val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ control_flow_simplification[317d]::NeedsDrop[0]::NEEDS[0]), const_param_did: None }, [bool], None)
-+ // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/control-flow-simplification.rs:12:8: 12:21
-- // + literal: Const { ty: bool, val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ control_flow_simplification[317d]::NeedsDrop[0]::NEEDS[0]), const_param_did: None }, [bool], None) }
- switchInt(_1) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/control-flow-simplification.rs:12:5: 14:6
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
++ _1 = const false; // scope 0 at $DIR/control-flow-simplification.rs:12:8: 12:21
+ switchInt(const false) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/control-flow-simplification.rs:12:5: 14:6
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
-+ // mir::Constant
-+ // + span: $DIR/control-flow-simplification.rs:12:5: 14:6
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
}
bb1: {
StorageLive(_2); // scope 0 at $DIR/discriminant.rs:11:13: 11:64
StorageLive(_3); // scope 0 at $DIR/discriminant.rs:11:34: 11:44
((_3 as Some).0: bool) = const true; // scope 0 at $DIR/discriminant.rs:11:34: 11:44
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/discriminant.rs:11:39: 11:43
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
discriminant(_3) = 1; // scope 0 at $DIR/discriminant.rs:11:34: 11:44
- _4 = discriminant(_3); // scope 0 at $DIR/discriminant.rs:11:21: 11:31
- switchInt(move _4) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/discriminant.rs:11:21: 11:31
+ _4 = const 1_isize; // scope 0 at $DIR/discriminant.rs:11:21: 11:31
-+ // ty::Const
-+ // + ty: isize
-+ // + val: Value(Scalar(0x00000001))
-+ // mir::Constant
-+ // + span: $DIR/discriminant.rs:11:21: 11:31
-+ // + literal: Const { ty: isize, val: Value(Scalar(0x00000001)) }
+ switchInt(const 1_isize) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/discriminant.rs:11:21: 11:31
-+ // ty::Const
-+ // + ty: isize
-+ // + val: Value(Scalar(0x00000001))
-+ // mir::Constant
-+ // + span: $DIR/discriminant.rs:11:21: 11:31
-+ // + literal: Const { ty: isize, val: Value(Scalar(0x00000001)) }
}
bb1: {
_2 = const 10_i32; // scope 0 at $DIR/discriminant.rs:11:59: 11:61
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x0000000a))
- // mir::Constant
- // + span: $DIR/discriminant.rs:11:59: 11:61
- // + literal: Const { ty: i32, val: Value(Scalar(0x0000000a)) }
goto -> bb4; // scope 0 at $DIR/discriminant.rs:11:13: 11:64
}
bb3: {
_2 = const 42_i32; // scope 0 at $DIR/discriminant.rs:11:47: 11:49
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/discriminant.rs:11:47: 11:49
- // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
goto -> bb4; // scope 0 at $DIR/discriminant.rs:11:13: 11:64
}
bb4: {
_1 = Add(move _2, const 0_i32); // scope 0 at $DIR/discriminant.rs:11:13: 11:68
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/discriminant.rs:11:67: 11:68
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
StorageDead(_2); // scope 0 at $DIR/discriminant.rs:11:67: 11:68
StorageDead(_3); // scope 0 at $DIR/discriminant.rs:11:68: 11:69
_0 = const (); // scope 0 at $DIR/discriminant.rs:10:11: 12:2
StorageLive(_2); // scope 0 at $DIR/discriminant.rs:11:13: 11:64
StorageLive(_3); // scope 0 at $DIR/discriminant.rs:11:34: 11:44
((_3 as Some).0: bool) = const true; // scope 0 at $DIR/discriminant.rs:11:34: 11:44
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/discriminant.rs:11:39: 11:43
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
discriminant(_3) = 1; // scope 0 at $DIR/discriminant.rs:11:34: 11:44
- _4 = discriminant(_3); // scope 0 at $DIR/discriminant.rs:11:21: 11:31
- switchInt(move _4) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/discriminant.rs:11:21: 11:31
+ _4 = const 1_isize; // scope 0 at $DIR/discriminant.rs:11:21: 11:31
-+ // ty::Const
-+ // + ty: isize
-+ // + val: Value(Scalar(0x0000000000000001))
-+ // mir::Constant
-+ // + span: $DIR/discriminant.rs:11:21: 11:31
-+ // + literal: Const { ty: isize, val: Value(Scalar(0x0000000000000001)) }
+ switchInt(const 1_isize) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/discriminant.rs:11:21: 11:31
-+ // ty::Const
-+ // + ty: isize
-+ // + val: Value(Scalar(0x0000000000000001))
-+ // mir::Constant
-+ // + span: $DIR/discriminant.rs:11:21: 11:31
-+ // + literal: Const { ty: isize, val: Value(Scalar(0x0000000000000001)) }
}
bb1: {
_2 = const 10_i32; // scope 0 at $DIR/discriminant.rs:11:59: 11:61
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x0000000a))
- // mir::Constant
- // + span: $DIR/discriminant.rs:11:59: 11:61
- // + literal: Const { ty: i32, val: Value(Scalar(0x0000000a)) }
goto -> bb4; // scope 0 at $DIR/discriminant.rs:11:13: 11:64
}
bb3: {
_2 = const 42_i32; // scope 0 at $DIR/discriminant.rs:11:47: 11:49
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/discriminant.rs:11:47: 11:49
- // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
goto -> bb4; // scope 0 at $DIR/discriminant.rs:11:13: 11:64
}
bb4: {
_1 = Add(move _2, const 0_i32); // scope 0 at $DIR/discriminant.rs:11:13: 11:68
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/discriminant.rs:11:67: 11:68
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
StorageDead(_2); // scope 0 at $DIR/discriminant.rs:11:67: 11:68
StorageDead(_3); // scope 0 at $DIR/discriminant.rs:11:68: 11:69
_0 = const (); // scope 0 at $DIR/discriminant.rs:10:11: 12:2
StorageLive(_1); // scope 0 at $DIR/indirect.rs:5:9: 5:10
StorageLive(_2); // scope 0 at $DIR/indirect.rs:5:13: 5:25
- _2 = const 2_u32 as u8 (Misc); // scope 0 at $DIR/indirect.rs:5:13: 5:25
-+ _2 = const 2_u8; // scope 0 at $DIR/indirect.rs:5:13: 5:25
- // ty::Const
-- // + ty: u32
-- // + val: Value(Scalar(0x00000002))
-+ // + ty: u8
-+ // + val: Value(Scalar(0x02))
- // mir::Constant
-- // + span: $DIR/indirect.rs:5:14: 5:18
-- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
- _3 = CheckedAdd(_2, const 1_u8); // scope 0 at $DIR/indirect.rs:5:13: 5:29
-+ // + span: $DIR/indirect.rs:5:13: 5:25
-+ // + literal: Const { ty: u8, val: Value(Scalar(0x02)) }
-+ _3 = (const 3_u8, const false); // scope 0 at $DIR/indirect.rs:5:13: 5:29
- // ty::Const
- // + ty: u8
-- // + val: Value(Scalar(0x01))
-+ // + val: Value(Scalar(0x03))
- // mir::Constant
-- // + span: $DIR/indirect.rs:5:28: 5:29
-- // + literal: Const { ty: u8, val: Value(Scalar(0x01)) }
- assert(!move (_3.1: bool), "attempt to compute `{} + {}` which would overflow", move _2, const 1_u8) -> bb1; // scope 0 at $DIR/indirect.rs:5:13: 5:29
-+ // + span: $DIR/indirect.rs:5:13: 5:29
-+ // + literal: Const { ty: u8, val: Value(Scalar(0x03)) }
- // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
-+ // mir::Constant
-+ // + span: $DIR/indirect.rs:5:13: 5:29
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
++ _2 = const 2_u8; // scope 0 at $DIR/indirect.rs:5:13: 5:25
++ _3 = (const 3_u8, const false); // scope 0 at $DIR/indirect.rs:5:13: 5:29
+ assert(!const false, "attempt to compute `{} + {}` which would overflow", const 2_u8, const 1_u8) -> bb1; // scope 0 at $DIR/indirect.rs:5:13: 5:29
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
-+ // mir::Constant
-+ // + span: $DIR/indirect.rs:5:13: 5:29
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
-+ // ty::Const
- // + ty: u8
-+ // + val: Value(Scalar(0x02))
-+ // mir::Constant
-+ // + span: $DIR/indirect.rs:5:13: 5:29
-+ // + literal: Const { ty: u8, val: Value(Scalar(0x02)) }
-+ // ty::Const
-+ // + ty: u8
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/indirect.rs:5:28: 5:29
- // + literal: Const { ty: u8, val: Value(Scalar(0x01)) }
}
bb1: {
- _1 = move (_3.0: u8); // scope 0 at $DIR/indirect.rs:5:13: 5:29
+ _1 = const 3_u8; // scope 0 at $DIR/indirect.rs:5:13: 5:29
-+ // ty::Const
-+ // + ty: u8
-+ // + val: Value(Scalar(0x03))
-+ // mir::Constant
-+ // + span: $DIR/indirect.rs:5:13: 5:29
-+ // + literal: Const { ty: u8, val: Value(Scalar(0x03)) }
StorageDead(_2); // scope 0 at $DIR/indirect.rs:5:28: 5:29
_0 = const (); // scope 0 at $DIR/indirect.rs:4:11: 6:2
// ty::Const
+ // + span: $DIR/issue-66971.rs:16:12: 16:22
+ // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
(_2.1: u8) = const 0_u8; // scope 0 at $DIR/issue-66971.rs:16:12: 16:22
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-66971.rs:16:17: 16:18
- // + literal: Const { ty: u8, val: Value(Scalar(0x00)) }
(_2.2: u8) = const 0_u8; // scope 0 at $DIR/issue-66971.rs:16:12: 16:22
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-66971.rs:16:20: 16:21
- // + literal: Const { ty: u8, val: Value(Scalar(0x00)) }
StorageDead(_3); // scope 0 at $DIR/issue-66971.rs:16:21: 16:22
_1 = const encode(move _2) -> bb1; // scope 0 at $DIR/issue-66971.rs:16:5: 16:23
// ty::Const
StorageLive(_2); // scope 0 at $DIR/issue-67019.rs:11:10: 11:19
StorageLive(_3); // scope 0 at $DIR/issue-67019.rs:11:11: 11:17
(_3.0: u8) = const 1_u8; // scope 0 at $DIR/issue-67019.rs:11:11: 11:17
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/issue-67019.rs:11:12: 11:13
- // + literal: Const { ty: u8, val: Value(Scalar(0x01)) }
(_3.1: u8) = const 2_u8; // scope 0 at $DIR/issue-67019.rs:11:11: 11:17
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x02))
- // mir::Constant
- // + span: $DIR/issue-67019.rs:11:15: 11:16
- // + literal: Const { ty: u8, val: Value(Scalar(0x02)) }
- (_2.0: (u8, u8)) = move _3; // scope 0 at $DIR/issue-67019.rs:11:10: 11:19
+ (_2.0: (u8, u8)) = (const 1_u8, const 2_u8); // scope 0 at $DIR/issue-67019.rs:11:10: 11:19
-+ // ty::Const
-+ // + ty: u8
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/issue-67019.rs:11:10: 11:19
-+ // + literal: Const { ty: u8, val: Value(Scalar(0x01)) }
-+ // ty::Const
-+ // + ty: u8
-+ // + val: Value(Scalar(0x02))
-+ // mir::Constant
-+ // + span: $DIR/issue-67019.rs:11:10: 11:19
-+ // + literal: Const { ty: u8, val: Value(Scalar(0x02)) }
StorageDead(_3); // scope 0 at $DIR/issue-67019.rs:11:18: 11:19
_1 = const test(move _2) -> bb1; // scope 0 at $DIR/issue-67019.rs:11:5: 11:20
// ty::Const
StorageLive(_1); // scope 0 at $DIR/large_array_index.rs:6:9: 6:10
StorageLive(_2); // scope 0 at $DIR/large_array_index.rs:6:17: 6:29
_2 = [const 0_u8; 5000]; // scope 0 at $DIR/large_array_index.rs:6:17: 6:29
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/large_array_index.rs:6:18: 6:22
- // + literal: Const { ty: u8, val: Value(Scalar(0x00)) }
StorageLive(_3); // scope 0 at $DIR/large_array_index.rs:6:30: 6:31
_3 = const 2_usize; // scope 0 at $DIR/large_array_index.rs:6:30: 6:31
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/large_array_index.rs:6:30: 6:31
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000002)) }
_4 = const 5000_usize; // scope 0 at $DIR/large_array_index.rs:6:17: 6:32
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00001388))
- // mir::Constant
- // + span: $DIR/large_array_index.rs:6:17: 6:32
- // + literal: Const { ty: usize, val: Value(Scalar(0x00001388)) }
- _5 = Lt(_3, _4); // scope 0 at $DIR/large_array_index.rs:6:17: 6:32
- assert(move _5, "index out of bounds: the len is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/large_array_index.rs:6:17: 6:32
+ _5 = const true; // scope 0 at $DIR/large_array_index.rs:6:17: 6:32
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/large_array_index.rs:6:17: 6:32
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
+ assert(const true, "index out of bounds: the len is {} but the index is {}", const 5000_usize, const 2_usize) -> bb1; // scope 0 at $DIR/large_array_index.rs:6:17: 6:32
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/large_array_index.rs:6:17: 6:32
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x00001388))
-+ // mir::Constant
-+ // + span: $DIR/large_array_index.rs:6:17: 6:32
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x00001388)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x00000002))
-+ // mir::Constant
-+ // + span: $DIR/large_array_index.rs:6:17: 6:32
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x00000002)) }
}
bb1: {
StorageLive(_1); // scope 0 at $DIR/large_array_index.rs:6:9: 6:10
StorageLive(_2); // scope 0 at $DIR/large_array_index.rs:6:17: 6:29
_2 = [const 0_u8; 5000]; // scope 0 at $DIR/large_array_index.rs:6:17: 6:29
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/large_array_index.rs:6:18: 6:22
- // + literal: Const { ty: u8, val: Value(Scalar(0x00)) }
StorageLive(_3); // scope 0 at $DIR/large_array_index.rs:6:30: 6:31
_3 = const 2_usize; // scope 0 at $DIR/large_array_index.rs:6:30: 6:31
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000002))
- // mir::Constant
- // + span: $DIR/large_array_index.rs:6:30: 6:31
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000002)) }
_4 = const 5000_usize; // scope 0 at $DIR/large_array_index.rs:6:17: 6:32
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000001388))
- // mir::Constant
- // + span: $DIR/large_array_index.rs:6:17: 6:32
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000001388)) }
- _5 = Lt(_3, _4); // scope 0 at $DIR/large_array_index.rs:6:17: 6:32
- assert(move _5, "index out of bounds: the len is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/large_array_index.rs:6:17: 6:32
+ _5 = const true; // scope 0 at $DIR/large_array_index.rs:6:17: 6:32
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/large_array_index.rs:6:17: 6:32
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
+ assert(const true, "index out of bounds: the len is {} but the index is {}", const 5000_usize, const 2_usize) -> bb1; // scope 0 at $DIR/large_array_index.rs:6:17: 6:32
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/large_array_index.rs:6:17: 6:32
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x0000000000001388))
-+ // mir::Constant
-+ // + span: $DIR/large_array_index.rs:6:17: 6:32
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000001388)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x0000000000000002))
-+ // mir::Constant
-+ // + span: $DIR/large_array_index.rs:6:17: 6:32
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000002)) }
}
bb1: {
_2 = _1; // scope 0 at $DIR/mult_by_zero.rs:5:3: 5:4
- _0 = Mul(move _2, const 0_i32); // scope 0 at $DIR/mult_by_zero.rs:5:3: 5:8
+ _0 = const 0_i32; // scope 0 at $DIR/mult_by_zero.rs:5:3: 5:8
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
-- // + span: $DIR/mult_by_zero.rs:5:7: 5:8
-+ // + span: $DIR/mult_by_zero.rs:5:3: 5:8
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
StorageDead(_2); // scope 0 at $DIR/mult_by_zero.rs:5:7: 5:8
return; // scope 0 at $DIR/mult_by_zero.rs:6:2: 6:2
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/mutable_variable.rs:5:9: 5:14
_1 = const 42_i32; // scope 0 at $DIR/mutable_variable.rs:5:17: 5:19
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/mutable_variable.rs:5:17: 5:19
- // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
_1 = const 99_i32; // scope 1 at $DIR/mutable_variable.rs:6:5: 6:11
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000063))
- // mir::Constant
- // + span: $DIR/mutable_variable.rs:6:9: 6:11
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000063)) }
StorageLive(_2); // scope 1 at $DIR/mutable_variable.rs:7:9: 7:10
- _2 = _1; // scope 1 at $DIR/mutable_variable.rs:7:13: 7:14
+ _2 = const 99_i32; // scope 1 at $DIR/mutable_variable.rs:7:13: 7:14
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x00000063))
-+ // mir::Constant
-+ // + span: $DIR/mutable_variable.rs:7:13: 7:14
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000063)) }
_0 = const (); // scope 0 at $DIR/mutable_variable.rs:4:11: 8:2
// ty::Const
// + ty: ()
bb0: {
StorageLive(_1); // scope 0 at $DIR/mutable_variable_aggregate.rs:5:9: 5:14
(_1.0: i32) = const 42_i32; // scope 0 at $DIR/mutable_variable_aggregate.rs:5:17: 5:25
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/mutable_variable_aggregate.rs:5:18: 5:20
- // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
(_1.1: i32) = const 43_i32; // scope 0 at $DIR/mutable_variable_aggregate.rs:5:17: 5:25
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x0000002b))
- // mir::Constant
- // + span: $DIR/mutable_variable_aggregate.rs:5:22: 5:24
- // + literal: Const { ty: i32, val: Value(Scalar(0x0000002b)) }
(_1.1: i32) = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate.rs:6:5: 6:13
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000063))
- // mir::Constant
- // + span: $DIR/mutable_variable_aggregate.rs:6:11: 6:13
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000063)) }
StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate.rs:7:9: 7:10
- _2 = _1; // scope 1 at $DIR/mutable_variable_aggregate.rs:7:13: 7:14
+ _2 = (const 42_i32, const 99_i32); // scope 1 at $DIR/mutable_variable_aggregate.rs:7:13: 7:14
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x0000002a))
-+ // mir::Constant
-+ // + span: $DIR/mutable_variable_aggregate.rs:7:13: 7:14
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x00000063))
-+ // mir::Constant
-+ // + span: $DIR/mutable_variable_aggregate.rs:7:13: 7:14
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000063)) }
_0 = const (); // scope 0 at $DIR/mutable_variable_aggregate.rs:4:11: 8:2
// ty::Const
// + ty: ()
bb0: {
StorageLive(_1); // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:5:9: 5:14
(_1.0: i32) = const 42_i32; // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:5:17: 5:25
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/mutable_variable_aggregate_mut_ref.rs:5:18: 5:20
- // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
(_1.1: i32) = const 43_i32; // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:5:17: 5:25
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x0000002b))
- // mir::Constant
- // + span: $DIR/mutable_variable_aggregate_mut_ref.rs:5:22: 5:24
- // + literal: Const { ty: i32, val: Value(Scalar(0x0000002b)) }
StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:6:9: 6:10
_2 = &mut _1; // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:6:13: 6:19
((*_2).1: i32) = const 99_i32; // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:7:5: 7:13
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000063))
- // mir::Constant
- // + span: $DIR/mutable_variable_aggregate_mut_ref.rs:7:11: 7:13
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000063)) }
StorageLive(_3); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:8:9: 8:10
_3 = _1; // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:8:13: 8:14
_0 = const (); // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:4:11: 9:2
bb1: {
(_1.1: i32) = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:6:5: 6:13
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000063))
- // mir::Constant
- // + span: $DIR/mutable_variable_aggregate_partial_read.rs:6:11: 6:13
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000063)) }
(_1.0: i32) = const 42_i32; // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:7:5: 7:13
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/mutable_variable_aggregate_partial_read.rs:7:11: 7:13
- // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:8:9: 8:10
- _2 = (_1.1: i32); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:8:13: 8:16
+ _2 = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:8:13: 8:16
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x00000063))
-+ // mir::Constant
-+ // + span: $DIR/mutable_variable_aggregate_partial_read.rs:8:13: 8:16
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000063)) }
_0 = const (); // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:4:11: 9:2
// ty::Const
// + ty: ()
bb0: {
StorageLive(_1); // scope 0 at $DIR/mutable_variable_no_prop.rs:7:9: 7:14
_1 = const 42_u32; // scope 0 at $DIR/mutable_variable_no_prop.rs:7:17: 7:19
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/mutable_variable_no_prop.rs:7:17: 7:19
- // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
StorageLive(_2); // scope 1 at $DIR/mutable_variable_no_prop.rs:8:5: 10:6
StorageLive(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19
StorageLive(_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19
bb1: {
StorageLive(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:6:9: 6:14
(_2.0: i32) = const 1_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:6:29: 6:35
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/mutable_variable_unprop_assign.rs:6:30: 6:31
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
(_2.1: i32) = const 2_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:6:29: 6:35
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/mutable_variable_unprop_assign.rs:6:33: 6:34
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
StorageLive(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:7:11: 7:12
_3 = _1; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:7:11: 7:12
(_2.1: i32) = move _3; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:7:5: 7:12
bb0: {
StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:12:9: 12:10
- _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
-+ _2 = (const 4_i32, const false); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
- // ty::Const
- // + ty: i32
-- // + val: Value(Scalar(0x00000002))
-+ // + val: Value(Scalar(0x00000004))
- // mir::Constant
-- // + span: $DIR/optimizes_into_variable.rs:12:13: 12:14
-- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
-+ // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) }
- // ty::Const
-- // + ty: i32
-- // + val: Value(Scalar(0x00000002))
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
- // mir::Constant
-- // + span: $DIR/optimizes_into_variable.rs:12:17: 12:18
-- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
- assert(!move (_2.1: bool), "attempt to compute `{} + {}` which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
-+ // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
++ _2 = (const 4_i32, const false); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
+ assert(!const false, "attempt to compute `{} + {}` which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
- // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
-+ // mir::Constant
-+ // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
-+ // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:12:13: 12:14
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:12:17: 12:18
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
}
bb1: {
- _1 = move (_2.0: i32); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
+ _1 = const 4_i32; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x00000004))
-+ // mir::Constant
-+ // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) }
StorageLive(_3); // scope 1 at $DIR/optimizes_into_variable.rs:13:9: 13:10
StorageLive(_4); // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:31
_4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:31
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:13:14: 13:15
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:13:17: 13:18
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:13:20: 13:21
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:13:23: 13:24
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000004))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:13:26: 13:27
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) }
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000005))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:13:29: 13:30
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000005)) }
StorageLive(_5); // scope 1 at $DIR/optimizes_into_variable.rs:13:32: 13:33
_5 = const 3_usize; // scope 1 at $DIR/optimizes_into_variable.rs:13:32: 13:33
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:13:32: 13:33
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000003)) }
_6 = const 6_usize; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000006))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:13:13: 13:34
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000006)) }
- _7 = Lt(_5, _6); // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34
- assert(move _7, "index out of bounds: the len is {} but the index is {}", move _6, _5) -> bb2; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34
+ _7 = const true; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/optimizes_into_variable.rs:13:13: 13:34
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
+ assert(const true, "index out of bounds: the len is {} but the index is {}", const 6_usize, const 3_usize) -> bb2; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/optimizes_into_variable.rs:13:13: 13:34
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x00000006))
-+ // mir::Constant
-+ // + span: $DIR/optimizes_into_variable.rs:13:13: 13:34
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x00000006)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x00000003))
-+ // mir::Constant
-+ // + span: $DIR/optimizes_into_variable.rs:13:13: 13:34
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x00000003)) }
}
bb2: {
- _3 = _4[_5]; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34
+ _3 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x00000003))
-+ // mir::Constant
-+ // + span: $DIR/optimizes_into_variable.rs:13:13: 13:34
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:13:34: 13:35
StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:13:34: 13:35
StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10
StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:36
(_9.0: u32) = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:36
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x0000000c))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:14:25: 14:27
- // + literal: Const { ty: u32, val: Value(Scalar(0x0000000c)) }
(_9.1: u32) = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:36
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:14:32: 14:34
- // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:38
+ _8 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:38
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x0000002a))
-+ // mir::Constant
-+ // + span: $DIR/optimizes_into_variable.rs:14:13: 14:38
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:14:38: 14:39
_0 = const (); // scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2
// ty::Const
bb0: {
StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:12:9: 12:10
- _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
-+ _2 = (const 4_i32, const false); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
- // ty::Const
- // + ty: i32
-- // + val: Value(Scalar(0x00000002))
-+ // + val: Value(Scalar(0x00000004))
- // mir::Constant
-- // + span: $DIR/optimizes_into_variable.rs:12:13: 12:14
-- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
-+ // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) }
- // ty::Const
-- // + ty: i32
-- // + val: Value(Scalar(0x00000002))
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
- // mir::Constant
-- // + span: $DIR/optimizes_into_variable.rs:12:17: 12:18
-- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
- assert(!move (_2.1: bool), "attempt to compute `{} + {}` which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
-+ // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
++ _2 = (const 4_i32, const false); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
+ assert(!const false, "attempt to compute `{} + {}` which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
- // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
-+ // mir::Constant
-+ // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
-+ // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:12:13: 12:14
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:12:17: 12:18
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
}
bb1: {
- _1 = move (_2.0: i32); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
+ _1 = const 4_i32; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x00000004))
-+ // mir::Constant
-+ // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) }
StorageLive(_3); // scope 1 at $DIR/optimizes_into_variable.rs:13:9: 13:10
StorageLive(_4); // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:31
_4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:31
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:13:14: 13:15
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:13:17: 13:18
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:13:20: 13:21
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:13:23: 13:24
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000004))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:13:26: 13:27
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) }
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000005))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:13:29: 13:30
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000005)) }
StorageLive(_5); // scope 1 at $DIR/optimizes_into_variable.rs:13:32: 13:33
_5 = const 3_usize; // scope 1 at $DIR/optimizes_into_variable.rs:13:32: 13:33
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000003))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:13:32: 13:33
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000003)) }
_6 = const 6_usize; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000006))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:13:13: 13:34
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000006)) }
- _7 = Lt(_5, _6); // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34
- assert(move _7, "index out of bounds: the len is {} but the index is {}", move _6, _5) -> bb2; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34
+ _7 = const true; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/optimizes_into_variable.rs:13:13: 13:34
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
+ assert(const true, "index out of bounds: the len is {} but the index is {}", const 6_usize, const 3_usize) -> bb2; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/optimizes_into_variable.rs:13:13: 13:34
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x0000000000000006))
-+ // mir::Constant
-+ // + span: $DIR/optimizes_into_variable.rs:13:13: 13:34
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000006)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x0000000000000003))
-+ // mir::Constant
-+ // + span: $DIR/optimizes_into_variable.rs:13:13: 13:34
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000003)) }
}
bb2: {
- _3 = _4[_5]; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34
+ _3 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x00000003))
-+ // mir::Constant
-+ // + span: $DIR/optimizes_into_variable.rs:13:13: 13:34
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:13:34: 13:35
StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:13:34: 13:35
StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10
StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:36
(_9.0: u32) = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:36
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x0000000c))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:14:25: 14:27
- // + literal: Const { ty: u32, val: Value(Scalar(0x0000000c)) }
(_9.1: u32) = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:36
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:14:32: 14:34
- // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:38
+ _8 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:38
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x0000002a))
-+ // mir::Constant
-+ // + span: $DIR/optimizes_into_variable.rs:14:13: 14:38
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:14:38: 14:39
_0 = const (); // scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2
// ty::Const
bb0: {
StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:12:9: 12:10
_1 = const 4_i32; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000004))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) }
StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:13:9: 13:10
_2 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:13:13: 13:34
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10
_3 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:38
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:14:13: 14:38
- // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
_0 = const (); // scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2
// ty::Const
// + ty: ()
bb0: {
StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:12:9: 12:10
_1 = const 4_i32; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000004))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) }
StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:13:9: 13:10
_2 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:13:13: 13:34
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10
_3 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:38
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/optimizes_into_variable.rs:14:13: 14:38
- // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
_0 = const (); // scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2
// ty::Const
// + ty: ()
// + literal: Const { ty: &u8, val: Value(Scalar(alloc0)) }
- _2 = (*_3); // scope 0 at $DIR/read_immutable_static.rs:7:13: 7:16
+ _2 = const 2_u8; // scope 0 at $DIR/read_immutable_static.rs:7:13: 7:16
-+ // ty::Const
-+ // + ty: u8
-+ // + val: Value(Scalar(0x02))
-+ // mir::Constant
-+ // + span: $DIR/read_immutable_static.rs:7:13: 7:16
-+ // + literal: Const { ty: u8, val: Value(Scalar(0x02)) }
StorageLive(_4); // scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22
StorageLive(_5); // scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22
_5 = const {alloc0: &u8}; // scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22
- _4 = (*_5); // scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22
- _1 = Add(move _2, move _4); // scope 0 at $DIR/read_immutable_static.rs:7:13: 7:22
+ _4 = const 2_u8; // scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22
-+ // ty::Const
-+ // + ty: u8
-+ // + val: Value(Scalar(0x02))
-+ // mir::Constant
-+ // + span: $DIR/read_immutable_static.rs:7:19: 7:22
-+ // + literal: Const { ty: u8, val: Value(Scalar(0x02)) }
+ _1 = const 4_u8; // scope 0 at $DIR/read_immutable_static.rs:7:13: 7:22
-+ // ty::Const
-+ // + ty: u8
-+ // + val: Value(Scalar(0x04))
-+ // mir::Constant
-+ // + span: $DIR/read_immutable_static.rs:7:13: 7:22
-+ // + literal: Const { ty: u8, val: Value(Scalar(0x04)) }
StorageDead(_4); // scope 0 at $DIR/read_immutable_static.rs:7:21: 7:22
StorageDead(_2); // scope 0 at $DIR/read_immutable_static.rs:7:21: 7:22
StorageDead(_5); // scope 0 at $DIR/read_immutable_static.rs:7:22: 7:23
_2 = _4; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
- _1 = (*_2); // scope 0 at $DIR/ref_deref.rs:5:5: 5:10
+ _1 = const 4_i32; // scope 0 at $DIR/ref_deref.rs:5:5: 5:10
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x00000004))
-+ // mir::Constant
-+ // + span: $DIR/ref_deref.rs:5:5: 5:10
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) }
StorageDead(_2); // scope 0 at $DIR/ref_deref.rs:5:10: 5:11
StorageDead(_1); // scope 0 at $DIR/ref_deref.rs:5:10: 5:11
_0 = const (); // scope 0 at $DIR/ref_deref.rs:4:11: 6:2
StorageLive(_2); // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
- StorageLive(_3); // scope 0 at $DIR/ref_deref.rs:5:8: 5:9
- _3 = const 4_i32; // scope 0 at $DIR/ref_deref.rs:5:8: 5:9
+- _2 = &_3; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
+ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
- // ty::Const
-- // + ty: i32
-- // + val: Value(Scalar(0x00000004))
++ // ty::Const
+ // + ty: &i32
+ // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main[0]), const_param_did: None }, [], Some(promoted[0]))
- // mir::Constant
-- // + span: $DIR/ref_deref.rs:5:8: 5:9
-- // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) }
-- _2 = &_3; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
++ // mir::Constant
+ // + span: $DIR/ref_deref.rs:5:6: 5:10
+ // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) }
+ _2 = &(*_4); // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
StorageLive(_2); // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
- StorageLive(_3); // scope 0 at $DIR/ref_deref_project.rs:5:8: 5:14
- _3 = (const 4_i32, const 5_i32); // scope 0 at $DIR/ref_deref_project.rs:5:8: 5:14
+- _2 = &(_3.1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
+ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
- // ty::Const
-- // + ty: i32
-- // + val: Value(Scalar(0x00000004))
++ // ty::Const
+ // + ty: &(i32, i32)
+ // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main[0]), const_param_did: None }, [], Some(promoted[0]))
- // mir::Constant
-- // + span: $DIR/ref_deref_project.rs:5:9: 5:10
-- // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) }
-- // ty::Const
-- // + ty: i32
-- // + val: Value(Scalar(0x00000005))
-- // mir::Constant
-- // + span: $DIR/ref_deref_project.rs:5:12: 5:13
-- // + literal: Const { ty: i32, val: Value(Scalar(0x00000005)) }
-- _2 = &(_3.1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
++ // mir::Constant
+ // + span: $DIR/ref_deref_project.rs:5:6: 5:17
+ // + literal: Const { ty: &(i32, i32), val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) }
+ _2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
StorageLive(_2); // scope 0 at $DIR/repeat.rs:6:18: 6:28
StorageLive(_3); // scope 0 at $DIR/repeat.rs:6:18: 6:25
_3 = [const 42_u32; 8]; // scope 0 at $DIR/repeat.rs:6:18: 6:25
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/repeat.rs:6:19: 6:21
- // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
StorageLive(_4); // scope 0 at $DIR/repeat.rs:6:26: 6:27
_4 = const 2_usize; // scope 0 at $DIR/repeat.rs:6:26: 6:27
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/repeat.rs:6:26: 6:27
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000002)) }
_5 = const 8_usize; // scope 0 at $DIR/repeat.rs:6:18: 6:28
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000008))
- // mir::Constant
- // + span: $DIR/repeat.rs:6:18: 6:28
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000008)) }
- _6 = Lt(_4, _5); // scope 0 at $DIR/repeat.rs:6:18: 6:28
- assert(move _6, "index out of bounds: the len is {} but the index is {}", move _5, _4) -> bb1; // scope 0 at $DIR/repeat.rs:6:18: 6:28
+ _6 = const true; // scope 0 at $DIR/repeat.rs:6:18: 6:28
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/repeat.rs:6:18: 6:28
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
+ assert(const true, "index out of bounds: the len is {} but the index is {}", const 8_usize, const 2_usize) -> bb1; // scope 0 at $DIR/repeat.rs:6:18: 6:28
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/repeat.rs:6:18: 6:28
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x00000008))
-+ // mir::Constant
-+ // + span: $DIR/repeat.rs:6:18: 6:28
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x00000008)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x00000002))
-+ // mir::Constant
-+ // + span: $DIR/repeat.rs:6:18: 6:28
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x00000002)) }
}
bb1: {
- _2 = _3[_4]; // scope 0 at $DIR/repeat.rs:6:18: 6:28
- _1 = Add(move _2, const 0_u32); // scope 0 at $DIR/repeat.rs:6:18: 6:32
+ _2 = const 42_u32; // scope 0 at $DIR/repeat.rs:6:18: 6:28
- // ty::Const
- // + ty: u32
-- // + val: Value(Scalar(0x00000000))
-+ // + val: Value(Scalar(0x0000002a))
- // mir::Constant
-- // + span: $DIR/repeat.rs:6:31: 6:32
-- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
-+ // + span: $DIR/repeat.rs:6:18: 6:28
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
+ _1 = const 42_u32; // scope 0 at $DIR/repeat.rs:6:18: 6:32
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x0000002a))
-+ // mir::Constant
-+ // + span: $DIR/repeat.rs:6:18: 6:32
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
StorageDead(_2); // scope 0 at $DIR/repeat.rs:6:31: 6:32
StorageDead(_4); // scope 0 at $DIR/repeat.rs:6:32: 6:33
StorageDead(_3); // scope 0 at $DIR/repeat.rs:6:32: 6:33
StorageLive(_2); // scope 0 at $DIR/repeat.rs:6:18: 6:28
StorageLive(_3); // scope 0 at $DIR/repeat.rs:6:18: 6:25
_3 = [const 42_u32; 8]; // scope 0 at $DIR/repeat.rs:6:18: 6:25
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/repeat.rs:6:19: 6:21
- // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
StorageLive(_4); // scope 0 at $DIR/repeat.rs:6:26: 6:27
_4 = const 2_usize; // scope 0 at $DIR/repeat.rs:6:26: 6:27
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000002))
- // mir::Constant
- // + span: $DIR/repeat.rs:6:26: 6:27
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000002)) }
_5 = const 8_usize; // scope 0 at $DIR/repeat.rs:6:18: 6:28
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000008))
- // mir::Constant
- // + span: $DIR/repeat.rs:6:18: 6:28
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000008)) }
- _6 = Lt(_4, _5); // scope 0 at $DIR/repeat.rs:6:18: 6:28
- assert(move _6, "index out of bounds: the len is {} but the index is {}", move _5, _4) -> bb1; // scope 0 at $DIR/repeat.rs:6:18: 6:28
+ _6 = const true; // scope 0 at $DIR/repeat.rs:6:18: 6:28
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/repeat.rs:6:18: 6:28
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
+ assert(const true, "index out of bounds: the len is {} but the index is {}", const 8_usize, const 2_usize) -> bb1; // scope 0 at $DIR/repeat.rs:6:18: 6:28
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/repeat.rs:6:18: 6:28
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x0000000000000008))
-+ // mir::Constant
-+ // + span: $DIR/repeat.rs:6:18: 6:28
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000008)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x0000000000000002))
-+ // mir::Constant
-+ // + span: $DIR/repeat.rs:6:18: 6:28
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000002)) }
}
bb1: {
- _2 = _3[_4]; // scope 0 at $DIR/repeat.rs:6:18: 6:28
- _1 = Add(move _2, const 0_u32); // scope 0 at $DIR/repeat.rs:6:18: 6:32
+ _2 = const 42_u32; // scope 0 at $DIR/repeat.rs:6:18: 6:28
- // ty::Const
- // + ty: u32
-- // + val: Value(Scalar(0x00000000))
-+ // + val: Value(Scalar(0x0000002a))
- // mir::Constant
-- // + span: $DIR/repeat.rs:6:31: 6:32
-- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
-+ // + span: $DIR/repeat.rs:6:18: 6:28
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
+ _1 = const 42_u32; // scope 0 at $DIR/repeat.rs:6:18: 6:32
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x0000002a))
-+ // mir::Constant
-+ // + span: $DIR/repeat.rs:6:18: 6:32
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
StorageDead(_2); // scope 0 at $DIR/repeat.rs:6:31: 6:32
StorageDead(_4); // scope 0 at $DIR/repeat.rs:6:32: 6:33
StorageDead(_3); // scope 0 at $DIR/repeat.rs:6:32: 6:33
bb0: {
- _1 = CheckedAdd(const 2_u32, const 2_u32); // scope 0 at $DIR/return_place.rs:6:5: 6:10
-+ _1 = (const 4_u32, const false); // scope 0 at $DIR/return_place.rs:6:5: 6:10
- // ty::Const
- // + ty: u32
-- // + val: Value(Scalar(0x00000002))
-+ // + val: Value(Scalar(0x00000004))
- // mir::Constant
-- // + span: $DIR/return_place.rs:6:5: 6:6
-- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
-+ // + span: $DIR/return_place.rs:6:5: 6:10
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000004)) }
- // ty::Const
-- // + ty: u32
-- // + val: Value(Scalar(0x00000002))
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
- // mir::Constant
-- // + span: $DIR/return_place.rs:6:9: 6:10
-- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
- assert(!move (_1.1: bool), "attempt to compute `{} + {}` which would overflow", const 2_u32, const 2_u32) -> bb1; // scope 0 at $DIR/return_place.rs:6:5: 6:10
-+ // + span: $DIR/return_place.rs:6:5: 6:10
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
++ _1 = (const 4_u32, const false); // scope 0 at $DIR/return_place.rs:6:5: 6:10
+ assert(!const false, "attempt to compute `{} + {}` which would overflow", const 2_u32, const 2_u32) -> bb1; // scope 0 at $DIR/return_place.rs:6:5: 6:10
- // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
-+ // mir::Constant
-+ // + span: $DIR/return_place.rs:6:5: 6:10
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
-+ // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/return_place.rs:6:5: 6:6
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/return_place.rs:6:9: 6:10
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
}
bb1: {
- _0 = move (_1.0: u32); // scope 0 at $DIR/return_place.rs:6:5: 6:10
+ _0 = const 4_u32; // scope 0 at $DIR/return_place.rs:6:5: 6:10
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x00000004))
-+ // mir::Constant
-+ // + span: $DIR/return_place.rs:6:5: 6:10
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000004)) }
return; // scope 0 at $DIR/return_place.rs:7:2: 7:2
}
}
bb0: {
_0 = const 4_u32; // scope 0 at $DIR/return_place.rs:6:5: 6:10
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000004))
- // mir::Constant
- // + span: $DIR/return_place.rs:6:5: 6:10
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000004)) }
return; // scope 0 at $DIR/return_place.rs:7:2: 7:2
}
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/scalar_literal_propagation.rs:3:9: 3:10
_1 = const 1_u32; // scope 0 at $DIR/scalar_literal_propagation.rs:3:13: 3:14
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/scalar_literal_propagation.rs:3:13: 3:14
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
StorageLive(_2); // scope 1 at $DIR/scalar_literal_propagation.rs:4:5: 4:15
StorageLive(_3); // scope 1 at $DIR/scalar_literal_propagation.rs:4:13: 4:14
- _3 = _1; // scope 1 at $DIR/scalar_literal_propagation.rs:4:13: 4:14
- _2 = const consume(move _3) -> bb1; // scope 1 at $DIR/scalar_literal_propagation.rs:4:5: 4:15
+ _3 = const 1_u32; // scope 1 at $DIR/scalar_literal_propagation.rs:4:13: 4:14
- // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x00000001))
-+ // mir::Constant
-+ // + span: $DIR/scalar_literal_propagation.rs:4:13: 4:14
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
+ _2 = const consume(const 1_u32) -> bb1; // scope 1 at $DIR/scalar_literal_propagation.rs:4:5: 4:15
-+ // ty::Const
+ // ty::Const
// + ty: fn(u32) {consume}
// + val: Value(Scalar(<ZST>))
// mir::Constant
// + span: $DIR/scalar_literal_propagation.rs:4:5: 4:12
// + literal: Const { ty: fn(u32) {consume}, val: Value(Scalar(<ZST>)) }
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x00000001))
-+ // mir::Constant
-+ // + span: $DIR/scalar_literal_propagation.rs:4:5: 4:15
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
}
bb1: {
StorageDead(_3); // scope 0 at $DIR/slice_len.rs:5:18: 5:19
StorageLive(_6); // scope 0 at $DIR/slice_len.rs:5:31: 5:32
_6 = const 1_usize; // scope 0 at $DIR/slice_len.rs:5:31: 5:32
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/slice_len.rs:5:31: 5:32
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000001)) }
- _7 = Len((*_2)); // scope 0 at $DIR/slice_len.rs:5:5: 5:33
- _8 = Lt(_6, _7); // scope 0 at $DIR/slice_len.rs:5:5: 5:33
- assert(move _8, "index out of bounds: the len is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
+ _7 = const 3_usize; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x00000003))
-+ // mir::Constant
-+ // + span: $DIR/slice_len.rs:5:5: 5:33
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x00000003)) }
+ _8 = const true; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/slice_len.rs:5:5: 5:33
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
+ assert(const true, "index out of bounds: the len is {} but the index is {}", const 3_usize, const 1_usize) -> bb1; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/slice_len.rs:5:5: 5:33
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x00000003))
-+ // mir::Constant
-+ // + span: $DIR/slice_len.rs:5:5: 5:33
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x00000003)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x00000001))
-+ // mir::Constant
-+ // + span: $DIR/slice_len.rs:5:5: 5:33
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x00000001)) }
}
bb1: {
- _1 = (*_2)[_6]; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
+ _1 = const 2_u32; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x00000002))
-+ // mir::Constant
-+ // + span: $DIR/slice_len.rs:5:5: 5:33
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageDead(_6); // scope 0 at $DIR/slice_len.rs:5:33: 5:34
StorageDead(_4); // scope 0 at $DIR/slice_len.rs:5:33: 5:34
StorageDead(_2); // scope 0 at $DIR/slice_len.rs:5:33: 5:34
StorageDead(_3); // scope 0 at $DIR/slice_len.rs:5:18: 5:19
StorageLive(_6); // scope 0 at $DIR/slice_len.rs:5:31: 5:32
_6 = const 1_usize; // scope 0 at $DIR/slice_len.rs:5:31: 5:32
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000001))
- // mir::Constant
- // + span: $DIR/slice_len.rs:5:31: 5:32
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000001)) }
- _7 = Len((*_2)); // scope 0 at $DIR/slice_len.rs:5:5: 5:33
- _8 = Lt(_6, _7); // scope 0 at $DIR/slice_len.rs:5:5: 5:33
- assert(move _8, "index out of bounds: the len is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
+ _7 = const 3_usize; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x0000000000000003))
-+ // mir::Constant
-+ // + span: $DIR/slice_len.rs:5:5: 5:33
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000003)) }
+ _8 = const true; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/slice_len.rs:5:5: 5:33
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
+ assert(const true, "index out of bounds: the len is {} but the index is {}", const 3_usize, const 1_usize) -> bb1; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/slice_len.rs:5:5: 5:33
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x0000000000000003))
-+ // mir::Constant
-+ // + span: $DIR/slice_len.rs:5:5: 5:33
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000003)) }
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x0000000000000001))
-+ // mir::Constant
-+ // + span: $DIR/slice_len.rs:5:5: 5:33
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000001)) }
}
bb1: {
- _1 = (*_2)[_6]; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
+ _1 = const 2_u32; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x00000002))
-+ // mir::Constant
-+ // + span: $DIR/slice_len.rs:5:5: 5:33
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageDead(_6); // scope 0 at $DIR/slice_len.rs:5:33: 5:34
StorageDead(_4); // scope 0 at $DIR/slice_len.rs:5:33: 5:34
StorageDead(_2); // scope 0 at $DIR/slice_len.rs:5:33: 5:34
bb0: {
StorageLive(_1); // scope 0 at $DIR/switch_int.rs:7:11: 7:12
_1 = const 1_i32; // scope 0 at $DIR/switch_int.rs:7:11: 7:12
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/switch_int.rs:7:11: 7:12
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
- switchInt(_1) -> [1_i32: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:8:9: 8:10
+ switchInt(const 1_i32) -> [1_i32: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:8:9: 8:10
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x00000001))
-+ // mir::Constant
-+ // + span: $DIR/switch_int.rs:8:9: 8:10
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
}
bb1: {
// mir::Constant
// + span: $DIR/switch_int.rs:9:14: 9:17
// + literal: Const { ty: fn(i32) {foo}, val: Value(Scalar(<ZST>)) }
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0xffffffff))
- // mir::Constant
- // + span: $DIR/switch_int.rs:9:18: 9:20
- // + literal: Const { ty: i32, val: Value(Scalar(0xffffffff)) }
}
bb2: {
// mir::Constant
// + span: $DIR/switch_int.rs:8:14: 8:17
// + literal: Const { ty: fn(i32) {foo}, val: Value(Scalar(<ZST>)) }
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/switch_int.rs:8:18: 8:19
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
}
bb3: {
bb0: {
StorageLive(_1); // scope 0 at $DIR/switch_int.rs:7:11: 7:12
_1 = const 1_i32; // scope 0 at $DIR/switch_int.rs:7:11: 7:12
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/switch_int.rs:7:11: 7:12
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
- switchInt(const 1_i32) -> [1_i32: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:8:9: 8:10
-- // ty::Const
-- // + ty: i32
-- // + val: Value(Scalar(0x00000001))
-- // mir::Constant
-- // + span: $DIR/switch_int.rs:8:9: 8:10
-- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
+ goto -> bb2; // scope 0 at $DIR/switch_int.rs:8:9: 8:10
}
// mir::Constant
// + span: $DIR/switch_int.rs:9:14: 9:17
// + literal: Const { ty: fn(i32) {foo}, val: Value(Scalar(<ZST>)) }
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0xffffffff))
- // mir::Constant
- // + span: $DIR/switch_int.rs:9:18: 9:20
- // + literal: Const { ty: i32, val: Value(Scalar(0xffffffff)) }
}
bb2: {
// mir::Constant
// + span: $DIR/switch_int.rs:8:14: 8:17
// + literal: Const { ty: fn(i32) {foo}, val: Value(Scalar(<ZST>)) }
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/switch_int.rs:8:18: 8:19
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
}
bb3: {
bb0: {
StorageLive(_1); // scope 0 at $DIR/tuple_literal_propagation.rs:3:9: 3:10
(_1.0: u32) = const 1_u32; // scope 0 at $DIR/tuple_literal_propagation.rs:3:13: 3:19
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/tuple_literal_propagation.rs:3:14: 3:15
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
(_1.1: u32) = const 2_u32; // scope 0 at $DIR/tuple_literal_propagation.rs:3:13: 3:19
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/tuple_literal_propagation.rs:3:17: 3:18
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageLive(_2); // scope 1 at $DIR/tuple_literal_propagation.rs:5:5: 5:15
StorageLive(_3); // scope 1 at $DIR/tuple_literal_propagation.rs:5:13: 5:14
- _3 = _1; // scope 1 at $DIR/tuple_literal_propagation.rs:5:13: 5:14
+ _3 = (const 1_u32, const 2_u32); // scope 1 at $DIR/tuple_literal_propagation.rs:5:13: 5:14
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x00000001))
-+ // mir::Constant
-+ // + span: $DIR/tuple_literal_propagation.rs:5:13: 5:14
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x00000002))
-+ // mir::Constant
-+ // + span: $DIR/tuple_literal_propagation.rs:5:13: 5:14
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
_2 = const consume(move _3) -> bb1; // scope 1 at $DIR/tuple_literal_propagation.rs:5:5: 5:15
// ty::Const
// + ty: fn((u32, u32)) {consume}
bb0: {
StorageLive(_1); // scope 0 at $DIR/const_prop_miscompile.rs:12:9: 12:14
(_1.0: i32) = const 1_i32; // scope 0 at $DIR/const_prop_miscompile.rs:12:17: 12:21
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/const_prop_miscompile.rs:12:18: 12:19
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
StorageLive(_2); // scope 1 at $DIR/const_prop_miscompile.rs:13:5: 15:6
StorageLive(_3); // scope 2 at $DIR/const_prop_miscompile.rs:14:10: 14:22
_3 = &raw mut (_1.0: i32); // scope 2 at $DIR/const_prop_miscompile.rs:14:10: 14:22
(*_3) = const 5_i32; // scope 2 at $DIR/const_prop_miscompile.rs:14:9: 14:26
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000005))
- // mir::Constant
- // + span: $DIR/const_prop_miscompile.rs:14:25: 14:26
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000005)) }
StorageDead(_3); // scope 2 at $DIR/const_prop_miscompile.rs:14:26: 14:27
_2 = const (); // scope 2 at $DIR/const_prop_miscompile.rs:13:5: 15:6
// ty::Const
StorageLive(_5); // scope 1 at $DIR/const_prop_miscompile.rs:16:13: 16:20
_5 = (_1.0: i32); // scope 1 at $DIR/const_prop_miscompile.rs:16:15: 16:18
_4 = Eq(move _5, const 5_i32); // scope 1 at $DIR/const_prop_miscompile.rs:16:13: 16:25
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000005))
- // mir::Constant
- // + span: $DIR/const_prop_miscompile.rs:16:24: 16:25
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000005)) }
StorageDead(_5); // scope 1 at $DIR/const_prop_miscompile.rs:16:24: 16:25
_0 = const (); // scope 0 at $DIR/const_prop_miscompile.rs:11:10: 17:2
// ty::Const
bb0: {
StorageLive(_1); // scope 0 at $DIR/const_prop_miscompile.rs:5:9: 5:14
(_1.0: i32) = const 1_i32; // scope 0 at $DIR/const_prop_miscompile.rs:5:17: 5:21
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/const_prop_miscompile.rs:5:18: 5:19
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
StorageLive(_2); // scope 1 at $DIR/const_prop_miscompile.rs:6:6: 6:14
_2 = &mut (_1.0: i32); // scope 1 at $DIR/const_prop_miscompile.rs:6:6: 6:14
(*_2) = const 5_i32; // scope 1 at $DIR/const_prop_miscompile.rs:6:5: 6:18
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000005))
- // mir::Constant
- // + span: $DIR/const_prop_miscompile.rs:6:17: 6:18
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000005)) }
StorageDead(_2); // scope 1 at $DIR/const_prop_miscompile.rs:6:18: 6:19
StorageLive(_3); // scope 1 at $DIR/const_prop_miscompile.rs:7:9: 7:10
StorageLive(_4); // scope 1 at $DIR/const_prop_miscompile.rs:7:13: 7:20
_4 = (_1.0: i32); // scope 1 at $DIR/const_prop_miscompile.rs:7:15: 7:18
_3 = Eq(move _4, const 5_i32); // scope 1 at $DIR/const_prop_miscompile.rs:7:13: 7:25
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000005))
- // mir::Constant
- // + span: $DIR/const_prop_miscompile.rs:7:24: 7:25
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000005)) }
StorageDead(_4); // scope 1 at $DIR/const_prop_miscompile.rs:7:24: 7:25
_0 = const (); // scope 0 at $DIR/const_prop_miscompile.rs:4:10: 8:2
// ty::Const
StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:28:9: 28:10
_2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:28:13: 28:14
_1 = const 123_i32; // scope 1 at $DIR/copy_propagation_arg.rs:29:5: 29:12
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x0000007b))
- // mir::Constant
- // + span: $DIR/copy_propagation_arg.rs:29:9: 29:12
- // + literal: Const { ty: i32, val: Value(Scalar(0x0000007b)) }
_0 = _2; // scope 1 at $DIR/copy_propagation_arg.rs:30:5: 30:6
StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:31:1: 31:2
return; // scope 0 at $DIR/copy_propagation_arg.rs:31:2: 31:2
StorageDead(_3); // scope 0 at $DIR/copy_propagation_arg.rs:16:12: 16:13
StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:16:13: 16:14
_1 = const 5_u8; // scope 0 at $DIR/copy_propagation_arg.rs:17:5: 17:10
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x05))
- // mir::Constant
- // + span: $DIR/copy_propagation_arg.rs:17:9: 17:10
- // + literal: Const { ty: u8, val: Value(Scalar(0x05)) }
_0 = const (); // scope 0 at $DIR/copy_propagation_arg.rs:15:19: 18:2
// ty::Const
// + ty: ()
// + span: $DIR/deaggregator_test.rs:9:20: 9:23
// + literal: Const { ty: f32, val: Value(Scalar(0x00000000)) }
+ (_0.2: bool) = const false; // scope 0 at $DIR/deaggregator_test.rs:9:5: 9:35
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/deaggregator_test.rs:9:28: 9:33
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
StorageDead(_2); // scope 0 at $DIR/deaggregator_test.rs:9:34: 9:35
return; // scope 0 at $DIR/deaggregator_test.rs:10:2: 10:2
}
bb1: {
_0 = const 0_u32; // scope 0 at $DIR/exponential-or.rs:9:14: 9:15
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/exponential-or.rs:9:14: 9:15
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
goto -> bb10; // scope 0 at $DIR/exponential-or.rs:7:5: 10:6
}
bb4: {
_5 = Le(const 6_u32, (_1.3: u32)); // scope 0 at $DIR/exponential-or.rs:8:62: 8:67
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000006))
- // mir::Constant
- // + span: $DIR/exponential-or.rs:8:62: 8:67
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000006)) }
switchInt(move _5) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/exponential-or.rs:8:62: 8:67
}
bb5: {
_6 = Le((_1.3: u32), const 9_u32); // scope 0 at $DIR/exponential-or.rs:8:62: 8:67
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000009))
- // mir::Constant
- // + span: $DIR/exponential-or.rs:8:62: 8:67
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000009)) }
switchInt(move _6) -> [false: bb6, otherwise: bb8]; // scope 0 at $DIR/exponential-or.rs:8:62: 8:67
}
bb6: {
_3 = Le(const 13_u32, (_1.3: u32)); // scope 0 at $DIR/exponential-or.rs:8:70: 8:77
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x0000000d))
- // mir::Constant
- // + span: $DIR/exponential-or.rs:8:70: 8:77
- // + literal: Const { ty: u32, val: Value(Scalar(0x0000000d)) }
switchInt(move _3) -> [false: bb1, otherwise: bb7]; // scope 0 at $DIR/exponential-or.rs:8:70: 8:77
}
bb7: {
_4 = Le((_1.3: u32), const 16_u32); // scope 0 at $DIR/exponential-or.rs:8:70: 8:77
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000010))
- // mir::Constant
- // + span: $DIR/exponential-or.rs:8:70: 8:77
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000010)) }
switchInt(move _4) -> [false: bb1, otherwise: bb8]; // scope 0 at $DIR/exponential-or.rs:8:70: 8:77
}
_15 = move _16 as u32 (Misc); // scope 3 at $DIR/funky_arms.rs:26:59: 26:75
StorageDead(_16); // scope 3 at $DIR/funky_arms.rs:26:74: 26:75
_14 = Add(move _15, const 1_u32); // scope 3 at $DIR/funky_arms.rs:26:59: 26:79
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/funky_arms.rs:26:78: 26:79
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
StorageDead(_15); // scope 3 at $DIR/funky_arms.rs:26:78: 26:79
StorageLive(_17); // scope 3 at $DIR/funky_arms.rs:26:81: 26:86
_17 = _3; // scope 3 at $DIR/funky_arms.rs:26:81: 26:86
bb0: {
StorageLive(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:23:13: 23:14
(_3.0: i32) = const 5_i32; // scope 0 at $DIR/generator-storage-dead-unwind.rs:23:17: 23:23
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000005))
- // mir::Constant
- // + span: $DIR/generator-storage-dead-unwind.rs:23:21: 23:22
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000005)) }
StorageLive(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:24:13: 24:14
(_4.0: i32) = const 6_i32; // scope 1 at $DIR/generator-storage-dead-unwind.rs:24:17: 24:23
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000006))
- // mir::Constant
- // + span: $DIR/generator-storage-dead-unwind.rs:24:21: 24:22
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000006)) }
StorageLive(_5); // scope 2 at $DIR/generator-storage-dead-unwind.rs:25:9: 25:14
StorageLive(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:25:9: 25:14
_5 = yield(move _6) -> [resume: bb2, drop: bb4]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:25:9: 25:14
StorageLive(_2); // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:6
_2 = _1; // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:6
_3 = const 1_i32; // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/inline-any-operand.rs:12:7: 12:8
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
_4 = const -1_i32; // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0xffffffff))
- // mir::Constant
- // + span: $DIR/inline-any-operand.rs:12:10: 12:12
- // + literal: Const { ty: i32, val: Value(Scalar(0xffffffff)) }
_0 = Eq(move _3, move _4); // scope 2 at $DIR/inline-any-operand.rs:17:5: 17:11
StorageDead(_2); // scope 1 at $DIR/inline-any-operand.rs:12:12: 12:13
StorageDead(_1); // scope 0 at $DIR/inline-any-operand.rs:13:1: 13:2
+ // + user_ty: UserType(0)
+ // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
+ ((*_4).1: usize) = const 0_usize; // scope 2 at $SRC_DIR/alloc/src/vec.rs:LL:COL
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x00000000))
-+ // mir::Constant
-+ // + span: $SRC_DIR/alloc/src/vec.rs:LL:COL
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x00000000)) }
_1 = move _2; // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
StorageDead(_2); // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
_0 = const (); // scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2
+ // + user_ty: UserType(0)
+ // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [65535], len: Size { raw: 16 } }, size: Size { raw: 16 }, align: Align { pow2: 3 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
+ ((*_4).1: usize) = const 0_usize; // scope 2 at $SRC_DIR/alloc/src/vec.rs:LL:COL
-+ // ty::Const
-+ // + ty: usize
-+ // + val: Value(Scalar(0x0000000000000000))
-+ // mir::Constant
-+ // + span: $SRC_DIR/alloc/src/vec.rs:LL:COL
-+ // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) }
_1 = move _2; // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
StorageDead(_2); // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
_0 = const (); // scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2
bb0: {
StorageLive(_1); // scope 0 at $DIR/inline-specialization.rs:5:9: 5:10
- _1 = const <std::vec::Vec<()> as Foo>::bar() -> bb1; // scope 0 at $DIR/inline-specialization.rs:5:13: 5:38
-+ _1 = const 123_u32; // scope 2 at $DIR/inline-specialization.rs:14:31: 14:34
- // ty::Const
+- // ty::Const
- // + ty: fn() -> u32 {<std::vec::Vec<()> as Foo>::bar}
- // + val: Value(Scalar(<ZST>))
-+ // + ty: u32
-+ // + val: Value(Scalar(0x0000007b))
- // mir::Constant
+- // mir::Constant
- // + span: $DIR/inline-specialization.rs:5:13: 5:36
- // + literal: Const { ty: fn() -> u32 {<std::vec::Vec<()> as Foo>::bar}, val: Value(Scalar(<ZST>)) }
- }
-
- bb1: {
-+ // + span: $DIR/inline-specialization.rs:14:31: 14:34
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x0000007b)) }
++ _1 = const 123_u32; // scope 2 at $DIR/inline-specialization.rs:14:31: 14:34
_0 = const (); // scope 0 at $DIR/inline-specialization.rs:4:11: 6:2
// ty::Const
// + ty: ()
+ // + span: /the/src/instrument_coverage.rs:19:18: 19:18
+ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u64, u32, &'static str, u32, u32, u32, u32) {std::intrinsics::count_code_region}, val: Value(Scalar(<ZST>)) }
+ // ty::Const
-+ // + ty: u64
-+ // + val: Value(Scalar(0x8dabe565aaa2aefd))
-+ // mir::Constant
-+ // + span: /the/src/instrument_coverage.rs:19:18: 19:18
-+ // + literal: Const { ty: u64, val: Value(Scalar(0x8dabe565aaa2aefd)) }
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x00000000))
-+ // mir::Constant
-+ // + span: /the/src/instrument_coverage.rs:19:18: 19:18
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
-+ // ty::Const
+ // + ty: &str
+ // + val: Value(Slice { data: Allocation { bytes: [47, 116, 104, 101, 47, 115, 114, 99, 47, 105, 110, 115, 116, 114, 117, 109, 101, 110, 116, 95, 99, 111, 118, 101, 114, 97, 103, 101, 46, 114, 115], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [2147483647], len: Size { raw: 31 } }, size: Size { raw: 31 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 31 })
+ // mir::Constant
+ // + span: /the/src/instrument_coverage.rs:19:18: 19:18
+ // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [47, 116, 104, 101, 47, 115, 114, 99, 47, 105, 110, 115, 116, 114, 117, 109, 101, 110, 116, 95, 99, 111, 118, 101, 114, 97, 103, 101, 46, 114, 115], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [2147483647], len: Size { raw: 31 } }, size: Size { raw: 31 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 31 }) }
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x00000013))
-+ // mir::Constant
-+ // + span: /the/src/instrument_coverage.rs:19:18: 19:18
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000013)) }
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x00000012))
-+ // mir::Constant
-+ // + span: /the/src/instrument_coverage.rs:19:18: 19:18
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000012)) }
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x00000015))
-+ // mir::Constant
-+ // + span: /the/src/instrument_coverage.rs:19:18: 19:18
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000015)) }
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x00000002))
-+ // mir::Constant
-+ // + span: /the/src/instrument_coverage.rs:19:18: 19:18
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
+ }
+
+ bb1 (cleanup): {
+ bb2: {
+ StorageDead(_1); // scope 0 at /the/src/instrument_coverage.rs:20:5: 20:9
_0 = const true; // scope 0 at /the/src/instrument_coverage.rs:20:5: 20:9
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: /the/src/instrument_coverage.rs:20:5: 20:9
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
return; // scope 0 at /the/src/instrument_coverage.rs:21:2: 21:2
}
}
+ // + span: /the/src/instrument_coverage.rs:10:11: 10:11
+ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u64, u32, &'static str, u32, u32, u32, u32) {std::intrinsics::count_code_region}, val: Value(Scalar(<ZST>)) }
+ // ty::Const
-+ // + ty: u64
-+ // + val: Value(Scalar(0xde1b3f75a72fc7f7))
-+ // mir::Constant
-+ // + span: /the/src/instrument_coverage.rs:10:11: 10:11
-+ // + literal: Const { ty: u64, val: Value(Scalar(0xde1b3f75a72fc7f7)) }
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x00000000))
-+ // mir::Constant
-+ // + span: /the/src/instrument_coverage.rs:10:11: 10:11
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
-+ // ty::Const
+ // + ty: &str
+ // + val: Value(Slice { data: Allocation { bytes: [47, 116, 104, 101, 47, 115, 114, 99, 47, 105, 110, 115, 116, 114, 117, 109, 101, 110, 116, 95, 99, 111, 118, 101, 114, 97, 103, 101, 46, 114, 115], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [2147483647], len: Size { raw: 31 } }, size: Size { raw: 31 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 31 })
+ // mir::Constant
+ // + span: /the/src/instrument_coverage.rs:10:11: 10:11
+ // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [47, 116, 104, 101, 47, 115, 114, 99, 47, 105, 110, 115, 116, 114, 117, 109, 101, 110, 116, 95, 99, 111, 118, 101, 114, 97, 103, 101, 46, 114, 115], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [2147483647], len: Size { raw: 31 } }, size: Size { raw: 31 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 31 }) }
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x0000000a))
-+ // mir::Constant
-+ // + span: /the/src/instrument_coverage.rs:10:11: 10:11
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x0000000a)) }
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x0000000b))
-+ // mir::Constant
-+ // + span: /the/src/instrument_coverage.rs:10:11: 10:11
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x0000000b)) }
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x00000010))
-+ // mir::Constant
-+ // + span: /the/src/instrument_coverage.rs:10:11: 10:11
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000010)) }
-+ // ty::Const
-+ // + ty: u32
-+ // + val: Value(Scalar(0x00000002))
-+ // mir::Constant
-+ // + span: /the/src/instrument_coverage.rs:10:11: 10:11
-+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
}
bb1: {
bb0: {
StorageLive(_1); // scope 0 at $DIR/issue-38669.rs:5:9: 5:25
_1 = const false; // scope 0 at $DIR/issue-38669.rs:5:28: 5:33
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-38669.rs:5:28: 5:33
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
FakeRead(ForLet, _1); // scope 0 at $DIR/issue-38669.rs:5:9: 5:25
goto -> bb2; // scope 1 at $DIR/issue-38669.rs:6:5: 11:6
}
StorageDead(_4); // scope 1 at $DIR/issue-38669.rs:9:9: 9:10
StorageDead(_3); // scope 1 at $DIR/issue-38669.rs:9:9: 9:10
_1 = const true; // scope 1 at $DIR/issue-38669.rs:10:9: 10:28
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/issue-38669.rs:10:24: 10:28
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
_2 = const (); // scope 1 at $DIR/issue-38669.rs:6:10: 11:6
// ty::Const
// + ty: ()
bb0: {
_5 = const false; // scope 0 at $DIR/issue-41110.rs:8:9: 8:10
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-41110.rs:8:9: 8:10
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
StorageLive(_1); // scope 0 at $DIR/issue-41110.rs:8:9: 8:10
StorageLive(_2); // scope 0 at $DIR/issue-41110.rs:8:13: 8:14
_5 = const true; // scope 0 at $DIR/issue-41110.rs:8:13: 8:14
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/issue-41110.rs:8:13: 8:14
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
_2 = S; // scope 0 at $DIR/issue-41110.rs:8:13: 8:14
StorageLive(_3); // scope 0 at $DIR/issue-41110.rs:8:21: 8:27
StorageLive(_4); // scope 0 at $DIR/issue-41110.rs:8:21: 8:22
bb2: {
StorageDead(_4); // scope 0 at $DIR/issue-41110.rs:8:26: 8:27
_5 = const false; // scope 0 at $DIR/issue-41110.rs:8:13: 8:28
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-41110.rs:8:13: 8:28
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
_1 = const S::other(move _2, move _3) -> [return: bb6, unwind: bb5]; // scope 0 at $DIR/issue-41110.rs:8:13: 8:28
// ty::Const
// + ty: fn(S, S) {S::other}
bb6: {
StorageDead(_3); // scope 0 at $DIR/issue-41110.rs:8:27: 8:28
_5 = const false; // scope 0 at $DIR/issue-41110.rs:8:27: 8:28
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-41110.rs:8:27: 8:28
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
StorageDead(_2); // scope 0 at $DIR/issue-41110.rs:8:27: 8:28
_0 = const (); // scope 0 at $DIR/issue-41110.rs:7:11: 9:2
// ty::Const
bb8 (cleanup): {
_5 = const false; // scope 0 at $DIR/issue-41110.rs:8:27: 8:28
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-41110.rs:8:27: 8:28
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
goto -> bb7; // scope 0 at $DIR/issue-41110.rs:8:27: 8:28
}
bb0: {
_6 = const false; // scope 0 at $DIR/issue-41110.rs:15:9: 15:10
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-41110.rs:15:9: 15:10
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
StorageLive(_1); // scope 0 at $DIR/issue-41110.rs:15:9: 15:10
_6 = const true; // scope 0 at $DIR/issue-41110.rs:15:13: 15:14
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/issue-41110.rs:15:13: 15:14
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
_1 = S; // scope 0 at $DIR/issue-41110.rs:15:13: 15:14
StorageLive(_2); // scope 1 at $DIR/issue-41110.rs:16:9: 16:14
_2 = S; // scope 1 at $DIR/issue-41110.rs:16:17: 16:18
StorageDead(_3); // scope 2 at $DIR/issue-41110.rs:17:12: 17:13
StorageLive(_5); // scope 2 at $DIR/issue-41110.rs:18:9: 18:10
_6 = const false; // scope 2 at $DIR/issue-41110.rs:18:9: 18:10
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-41110.rs:18:9: 18:10
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
_5 = move _1; // scope 2 at $DIR/issue-41110.rs:18:9: 18:10
goto -> bb12; // scope 2 at $DIR/issue-41110.rs:18:5: 18:6
}
bb10: {
_6 = const false; // scope 0 at $DIR/issue-41110.rs:19:1: 19:2
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-41110.rs:19:1: 19:2
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
StorageDead(_1); // scope 0 at $DIR/issue-41110.rs:19:1: 19:2
return; // scope 0 at $DIR/issue-41110.rs:19:2: 19:2
}
bb14 (cleanup): {
_6 = const false; // scope 0 at $DIR/issue-41110.rs:19:1: 19:2
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-41110.rs:19:1: 19:2
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
goto -> bb13; // scope 0 at $DIR/issue-41110.rs:19:1: 19:2
}
bb0: {
_1 = CheckedAdd(const 1_usize, const 1_usize); // scope 0 at $DIR/issue-41697.rs:18:19: 18:22
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/issue-41697.rs:18:19: 18:20
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000001)) }
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/issue-41697.rs:18:21: 18:22
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000001)) }
assert(!move (_1.1: bool), "attempt to compute `{} + {}` which would overflow", const 1_usize, const 1_usize) -> [success: bb2, unwind: bb1]; // scope 0 at $DIR/issue-41697.rs:18:19: 18:22
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/issue-41697.rs:18:19: 18:20
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000001)) }
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/issue-41697.rs:18:21: 18:22
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000001)) }
}
bb1 (cleanup): {
bb0: {
_1 = CheckedAdd(const 1_usize, const 1_usize); // scope 0 at $DIR/issue-41697.rs:18:19: 18:22
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000001))
- // mir::Constant
- // + span: $DIR/issue-41697.rs:18:19: 18:20
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000001)) }
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000001))
- // mir::Constant
- // + span: $DIR/issue-41697.rs:18:21: 18:22
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000001)) }
assert(!move (_1.1: bool), "attempt to compute `{} + {}` which would overflow", const 1_usize, const 1_usize) -> [success: bb2, unwind: bb1]; // scope 0 at $DIR/issue-41697.rs:18:19: 18:22
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000001))
- // mir::Constant
- // + span: $DIR/issue-41697.rs:18:19: 18:20
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000001)) }
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000001))
- // mir::Constant
- // + span: $DIR/issue-41697.rs:18:21: 18:22
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000001)) }
}
bb1 (cleanup): {
bb0: {
_9 = const false; // scope 0 at $DIR/issue-41888.rs:7:9: 7:10
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-41888.rs:7:9: 7:10
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
_7 = const false; // scope 0 at $DIR/issue-41888.rs:7:9: 7:10
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-41888.rs:7:9: 7:10
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
_8 = const false; // scope 0 at $DIR/issue-41888.rs:7:9: 7:10
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-41888.rs:7:9: 7:10
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
StorageLive(_1); // scope 0 at $DIR/issue-41888.rs:7:9: 7:10
StorageLive(_2); // scope 1 at $DIR/issue-41888.rs:8:8: 8:14
_2 = const cond() -> [return: bb2, unwind: bb3]; // scope 1 at $DIR/issue-41888.rs:8:8: 8:14
bb10: {
StorageLive(_6); // scope 1 at $DIR/issue-41888.rs:10:21: 10:23
_9 = const false; // scope 1 at $DIR/issue-41888.rs:10:21: 10:23
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-41888.rs:10:21: 10:23
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
_6 = move ((_1 as F).0: K); // scope 1 at $DIR/issue-41888.rs:10:21: 10:23
_0 = const (); // scope 2 at $DIR/issue-41888.rs:10:29: 13:10
// ty::Const
bb12: {
_7 = const false; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-41888.rs:15:1: 15:2
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
_8 = const false; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-41888.rs:15:1: 15:2
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
_9 = const false; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-41888.rs:15:1: 15:2
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
StorageDead(_1); // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
StorageDead(_2); // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
return; // scope 0 at $DIR/issue-41888.rs:15:2: 15:2
bb13 (cleanup): {
_7 = const true; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/issue-41888.rs:9:9: 9:10
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
_8 = const true; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/issue-41888.rs:9:9: 9:10
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
_9 = const true; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/issue-41888.rs:9:9: 9:10
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
_1 = move _3; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
goto -> bb7; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
}
bb14: {
_7 = const true; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/issue-41888.rs:9:9: 9:10
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
_8 = const true; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/issue-41888.rs:9:9: 9:10
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
_9 = const true; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/issue-41888.rs:9:9: 9:10
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
_1 = move _3; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
goto -> bb6; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
}
bb15: {
_7 = const false; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-41888.rs:15:1: 15:2
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
goto -> bb12; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
}
bb16 (cleanup): {
_7 = const false; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/issue-41888.rs:15:1: 15:2
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
goto -> bb1; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
}
StorageLive(_2); // scope 0 at $DIR/issue-49232.rs:7:13: 7:19
StorageLive(_3); // scope 0 at $DIR/issue-49232.rs:8:19: 8:23
_3 = const true; // scope 0 at $DIR/issue-49232.rs:8:19: 8:23
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/issue-49232.rs:8:19: 8:23
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
FakeRead(ForMatchedPlace, _3); // scope 0 at $DIR/issue-49232.rs:8:19: 8:23
switchInt(_3) -> [false: bb5, otherwise: bb6]; // scope 0 at $DIR/issue-49232.rs:9:17: 9:22
}
bb7: {
_2 = const 4_i32; // scope 0 at $DIR/issue-49232.rs:9:26: 9:27
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000004))
- // mir::Constant
- // + span: $DIR/issue-49232.rs:9:26: 9:27
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) }
goto -> bb12; // scope 0 at $DIR/issue-49232.rs:8:13: 11:14
}
bb0: {
StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:16:43: 16:44
_2 = const 0_usize; // scope 0 at $DIR/issue-72181.rs:16:43: 16:44
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/issue-72181.rs:16:43: 16:44
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000000)) }
_3 = Len(_1); // scope 0 at $DIR/issue-72181.rs:16:40: 16:45
_4 = Lt(_2, _3); // scope 0 at $DIR/issue-72181.rs:16:40: 16:45
assert(move _4, "index out of bounds: the len is {} but the index is {}", move _3, _2) -> [success: bb2, unwind: bb1]; // scope 0 at $DIR/issue-72181.rs:16:40: 16:45
bb0: {
StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:16:43: 16:44
_2 = const 0_usize; // scope 0 at $DIR/issue-72181.rs:16:43: 16:44
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000000))
- // mir::Constant
- // + span: $DIR/issue-72181.rs:16:43: 16:44
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) }
_3 = Len(_1); // scope 0 at $DIR/issue-72181.rs:16:40: 16:45
_4 = Lt(_2, _3); // scope 0 at $DIR/issue-72181.rs:16:40: 16:45
assert(move _4, "index out of bounds: the len is {} but the index is {}", move _3, _2) -> [success: bb2, unwind: bb1]; // scope 0 at $DIR/issue-72181.rs:16:40: 16:45
StorageLive(_2); // scope 1 at $DIR/issue-72181.rs:26:9: 26:10
StorageLive(_3); // scope 1 at $DIR/issue-72181.rs:26:14: 26:27
_3 = Foo { a: const 42_u64 }; // scope 1 at $DIR/issue-72181.rs:26:14: 26:27
- // ty::Const
- // + ty: u64
- // + val: Value(Scalar(0x000000000000002a))
- // mir::Constant
- // + span: $DIR/issue-72181.rs:26:23: 26:25
- // + literal: Const { ty: u64, val: Value(Scalar(0x000000000000002a)) }
StorageLive(_4); // scope 1 at $DIR/issue-72181.rs:26:29: 26:42
_4 = Foo { a: const 10_u64 }; // scope 1 at $DIR/issue-72181.rs:26:29: 26:42
- // ty::Const
- // + ty: u64
- // + val: Value(Scalar(0x000000000000000a))
- // mir::Constant
- // + span: $DIR/issue-72181.rs:26:38: 26:40
- // + literal: Const { ty: u64, val: Value(Scalar(0x000000000000000a)) }
_2 = [move _3, move _4]; // scope 1 at $DIR/issue-72181.rs:26:13: 26:43
StorageDead(_4); // scope 1 at $DIR/issue-72181.rs:26:42: 26:43
StorageDead(_3); // scope 1 at $DIR/issue-72181.rs:26:42: 26:43
StorageLive(_5); // scope 2 at $DIR/issue-72181.rs:27:13: 27:30
StorageLive(_6); // scope 4 at $DIR/issue-72181.rs:27:24: 27:25
_6 = const 0_usize; // scope 4 at $DIR/issue-72181.rs:27:24: 27:25
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/issue-72181.rs:27:24: 27:25
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000000)) }
_7 = Len(_2); // scope 4 at $DIR/issue-72181.rs:27:22: 27:26
_8 = Lt(_6, _7); // scope 4 at $DIR/issue-72181.rs:27:22: 27:26
assert(move _8, "index out of bounds: the len is {} but the index is {}", move _7, _6) -> [success: bb3, unwind: bb1]; // scope 4 at $DIR/issue-72181.rs:27:22: 27:26
StorageLive(_2); // scope 1 at $DIR/issue-72181.rs:26:9: 26:10
StorageLive(_3); // scope 1 at $DIR/issue-72181.rs:26:14: 26:27
_3 = Foo { a: const 42_u64 }; // scope 1 at $DIR/issue-72181.rs:26:14: 26:27
- // ty::Const
- // + ty: u64
- // + val: Value(Scalar(0x000000000000002a))
- // mir::Constant
- // + span: $DIR/issue-72181.rs:26:23: 26:25
- // + literal: Const { ty: u64, val: Value(Scalar(0x000000000000002a)) }
StorageLive(_4); // scope 1 at $DIR/issue-72181.rs:26:29: 26:42
_4 = Foo { a: const 10_u64 }; // scope 1 at $DIR/issue-72181.rs:26:29: 26:42
- // ty::Const
- // + ty: u64
- // + val: Value(Scalar(0x000000000000000a))
- // mir::Constant
- // + span: $DIR/issue-72181.rs:26:38: 26:40
- // + literal: Const { ty: u64, val: Value(Scalar(0x000000000000000a)) }
_2 = [move _3, move _4]; // scope 1 at $DIR/issue-72181.rs:26:13: 26:43
StorageDead(_4); // scope 1 at $DIR/issue-72181.rs:26:42: 26:43
StorageDead(_3); // scope 1 at $DIR/issue-72181.rs:26:42: 26:43
StorageLive(_5); // scope 2 at $DIR/issue-72181.rs:27:13: 27:30
StorageLive(_6); // scope 4 at $DIR/issue-72181.rs:27:24: 27:25
_6 = const 0_usize; // scope 4 at $DIR/issue-72181.rs:27:24: 27:25
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000000))
- // mir::Constant
- // + span: $DIR/issue-72181.rs:27:24: 27:25
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) }
_7 = Len(_2); // scope 4 at $DIR/issue-72181.rs:27:22: 27:26
_8 = Lt(_6, _7); // scope 4 at $DIR/issue-72181.rs:27:22: 27:26
assert(move _8, "index out of bounds: the len is {} but the index is {}", move _7, _6) -> [success: bb3, unwind: bb1]; // scope 4 at $DIR/issue-72181.rs:27:22: 27:26
bb0: {
StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:2:23: 2:30
((_1 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:2:23: 2:30
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/issue-73223.rs:2:28: 2:29
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
discriminant(_1) = 1; // scope 0 at $DIR/issue-73223.rs:2:23: 2:30
_2 = ((_1 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:3:14: 3:15
StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:5:6: 5:7
StorageLive(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_11 = (*_7); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_10 = Eq(move _11, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
StorageDead(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_9 = Not(move _10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
bb0: {
StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:2:23: 2:30
((_1 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:2:23: 2:30
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/issue-73223.rs:2:28: 2:29
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
discriminant(_1) = 1; // scope 0 at $DIR/issue-73223.rs:2:23: 2:30
_2 = ((_1 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:3:14: 3:15
StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:5:6: 5:7
StorageLive(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_11 = (*_7); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_10 = Eq(move _11, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
StorageDead(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_9 = Not(move _10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:2:9: 2:14
StorageLive(_2); // scope 0 at $DIR/issue-73223.rs:2:23: 2:30
((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:2:23: 2:30
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/issue-73223.rs:2:28: 2:29
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:2:23: 2:30
_3 = const 1_isize; // scope 0 at $DIR/issue-73223.rs:3:9: 3:16
- // ty::Const
- // + ty: isize
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/issue-73223.rs:3:9: 3:16
- // + literal: Const { ty: isize, val: Value(Scalar(0x00000001)) }
goto -> bb2; // scope 0 at $DIR/issue-73223.rs:3:9: 3:16
}
_17 = (*_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_18 = const 1_i32; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
_16 = Eq(move _17, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
StorageDead(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_15 = Not(move _16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:2:9: 2:14
StorageLive(_2); // scope 0 at $DIR/issue-73223.rs:2:23: 2:30
((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:2:23: 2:30
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/issue-73223.rs:2:28: 2:29
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:2:23: 2:30
_3 = const 1_isize; // scope 0 at $DIR/issue-73223.rs:3:9: 3:16
- // ty::Const
- // + ty: isize
- // + val: Value(Scalar(0x0000000000000001))
- // mir::Constant
- // + span: $DIR/issue-73223.rs:3:9: 3:16
- // + literal: Const { ty: isize, val: Value(Scalar(0x0000000000000001)) }
goto -> bb2; // scope 0 at $DIR/issue-73223.rs:3:9: 3:16
}
_17 = (*_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_18 = const 1_i32; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
_16 = Eq(move _17, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
StorageDead(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_15 = Not(move _16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_1); // scope 0 at $DIR/loop_test.rs:10:5: 12:6
StorageLive(_2); // scope 0 at $DIR/loop_test.rs:10:8: 10:12
_2 = const true; // scope 0 at $DIR/loop_test.rs:10:8: 10:12
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/loop_test.rs:10:8: 10:12
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
FakeRead(ForMatchedPlace, _2); // scope 0 at $DIR/loop_test.rs:10:8: 10:12
switchInt(_2) -> [false: bb3, otherwise: bb2]; // scope 0 at $DIR/loop_test.rs:10:5: 12:6
}
bb6: {
StorageLive(_6); // scope 0 at $DIR/loop_test.rs:14:13: 14:14
_6 = const 1_i32; // scope 0 at $DIR/loop_test.rs:14:17: 14:18
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/loop_test.rs:14:17: 14:18
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
FakeRead(ForLet, _6); // scope 0 at $DIR/loop_test.rs:14:13: 14:14
StorageDead(_6); // scope 0 at $DIR/loop_test.rs:16:5: 16:6
goto -> bb5; // scope 0 at $DIR/loop_test.rs:15:9: 15:17
- bb8: {
+ bb5: {
_0 = const 1_i32; // scope 1 at $DIR/match-arm-scopes.rs:15:77: 15:78
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/match-arm-scopes.rs:15:77: 15:78
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
- drop(_7) -> [return: bb24, unwind: bb14]; // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
+ drop(_7) -> [return: bb19, unwind: bb10]; // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
}
- bb12: {
+ bb8: {
_0 = const 3_i32; // scope 0 at $DIR/match-arm-scopes.rs:15:59: 15:60
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/match-arm-scopes.rs:15:59: 15:60
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:15:72: 15:73
StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
- bb21: {
+ bb16: {
_0 = const 3_i32; // scope 0 at $DIR/match-arm-scopes.rs:15:59: 15:60
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/match-arm-scopes.rs:15:59: 15:60
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:15:72: 15:73
StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
- bb25: {
+ bb20: {
_0 = const 2_i32; // scope 2 at $DIR/match-arm-scopes.rs:16:41: 16:42
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/match-arm-scopes.rs:16:41: 16:42
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
- drop(_16) -> [return: bb27, unwind: bb14]; // scope 0 at $DIR/match-arm-scopes.rs:16:41: 16:42
+ drop(_16) -> [return: bb22, unwind: bb10]; // scope 0 at $DIR/match-arm-scopes.rs:16:41: 16:42
}
StorageLive(_1); // scope 0 at $DIR/match_false_edges.rs:15:13: 19:6
StorageLive(_2); // scope 0 at $DIR/match_false_edges.rs:15:19: 15:27
_2 = std::option::Option::<i32>::Some(const 42_i32); // scope 0 at $DIR/match_false_edges.rs:15:19: 15:27
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/match_false_edges.rs:15:24: 15:26
- // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
FakeRead(ForMatchedPlace, _2); // scope 0 at $DIR/match_false_edges.rs:15:19: 15:27
_3 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:16:9: 16:16
switchInt(move _3) -> [0_isize: bb2, 1_isize: bb3, otherwise: bb5]; // scope 0 at $DIR/match_false_edges.rs:16:9: 16:16
bb2: {
_1 = (const 3_i32, const 3_i32); // scope 0 at $DIR/match_false_edges.rs:18:17: 18:23
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/match_false_edges.rs:18:18: 18:19
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/match_false_edges.rs:18:21: 18:22
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
goto -> bb11; // scope 0 at $DIR/match_false_edges.rs:15:13: 19:6
}
StorageLive(_8); // scope 2 at $DIR/match_false_edges.rs:16:35: 16:36
_8 = _5; // scope 2 at $DIR/match_false_edges.rs:16:35: 16:36
_1 = (const 1_i32, move _8); // scope 2 at $DIR/match_false_edges.rs:16:31: 16:37
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/match_false_edges.rs:16:32: 16:33
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
StorageDead(_8); // scope 2 at $DIR/match_false_edges.rs:16:36: 16:37
StorageDead(_5); // scope 0 at $DIR/match_false_edges.rs:16:36: 16:37
StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:16:36: 16:37
StorageLive(_10); // scope 3 at $DIR/match_false_edges.rs:17:24: 17:25
_10 = _9; // scope 3 at $DIR/match_false_edges.rs:17:24: 17:25
_1 = (const 2_i32, move _10); // scope 3 at $DIR/match_false_edges.rs:17:20: 17:26
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/match_false_edges.rs:17:21: 17:22
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
StorageDead(_10); // scope 3 at $DIR/match_false_edges.rs:17:25: 17:26
StorageDead(_9); // scope 0 at $DIR/match_false_edges.rs:17:25: 17:26
goto -> bb11; // scope 0 at $DIR/match_false_edges.rs:15:13: 19:6
StorageLive(_1); // scope 0 at $DIR/match_false_edges.rs:26:13: 30:6
StorageLive(_2); // scope 0 at $DIR/match_false_edges.rs:26:19: 26:27
_2 = std::option::Option::<i32>::Some(const 42_i32); // scope 0 at $DIR/match_false_edges.rs:26:19: 26:27
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/match_false_edges.rs:26:24: 26:26
- // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
FakeRead(ForMatchedPlace, _2); // scope 0 at $DIR/match_false_edges.rs:26:19: 26:27
_3 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:27:9: 27:16
switchInt(move _3) -> [0_isize: bb2, 1_isize: bb3, otherwise: bb5]; // scope 0 at $DIR/match_false_edges.rs:27:9: 27:16
StorageLive(_10); // scope 3 at $DIR/match_false_edges.rs:29:24: 29:25
_10 = _9; // scope 3 at $DIR/match_false_edges.rs:29:24: 29:25
_1 = (const 2_i32, move _10); // scope 3 at $DIR/match_false_edges.rs:29:20: 29:26
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/match_false_edges.rs:29:21: 29:22
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
StorageDead(_10); // scope 3 at $DIR/match_false_edges.rs:29:25: 29:26
StorageDead(_9); // scope 0 at $DIR/match_false_edges.rs:29:25: 29:26
goto -> bb11; // scope 0 at $DIR/match_false_edges.rs:26:13: 30:6
StorageLive(_8); // scope 2 at $DIR/match_false_edges.rs:27:35: 27:36
_8 = _5; // scope 2 at $DIR/match_false_edges.rs:27:35: 27:36
_1 = (const 1_i32, move _8); // scope 2 at $DIR/match_false_edges.rs:27:31: 27:37
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/match_false_edges.rs:27:32: 27:33
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
StorageDead(_8); // scope 2 at $DIR/match_false_edges.rs:27:36: 27:37
StorageDead(_5); // scope 0 at $DIR/match_false_edges.rs:27:36: 27:37
StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:27:36: 27:37
bb10: {
_1 = (const 3_i32, const 3_i32); // scope 0 at $DIR/match_false_edges.rs:28:17: 28:23
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/match_false_edges.rs:28:18: 28:19
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/match_false_edges.rs:28:21: 28:22
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
goto -> bb11; // scope 0 at $DIR/match_false_edges.rs:26:13: 30:6
}
StorageLive(_1); // scope 0 at $DIR/match_false_edges.rs:35:13: 40:6
StorageLive(_2); // scope 0 at $DIR/match_false_edges.rs:35:19: 35:26
_2 = std::option::Option::<i32>::Some(const 1_i32); // scope 0 at $DIR/match_false_edges.rs:35:19: 35:26
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/match_false_edges.rs:35:24: 35:25
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
FakeRead(ForMatchedPlace, _2); // scope 0 at $DIR/match_false_edges.rs:35:19: 35:26
_4 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:36:9: 36:17
switchInt(move _4) -> [1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/match_false_edges.rs:36:9: 36:17
StorageLive(_14); // scope 0 at $DIR/match_false_edges.rs:39:9: 39:11
_14 = _2; // scope 0 at $DIR/match_false_edges.rs:39:9: 39:11
_1 = const 4_i32; // scope 5 at $DIR/match_false_edges.rs:39:15: 39:16
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000004))
- // mir::Constant
- // + span: $DIR/match_false_edges.rs:39:15: 39:16
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) }
StorageDead(_14); // scope 0 at $DIR/match_false_edges.rs:39:15: 39:16
goto -> bb15; // scope 0 at $DIR/match_false_edges.rs:35:13: 40:6
}
StorageLive(_6); // scope 0 at $DIR/match_false_edges.rs:36:14: 36:16
_6 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:36:14: 36:16
_1 = const 1_i32; // scope 2 at $DIR/match_false_edges.rs:36:32: 36:33
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/match_false_edges.rs:36:32: 36:33
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:36:32: 36:33
StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:36:32: 36:33
goto -> bb15; // scope 0 at $DIR/match_false_edges.rs:35:13: 40:6
StorageLive(_9); // scope 0 at $DIR/match_false_edges.rs:37:9: 37:11
_9 = _2; // scope 0 at $DIR/match_false_edges.rs:37:9: 37:11
_1 = const 2_i32; // scope 3 at $DIR/match_false_edges.rs:37:15: 37:16
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/match_false_edges.rs:37:15: 37:16
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
StorageDead(_9); // scope 0 at $DIR/match_false_edges.rs:37:15: 37:16
goto -> bb15; // scope 0 at $DIR/match_false_edges.rs:35:13: 40:6
}
StorageLive(_10); // scope 0 at $DIR/match_false_edges.rs:38:14: 38:15
_10 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:38:14: 38:15
_1 = const 3_i32; // scope 4 at $DIR/match_false_edges.rs:38:33: 38:34
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/match_false_edges.rs:38:33: 38:34
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
StorageDead(_10); // scope 0 at $DIR/match_false_edges.rs:38:33: 38:34
StorageDead(_11); // scope 0 at $DIR/match_false_edges.rs:38:33: 38:34
goto -> bb15; // scope 0 at $DIR/match_false_edges.rs:35:13: 40:6
bb0: {
StorageLive(_1); // scope 0 at $DIR/match_test.rs:7:9: 7:10
_1 = const 3_i32; // scope 0 at $DIR/match_test.rs:7:13: 7:14
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/match_test.rs:7:13: 7:14
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
FakeRead(ForLet, _1); // scope 0 at $DIR/match_test.rs:7:9: 7:10
StorageLive(_2); // scope 1 at $DIR/match_test.rs:8:9: 8:10
_2 = const true; // scope 1 at $DIR/match_test.rs:8:13: 8:17
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/match_test.rs:8:13: 8:17
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
FakeRead(ForLet, _2); // scope 1 at $DIR/match_test.rs:8:9: 8:10
StorageLive(_3); // scope 2 at $DIR/match_test.rs:12:5: 17:6
FakeRead(ForMatchedPlace, _1); // scope 2 at $DIR/match_test.rs:12:11: 12:12
_6 = Le(const 0_i32, _1); // scope 2 at $DIR/match_test.rs:13:9: 13:14
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/match_test.rs:13:9: 13:14
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
switchInt(move _6) -> [false: bb4, otherwise: bb1]; // scope 2 at $DIR/match_test.rs:13:9: 13:14
}
bb1: {
_7 = Lt(_1, const 10_i32); // scope 2 at $DIR/match_test.rs:13:9: 13:14
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x0000000a))
- // mir::Constant
- // + span: $DIR/match_test.rs:13:9: 13:14
- // + literal: Const { ty: i32, val: Value(Scalar(0x0000000a)) }
switchInt(move _7) -> [false: bb4, otherwise: bb2]; // scope 2 at $DIR/match_test.rs:13:9: 13:14
}
bb3: {
_3 = const 3_i32; // scope 2 at $DIR/match_test.rs:16:14: 16:15
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/match_test.rs:16:14: 16:15
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
goto -> bb14; // scope 2 at $DIR/match_test.rs:12:5: 17:6
}
bb4: {
_4 = Le(const 10_i32, _1); // scope 2 at $DIR/match_test.rs:14:9: 14:16
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x0000000a))
- // mir::Constant
- // + span: $DIR/match_test.rs:14:9: 14:16
- // + literal: Const { ty: i32, val: Value(Scalar(0x0000000a)) }
switchInt(move _4) -> [false: bb7, otherwise: bb5]; // scope 2 at $DIR/match_test.rs:14:9: 14:16
}
bb5: {
_5 = Le(_1, const 20_i32); // scope 2 at $DIR/match_test.rs:14:9: 14:16
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000014))
- // mir::Constant
- // + span: $DIR/match_test.rs:14:9: 14:16
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000014)) }
switchInt(move _5) -> [false: bb7, otherwise: bb6]; // scope 2 at $DIR/match_test.rs:14:9: 14:16
}
StorageDead(_9); // scope 2 at $DIR/match_test.rs:13:23: 13:24
FakeRead(ForMatchGuard, _8); // scope 2 at $DIR/match_test.rs:13:18: 13:19
_3 = const 0_i32; // scope 2 at $DIR/match_test.rs:13:23: 13:24
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/match_test.rs:13:23: 13:24
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
goto -> bb14; // scope 2 at $DIR/match_test.rs:12:5: 17:6
}
bb12: {
_3 = const 1_i32; // scope 2 at $DIR/match_test.rs:14:20: 14:21
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/match_test.rs:14:20: 14:21
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
goto -> bb14; // scope 2 at $DIR/match_test.rs:12:5: 17:6
}
bb13: {
_3 = const 2_i32; // scope 2 at $DIR/match_test.rs:15:15: 15:16
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/match_test.rs:15:15: 15:16
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
goto -> bb14; // scope 2 at $DIR/match_test.rs:12:5: 17:6
}
StorageLive(_6); // scope 4 at $DIR/matches_reduce_branches.rs:17:5: 32:6
- switchInt(_1) -> [7_i32: bb2, otherwise: bb1]; // scope 4 at $DIR/matches_reduce_branches.rs:18:9: 18:10
+ _2 = Ne(_1, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:19:13: 19:22
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x00000007))
-+ // mir::Constant
-+ // + span: $DIR/matches_reduce_branches.rs:1:1: 1:1
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000007)) }
+ _3 = Eq(_1, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:20:13: 20:21
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x00000007))
-+ // mir::Constant
-+ // + span: $DIR/matches_reduce_branches.rs:1:1: 1:1
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000007)) }
+ _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:21:13: 21:22
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
-+ // mir::Constant
-+ // + span: $DIR/matches_reduce_branches.rs:21:17: 21:22
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
+ _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:22:13: 22:21
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/matches_reduce_branches.rs:22:17: 22:21
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
+ goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:18:9: 18:10
}
bb1: {
_2 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:26:13: 26:21
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/matches_reduce_branches.rs:26:17: 26:21
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
_3 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:27:13: 27:22
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/matches_reduce_branches.rs:27:17: 27:22
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
_4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:28:13: 28:22
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/matches_reduce_branches.rs:28:17: 28:22
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
_5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:29:13: 29:21
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/matches_reduce_branches.rs:29:17: 29:21
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:17:5: 32:6
}
bb2: {
_2 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:19:13: 19:22
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/matches_reduce_branches.rs:19:17: 19:22
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
_3 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:20:13: 20:21
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/matches_reduce_branches.rs:20:17: 20:21
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
_4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:21:13: 21:22
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/matches_reduce_branches.rs:21:17: 21:22
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
_5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:22:13: 22:21
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/matches_reduce_branches.rs:22:17: 22:21
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:17:5: 32:6
}
StorageLive(_6); // scope 4 at $DIR/matches_reduce_branches.rs:17:5: 32:6
- switchInt(_1) -> [7_i32: bb2, otherwise: bb1]; // scope 4 at $DIR/matches_reduce_branches.rs:18:9: 18:10
+ _2 = Ne(_1, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:19:13: 19:22
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x00000007))
-+ // mir::Constant
-+ // + span: $DIR/matches_reduce_branches.rs:1:1: 1:1
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000007)) }
+ _3 = Eq(_1, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:20:13: 20:21
-+ // ty::Const
-+ // + ty: i32
-+ // + val: Value(Scalar(0x00000007))
-+ // mir::Constant
-+ // + span: $DIR/matches_reduce_branches.rs:1:1: 1:1
-+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000007)) }
+ _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:21:13: 21:22
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
-+ // mir::Constant
-+ // + span: $DIR/matches_reduce_branches.rs:21:17: 21:22
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
+ _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:22:13: 22:21
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x01))
-+ // mir::Constant
-+ // + span: $DIR/matches_reduce_branches.rs:22:17: 22:21
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
+ goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:18:9: 18:10
}
bb1: {
_2 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:26:13: 26:21
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/matches_reduce_branches.rs:26:17: 26:21
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
_3 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:27:13: 27:22
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/matches_reduce_branches.rs:27:17: 27:22
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
_4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:28:13: 28:22
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/matches_reduce_branches.rs:28:17: 28:22
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
_5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:29:13: 29:21
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/matches_reduce_branches.rs:29:17: 29:21
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:17:5: 32:6
}
bb2: {
_2 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:19:13: 19:22
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/matches_reduce_branches.rs:19:17: 19:22
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
_3 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:20:13: 20:21
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/matches_reduce_branches.rs:20:17: 20:21
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
_4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:21:13: 21:22
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/matches_reduce_branches.rs:21:17: 21:22
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
_5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:22:13: 22:21
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/matches_reduce_branches.rs:22:17: 22:21
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:17:5: 32:6
}
_3 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:6:22: 6:26
- switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:6:22: 6:26
+ _2 = Eq(_3, const 0_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-+ // ty::Const
-+ // + ty: isize
-+ // + val: Value(Scalar(0x00000000))
-+ // mir::Constant
-+ // + span: $DIR/matches_reduce_branches.rs:1:1: 1:1
-+ // + literal: Const { ty: isize, val: Value(Scalar(0x00000000)) }
+ goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:6:22: 6:26
}
bb1: {
_2 = const false; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
}
bb2: {
_2 = const true; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
}
_3 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:6:22: 6:26
- switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:6:22: 6:26
+ _2 = Eq(_3, const 0_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-+ // ty::Const
-+ // + ty: isize
-+ // + val: Value(Scalar(0x0000000000000000))
-+ // mir::Constant
-+ // + span: $DIR/matches_reduce_branches.rs:1:1: 1:1
-+ // + literal: Const { ty: isize, val: Value(Scalar(0x0000000000000000)) }
+ goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:6:22: 6:26
}
bb1: {
_2 = const false; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
}
bb2: {
_2 = const true; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
}
bb1: {
_0 = const 1_u8; // scope 0 at $DIR/matches_u8.rs:14:17: 14:18
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/matches_u8.rs:14:17: 14:18
- // + literal: Const { ty: u8, val: Value(Scalar(0x01)) }
goto -> bb3; // scope 0 at $DIR/matches_u8.rs:12:5: 15:6
}
bb2: {
_0 = const 0_u8; // scope 0 at $DIR/matches_u8.rs:13:17: 13:18
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/matches_u8.rs:13:17: 13:18
- // + literal: Const { ty: u8, val: Value(Scalar(0x00)) }
goto -> bb3; // scope 0 at $DIR/matches_u8.rs:12:5: 15:6
}
bb1: {
_0 = const 1_u8; // scope 0 at $DIR/matches_u8.rs:14:17: 14:18
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/matches_u8.rs:14:17: 14:18
- // + literal: Const { ty: u8, val: Value(Scalar(0x01)) }
goto -> bb3; // scope 0 at $DIR/matches_u8.rs:12:5: 15:6
}
bb2: {
_0 = const 0_u8; // scope 0 at $DIR/matches_u8.rs:13:17: 13:18
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/matches_u8.rs:13:17: 13:18
- // + literal: Const { ty: u8, val: Value(Scalar(0x00)) }
goto -> bb3; // scope 0 at $DIR/matches_u8.rs:12:5: 15:6
}
bb1: {
_0 = const 1_i8; // scope 0 at $DIR/matches_u8.rs:22:17: 22:18
- // ty::Const
- // + ty: i8
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/matches_u8.rs:22:17: 22:18
- // + literal: Const { ty: i8, val: Value(Scalar(0x01)) }
goto -> bb3; // scope 0 at $DIR/matches_u8.rs:20:5: 23:6
}
bb2: {
_0 = const 0_i8; // scope 0 at $DIR/matches_u8.rs:21:17: 21:18
- // ty::Const
- // + ty: i8
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/matches_u8.rs:21:17: 21:18
- // + literal: Const { ty: i8, val: Value(Scalar(0x00)) }
goto -> bb3; // scope 0 at $DIR/matches_u8.rs:20:5: 23:6
}
bb1: {
_0 = const 1_i8; // scope 0 at $DIR/matches_u8.rs:22:17: 22:18
- // ty::Const
- // + ty: i8
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/matches_u8.rs:22:17: 22:18
- // + literal: Const { ty: i8, val: Value(Scalar(0x01)) }
goto -> bb3; // scope 0 at $DIR/matches_u8.rs:20:5: 23:6
}
bb2: {
_0 = const 0_i8; // scope 0 at $DIR/matches_u8.rs:21:17: 21:18
- // ty::Const
- // + ty: i8
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/matches_u8.rs:21:17: 21:18
- // + literal: Const { ty: i8, val: Value(Scalar(0x00)) }
goto -> bb3; // scope 0 at $DIR/matches_u8.rs:20:5: 23:6
}
bb0: {
_0 = const Const(Value(Scalar(0x01)): bool); // bb0[0]: scope 0 at $DIR/named-lifetimes-basic.rs:12:88: 12:92
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/named-lifetimes-basic.rs:12:88: 12:92
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
return; // bb0[1]: scope 0 at $DIR/named-lifetimes-basic.rs:12:94: 12:94
}
}
bb0: {
StorageLive(_1); // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14
_1 = [const Const(Value(Scalar(0x00000001)): usize), const Const(Value(Scalar(0x00000002)): usize), const Const(Value(Scalar(0x00000003)): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:17:17: 17:26
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/region-subtyping-basic.rs:17:18: 17:19
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000001)) }
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/region-subtyping-basic.rs:17:21: 17:22
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000002)) }
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/region-subtyping-basic.rs:17:24: 17:25
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000003)) }
FakeRead(ForLet, _1); // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14
StorageLive(_2); // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:18:9: 18:10
StorageLive(_3); // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:18:16: 18:17
_3 = const Const(Value(Scalar(0x00000000)): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:18:16: 18:17
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/region-subtyping-basic.rs:18:16: 18:17
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000000)) }
_4 = Len(_1); // bb0[6]: scope 1 at $DIR/region-subtyping-basic.rs:18:14: 18:18
_5 = Lt(_3, _4); // bb0[7]: scope 1 at $DIR/region-subtyping-basic.rs:18:14: 18:18
assert(move _5, "index out of bounds: the len is {} but the index is {}", move _4, _3) -> [success: bb2, unwind: bb1]; // bb0[8]: scope 1 at $DIR/region-subtyping-basic.rs:18:14: 18:18
FakeRead(ForLet, _6); // bb2[4]: scope 2 at $DIR/region-subtyping-basic.rs:19:9: 19:10
StorageLive(_7); // bb2[5]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
_7 = const Const(Value(Scalar(0x01)): bool); // bb2[6]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/region-subtyping-basic.rs:20:8: 20:12
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
FakeRead(ForMatchedPlace, _7); // bb2[7]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
switchInt(_7) -> [Const(Value(Scalar(0x00)): bool): bb4, otherwise: bb3]; // bb2[8]: scope 3 at $DIR/region-subtyping-basic.rs:20:5: 24:6
}
// mir::Constant
// + span: $DIR/region-subtyping-basic.rs:23:9: 23:14
// + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(Scalar(<ZST>)) }
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000016))
- // mir::Constant
- // + span: $DIR/region-subtyping-basic.rs:23:15: 23:17
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000016)) }
}
bb5: {
bb0: {
StorageLive(_1); // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14
_1 = [const Const(Value(Scalar(0x0000000000000001)): usize), const Const(Value(Scalar(0x0000000000000002)): usize), const Const(Value(Scalar(0x0000000000000003)): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:17:17: 17:26
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000001))
- // mir::Constant
- // + span: $DIR/region-subtyping-basic.rs:17:18: 17:19
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000001)) }
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000002))
- // mir::Constant
- // + span: $DIR/region-subtyping-basic.rs:17:21: 17:22
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000002)) }
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000003))
- // mir::Constant
- // + span: $DIR/region-subtyping-basic.rs:17:24: 17:25
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000003)) }
FakeRead(ForLet, _1); // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14
StorageLive(_2); // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:18:9: 18:10
StorageLive(_3); // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:18:16: 18:17
_3 = const Const(Value(Scalar(0x0000000000000000)): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:18:16: 18:17
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000000))
- // mir::Constant
- // + span: $DIR/region-subtyping-basic.rs:18:16: 18:17
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) }
_4 = Len(_1); // bb0[6]: scope 1 at $DIR/region-subtyping-basic.rs:18:14: 18:18
_5 = Lt(_3, _4); // bb0[7]: scope 1 at $DIR/region-subtyping-basic.rs:18:14: 18:18
assert(move _5, "index out of bounds: the len is {} but the index is {}", move _4, _3) -> [success: bb2, unwind: bb1]; // bb0[8]: scope 1 at $DIR/region-subtyping-basic.rs:18:14: 18:18
FakeRead(ForLet, _6); // bb2[4]: scope 2 at $DIR/region-subtyping-basic.rs:19:9: 19:10
StorageLive(_7); // bb2[5]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
_7 = const Const(Value(Scalar(0x01)): bool); // bb2[6]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/region-subtyping-basic.rs:20:8: 20:12
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
FakeRead(ForMatchedPlace, _7); // bb2[7]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
switchInt(_7) -> [Const(Value(Scalar(0x00)): bool): bb4, otherwise: bb3]; // bb2[8]: scope 3 at $DIR/region-subtyping-basic.rs:20:5: 24:6
}
// mir::Constant
// + span: $DIR/region-subtyping-basic.rs:23:9: 23:14
// + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(Scalar(<ZST>)) }
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000016))
- // mir::Constant
- // + span: $DIR/region-subtyping-basic.rs:23:15: 23:17
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000016)) }
}
bb5: {
- StorageLive(_2); // scope 0 at $DIR/nrvo-simple.rs:3:9: 3:16
- _2 = [const 0_u8; 1024]; // scope 0 at $DIR/nrvo-simple.rs:3:19: 3:28
+ _0 = [const 0_u8; 1024]; // scope 0 at $DIR/nrvo-simple.rs:3:19: 3:28
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/nrvo-simple.rs:3:20: 3:21
- // + literal: Const { ty: u8, val: Value(Scalar(0x00)) }
StorageLive(_3); // scope 1 at $DIR/nrvo-simple.rs:4:5: 4:19
StorageLive(_5); // scope 1 at $DIR/nrvo-simple.rs:4:10: 4:18
StorageLive(_6); // scope 1 at $DIR/nrvo-simple.rs:4:10: 4:18
StorageLive(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:6:24: 6:42
StorageLive(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:6:32: 6:41
_3 = Droppy(const 0_usize); // scope 0 at $DIR/packed-struct-drop-aligned.rs:6:32: 6:41
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/packed-struct-drop-aligned.rs:6:39: 6:40
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000000)) }
_2 = Aligned(move _3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:6:24: 6:42
StorageDead(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:6:41: 6:42
_1 = Packed(move _2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:6:17: 6:43
StorageLive(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:7:11: 7:29
StorageLive(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:7:19: 7:28
_5 = Droppy(const 0_usize); // scope 1 at $DIR/packed-struct-drop-aligned.rs:7:19: 7:28
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/packed-struct-drop-aligned.rs:7:26: 7:27
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000000)) }
_4 = Aligned(move _5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:7:11: 7:29
StorageDead(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:7:28: 7:29
StorageLive(_6); // scope 1 at $DIR/packed-struct-drop-aligned.rs:7:5: 7:8
StorageLive(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:6:24: 6:42
StorageLive(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:6:32: 6:41
_3 = Droppy(const 0_usize); // scope 0 at $DIR/packed-struct-drop-aligned.rs:6:32: 6:41
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000000))
- // mir::Constant
- // + span: $DIR/packed-struct-drop-aligned.rs:6:39: 6:40
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) }
_2 = Aligned(move _3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:6:24: 6:42
StorageDead(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:6:41: 6:42
_1 = Packed(move _2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:6:17: 6:43
StorageLive(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:7:11: 7:29
StorageLive(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:7:19: 7:28
_5 = Droppy(const 0_usize); // scope 1 at $DIR/packed-struct-drop-aligned.rs:7:19: 7:28
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000000))
- // mir::Constant
- // + span: $DIR/packed-struct-drop-aligned.rs:7:26: 7:27
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) }
_4 = Aligned(move _5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:7:11: 7:29
StorageDead(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:7:28: 7:29
StorageLive(_6); // scope 1 at $DIR/packed-struct-drop-aligned.rs:7:5: 7:8
bb1: {
_0 = const 1_i32; // scope 0 at $DIR/remove_fake_borrows.rs:9:14: 9:15
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/remove_fake_borrows.rs:9:14: 9:15
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
goto -> bb7; // scope 0 at $DIR/remove_fake_borrows.rs:7:5: 10:6
}
+ nop; // scope 0 at $DIR/remove_fake_borrows.rs:8:20: 8:21
+ nop; // scope 0 at $DIR/remove_fake_borrows.rs:8:20: 8:21
_0 = const 0_i32; // scope 0 at $DIR/remove_fake_borrows.rs:8:25: 8:26
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/remove_fake_borrows.rs:8:25: 8:26
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
goto -> bb7; // scope 0 at $DIR/remove_fake_borrows.rs:7:5: 10:6
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/retag.rs:30:9: 30:14
_1 = const 0_i32; // scope 0 at $DIR/retag.rs:30:17: 30:18
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/retag.rs:30:17: 30:18
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
StorageLive(_2); // scope 1 at $DIR/retag.rs:31:5: 37:6
StorageLive(_3); // scope 1 at $DIR/retag.rs:32:13: 32:14
StorageLive(_4); // scope 1 at $DIR/retag.rs:32:17: 32:24
StorageLive(_5); // scope 1 at $DIR/retag.rs:32:17: 32:24
_5 = Test(const 0_i32); // scope 1 at $DIR/retag.rs:32:17: 32:24
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/retag.rs:32:22: 32:23
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
_4 = &_5; // scope 1 at $DIR/retag.rs:32:17: 32:24
Retag(_4); // scope 1 at $DIR/retag.rs:32:17: 32:24
StorageLive(_6); // scope 1 at $DIR/retag.rs:32:29: 32:35
StorageLive(_20); // scope 7 at $DIR/retag.rs:47:5: 47:12
StorageLive(_21); // scope 7 at $DIR/retag.rs:47:5: 47:12
_21 = Test(const 0_i32); // scope 7 at $DIR/retag.rs:47:5: 47:12
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/retag.rs:47:10: 47:11
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
_20 = &_21; // scope 7 at $DIR/retag.rs:47:5: 47:12
Retag(_20); // scope 7 at $DIR/retag.rs:47:5: 47:12
StorageLive(_22); // scope 7 at $DIR/retag.rs:47:21: 47:23
bb3: {
_0 = const 20_usize; // scope 0 at $DIR/simple-match.rs:8:14: 8:16
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000014))
- // mir::Constant
- // + span: $DIR/simple-match.rs:8:14: 8:16
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000014)) }
goto -> bb5; // scope 0 at $DIR/simple-match.rs:6:5: 9:6
}
bb4: {
_0 = const 10_usize; // scope 0 at $DIR/simple-match.rs:7:17: 7:19
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000a))
- // mir::Constant
- // + span: $DIR/simple-match.rs:7:17: 7:19
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000a)) }
goto -> bb5; // scope 0 at $DIR/simple-match.rs:6:5: 9:6
}
bb3: {
_0 = const 20_usize; // scope 0 at $DIR/simple-match.rs:8:14: 8:16
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000014))
- // mir::Constant
- // + span: $DIR/simple-match.rs:8:14: 8:16
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000014)) }
goto -> bb5; // scope 0 at $DIR/simple-match.rs:6:5: 9:6
}
bb4: {
_0 = const 10_usize; // scope 0 at $DIR/simple-match.rs:7:17: 7:19
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x000000000000000a))
- // mir::Constant
- // + span: $DIR/simple-match.rs:7:17: 7:19
- // + literal: Const { ty: usize, val: Value(Scalar(0x000000000000000a)) }
goto -> bb5; // scope 0 at $DIR/simple-match.rs:6:5: 9:6
}
-// compile-flags: -Z mir-opt-level=1
+// compile-flags: -Z mir-opt-level=2
// EMIT_MIR simplify_arm.id.SimplifyArmIdentity.diff
// EMIT_MIR simplify_arm.id.SimplifyBranchSame.diff
// EMIT_MIR simplify_arm.id_result.SimplifyArmIdentity.diff
let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:11:14: 11:15
let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:11:25: 11:26
scope 1 {
- debug v => _3; // in scope 1 at $DIR/simplify-arm.rs:11:14: 11:15
+- debug v => _3; // in scope 1 at $DIR/simplify-arm.rs:11:14: 11:15
++ debug v => ((_0 as Some).0: u8); // in scope 1 at $DIR/simplify-arm.rs:11:14: 11:15
}
bb0: {
}
bb3: {
- StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:11:14: 11:15
- _3 = ((_1 as Some).0: u8); // scope 0 at $DIR/simplify-arm.rs:11:14: 11:15
- StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:11:25: 11:26
- _4 = _3; // scope 1 at $DIR/simplify-arm.rs:11:25: 11:26
- ((_0 as Some).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:11:20: 11:27
- discriminant(_0) = 1; // scope 1 at $DIR/simplify-arm.rs:11:20: 11:27
- StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:11:26: 11:27
- StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:11:26: 11:27
+- StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:11:14: 11:15
+- _3 = ((_1 as Some).0: u8); // scope 0 at $DIR/simplify-arm.rs:11:14: 11:15
+- StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:11:25: 11:26
+- _4 = _3; // scope 1 at $DIR/simplify-arm.rs:11:25: 11:26
+- ((_0 as Some).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:11:20: 11:27
+- discriminant(_0) = 1; // scope 1 at $DIR/simplify-arm.rs:11:20: 11:27
+- StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:11:26: 11:27
+- StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:11:26: 11:27
++ _0 = move _1; // scope 1 at $DIR/simplify-arm.rs:11:20: 11:27
goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:10:5: 13:6
}
let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:11:14: 11:15
let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:11:25: 11:26
scope 1 {
- debug v => _3; // in scope 1 at $DIR/simplify-arm.rs:11:14: 11:15
+ debug v => ((_0 as Some).0: u8); // in scope 1 at $DIR/simplify-arm.rs:11:14: 11:15
}
bb0: {
_2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:11:9: 11:16
- switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:11:9: 11:16
+- switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:11:9: 11:16
++ goto -> bb1; // scope 0 at $DIR/simplify-arm.rs:11:9: 11:16
}
bb1: {
- discriminant(_0) = 0; // scope 0 at $DIR/simplify-arm.rs:12:17: 12:21
- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:10:5: 13:6
+- discriminant(_0) = 0; // scope 0 at $DIR/simplify-arm.rs:12:17: 12:21
+- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:10:5: 13:6
+- }
+-
+- bb2: {
+- unreachable; // scope 0 at $DIR/simplify-arm.rs:10:11: 10:12
+- }
+-
+- bb3: {
+ _0 = move _1; // scope 1 at $DIR/simplify-arm.rs:11:20: 11:27
+- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:10:5: 13:6
++ goto -> bb2; // scope 0 at $DIR/simplify-arm.rs:10:5: 13:6
}
- bb2: {
- unreachable; // scope 0 at $DIR/simplify-arm.rs:10:11: 10:12
- }
-
- bb3: {
- StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:11:14: 11:15
- _3 = ((_1 as Some).0: u8); // scope 0 at $DIR/simplify-arm.rs:11:14: 11:15
- StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:11:25: 11:26
- _4 = _3; // scope 1 at $DIR/simplify-arm.rs:11:25: 11:26
- ((_0 as Some).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:11:20: 11:27
- discriminant(_0) = 1; // scope 1 at $DIR/simplify-arm.rs:11:20: 11:27
- StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:11:26: 11:27
- StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:11:26: 11:27
- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:10:5: 13:6
- }
-
- bb4: {
+- bb4: {
++ bb2: {
return; // scope 0 at $DIR/simplify-arm.rs:14:2: 14:2
}
}
let _5: i32; // in scope 0 at $DIR/simplify-arm.rs:19:13: 19:14
let mut _6: i32; // in scope 0 at $DIR/simplify-arm.rs:19:23: 19:24
scope 1 {
- debug x => _3; // in scope 1 at $DIR/simplify-arm.rs:18:12: 18:13
+- debug x => _3; // in scope 1 at $DIR/simplify-arm.rs:18:12: 18:13
++ debug x => ((_0 as Ok).0: u8); // in scope 1 at $DIR/simplify-arm.rs:18:12: 18:13
}
scope 2 {
- debug y => _5; // in scope 2 at $DIR/simplify-arm.rs:19:13: 19:14
+- debug y => _5; // in scope 2 at $DIR/simplify-arm.rs:19:13: 19:14
++ debug y => ((_0 as Err).0: i32); // in scope 2 at $DIR/simplify-arm.rs:19:13: 19:14
}
bb0: {
}
bb1: {
- StorageLive(_5); // scope 0 at $DIR/simplify-arm.rs:19:13: 19:14
- _5 = ((_1 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:19:13: 19:14
- StorageLive(_6); // scope 2 at $DIR/simplify-arm.rs:19:23: 19:24
- _6 = _5; // scope 2 at $DIR/simplify-arm.rs:19:23: 19:24
- ((_0 as Err).0: i32) = move _6; // scope 2 at $DIR/simplify-arm.rs:19:19: 19:25
- discriminant(_0) = 1; // scope 2 at $DIR/simplify-arm.rs:19:19: 19:25
- StorageDead(_6); // scope 2 at $DIR/simplify-arm.rs:19:24: 19:25
- StorageDead(_5); // scope 0 at $DIR/simplify-arm.rs:19:24: 19:25
+- StorageLive(_5); // scope 0 at $DIR/simplify-arm.rs:19:13: 19:14
+- _5 = ((_1 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:19:13: 19:14
+- StorageLive(_6); // scope 2 at $DIR/simplify-arm.rs:19:23: 19:24
+- _6 = _5; // scope 2 at $DIR/simplify-arm.rs:19:23: 19:24
+- ((_0 as Err).0: i32) = move _6; // scope 2 at $DIR/simplify-arm.rs:19:19: 19:25
+- discriminant(_0) = 1; // scope 2 at $DIR/simplify-arm.rs:19:19: 19:25
+- StorageDead(_6); // scope 2 at $DIR/simplify-arm.rs:19:24: 19:25
+- StorageDead(_5); // scope 0 at $DIR/simplify-arm.rs:19:24: 19:25
++ _0 = move _1; // scope 2 at $DIR/simplify-arm.rs:19:19: 19:25
goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:17:5: 20:6
}
}
bb3: {
- StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:18:12: 18:13
- _3 = ((_1 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:18:12: 18:13
- StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:18:21: 18:22
- _4 = _3; // scope 1 at $DIR/simplify-arm.rs:18:21: 18:22
- ((_0 as Ok).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:18:18: 18:23
- discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:18:18: 18:23
- StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:18:22: 18:23
- StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:18:22: 18:23
+- StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:18:12: 18:13
+- _3 = ((_1 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:18:12: 18:13
+- StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:18:21: 18:22
+- _4 = _3; // scope 1 at $DIR/simplify-arm.rs:18:21: 18:22
+- ((_0 as Ok).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:18:18: 18:23
+- discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:18:18: 18:23
+- StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:18:22: 18:23
+- StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:18:22: 18:23
++ _0 = move _1; // scope 1 at $DIR/simplify-arm.rs:18:18: 18:23
goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:17:5: 20:6
}
let _5: i32; // in scope 0 at $DIR/simplify-arm.rs:19:13: 19:14
let mut _6: i32; // in scope 0 at $DIR/simplify-arm.rs:19:23: 19:24
scope 1 {
- debug x => _3; // in scope 1 at $DIR/simplify-arm.rs:18:12: 18:13
+ debug x => ((_0 as Ok).0: u8); // in scope 1 at $DIR/simplify-arm.rs:18:12: 18:13
}
scope 2 {
- debug y => _5; // in scope 2 at $DIR/simplify-arm.rs:19:13: 19:14
+ debug y => ((_0 as Err).0: i32); // in scope 2 at $DIR/simplify-arm.rs:19:13: 19:14
}
bb0: {
_2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:18:9: 18:14
- switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:18:9: 18:14
+- switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:18:9: 18:14
++ goto -> bb1; // scope 0 at $DIR/simplify-arm.rs:18:9: 18:14
}
bb1: {
- StorageLive(_5); // scope 0 at $DIR/simplify-arm.rs:19:13: 19:14
- _5 = ((_1 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:19:13: 19:14
- StorageLive(_6); // scope 2 at $DIR/simplify-arm.rs:19:23: 19:24
- _6 = _5; // scope 2 at $DIR/simplify-arm.rs:19:23: 19:24
- ((_0 as Err).0: i32) = move _6; // scope 2 at $DIR/simplify-arm.rs:19:19: 19:25
- discriminant(_0) = 1; // scope 2 at $DIR/simplify-arm.rs:19:19: 19:25
- StorageDead(_6); // scope 2 at $DIR/simplify-arm.rs:19:24: 19:25
- StorageDead(_5); // scope 0 at $DIR/simplify-arm.rs:19:24: 19:25
- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:17:5: 20:6
+- _0 = move _1; // scope 2 at $DIR/simplify-arm.rs:19:19: 19:25
+- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:17:5: 20:6
+- }
+-
+- bb2: {
+- unreachable; // scope 0 at $DIR/simplify-arm.rs:17:11: 17:12
+- }
+-
+- bb3: {
+ _0 = move _1; // scope 1 at $DIR/simplify-arm.rs:18:18: 18:23
+- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:17:5: 20:6
++ goto -> bb2; // scope 0 at $DIR/simplify-arm.rs:17:5: 20:6
}
- bb2: {
- unreachable; // scope 0 at $DIR/simplify-arm.rs:17:11: 17:12
- }
-
- bb3: {
- StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:18:12: 18:13
- _3 = ((_1 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:18:12: 18:13
- StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:18:21: 18:22
- _4 = _3; // scope 1 at $DIR/simplify-arm.rs:18:21: 18:22
- ((_0 as Ok).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:18:18: 18:23
- discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:18:18: 18:23
- StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:18:22: 18:23
- StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:18:22: 18:23
- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:17:5: 20:6
- }
-
- bb4: {
+- bb4: {
++ bb2: {
return; // scope 0 at $DIR/simplify-arm.rs:21:2: 21:2
}
}
let _10: u8; // in scope 0 at $DIR/simplify-arm.rs:24:13: 24:15
let mut _11: u8; // in scope 0 at $DIR/simplify-arm.rs:25:8: 25:9
scope 1 {
- debug x => _2; // in scope 1 at $DIR/simplify-arm.rs:24:9: 24:10
+- debug x => _2; // in scope 1 at $DIR/simplify-arm.rs:24:9: 24:10
++ debug x => ((_0 as Ok).0: u8); // in scope 1 at $DIR/simplify-arm.rs:24:9: 24:10
}
scope 2 {
- debug err => _6; // in scope 2 at $DIR/simplify-arm.rs:24:14: 24:15
+- debug err => _6; // in scope 2 at $DIR/simplify-arm.rs:24:14: 24:15
++ debug err => ((_0 as Err).0: i32); // in scope 2 at $DIR/simplify-arm.rs:24:14: 24:15
scope 3 {
+ scope 7 {
+- debug t => _9; // in scope 7 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
++ debug t => ((_0 as Err).0: i32); // in scope 7 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ }
+ scope 8 {
+- debug v => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
++ debug v => ((_0 as Err).0: i32); // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _12: i32; // in scope 8 at $DIR/simplify-arm.rs:24:14: 24:15
+ }
}
}
scope 4 {
- debug val => _10; // in scope 4 at $DIR/simplify-arm.rs:24:13: 24:15
+- debug val => _10; // in scope 4 at $DIR/simplify-arm.rs:24:13: 24:15
++ debug val => ((_0 as Ok).0: u8); // in scope 4 at $DIR/simplify-arm.rs:24:13: 24:15
scope 5 {
}
}
+ scope 6 {
+ debug self => _4; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ }
bb0: {
StorageLive(_2); // scope 0 at $DIR/simplify-arm.rs:24:9: 24:10
StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15
StorageLive(_4); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:14
_4 = _1; // scope 0 at $DIR/simplify-arm.rs:24:13: 24:14
- _3 = const <std::result::Result<u8, i32> as std::ops::Try>::into_result(move _4) -> bb1; // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15
- // ty::Const
- // + ty: fn(std::result::Result<u8, i32>) -> std::result::Result<<std::result::Result<u8, i32> as std::ops::Try>::Ok, <std::result::Result<u8, i32> as std::ops::Try>::Error> {<std::result::Result<u8, i32> as std::ops::Try>::into_result}
- // + val: Value(Scalar(<ZST>))
- // mir::Constant
- // + span: $DIR/simplify-arm.rs:24:13: 24:15
- // + literal: Const { ty: fn(std::result::Result<u8, i32>) -> std::result::Result<<std::result::Result<u8, i32> as std::ops::Try>::Ok, <std::result::Result<u8, i32> as std::ops::Try>::Error> {<std::result::Result<u8, i32> as std::ops::Try>::into_result}, val: Value(Scalar(<ZST>)) }
- }
-
- bb1: {
+ _3 = move _4; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
StorageDead(_4); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
_5 = discriminant(_3); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
- switchInt(move _5) -> [0_isize: bb2, 1_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
+ switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
}
- bb2: {
- StorageLive(_10); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15
- _10 = ((_3 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15
- _2 = _10; // scope 5 at $DIR/simplify-arm.rs:24:13: 24:15
- StorageDead(_10); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
+ bb1: {
+- StorageLive(_10); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15
+- _10 = ((_3 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15
+- _2 = _10; // scope 5 at $DIR/simplify-arm.rs:24:13: 24:15
+- StorageDead(_10); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
++ _0 = move _3; // scope 1 at $DIR/simplify-arm.rs:25:5: 25:10
StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:24:15: 24:16
- StorageLive(_11); // scope 1 at $DIR/simplify-arm.rs:25:8: 25:9
- _11 = _2; // scope 1 at $DIR/simplify-arm.rs:25:8: 25:9
- ((_0 as Ok).0: u8) = move _11; // scope 1 at $DIR/simplify-arm.rs:25:5: 25:10
- discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:25:5: 25:10
- StorageDead(_11); // scope 1 at $DIR/simplify-arm.rs:25:9: 25:10
+- StorageLive(_11); // scope 1 at $DIR/simplify-arm.rs:25:8: 25:9
+- _11 = _2; // scope 1 at $DIR/simplify-arm.rs:25:8: 25:9
+- ((_0 as Ok).0: u8) = move _11; // scope 1 at $DIR/simplify-arm.rs:25:5: 25:10
+- discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:25:5: 25:10
+- StorageDead(_11); // scope 1 at $DIR/simplify-arm.rs:25:9: 25:10
StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:26:1: 26:2
- goto -> bb5; // scope 0 at $DIR/simplify-arm.rs:26:2: 26:2
+ goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:26:2: 26:2
}
- bb3: {
+ bb2: {
unreachable; // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15
}
- bb4: {
- StorageLive(_6); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
- _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
- StorageLive(_8); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
- StorageLive(_9); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
- _9 = _6; // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
- _8 = const <i32 as std::convert::From<i32>>::from(move _9) -> bb6; // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
- // ty::Const
- // + ty: fn(i32) -> i32 {<i32 as std::convert::From<i32>>::from}
- // + val: Value(Scalar(<ZST>))
- // mir::Constant
- // + span: $DIR/simplify-arm.rs:24:14: 24:15
- // + literal: Const { ty: fn(i32) -> i32 {<i32 as std::convert::From<i32>>::from}, val: Value(Scalar(<ZST>)) }
+ bb3: {
+- StorageLive(_6); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
+- _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
+- StorageLive(_8); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
+- StorageLive(_9); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
+- _9 = _6; // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
+- _8 = move _9; // scope 7 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+- StorageDead(_9); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
+- StorageLive(_12); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+- _12 = move _8; // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+- ((_0 as Err).0: i32) = move _12; // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+- discriminant(_0) = 1; // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+- StorageDead(_12); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+- StorageDead(_8); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
+- StorageDead(_6); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
++ _0 = move _3; // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:24:15: 24:16
+ StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:26:1: 26:2
+ goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
}
- bb5: {
+ bb4: {
return; // scope 0 at $DIR/simplify-arm.rs:26:2: 26:2
}
-
- bb6: {
- StorageDead(_9); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
- _0 = const <std::result::Result<u8, i32> as std::ops::Try>::from_error(move _8) -> bb7; // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
- // ty::Const
- // + ty: fn(<std::result::Result<u8, i32> as std::ops::Try>::Error) -> std::result::Result<u8, i32> {<std::result::Result<u8, i32> as std::ops::Try>::from_error}
- // + val: Value(Scalar(<ZST>))
- // mir::Constant
- // + span: $DIR/simplify-arm.rs:24:13: 24:15
- // + literal: Const { ty: fn(<std::result::Result<u8, i32> as std::ops::Try>::Error) -> std::result::Result<u8, i32> {<std::result::Result<u8, i32> as std::ops::Try>::from_error}, val: Value(Scalar(<ZST>)) }
- }
-
- bb7: {
- StorageDead(_8); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
- StorageDead(_6); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
- StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:24:15: 24:16
- StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:26:1: 26:2
- goto -> bb5; // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
- }
}
let _10: u8; // in scope 0 at $DIR/simplify-arm.rs:24:13: 24:15
let mut _11: u8; // in scope 0 at $DIR/simplify-arm.rs:25:8: 25:9
scope 1 {
- debug x => _2; // in scope 1 at $DIR/simplify-arm.rs:24:9: 24:10
+ debug x => ((_0 as Ok).0: u8); // in scope 1 at $DIR/simplify-arm.rs:24:9: 24:10
}
scope 2 {
- debug err => _6; // in scope 2 at $DIR/simplify-arm.rs:24:14: 24:15
+ debug err => ((_0 as Err).0: i32); // in scope 2 at $DIR/simplify-arm.rs:24:14: 24:15
scope 3 {
+ scope 7 {
+ debug t => ((_0 as Err).0: i32); // in scope 7 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ }
+ scope 8 {
+ debug v => ((_0 as Err).0: i32); // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ let mut _12: i32; // in scope 8 at $DIR/simplify-arm.rs:24:14: 24:15
+ }
}
}
scope 4 {
- debug val => _10; // in scope 4 at $DIR/simplify-arm.rs:24:13: 24:15
+ debug val => ((_0 as Ok).0: u8); // in scope 4 at $DIR/simplify-arm.rs:24:13: 24:15
scope 5 {
}
}
+ scope 6 {
+ debug self => _4; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+ }
bb0: {
StorageLive(_2); // scope 0 at $DIR/simplify-arm.rs:24:9: 24:10
StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15
StorageLive(_4); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:14
_4 = _1; // scope 0 at $DIR/simplify-arm.rs:24:13: 24:14
- _3 = const <std::result::Result<u8, i32> as std::ops::Try>::into_result(move _4) -> bb1; // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15
- // ty::Const
- // + ty: fn(std::result::Result<u8, i32>) -> std::result::Result<<std::result::Result<u8, i32> as std::ops::Try>::Ok, <std::result::Result<u8, i32> as std::ops::Try>::Error> {<std::result::Result<u8, i32> as std::ops::Try>::into_result}
- // + val: Value(Scalar(<ZST>))
- // mir::Constant
- // + span: $DIR/simplify-arm.rs:24:13: 24:15
- // + literal: Const { ty: fn(std::result::Result<u8, i32>) -> std::result::Result<<std::result::Result<u8, i32> as std::ops::Try>::Ok, <std::result::Result<u8, i32> as std::ops::Try>::Error> {<std::result::Result<u8, i32> as std::ops::Try>::into_result}, val: Value(Scalar(<ZST>)) }
- }
-
- bb1: {
+ _3 = move _4; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
StorageDead(_4); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
_5 = discriminant(_3); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
- switchInt(move _5) -> [0_isize: bb2, 1_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
+- switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
++ goto -> bb1; // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
}
- bb2: {
- StorageLive(_10); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15
- _10 = ((_3 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15
- _2 = _10; // scope 5 at $DIR/simplify-arm.rs:24:13: 24:15
- StorageDead(_10); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
+ bb1: {
+ _0 = move _3; // scope 1 at $DIR/simplify-arm.rs:25:5: 25:10
StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:24:15: 24:16
- StorageLive(_11); // scope 1 at $DIR/simplify-arm.rs:25:8: 25:9
- _11 = _2; // scope 1 at $DIR/simplify-arm.rs:25:8: 25:9
- ((_0 as Ok).0: u8) = move _11; // scope 1 at $DIR/simplify-arm.rs:25:5: 25:10
- discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:25:5: 25:10
- StorageDead(_11); // scope 1 at $DIR/simplify-arm.rs:25:9: 25:10
StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:26:1: 26:2
- goto -> bb5; // scope 0 at $DIR/simplify-arm.rs:26:2: 26:2
- }
-
- bb3: {
- unreachable; // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15
+- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:26:2: 26:2
++ goto -> bb2; // scope 0 at $DIR/simplify-arm.rs:26:2: 26:2
}
- bb4: {
- StorageLive(_6); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
- _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
- StorageLive(_8); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
- StorageLive(_9); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
- _9 = _6; // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
- _8 = const <i32 as std::convert::From<i32>>::from(move _9) -> bb6; // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
- // ty::Const
- // + ty: fn(i32) -> i32 {<i32 as std::convert::From<i32>>::from}
- // + val: Value(Scalar(<ZST>))
- // mir::Constant
- // + span: $DIR/simplify-arm.rs:24:14: 24:15
- // + literal: Const { ty: fn(i32) -> i32 {<i32 as std::convert::From<i32>>::from}, val: Value(Scalar(<ZST>)) }
- }
-
- bb5: {
+ bb2: {
+- unreachable; // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15
+- }
+-
+- bb3: {
+- _0 = move _3; // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+- StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:24:15: 24:16
+- StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:26:1: 26:2
+- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
+- }
+-
+- bb4: {
return; // scope 0 at $DIR/simplify-arm.rs:26:2: 26:2
}
-
- bb6: {
- StorageDead(_9); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
- _0 = const <std::result::Result<u8, i32> as std::ops::Try>::from_error(move _8) -> bb7; // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
- // ty::Const
- // + ty: fn(<std::result::Result<u8, i32> as std::ops::Try>::Error) -> std::result::Result<u8, i32> {<std::result::Result<u8, i32> as std::ops::Try>::from_error}
- // + val: Value(Scalar(<ZST>))
- // mir::Constant
- // + span: $DIR/simplify-arm.rs:24:13: 24:15
- // + literal: Const { ty: fn(<std::result::Result<u8, i32> as std::ops::Try>::Error) -> std::result::Result<u8, i32> {<std::result::Result<u8, i32> as std::ops::Try>::from_error}, val: Value(Scalar(<ZST>)) }
- }
-
- bb7: {
- StorageDead(_8); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15
- StorageDead(_6); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
- StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:24:15: 24:16
- StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:26:1: 26:2
- goto -> bb5; // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15
- }
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/simplify-arm-identity.rs:18:9: 18:10
((_1 as Foo).0: u8) = const 0_u8; // scope 0 at $DIR/simplify-arm-identity.rs:18:18: 18:29
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/simplify-arm-identity.rs:18:27: 18:28
- // + literal: Const { ty: u8, val: Value(Scalar(0x00)) }
discriminant(_1) = 0; // scope 0 at $DIR/simplify-arm-identity.rs:18:18: 18:29
StorageLive(_2); // scope 1 at $DIR/simplify-arm-identity.rs:19:18: 22:6
_3 = const 0_isize; // scope 1 at $DIR/simplify-arm-identity.rs:20:9: 20:20
- // ty::Const
- // + ty: isize
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/simplify-arm-identity.rs:20:9: 20:20
- // + literal: Const { ty: isize, val: Value(Scalar(0x00000000)) }
goto -> bb3; // scope 1 at $DIR/simplify-arm-identity.rs:20:9: 20:20
}
bb1: {
((_2 as Foo).0: u8) = const 0_u8; // scope 1 at $DIR/simplify-arm-identity.rs:21:21: 21:32
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/simplify-arm-identity.rs:21:30: 21:31
- // + literal: Const { ty: u8, val: Value(Scalar(0x00)) }
discriminant(_2) = 0; // scope 1 at $DIR/simplify-arm-identity.rs:21:21: 21:32
goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:19:18: 22:6
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/simplify-arm-identity.rs:18:9: 18:10
((_1 as Foo).0: u8) = const 0_u8; // scope 0 at $DIR/simplify-arm-identity.rs:18:18: 18:29
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/simplify-arm-identity.rs:18:27: 18:28
- // + literal: Const { ty: u8, val: Value(Scalar(0x00)) }
discriminant(_1) = 0; // scope 0 at $DIR/simplify-arm-identity.rs:18:18: 18:29
StorageLive(_2); // scope 1 at $DIR/simplify-arm-identity.rs:19:18: 22:6
_3 = const 0_isize; // scope 1 at $DIR/simplify-arm-identity.rs:20:9: 20:20
- // ty::Const
- // + ty: isize
- // + val: Value(Scalar(0x0000000000000000))
- // mir::Constant
- // + span: $DIR/simplify-arm-identity.rs:20:9: 20:20
- // + literal: Const { ty: isize, val: Value(Scalar(0x0000000000000000)) }
goto -> bb3; // scope 1 at $DIR/simplify-arm-identity.rs:20:9: 20:20
}
bb1: {
((_2 as Foo).0: u8) = const 0_u8; // scope 1 at $DIR/simplify-arm-identity.rs:21:21: 21:32
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/simplify-arm-identity.rs:21:30: 21:31
- // + literal: Const { ty: u8, val: Value(Scalar(0x00)) }
discriminant(_2) = 0; // scope 1 at $DIR/simplify-arm-identity.rs:21:21: 21:32
goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:19:18: 22:6
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/simplify_if.rs:6:8: 6:13
_1 = const false; // scope 0 at $DIR/simplify_if.rs:6:8: 6:13
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/simplify_if.rs:6:8: 6:13
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
- switchInt(const false) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_if.rs:6:5: 8:6
-- // ty::Const
-- // + ty: bool
-- // + val: Value(Scalar(0x00))
-- // mir::Constant
-- // + span: $DIR/simplify_if.rs:6:5: 8:6
-- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
+ goto -> bb1; // scope 0 at $DIR/simplify_if.rs:6:5: 8:6
}
StorageLive(_8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13
_8 = _6; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13
_7 = Gt(move _8, const 42_u8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:20
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x2a))
- // mir::Constant
- // + span: $DIR/simplify-locals-fixedpoint.rs:5:16: 5:20
- // + literal: Const { ty: u8, val: Value(Scalar(0x2a)) }
StorageDead(_8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:19: 5:20
switchInt(_7) -> [false: bb4, otherwise: bb5]; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:9: 7:10
}
- StorageLive(_10); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:30
- StorageLive(_11); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:28
- (_11.0: u8) = const 40_u8; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:28
-+ StorageDead(_1); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:22: 14:23
-+ StorageLive(_2); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:5: 16:35
-+ _2 = const use_u8(const 42_u8) -> bb2; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:5: 16:35
- // ty::Const
-- // + ty: u8
-- // + val: Value(Scalar(0x28))
-- // mir::Constant
-- // + span: $DIR/simplify-locals-removes-unused-consts.rs:16:23: 16:25
-- // + literal: Const { ty: u8, val: Value(Scalar(0x28)) }
- _10 = const 40_u8; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:30
-- // ty::Const
-- // + ty: u8
-- // + val: Value(Scalar(0x28))
-- // mir::Constant
-- // + span: $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:30
-- // + literal: Const { ty: u8, val: Value(Scalar(0x28)) }
- _9 = const 42_u8; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:34
-- // ty::Const
-- // + ty: u8
-- // + val: Value(Scalar(0x2a))
-- // mir::Constant
-- // + span: $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:34
-- // + literal: Const { ty: u8, val: Value(Scalar(0x2a)) }
- StorageDead(_10); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:33: 16:34
- _8 = const use_u8(const 42_u8) -> bb2; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:5: 16:35
-- // ty::Const
++ StorageDead(_1); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:22: 14:23
++ StorageLive(_2); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:5: 16:35
++ _2 = const use_u8(const 42_u8) -> bb2; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:5: 16:35
+ // ty::Const
// + ty: fn(u8) {use_u8}
// + val: Value(Scalar(<ZST>))
// mir::Constant
// + span: $DIR/simplify-locals-removes-unused-consts.rs:16:5: 16:11
// + literal: Const { ty: fn(u8) {use_u8}, val: Value(Scalar(<ZST>)) }
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x2a))
- // mir::Constant
- // + span: $DIR/simplify-locals-removes-unused-consts.rs:16:5: 16:35
- // + literal: Const { ty: u8, val: Value(Scalar(0x2a)) }
}
bb2: {
fn map(_1: std::option::Option<std::boxed::Box<()>>) -> std::option::Option<std::boxed::Box<()>> {
debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:8: 1:9
let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:31: 1:46
- let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
+- let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
- let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15
- let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:25: 4:26
- let mut _5: bool; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2
bb0: {
- _5 = const false; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
-- // ty::Const
-- // + ty: bool
-- // + val: Value(Scalar(0x00))
-- // mir::Constant
-- // + span: $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
-- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
- _5 = const true; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
-- // ty::Const
-- // + ty: bool
-- // + val: Value(Scalar(0x01))
-- // mir::Constant
-- // + span: $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
-- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
- _2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
- switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
- }
-
- bb1: {
+- _2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
_0 = move _1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:20: 4:27
- goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6
- }
-
- bb2: {
- discriminant(_0) = 0; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:17: 3:21
- goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6
- }
-
- bb3: {
- _6 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2
return; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:2: 6:2
}
fn map(_1: std::option::Option<std::boxed::Box<()>>) -> std::option::Option<std::boxed::Box<()>> {
debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:8: 1:9
let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:31: 1:46
- let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
+- let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
- let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15
- let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:25: 4:26
- let mut _5: bool; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2
bb0: {
- _5 = const false; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
-- // ty::Const
-- // + ty: bool
-- // + val: Value(Scalar(0x00))
-- // mir::Constant
-- // + span: $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
-- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
- _5 = const true; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
-- // ty::Const
-- // + ty: bool
-- // + val: Value(Scalar(0x01))
-- // mir::Constant
-- // + span: $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
-- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
- _2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
- switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
- }
-
- bb1: {
+- _2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
_0 = move _1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:20: 4:27
- goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6
- }
-
- bb2: {
- discriminant(_0) = 0; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:17: 3:21
- goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6
- }
-
- bb3: {
- _6 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2
return; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:2: 6:2
}
StorageLive(_1); // scope 0 at $DIR/simplify_match.rs:6:11: 6:31
StorageLive(_2); // scope 0 at $DIR/simplify_match.rs:6:17: 6:18
_2 = const false; // scope 0 at $DIR/simplify_match.rs:6:21: 6:26
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x00))
- // mir::Constant
- // + span: $DIR/simplify_match.rs:6:21: 6:26
- // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
- _1 = _2; // scope 1 at $DIR/simplify_match.rs:6:28: 6:29
+ _1 = const false; // scope 1 at $DIR/simplify_match.rs:6:28: 6:29
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
-+ // mir::Constant
-+ // + span: $DIR/simplify_match.rs:6:28: 6:29
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
StorageDead(_2); // scope 0 at $DIR/simplify_match.rs:6:30: 6:31
- switchInt(_1) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:7:9: 7:13
+ switchInt(const false) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:7:9: 7:13
-+ // ty::Const
-+ // + ty: bool
-+ // + val: Value(Scalar(0x00))
-+ // mir::Constant
-+ // + span: $DIR/simplify_match.rs:7:9: 7:13
-+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
}
bb1: {
bb3 (cleanup): {
_5 = &raw mut (*_1)[_4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
_4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000001)) }
drop((*_5)) -> bb4; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
}
bb5: {
_7 = &raw mut (*_1)[_4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
_4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000001)) }
drop((*_7)) -> [return: bb6, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
}
bb7: {
_4 = const 0_usize; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000000)) }
goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
}
bb9 (cleanup): {
_11 = _9; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
_9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000001)) }
drop((*_11)) -> bb10; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
}
bb11: {
_13 = _9; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
_9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // + literal: Const { ty: usize, val: Value(Scalar(0x00000001)) }
drop((*_13)) -> [return: bb12, unwind: bb10]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
}
bb3 (cleanup): {
_5 = &raw mut (*_1)[_4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
_4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000001))
- // mir::Constant
- // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000001)) }
drop((*_5)) -> bb4; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
}
bb5: {
_7 = &raw mut (*_1)[_4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
_4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000001))
- // mir::Constant
- // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000001)) }
drop((*_7)) -> [return: bb6, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
}
bb7: {
_4 = const 0_usize; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000000))
- // mir::Constant
- // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) }
goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
}
bb9 (cleanup): {
_11 = _9; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
_9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000001))
- // mir::Constant
- // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000001)) }
drop((*_11)) -> bb10; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
}
bb11: {
_13 = _9; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
_9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // ty::Const
- // + ty: usize
- // + val: Value(Scalar(0x0000000000000001))
- // mir::Constant
- // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000001)) }
drop((*_13)) -> [return: bb12, unwind: bb10]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
}
StorageLive(_6); // scope 0 at $DIR/storage_live_dead_in_statics.rs:7:12: 22:6
StorageLive(_7); // scope 0 at $DIR/storage_live_dead_in_statics.rs:8:9: 8:15
_7 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:8:9: 8:15
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:8:10: 8:11
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:8:13: 8:14
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
StorageLive(_8); // scope 0 at $DIR/storage_live_dead_in_statics.rs:8:17: 8:23
_8 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:8:17: 8:23
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:8:18: 8:19
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:8:21: 8:22
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageLive(_9); // scope 0 at $DIR/storage_live_dead_in_statics.rs:8:25: 8:31
_9 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:8:25: 8:31
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:8:26: 8:27
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:8:29: 8:30
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000003)) }
StorageLive(_10); // scope 0 at $DIR/storage_live_dead_in_statics.rs:9:9: 9:15
_10 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:9:9: 9:15
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:9:10: 9:11
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:9:13: 9:14
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
StorageLive(_11); // scope 0 at $DIR/storage_live_dead_in_statics.rs:9:17: 9:23
_11 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:9:17: 9:23
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:9:18: 9:19
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:9:21: 9:22
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageLive(_12); // scope 0 at $DIR/storage_live_dead_in_statics.rs:9:25: 9:31
_12 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:9:25: 9:31
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:9:26: 9:27
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:9:29: 9:30
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000003)) }
StorageLive(_13); // scope 0 at $DIR/storage_live_dead_in_statics.rs:10:9: 10:15
_13 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:10:9: 10:15
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:10:10: 10:11
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:10:13: 10:14
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
StorageLive(_14); // scope 0 at $DIR/storage_live_dead_in_statics.rs:10:17: 10:23
_14 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:10:17: 10:23
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:10:18: 10:19
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:10:21: 10:22
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageLive(_15); // scope 0 at $DIR/storage_live_dead_in_statics.rs:10:25: 10:31
_15 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:10:25: 10:31
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:10:26: 10:27
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:10:29: 10:30
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000003)) }
StorageLive(_16); // scope 0 at $DIR/storage_live_dead_in_statics.rs:11:9: 11:15
_16 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:11:9: 11:15
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:11:10: 11:11
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:11:13: 11:14
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
StorageLive(_17); // scope 0 at $DIR/storage_live_dead_in_statics.rs:11:17: 11:23
_17 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:11:17: 11:23
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:11:18: 11:19
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:11:21: 11:22
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageLive(_18); // scope 0 at $DIR/storage_live_dead_in_statics.rs:11:25: 11:31
_18 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:11:25: 11:31
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:11:26: 11:27
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:11:29: 11:30
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000003)) }
StorageLive(_19); // scope 0 at $DIR/storage_live_dead_in_statics.rs:12:9: 12:15
_19 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:12:9: 12:15
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:12:10: 12:11
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:12:13: 12:14
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
StorageLive(_20); // scope 0 at $DIR/storage_live_dead_in_statics.rs:12:17: 12:23
_20 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:12:17: 12:23
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:12:18: 12:19
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:12:21: 12:22
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageLive(_21); // scope 0 at $DIR/storage_live_dead_in_statics.rs:12:25: 12:31
_21 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:12:25: 12:31
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:12:26: 12:27
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:12:29: 12:30
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000003)) }
StorageLive(_22); // scope 0 at $DIR/storage_live_dead_in_statics.rs:13:9: 13:15
_22 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:13:9: 13:15
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:13:10: 13:11
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:13:13: 13:14
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
StorageLive(_23); // scope 0 at $DIR/storage_live_dead_in_statics.rs:13:17: 13:23
_23 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:13:17: 13:23
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:13:18: 13:19
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:13:21: 13:22
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageLive(_24); // scope 0 at $DIR/storage_live_dead_in_statics.rs:13:25: 13:31
_24 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:13:25: 13:31
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:13:26: 13:27
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:13:29: 13:30
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000003)) }
StorageLive(_25); // scope 0 at $DIR/storage_live_dead_in_statics.rs:14:9: 14:15
_25 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:14:9: 14:15
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:14:10: 14:11
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:14:13: 14:14
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
StorageLive(_26); // scope 0 at $DIR/storage_live_dead_in_statics.rs:14:17: 14:23
_26 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:14:17: 14:23
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:14:18: 14:19
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:14:21: 14:22
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageLive(_27); // scope 0 at $DIR/storage_live_dead_in_statics.rs:14:25: 14:31
_27 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:14:25: 14:31
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:14:26: 14:27
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:14:29: 14:30
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000003)) }
StorageLive(_28); // scope 0 at $DIR/storage_live_dead_in_statics.rs:15:9: 15:15
_28 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:15:9: 15:15
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:15:10: 15:11
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:15:13: 15:14
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
StorageLive(_29); // scope 0 at $DIR/storage_live_dead_in_statics.rs:15:17: 15:23
_29 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:15:17: 15:23
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:15:18: 15:19
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:15:21: 15:22
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageLive(_30); // scope 0 at $DIR/storage_live_dead_in_statics.rs:15:25: 15:31
_30 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:15:25: 15:31
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:15:26: 15:27
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:15:29: 15:30
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000003)) }
StorageLive(_31); // scope 0 at $DIR/storage_live_dead_in_statics.rs:16:9: 16:15
_31 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:16:9: 16:15
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:16:10: 16:11
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:16:13: 16:14
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
StorageLive(_32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:16:17: 16:23
_32 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:16:17: 16:23
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:16:18: 16:19
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:16:21: 16:22
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageLive(_33); // scope 0 at $DIR/storage_live_dead_in_statics.rs:16:25: 16:31
_33 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:16:25: 16:31
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:16:26: 16:27
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:16:29: 16:30
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000003)) }
StorageLive(_34); // scope 0 at $DIR/storage_live_dead_in_statics.rs:17:9: 17:15
_34 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:17:9: 17:15
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:17:10: 17:11
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:17:13: 17:14
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
StorageLive(_35); // scope 0 at $DIR/storage_live_dead_in_statics.rs:17:17: 17:23
_35 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:17:17: 17:23
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:17:18: 17:19
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:17:21: 17:22
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageLive(_36); // scope 0 at $DIR/storage_live_dead_in_statics.rs:17:25: 17:31
_36 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:17:25: 17:31
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:17:26: 17:27
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:17:29: 17:30
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000003)) }
StorageLive(_37); // scope 0 at $DIR/storage_live_dead_in_statics.rs:18:9: 18:15
_37 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:18:9: 18:15
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:18:10: 18:11
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:18:13: 18:14
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
StorageLive(_38); // scope 0 at $DIR/storage_live_dead_in_statics.rs:18:17: 18:23
_38 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:18:17: 18:23
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:18:18: 18:19
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:18:21: 18:22
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageLive(_39); // scope 0 at $DIR/storage_live_dead_in_statics.rs:18:25: 18:31
_39 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:18:25: 18:31
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:18:26: 18:27
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:18:29: 18:30
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000003)) }
StorageLive(_40); // scope 0 at $DIR/storage_live_dead_in_statics.rs:19:9: 19:15
_40 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:19:9: 19:15
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:19:10: 19:11
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:19:13: 19:14
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
StorageLive(_41); // scope 0 at $DIR/storage_live_dead_in_statics.rs:19:17: 19:23
_41 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:19:17: 19:23
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:19:18: 19:19
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:19:21: 19:22
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageLive(_42); // scope 0 at $DIR/storage_live_dead_in_statics.rs:19:25: 19:31
_42 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:19:25: 19:31
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:19:26: 19:27
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:19:29: 19:30
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000003)) }
StorageLive(_43); // scope 0 at $DIR/storage_live_dead_in_statics.rs:20:9: 20:15
_43 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:20:9: 20:15
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:20:10: 20:11
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:20:13: 20:14
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
StorageLive(_44); // scope 0 at $DIR/storage_live_dead_in_statics.rs:20:17: 20:23
_44 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:20:17: 20:23
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:20:18: 20:19
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:20:21: 20:22
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageLive(_45); // scope 0 at $DIR/storage_live_dead_in_statics.rs:20:25: 20:31
_45 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:20:25: 20:31
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:20:26: 20:27
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:20:29: 20:30
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000003)) }
StorageLive(_46); // scope 0 at $DIR/storage_live_dead_in_statics.rs:21:9: 21:15
_46 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:21:9: 21:15
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:21:10: 21:11
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:21:13: 21:14
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
StorageLive(_47); // scope 0 at $DIR/storage_live_dead_in_statics.rs:21:17: 21:23
_47 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:21:17: 21:23
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:21:18: 21:19
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:21:21: 21:22
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
StorageLive(_48); // scope 0 at $DIR/storage_live_dead_in_statics.rs:21:25: 21:31
_48 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:21:25: 21:31
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:21:26: 21:27
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
- // ty::Const
- // + ty: u32
- // + val: Value(Scalar(0x00000003))
- // mir::Constant
- // + span: $DIR/storage_live_dead_in_statics.rs:21:29: 21:30
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000003)) }
_6 = [move _7, move _8, move _9, move _10, move _11, move _12, move _13, move _14, move _15, move _16, move _17, move _18, move _19, move _20, move _21, move _22, move _23, move _24, move _25, move _26, move _27, move _28, move _29, move _30, move _31, move _32, move _33, move _34, move _35, move _36, move _37, move _38, move _39, move _40, move _41, move _42, move _43, move _44, move _45, move _46, move _47, move _48]; // scope 0 at $DIR/storage_live_dead_in_statics.rs:7:12: 22:6
_5 = &_6; // scope 0 at $DIR/storage_live_dead_in_statics.rs:7:11: 22:6
_4 = &(*_5); // scope 0 at $DIR/storage_live_dead_in_statics.rs:7:11: 22:6
bb0: {
StorageLive(_1); // scope 0 at $DIR/storage_ranges.rs:4:9: 4:10
_1 = const 0_i32; // scope 0 at $DIR/storage_ranges.rs:4:13: 4:14
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/storage_ranges.rs:4:13: 4:14
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
FakeRead(ForLet, _1); // scope 0 at $DIR/storage_ranges.rs:4:9: 4:10
StorageLive(_2); // scope 1 at $DIR/storage_ranges.rs:5:5: 7:6
StorageLive(_3); // scope 1 at $DIR/storage_ranges.rs:6:13: 6:14
StorageDead(_2); // scope 1 at $DIR/storage_ranges.rs:7:5: 7:6
StorageLive(_6); // scope 1 at $DIR/storage_ranges.rs:8:9: 8:10
_6 = const 1_i32; // scope 1 at $DIR/storage_ranges.rs:8:13: 8:14
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/storage_ranges.rs:8:13: 8:14
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
FakeRead(ForLet, _6); // scope 1 at $DIR/storage_ranges.rs:8:9: 8:10
_0 = const (); // scope 0 at $DIR/storage_ranges.rs:3:11: 9:2
// ty::Const
StorageLive(_3); // scope 2 at $DIR/tls-access.rs:9:9: 9:12
_3 = &/*tls*/ mut FOO; // scope 2 at $DIR/tls-access.rs:9:9: 9:12
(*_3) = const 42_u8; // scope 2 at $DIR/tls-access.rs:9:9: 9:17
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x2a))
- // mir::Constant
- // + span: $DIR/tls-access.rs:9:15: 9:17
- // + literal: Const { ty: u8, val: Value(Scalar(0x2a)) }
StorageDead(_3); // scope 2 at $DIR/tls-access.rs:9:17: 9:18
_0 = const (); // scope 1 at $DIR/tls-access.rs:7:5: 10:6
// ty::Const
StorageLive(_3); // scope 0 at $DIR/uniform_array_move_out.rs:11:14: 11:19
_3 = Box(i32); // scope 0 at $DIR/uniform_array_move_out.rs:11:14: 11:19
(*_3) = const 1_i32; // scope 0 at $DIR/uniform_array_move_out.rs:11:18: 11:19
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/uniform_array_move_out.rs:11:18: 11:19
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
_2 = move _3; // scope 0 at $DIR/uniform_array_move_out.rs:11:14: 11:19
drop(_3) -> [return: bb4, unwind: bb2]; // scope 0 at $DIR/uniform_array_move_out.rs:11:18: 11:19
}
StorageLive(_5); // scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
_5 = Box(i32); // scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
(*_5) = const 2_i32; // scope 0 at $DIR/uniform_array_move_out.rs:11:25: 11:26
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/uniform_array_move_out.rs:11:25: 11:26
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
_4 = move _5; // scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
drop(_5) -> [return: bb7, unwind: bb5]; // scope 0 at $DIR/uniform_array_move_out.rs:11:25: 11:26
}
StorageLive(_3); // scope 0 at $DIR/uniform_array_move_out.rs:5:14: 5:19
_3 = Box(i32); // scope 0 at $DIR/uniform_array_move_out.rs:5:14: 5:19
(*_3) = const 1_i32; // scope 0 at $DIR/uniform_array_move_out.rs:5:18: 5:19
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/uniform_array_move_out.rs:5:18: 5:19
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
_2 = move _3; // scope 0 at $DIR/uniform_array_move_out.rs:5:14: 5:19
drop(_3) -> [return: bb4, unwind: bb2]; // scope 0 at $DIR/uniform_array_move_out.rs:5:18: 5:19
}
StorageLive(_5); // scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
_5 = Box(i32); // scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
(*_5) = const 2_i32; // scope 0 at $DIR/uniform_array_move_out.rs:5:25: 5:26
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/uniform_array_move_out.rs:5:25: 5:26
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
_4 = move _5; // scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
drop(_5) -> [return: bb7, unwind: bb5]; // scope 0 at $DIR/uniform_array_move_out.rs:5:25: 5:26
}
- StorageLive(_5); // scope 2 at $DIR/unreachable.rs:12:9: 16:10
- StorageLive(_6); // scope 2 at $DIR/unreachable.rs:12:12: 12:16
- _6 = const true; // scope 2 at $DIR/unreachable.rs:12:12: 12:16
-- // ty::Const
-- // + ty: bool
-- // + val: Value(Scalar(0x01))
-- // mir::Constant
-- // + span: $DIR/unreachable.rs:12:12: 12:16
-- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
- switchInt(_6) -> [false: bb4, otherwise: bb5]; // scope 2 at $DIR/unreachable.rs:12:9: 16:10
- }
-
- bb4: {
- _4 = const 42_i32; // scope 2 at $DIR/unreachable.rs:15:13: 15:20
-- // ty::Const
-- // + ty: i32
-- // + val: Value(Scalar(0x0000002a))
-- // mir::Constant
-- // + span: $DIR/unreachable.rs:15:18: 15:20
-- // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
- _5 = const (); // scope 2 at $DIR/unreachable.rs:14:16: 16:10
- // ty::Const
- // + ty: ()
-
- bb5: {
- _4 = const 21_i32; // scope 2 at $DIR/unreachable.rs:13:13: 13:20
-- // ty::Const
-- // + ty: i32
-- // + val: Value(Scalar(0x00000015))
-- // mir::Constant
-- // + span: $DIR/unreachable.rs:13:18: 13:20
-- // + literal: Const { ty: i32, val: Value(Scalar(0x00000015)) }
- _5 = const (); // scope 2 at $DIR/unreachable.rs:12:17: 14:10
- // ty::Const
- // + ty: ()
StorageLive(_5); // scope 2 at $DIR/unreachable_asm.rs:14:9: 18:10
StorageLive(_6); // scope 2 at $DIR/unreachable_asm.rs:14:12: 14:16
_6 = const true; // scope 2 at $DIR/unreachable_asm.rs:14:12: 14:16
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/unreachable_asm.rs:14:12: 14:16
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
switchInt(_6) -> [false: bb4, otherwise: bb5]; // scope 2 at $DIR/unreachable_asm.rs:14:9: 18:10
}
bb4: {
_4 = const 42_i32; // scope 2 at $DIR/unreachable_asm.rs:17:13: 17:20
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/unreachable_asm.rs:17:18: 17:20
- // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
_5 = const (); // scope 2 at $DIR/unreachable_asm.rs:16:16: 18:10
// ty::Const
// + ty: ()
bb5: {
_4 = const 21_i32; // scope 2 at $DIR/unreachable_asm.rs:15:13: 15:20
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000015))
- // mir::Constant
- // + span: $DIR/unreachable_asm.rs:15:18: 15:20
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000015)) }
_5 = const (); // scope 2 at $DIR/unreachable_asm.rs:14:17: 16:10
// ty::Const
// + ty: ()
StorageLive(_5); // scope 2 at $DIR/unreachable_asm_2.rs:14:9: 22:10
StorageLive(_6); // scope 2 at $DIR/unreachable_asm_2.rs:14:12: 14:16
_6 = const true; // scope 2 at $DIR/unreachable_asm_2.rs:14:12: 14:16
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/unreachable_asm_2.rs:14:12: 14:16
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
switchInt(_6) -> [false: bb4, otherwise: bb5]; // scope 2 at $DIR/unreachable_asm_2.rs:14:9: 22:10
}
// + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
StorageDead(_8); // scope 2 at $DIR/unreachable_asm_2.rs:20:40: 20:41
_4 = const 42_i32; // scope 2 at $DIR/unreachable_asm_2.rs:21:13: 21:20
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x0000002a))
- // mir::Constant
- // + span: $DIR/unreachable_asm_2.rs:21:18: 21:20
- // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
_5 = const (); // scope 2 at $DIR/unreachable_asm_2.rs:18:16: 22:10
// ty::Const
// + ty: ()
// + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
StorageDead(_7); // scope 2 at $DIR/unreachable_asm_2.rs:16:40: 16:41
_4 = const 21_i32; // scope 2 at $DIR/unreachable_asm_2.rs:17:13: 17:20
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000015))
- // mir::Constant
- // + span: $DIR/unreachable_asm_2.rs:17:18: 17:20
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000015)) }
_5 = const (); // scope 2 at $DIR/unreachable_asm_2.rs:14:17: 18:10
// ty::Const
// + ty: ()
bb0: {
StorageLive(_1); // scope 0 at $DIR/unreachable_diverging.rs:13:9: 13:10
_1 = const true; // scope 0 at $DIR/unreachable_diverging.rs:13:13: 13:17
- // ty::Const
- // + ty: bool
- // + val: Value(Scalar(0x01))
- // mir::Constant
- // + span: $DIR/unreachable_diverging.rs:13:13: 13:17
- // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
StorageLive(_2); // scope 1 at $DIR/unreachable_diverging.rs:14:25: 14:32
_2 = const empty() -> bb1; // scope 1 at $DIR/unreachable_diverging.rs:14:25: 14:32
// ty::Const
bb0: {
_0 = const 5_isize; // scope 0 at $DIR/unusual-item-types.rs:22:9: 22:10
- // ty::Const
- // + ty: isize
- // + val: Value(Scalar(0x00000005))
- // mir::Constant
- // + span: $DIR/unusual-item-types.rs:22:9: 22:10
- // + literal: Const { ty: isize, val: Value(Scalar(0x00000005)) }
return; // scope 0 at $DIR/unusual-item-types.rs:22:9: 22:10
}
bb0: {
_0 = const 5_isize; // scope 0 at $DIR/unusual-item-types.rs:22:9: 22:10
- // ty::Const
- // + ty: isize
- // + val: Value(Scalar(0x0000000000000005))
- // mir::Constant
- // + span: $DIR/unusual-item-types.rs:22:9: 22:10
- // + literal: Const { ty: isize, val: Value(Scalar(0x0000000000000005)) }
return; // scope 0 at $DIR/unusual-item-types.rs:22:9: 22:10
}
bb0: {
_0 = const 2_i32; // scope 0 at $DIR/unusual-item-types.rs:10:38: 10:39
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/unusual-item-types.rs:10:38: 10:39
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
return; // scope 0 at $DIR/unusual-item-types.rs:10:5: 10:40
}
bb0: {
_0 = const 2_i32; // scope 0 at $DIR/unusual-item-types.rs:10:38: 10:39
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000002))
- // mir::Constant
- // + span: $DIR/unusual-item-types.rs:10:38: 10:39
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
return; // scope 0 at $DIR/unusual-item-types.rs:10:5: 10:40
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:6:9: 6:15
_1 = const 0_i32; // scope 0 at $DIR/while_let_loops.rs:6:18: 6:19
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/while_let_loops.rs:6:18: 6:19
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
StorageLive(_3); // scope 1 at $DIR/while_let_loops.rs:7:28: 7:32
discriminant(_3) = 0; // scope 1 at $DIR/while_let_loops.rs:7:28: 7:32
- _4 = discriminant(_3); // scope 1 at $DIR/while_let_loops.rs:7:15: 7:25
- switchInt(move _4) -> [1_isize: bb2, otherwise: bb1]; // scope 1 at $DIR/while_let_loops.rs:7:15: 7:25
+ _4 = const 0_isize; // scope 1 at $DIR/while_let_loops.rs:7:15: 7:25
-+ // ty::Const
-+ // + ty: isize
-+ // + val: Value(Scalar(0x00000000))
-+ // mir::Constant
-+ // + span: $DIR/while_let_loops.rs:7:15: 7:25
-+ // + literal: Const { ty: isize, val: Value(Scalar(0x00000000)) }
+ switchInt(const 0_isize) -> [1_isize: bb2, otherwise: bb1]; // scope 1 at $DIR/while_let_loops.rs:7:15: 7:25
-+ // ty::Const
-+ // + ty: isize
-+ // + val: Value(Scalar(0x00000000))
-+ // mir::Constant
-+ // + span: $DIR/while_let_loops.rs:7:15: 7:25
-+ // + literal: Const { ty: isize, val: Value(Scalar(0x00000000)) }
}
bb1: {
bb3: {
_1 = const 1_i32; // scope 1 at $DIR/while_let_loops.rs:8:9: 8:15
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/while_let_loops.rs:8:14: 8:15
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
_0 = const (); // scope 1 at $DIR/while_let_loops.rs:9:9: 9:14
// ty::Const
// + ty: ()
bb0: {
StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:6:9: 6:15
_1 = const 0_i32; // scope 0 at $DIR/while_let_loops.rs:6:18: 6:19
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/while_let_loops.rs:6:18: 6:19
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
StorageLive(_3); // scope 1 at $DIR/while_let_loops.rs:7:28: 7:32
discriminant(_3) = 0; // scope 1 at $DIR/while_let_loops.rs:7:28: 7:32
- _4 = discriminant(_3); // scope 1 at $DIR/while_let_loops.rs:7:15: 7:25
- switchInt(move _4) -> [1_isize: bb2, otherwise: bb1]; // scope 1 at $DIR/while_let_loops.rs:7:15: 7:25
+ _4 = const 0_isize; // scope 1 at $DIR/while_let_loops.rs:7:15: 7:25
-+ // ty::Const
-+ // + ty: isize
-+ // + val: Value(Scalar(0x0000000000000000))
-+ // mir::Constant
-+ // + span: $DIR/while_let_loops.rs:7:15: 7:25
-+ // + literal: Const { ty: isize, val: Value(Scalar(0x0000000000000000)) }
+ switchInt(const 0_isize) -> [1_isize: bb2, otherwise: bb1]; // scope 1 at $DIR/while_let_loops.rs:7:15: 7:25
-+ // ty::Const
-+ // + ty: isize
-+ // + val: Value(Scalar(0x0000000000000000))
-+ // mir::Constant
-+ // + span: $DIR/while_let_loops.rs:7:15: 7:25
-+ // + literal: Const { ty: isize, val: Value(Scalar(0x0000000000000000)) }
}
bb1: {
bb3: {
_1 = const 1_i32; // scope 1 at $DIR/while_let_loops.rs:8:9: 8:15
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000001))
- // mir::Constant
- // + span: $DIR/while_let_loops.rs:8:14: 8:15
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
_0 = const (); // scope 1 at $DIR/while_let_loops.rs:9:9: 9:14
// ty::Const
// + ty: ()
bb0: {
StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:6:9: 6:15
_1 = const 0_i32; // scope 0 at $DIR/while_let_loops.rs:6:18: 6:19
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/while_let_loops.rs:6:18: 6:19
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
StorageLive(_2); // scope 1 at $DIR/while_let_loops.rs:7:28: 7:32
discriminant(_2) = 0; // scope 1 at $DIR/while_let_loops.rs:7:28: 7:32
_0 = const (); // scope 1 at $DIR/while_let_loops.rs:7:5: 10:6
bb0: {
StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:6:9: 6:15
_1 = const 0_i32; // scope 0 at $DIR/while_let_loops.rs:6:18: 6:19
- // ty::Const
- // + ty: i32
- // + val: Value(Scalar(0x00000000))
- // mir::Constant
- // + span: $DIR/while_let_loops.rs:6:18: 6:19
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
StorageLive(_2); // scope 1 at $DIR/while_let_loops.rs:7:28: 7:32
discriminant(_2) = 0; // scope 1 at $DIR/while_let_loops.rs:7:28: 7:32
_0 = const (); // scope 1 at $DIR/while_let_loops.rs:7:5: 10:6
use rustc_driver::plugin::Registry;
use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
-use rustc_ast::ast;
+use rustc_ast as ast;
declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
declare_lint_pass!(Pass => [TEST_LINT]);
use rustc_driver::plugin::Registry;
use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintId, LintPass};
-use rustc_ast::ast;
+use rustc_ast as ast;
declare_tool_lint!(pub clippy::TEST_LINT, Warn, "Warn about stuff");
declare_tool_lint!(
/// Some docs
use rustc_span::source_map::{Spanned, DUMMY_SP, FileName};
use rustc_span::source_map::FilePathMapping;
use rustc_span::symbol::Ident;
-use rustc_ast::ast::*;
+use rustc_ast::*;
use rustc_ast::mut_visit::{self, MutVisitor, visit_clobber};
use rustc_ast::ptr::P;
--- /dev/null
+// check-pass
+#![feature(const_raw_ptr_deref)]
+#![feature(raw_ref_macros)]
+
+use std::ptr;
+
+const fn test_fn(x: *const i32) {
+ let x2 = unsafe { ptr::raw_const!(*x) };
+}
+
+fn main() {}
-const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ is unsafe
+const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } }
//~^ dereferencing raw pointers in constant functions
const unsafe fn bad_const_unsafe_deref_raw(x: *mut usize) -> usize { *x }
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
-error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
- --> $DIR/min_const_fn_unsafe_bad.rs:1:77
- |
-LL | const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } }
- | ^^^ dereference of raw pointer
- |
- = note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
-
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
-Some errors have detailed explanations: E0133, E0658, E0723.
-For more information about an error, try `rustc --explain E0133`.
+Some errors have detailed explanations: E0658, E0723.
+For more information about an error, try `rustc --explain E0658`.
--- /dev/null
+// compile-flags: --crate-type=lib
+// normalize-stderr-32bit: "offset 8" -> "offset $$TWO_WORDS"
+// normalize-stderr-64bit: "offset 16" -> "offset $$TWO_WORDS"
+// normalize-stderr-32bit: "size 4" -> "size $$WORD"
+// normalize-stderr-64bit: "size 8" -> "size $$WORD"
+
+#![feature(
+ const_panic,
+ core_intrinsics,
+ const_raw_ptr_comparison,
+ const_ptr_offset,
+ const_raw_ptr_deref,
+ raw_ref_macros
+)]
+
+const FOO: &usize = &42;
+
+macro_rules! check {
+ (eq, $a:expr, $b:expr) => {
+ pub const _: () =
+ assert!(std::intrinsics::ptr_guaranteed_eq($a as *const u8, $b as *const u8));
+ };
+ (ne, $a:expr, $b:expr) => {
+ pub const _: () =
+ assert!(std::intrinsics::ptr_guaranteed_ne($a as *const u8, $b as *const u8));
+ };
+ (!eq, $a:expr, $b:expr) => {
+ pub const _: () =
+ assert!(!std::intrinsics::ptr_guaranteed_eq($a as *const u8, $b as *const u8));
+ };
+ (!ne, $a:expr, $b:expr) => {
+ pub const _: () =
+ assert!(!std::intrinsics::ptr_guaranteed_ne($a as *const u8, $b as *const u8));
+ };
+}
+
+check!(eq, 0, 0);
+check!(ne, 0, 1);
+check!(!eq, 0, 1);
+check!(!ne, 0, 0);
+check!(ne, FOO as *const _, 0);
+check!(!eq, FOO as *const _, 0);
+// We want pointers to be equal to themselves, but aren't checking this yet because
+// there are some open questions (e.g. whether function pointers to the same function
+// compare equal, they don't necessarily at runtime).
+// The case tested here should work eventually, but does not work yet.
+check!(!eq, FOO as *const _, FOO as *const _);
+check!(ne, unsafe { (FOO as *const usize).offset(1) }, 0);
+check!(!eq, unsafe { (FOO as *const usize).offset(1) }, 0);
+
+check!(ne, unsafe { (FOO as *const usize as *const u8).offset(3) }, 0);
+check!(!eq, unsafe { (FOO as *const usize as *const u8).offset(3) }, 0);
+
+///////////////////////////////////////////////////////////////////////////////
+// If any of the below start compiling, make sure to add a `check` test for it.
+// These invocations exist as canaries so we don't forget to check that the
+// behaviour of `guaranteed_eq` and `guaranteed_ne` is still correct.
+// All of these try to obtain an out of bounds pointer in some manner. If we
+// can create out of bounds pointers, we can offset a pointer far enough that
+// at runtime it would be zero and at compile-time it would not be zero.
+
+const _: *const usize = unsafe { (FOO as *const usize).offset(2) };
+//~^ NOTE
+
+const _: *const u8 =
+//~^ NOTE
+ unsafe { std::ptr::raw_const!((*(FOO as *const usize as *const [u8; 1000]))[999]) };
+//~^ ERROR any use of this value will cause an error
+
+const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
+//~^ ERROR any use of this value will cause an error
+//~| NOTE "pointer-to-integer cast" needs an rfc
+//~| NOTE
+
+const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 };
+//~^ ERROR any use of this value will cause an error
+//~| NOTE "pointer-to-integer cast" needs an rfc
+//~| NOTE
--- /dev/null
+error: any use of this value will cause an error
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+LL | unsafe { intrinsics::offset(self, count) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | inbounds test failed: pointer must be in-bounds at offset $TWO_WORDS, but is outside bounds of alloc2 which has size $WORD
+ | inside `std::ptr::const_ptr::<impl *const usize>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | inside `_` at $DIR/ptr_comparisons.rs:62:34
+ |
+ ::: $DIR/ptr_comparisons.rs:62:1
+ |
+LL | const _: *const usize = unsafe { (FOO as *const usize).offset(2) };
+ | -------------------------------------------------------------------
+ |
+ = note: `#[deny(const_err)]` on by default
+
+error: any use of this value will cause an error
+ --> $DIR/ptr_comparisons.rs:67:14
+ |
+LL | / const _: *const u8 =
+LL | |
+LL | | unsafe { std::ptr::raw_const!((*(FOO as *const usize as *const [u8; 1000]))[999]) };
+ | |______________^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^__-
+ | |
+ | memory access failed: pointer must be in-bounds at offset 1000, but is outside bounds of alloc2 which has size $WORD
+ |
+ = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: any use of this value will cause an error
+ --> $DIR/ptr_comparisons.rs:70:27
+ |
+LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
+ | --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | "pointer-to-integer cast" needs an rfc before being allowed inside constants
+
+error: any use of this value will cause an error
+ --> $DIR/ptr_comparisons.rs:75:27
+ |
+LL | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 };
+ | --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | "pointer-to-integer cast" needs an rfc before being allowed inside constants
+
+error: aborting due to 4 previous errors
+
--- /dev/null
+// compile-flags: --crate-type=lib
+// check-pass
+
+#![feature(const_ptr_is_null, const_panic)]
+
+const FOO: &usize = &42;
+
+pub const _: () = assert!(!(FOO as *const usize).is_null());
+
+pub const _: () = assert!(!(42 as *const usize).is_null());
+
+pub const _: () = assert!((0 as *const usize).is_null());
+
+pub const _: () = assert!(std::ptr::null::<usize>().is_null());
+
+pub const _: () = assert!(!("foo" as *const str).is_null());
--- /dev/null
+// Previously this ICE'd because `fn g()` would be lowered, but the block associated with `fn f()`
+// wasn't.
+
+// compile-flags: --crate-type=lib
+
+extern "C" {
+ fn f() {
+ //~^ incorrect function inside `extern` block
+ fn g() {}
+ }
+}
--- /dev/null
+error: incorrect function inside `extern` block
+ --> $DIR/issue-74120-lowering-of-ffi-block-bodies.rs:7:8
+ |
+LL | extern "C" {
+ | ---------- `extern` blocks define existing foreign functions and functions inside of them cannot have a body
+LL | fn f() {
+ | ________^___-
+ | | |
+ | | cannot have a body
+LL | |
+LL | | fn g() {}
+LL | | }
+ | |_____- help: remove the invalid body: `;`
+ |
+ = help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: aborting due to previous error
+
--- /dev/null
+// check-pass
+// edition:2018
+// aux-build:not-libstd.rs
+
+// Check that paths created in HIR are not affected by in scope names.
+
+extern crate not_libstd as std;
+
+async fn the_future() {
+ async {}.await;
+}
+
+fn main() -> Result<(), ()> {
+ for i in 0..10 {}
+ for j in 0..=10 {}
+ Ok(())?;
+ Ok(())
+}
--- /dev/null
+// Regression test for #66768.
+// check-pass
+#![allow(dead_code)]
+//-^ "dead code" is needed to reproduce the issue.
+
+use std::marker::PhantomData;
+use std::ops::{Add, Mul};
+
+fn problematic_function<Space>(material_surface_element: Edge2dElement)
+where
+ DefaultAllocator: FiniteElementAllocator<DimU1, Space>,
+{
+ let _: Point2<f64> = material_surface_element.map_reference_coords().into();
+}
+
+impl<T> ArrayLength<T> for UTerm {
+ type ArrayType = ();
+}
+impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B0> {
+ type ArrayType = GenericArrayImplEven<T, N>;
+}
+impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {
+ type ArrayType = GenericArrayImplOdd<T, N>;
+}
+impl<U> Add<U> for UTerm {
+ type Output = U;
+ fn add(self, _: U) -> Self::Output {
+ unimplemented!()
+ }
+}
+impl<Ul, Ur> Add<UInt<Ur, B1>> for UInt<Ul, B0>
+where
+ Ul: Add<Ur>,
+{
+ type Output = UInt<Sum<Ul, Ur>, B1>;
+ fn add(self, _: UInt<Ur, B1>) -> Self::Output {
+ unimplemented!()
+ }
+}
+impl<U> Mul<U> for UTerm {
+ type Output = UTerm;
+ fn mul(self, _: U) -> Self {
+ unimplemented!()
+ }
+}
+impl<Ul, B, Ur> Mul<UInt<Ur, B>> for UInt<Ul, B0>
+where
+ Ul: Mul<UInt<Ur, B>>,
+{
+ type Output = UInt<Prod<Ul, UInt<Ur, B>>, B0>;
+ fn mul(self, _: UInt<Ur, B>) -> Self::Output {
+ unimplemented!()
+ }
+}
+impl<Ul, B, Ur> Mul<UInt<Ur, B>> for UInt<Ul, B1>
+where
+ Ul: Mul<UInt<Ur, B>>,
+ UInt<Prod<Ul, UInt<Ur, B>>, B0>: Add<UInt<Ur, B>>,
+{
+ type Output = Sum<UInt<Prod<Ul, UInt<Ur, B>>, B0>, UInt<Ur, B>>;
+ fn mul(self, _: UInt<Ur, B>) -> Self::Output {
+ unimplemented!()
+ }
+}
+impl<N, R, C> Allocator<N, R, C> for DefaultAllocator
+where
+ R: DimName,
+ C: DimName,
+ R::Value: Mul<C::Value>,
+ Prod<R::Value, C::Value>: ArrayLength<N>,
+{
+ type Buffer = ArrayStorage<N, R, C>;
+ fn allocate_uninitialized(_: R, _: C) -> Self::Buffer {
+ unimplemented!()
+ }
+ fn allocate_from_iterator<I>(_: R, _: C, _: I) -> Self::Buffer {
+ unimplemented!()
+ }
+}
+impl<N, C> Allocator<N, Dynamic, C> for DefaultAllocator {
+ type Buffer = VecStorage<N, Dynamic, C>;
+ fn allocate_uninitialized(_: Dynamic, _: C) -> Self::Buffer {
+ unimplemented!()
+ }
+ fn allocate_from_iterator<I>(_: Dynamic, _: C, _: I) -> Self::Buffer {
+ unimplemented!()
+ }
+}
+impl DimName for DimU1 {
+ type Value = U1;
+ fn name() -> Self {
+ unimplemented!()
+ }
+}
+impl DimName for DimU2 {
+ type Value = U2;
+ fn name() -> Self {
+ unimplemented!()
+ }
+}
+impl<N, D> From<VectorN<N, D>> for Point<N, D>
+where
+ DefaultAllocator: Allocator<N, D>,
+{
+ fn from(_: VectorN<N, D>) -> Self {
+ unimplemented!()
+ }
+}
+impl<GeometryDim, NodalDim> FiniteElementAllocator<GeometryDim, NodalDim> for DefaultAllocator where
+ DefaultAllocator: Allocator<f64, GeometryDim> + Allocator<f64, NodalDim>
+{
+}
+impl ReferenceFiniteElement for Edge2dElement {
+ type NodalDim = DimU1;
+}
+impl FiniteElement<DimU2> for Edge2dElement {
+ fn map_reference_coords(&self) -> Vector2<f64> {
+ unimplemented!()
+ }
+}
+
+type Owned<N, R, C> = <DefaultAllocator as Allocator<N, R, C>>::Buffer;
+type MatrixMN<N, R, C> = Matrix<N, R, C, Owned<N, R, C>>;
+type VectorN<N, D> = MatrixMN<N, D, DimU1>;
+type Vector2<N> = VectorN<N, DimU2>;
+type Point2<N> = Point<N, DimU2>;
+type U1 = UInt<UTerm, B1>;
+type U2 = UInt<UInt<UTerm, B1>, B0>;
+type Sum<A, B> = <A as Add<B>>::Output;
+type Prod<A, B> = <A as Mul<B>>::Output;
+
+struct GenericArray<T, U: ArrayLength<T>> {
+ _data: U::ArrayType,
+}
+struct GenericArrayImplEven<T, U> {
+ _parent2: U,
+ _marker: T,
+}
+struct GenericArrayImplOdd<T, U> {
+ _parent2: U,
+ _data: T,
+}
+struct B0;
+struct B1;
+struct UTerm;
+struct UInt<U, B> {
+ _marker: PhantomData<(U, B)>,
+}
+struct DefaultAllocator;
+struct Dynamic;
+struct DimU1;
+struct DimU2;
+struct Matrix<N, R, C, S> {
+ _data: S,
+ _phantoms: PhantomData<(N, R, C)>,
+}
+struct ArrayStorage<N, R, C>
+where
+ R: DimName,
+ C: DimName,
+ R::Value: Mul<C::Value>,
+ Prod<R::Value, C::Value>: ArrayLength<N>,
+{
+ _data: GenericArray<N, Prod<R::Value, C::Value>>,
+}
+struct VecStorage<N, R, C> {
+ _data: N,
+ _nrows: R,
+ _ncols: C,
+}
+struct Point<N, D>
+where
+ DefaultAllocator: Allocator<N, D>,
+{
+ _coords: VectorN<N, D>,
+}
+struct Edge2dElement;
+
+trait ArrayLength<T> {
+ type ArrayType;
+}
+trait Allocator<Scalar, R, C = DimU1> {
+ type Buffer;
+ fn allocate_uninitialized(nrows: R, ncols: C) -> Self::Buffer;
+ fn allocate_from_iterator<I>(nrows: R, ncols: C, iter: I) -> Self::Buffer;
+}
+trait DimName {
+ type Value;
+ fn name() -> Self;
+}
+trait FiniteElementAllocator<GeometryDim, NodalDim>:
+ Allocator<f64, GeometryDim> + Allocator<f64, NodalDim>
+{
+}
+trait ReferenceFiniteElement {
+ type NodalDim;
+}
+trait FiniteElement<GeometryDim>: ReferenceFiniteElement
+where
+ DefaultAllocator: FiniteElementAllocator<GeometryDim, Self::NodalDim>,
+{
+ fn map_reference_coords(&self) -> VectorN<f64, GeometryDim>;
+}
+
+fn main() {}
|
LL | let range = *arr..;
| ^^^^^^ doesn't have a size known at compile-time
+ |
+ ::: $SRC_DIR/core/src/ops/range.rs:LL:COL
+ |
+LL | pub struct RangeFrom<Idx> {
+ | --- required by this bound in `std::ops::RangeFrom`
|
= help: the trait `std::marker::Sized` is not implemented for `[{integer}]`
- = note: required by `std::ops::RangeFrom`
error: aborting due to 3 previous errors
--- /dev/null
+fn main() {}
+fn foo(mut s: String) -> String {
+ s.push_str("asdf") //~ ERROR mismatched types
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/chain-method-call-mutation-in-place.rs:3:5
+ |
+LL | fn foo(mut s: String) -> String {
+ | ------ expected `std::string::String` because of return type
+LL | s.push_str("asdf")
+ | ^^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found `()`
+ |
+note: method `push_str` modifies its receiver in-place
+ --> $DIR/chain-method-call-mutation-in-place.rs:3:7
+ |
+LL | s.push_str("asdf")
+ | - ^^^^^^^^ this call modifies `s` in-place
+ | |
+ | you probably want to use this value after calling the method...
+ = note: ...instead of the `()` output of method `push_str`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
//
// error: internal compiler error: get_unique_type_id_of_type() -
// unexpected type: closure,
-// Closure(rustc_ast::ast::DefId{krate: 0, node: 66},
+// Closure(rustc_ast::DefId{krate: 0, node: 66},
// ReScope(63))
//
// This is a regression test for issue #17021.
span_lint_and_sugg, span_lint_and_then, without_block_comments,
};
use if_chain::if_chain;
-use rustc_ast::ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
+use rustc_ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
use rustc_ast::util::lev_distance::find_best_match_for_name;
use rustc_errors::Applicability;
use rustc_hir::{
]);
impl EarlyLintPass for EarlyAttributes {
- fn check_item(&mut self, cx: &EarlyContext<'_>, item: &rustc_ast::ast::Item) {
+ fn check_item(&mut self, cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
check_empty_line_after_outer_attr(cx, item);
}
}
}
-fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::ast::Item) {
+fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
for attr in &item.attrs {
let attr_item = if let AttrKind::Normal(ref attr) = attr.kind {
attr
);
}
},
- QPath::TypeRelative(..) => {},
+ QPath::TypeRelative(..) | QPath::LangItem(..) => {},
}
}
}
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if let ExprKind::Index(ref array, ref index) = &expr.kind {
let ty = cx.typeck_results().expr_ty(array);
- if let Some(range) = higher::range(cx, index) {
+ if let Some(range) = higher::range(index) {
// Ranged indexes, i.e., &x[n..m], &x[n..], &x[..n] and &x[..]
if let ty::Array(_, s) = ty.kind {
let size: u128 = if let Some(size) = s.try_eval_usize(cx.tcx, cx.param_env) {
Finite
}
},
- ExprKind::Struct(..) => higher::range(cx, expr).map_or(false, |r| r.end.is_none()).into(),
+ ExprKind::Struct(..) => higher::range(expr).map_or(false, |r| r.end.is_none()).into(),
_ => Finite,
}
}
fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
/// Special case ranges until `range_is_empty` is stabilized. See issue 3807.
fn should_skip_range(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
- higher::range(cx, expr).map_or(false, |_| {
+ higher::range(expr).map_or(false, |_| {
!cx.tcx
.features()
.declared_lib_features
}
#[doc(hidden)]
-pub fn read_conf(args: &[rustc_ast::ast::NestedMetaItem], sess: &Session) -> Conf {
+pub fn read_conf(args: &[rustc_ast::NestedMetaItem], sess: &Session) -> Conf {
use std::path::Path;
match utils::conf::file_from_args(args) {
Ok(file_name) => {
start: Some(start),
end: Some(end),
limits,
- }) = higher::range(cx, arg)
+ }) = higher::range(arg)
{
// the var must be a single name
if let PatKind::Binding(_, canonical_id, _, _) = pat.kind {
start: Some(start),
ref end,
limits,
- }) = higher::range(cx, arg)
+ }) = higher::range(arg)
{
// the var must be a single name
if let PatKind::Binding(_, canonical_id, ident, _) = pat.kind {
start: Some(start),
end: Some(end),
..
- }) = higher::range(cx, arg)
+ }) = higher::range(arg)
{
let mut_ids = vec![check_for_mutability(cx, start), check_for_mutability(cx, end)];
if mut_ids[0].is_some() || mut_ids[1].is_some() {
-use crate::utils::{self, is_type_diagnostic_item, match_type, snippet, span_lint_and_sugg, walk_ptrs_ty};
+use crate::utils::{is_type_diagnostic_item, is_type_lang_item, snippet, span_lint_and_sugg};
+use crate::utils::walk_ptrs_ty;
use if_chain::if_chain;
use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind, MatchSource};
+use rustc_hir::{Expr, ExprKind, LangItem, MatchSource};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_lint_pass, declare_tool_lint};
fn is_full_range(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
let ty = cx.typeck_results().expr_ty(expr);
let ty = walk_ptrs_ty(ty);
- match_type(cx, ty, &utils::paths::RANGE_FULL)
+ is_type_lang_item(cx, ty, LangItem::RangeFull)
}
if_chain! {
if let hir::ExprKind::Index(ref caller_var, ref index_expr) = &caller_expr.kind;
if let Some(higher::Range { start: Some(start_expr), end: None, limits: ast::RangeLimits::HalfOpen })
- = higher::range(cx, index_expr);
+ = higher::range(index_expr);
if let hir::ExprKind::Lit(ref start_lit) = &start_expr.kind;
if let ast::LitKind::Int(start_idx, _) = start_lit.node;
then {
return;
}
let binding = match expr.kind {
+ ExprKind::Path(hir::QPath::LangItem(..)) => None,
ExprKind::Path(ref qpath) => {
let binding = last_path_segment(qpath).ident.as_str();
if binding.starts_with('_') &&
if let ExprKind::MethodCall(ref iter_path, _, ref iter_args , _) = *iter;
if iter_path.ident.name == sym!(iter);
// range expression in `.zip()` call: `0..x.len()`
- if let Some(higher::Range { start: Some(start), end: Some(end), .. }) = higher::range(cx, zip_arg);
+ if let Some(higher::Range { start: Some(start), end: Some(end), .. }) = higher::range(zip_arg);
if is_integer_const(cx, start, 0);
// `.len()` call
if let ExprKind::MethodCall(ref len_path, _, ref len_args, _) = end.kind;
start,
end: Some(end),
limits: RangeLimits::HalfOpen
- }) = higher::range(cx, expr);
+ }) = higher::range(expr);
if let Some(y) = y_plus_one(cx, end);
then {
let span = if expr.span.from_expansion() {
// inclusive range minus one: `x..=(y-1)`
fn check_inclusive_range_minus_one(cx: &LateContext<'_>, expr: &Expr<'_>) {
if_chain! {
- if let Some(higher::Range { start, end: Some(end), limits: RangeLimits::Closed }) = higher::range(cx, expr);
+ if let Some(higher::Range { start, end: Some(end), limits: RangeLimits::Closed }) = higher::range(expr);
if let Some(y) = y_minus_one(cx, end);
then {
span_lint_and_then(
}
if_chain! {
- if let Some(higher::Range { start: Some(start), end: Some(end), limits }) = higher::range(cx, expr);
+ if let Some(higher::Range { start: Some(start), end: Some(end), limits }) = higher::range(expr);
let ty = cx.typeck_results().expr_ty(start);
if let ty::Int(_) | ty::Uint(_) = ty.kind;
if let Some((start_idx, _)) = constant(cx, cx.typeck_results(), start);
use crate::utils::{in_macro, span_lint_and_sugg};
use if_chain::if_chain;
-use rustc_ast::ast::{Item, ItemKind, UseTreeKind};
+use rustc_ast::{Item, ItemKind, UseTreeKind};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
use crate::utils::{snippet, snippet_with_applicability};
- use rustc_ast::ast::LitKind;
+ use rustc_ast::LitKind;
if_chain! {
if let ExprKind::MethodCall(path, _, args, _) = &e.kind;
span_lint_and_then, sugg,
};
use if_chain::if_chain;
-use rustc_ast::ast;
+use rustc_ast as ast;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, GenericArg, Mutability, QPath, TyKind, UnOp};
use rustc_lint::{LateContext, LateLintPass};
use crate::consts::{constant_context, Constant};
use crate::utils::{match_qpath, paths, span_lint};
use if_chain::if_chain;
-use rustc_ast::ast::LitKind;
+use rustc_ast::LitKind;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use crate::utils::{
- is_type_diagnostic_item, match_def_path, match_qpath, paths, snippet, snippet_with_macro_callsite,
- span_lint_and_sugg,
+ is_type_diagnostic_item, match_def_path, match_qpath, paths, snippet,
+ snippet_with_macro_callsite, span_lint_and_sugg,
};
use if_chain::if_chain;
use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind, MatchSource};
+use rustc_hir::{Expr, ExprKind, QPath, LangItem, MatchSource};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, Ty};
if let ExprKind::Match(ref match_arg, _, MatchSource::TryDesugar) = expr.kind;
if let ExprKind::Call(ref match_fun, ref try_args) = match_arg.kind;
if let ExprKind::Path(ref match_fun_path) = match_fun.kind;
- if match_qpath(match_fun_path, &paths::TRY_INTO_RESULT);
+ if matches!(match_fun_path, QPath::LangItem(LangItem::TryIntoResult, _));
if let Some(ref try_arg) = try_args.get(0);
if let ExprKind::Call(ref err_fun, ref err_args) = try_arg.kind;
if let Some(ref err_arg) = err_args.get(0);
use std::collections::BTreeMap;
use if_chain::if_chain;
-use rustc_ast::ast::{FloatTy, IntTy, LitFloatType, LitIntType, LitKind, UintTy};
+use rustc_ast::{FloatTy, IntTy, LitFloatType, LitIntType, LitKind, UintTy};
use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, FnKind, NestedVisitorMap, Visitor};
}
}
},
+ QPath::LangItem(..) => {},
}
},
TyKind::Rptr(ref lt, ref mut_ty) => self.check_ty_rptr(cx, hir_ty, is_local, lt, mut_ty),
use crate::utils::ast_utils::{eq_field_pat, eq_id, eq_pat, eq_path};
use crate::utils::{over, span_lint_and_then};
-use rustc_ast::ast::{self, Pat, PatKind, PatKind::*, DUMMY_NODE_ID};
+use rustc_ast::{self as ast, Pat, PatKind, PatKind::*, DUMMY_NODE_ID};
use rustc_ast::mut_visit::*;
use rustc_ast::ptr::P;
use rustc_ast_pretty::pprust;
-use crate::utils::{is_try, match_qpath, match_trait_method, paths, span_lint};
+use crate::utils::{is_try, match_trait_method, paths, span_lint};
use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
match expr.kind {
hir::ExprKind::Match(ref res, _, _) if is_try(expr).is_some() => {
if let hir::ExprKind::Call(ref func, ref args) = res.kind {
- if let hir::ExprKind::Path(ref path) = func.kind {
- if match_qpath(path, &paths::TRY_INTO_RESULT) && args.len() == 1 {
- check_method_call(cx, &args[0], expr);
- }
+ if matches!(
+ func.kind,
+ hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::TryIntoResult, _))
+ ) {
+ check_method_call(cx, &args[0], expr);
}
} else {
check_method_call(cx, res, expr);
#![allow(clippy::similar_names, clippy::wildcard_imports, clippy::enum_glob_use)]
use crate::utils::{both, over};
-use rustc_ast::ast::{self, *};
+use rustc_ast::{self as ast, *};
use rustc_ast::ptr::P;
use rustc_span::symbol::Ident;
use std::mem;
}
fn print_qpath(&mut self, path: &QPath<'_>) {
- print!(" if match_qpath({}, &[", self.current);
- print_path(path, &mut true);
- println!("]);");
+ match *path {
+ QPath::LangItem(lang_item, _) => {
+ println!(
+ " if matches!({}, QPath::LangItem(LangItem::{:?}, _));",
+ self.current, lang_item,
+ );
+ },
+ _ => {
+ print!(" if match_qpath({}, &[", self.current);
+ print_path(path, &mut true);
+ println!("]);");
+ },
+ }
}
}
},
ref other => print!("/* unimplemented: {:?}*/", other),
},
+ QPath::LangItem(..) => panic!("print_path: called for lang item qpath"),
}
}
#![deny(clippy::missing_docs_in_private_items)]
-use crate::utils::{is_expn_of, match_def_path, match_qpath, paths};
+use crate::utils::{is_expn_of, match_def_path, paths};
use if_chain::if_chain;
use rustc_ast::ast;
use rustc_hir as hir;
use rustc_lint::LateContext;
-use rustc_middle::ty;
/// Converts a hir binary operator to the corresponding `ast` type.
#[must_use]
}
/// Higher a `hir` range to something similar to `ast::ExprKind::Range`.
-pub fn range<'a, 'tcx>(cx: &LateContext<'tcx>, expr: &'a hir::Expr<'_>) -> Option<Range<'a>> {
+pub fn range<'a>(expr: &'a hir::Expr<'_>) -> Option<Range<'a>> {
/// Finds the field named `name` in the field. Always return `Some` for
/// convenience.
fn get_field<'c>(name: &str, fields: &'c [hir::Field<'_>]) -> Option<&'c hir::Expr<'c>> {
Some(expr)
}
- let def_path = match cx.typeck_results().expr_ty(expr).kind {
- ty::Adt(def, _) => cx.tcx.def_path(def.did),
- _ => return None,
- };
-
- // sanity checks for std::ops::RangeXXXX
- if def_path.data.len() != 3 {
- return None;
- }
- if def_path.data.get(0)?.data.as_symbol() != sym!(ops) {
- return None;
- }
- if def_path.data.get(1)?.data.as_symbol() != sym!(range) {
- return None;
- }
- let type_name = def_path.data.get(2)?.data.as_symbol();
- let range_types = [
- "RangeFrom",
- "RangeFull",
- "RangeInclusive",
- "Range",
- "RangeTo",
- "RangeToInclusive",
- ];
- if !range_types.contains(&&*type_name.as_str()) {
- return None;
- }
-
- // The range syntax is expanded to literal paths starting with `core` or `std`
- // depending on
- // `#[no_std]`. Testing both instead of resolving the paths.
-
match expr.kind {
- hir::ExprKind::Path(ref path) => {
- if match_qpath(path, &paths::RANGE_FULL_STD) || match_qpath(path, &paths::RANGE_FULL) {
- Some(Range {
+ hir::ExprKind::Call(ref path, ref args) if matches!(
+ path.kind,
+ hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, _))
+ ) => Some(Range {
+ start: Some(&args[0]),
+ end: Some(&args[1]),
+ limits: ast::RangeLimits::Closed,
+ }),
+ hir::ExprKind::Struct(ref path, ref fields, None) => {
+ match path {
+ hir::QPath::LangItem(hir::LangItem::RangeFull, _) => Some(Range {
start: None,
end: None,
limits: ast::RangeLimits::HalfOpen,
- })
- } else {
- None
- }
- },
- hir::ExprKind::Call(ref path, ref args) => {
- if let hir::ExprKind::Path(ref path) = path.kind {
- if match_qpath(path, &paths::RANGE_INCLUSIVE_STD_NEW) || match_qpath(path, &paths::RANGE_INCLUSIVE_NEW)
- {
- Some(Range {
- start: Some(&args[0]),
- end: Some(&args[1]),
- limits: ast::RangeLimits::Closed,
- })
- } else {
- None
- }
- } else {
- None
- }
- },
- hir::ExprKind::Struct(ref path, ref fields, None) => {
- if match_qpath(path, &paths::RANGE_FROM_STD) || match_qpath(path, &paths::RANGE_FROM) {
- Some(Range {
+ }),
+ hir::QPath::LangItem(hir::LangItem::RangeFrom, _) => Some(Range {
start: Some(get_field("start", fields)?),
end: None,
limits: ast::RangeLimits::HalfOpen,
- })
- } else if match_qpath(path, &paths::RANGE_STD) || match_qpath(path, &paths::RANGE) {
- Some(Range {
+ }),
+ hir::QPath::LangItem(hir::LangItem::Range, _) => Some(Range {
start: Some(get_field("start", fields)?),
end: Some(get_field("end", fields)?),
limits: ast::RangeLimits::HalfOpen,
- })
- } else if match_qpath(path, &paths::RANGE_TO_INCLUSIVE_STD) || match_qpath(path, &paths::RANGE_TO_INCLUSIVE)
- {
- Some(Range {
+ }),
+ hir::QPath::LangItem(hir::LangItem::RangeToInclusive, _) => Some(Range {
start: None,
end: Some(get_field("end", fields)?),
limits: ast::RangeLimits::Closed,
- })
- } else if match_qpath(path, &paths::RANGE_TO_STD) || match_qpath(path, &paths::RANGE_TO) {
- Some(Range {
+ }),
+ hir::QPath::LangItem(hir::LangItem::RangeTo, _) => Some(Range {
start: None,
end: Some(get_field("end", fields)?),
limits: ast::RangeLimits::HalfOpen,
- })
- } else {
- None
+ }),
+ _ => None,
}
},
_ => None,
use rustc_ast::ast::InlineAsmTemplatePiece;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_hir::{
- BinOpKind, Block, BlockCheckMode, BodyId, BorrowKind, CaptureBy, Expr, ExprKind, Field, FnRetTy, GenericArg,
- GenericArgs, Guard, InlineAsmOperand, Lifetime, LifetimeName, ParamName, Pat, PatKind, Path, PathSegment, QPath,
- Stmt, StmtKind, Ty, TyKind, TypeBinding,
+ BinOpKind, Block, BlockCheckMode, BodyId, BorrowKind, CaptureBy, Expr, ExprKind, Field, FieldPat,
+ FnRetTy, GenericArg, GenericArgs, Guard, InlineAsmOperand, Lifetime, LifetimeName, ParamName,
+ Pat, PatKind, Path, PathSegment, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding,
};
use rustc_lint::LateContext;
use rustc_middle::ich::StableHashingContextProvider;
left.name == right.name
}
+ pub fn eq_fieldpat(&mut self, left: &FieldPat<'_>, right: &FieldPat<'_>) -> bool {
+ match (&left, &right) {
+ (FieldPat { ident: li, pat: lp, .. }, FieldPat { ident: ri, pat: rp, .. }) =>
+ li.name.as_str() == ri.name.as_str() && self.eq_pat(lp, rp),
+ }
+ }
+
/// Checks whether two patterns are the same.
pub fn eq_pat(&mut self, left: &Pat<'_>, right: &Pat<'_>) -> bool {
match (&left.kind, &right.kind) {
(&PatKind::Box(ref l), &PatKind::Box(ref r)) => self.eq_pat(l, r),
+ (&PatKind::Struct(ref lp, ref la, ..), &PatKind::Struct(ref rp, ref ra, ..)) => {
+ self.eq_qpath(lp, rp) && over(la, ra, |l, r| self.eq_fieldpat(l, r))
+ },
(&PatKind::TupleStruct(ref lp, ref la, ls), &PatKind::TupleStruct(ref rp, ref ra, rs)) => {
self.eq_qpath(lp, rp) && over(la, ra, |l, r| self.eq_pat(l, r)) && ls == rs
},
(&QPath::TypeRelative(ref lty, ref lseg), &QPath::TypeRelative(ref rty, ref rseg)) => {
self.eq_ty(lty, rty) && self.eq_path_segment(lseg, rseg)
},
+ (&QPath::LangItem(llang_item, _), &QPath::LangItem(rlang_item, _)) =>
+ llang_item == rlang_item,
_ => false,
}
}
QPath::TypeRelative(_, ref path) => {
self.hash_name(path.ident.name);
},
+ QPath::LangItem(lang_item, ..) => {
+ lang_item.hash_stable(&mut self.cx.tcx.get_stable_hashing_context(), &mut self.s);
+ }
}
// self.maybe_typeck_results.unwrap().qpath_res(p, id).hash(&mut self.s);
}
self.hash_ty(ty);
segment.ident.name.hash(&mut self.s);
},
+ QPath::LangItem(lang_item, ..) => {
+ lang_item.hash(&mut self.s);
+ }
},
TyKind::OpaqueDef(_, arg_list) => {
self.hash_generic_args(arg_list);
println!("{}Relative Path, {:?}", ind, ty);
println!("{}seg: {:?}", ind, seg);
},
+ hir::ExprKind::Path(hir::QPath::LangItem(lang_item, ..)) => {
+ println!("{}Lang Item Path, {:?}", ind, lang_item.name());
+ },
hir::ExprKind::AddrOf(kind, ref muta, ref e) => {
println!("{}AddrOf", ind);
println!("kind: {:?}", kind);
println!("{}Relative Path, {:?}", ind, ty);
println!("{}seg: {:?}", ind, seg);
},
+ hir::PatKind::Path(hir::QPath::LangItem(lang_item, ..)) => {
+ println!("{}Lang Item Path, {:?}", ind, lang_item.name());
+ },
hir::PatKind::Tuple(pats, opt_dots_position) => {
println!("{}Tuple", ind);
if let Some(dot_position) = opt_dots_position {
}
}
+/// Checks if the type is equal to a lang item
+pub fn is_type_lang_item(cx: &LateContext<'_>, ty: Ty<'_>, lang_item: hir::LangItem) -> bool {
+ match ty.kind {
+ ty::Adt(adt, _) => cx.tcx.lang_items().require(lang_item).unwrap() == adt.did,
+ _ => false,
+ }
+}
+
/// Checks if the method call given in `expr` belongs to the given trait.
pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str]) -> bool {
let def_id = cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap();
match *path {
QPath::Resolved(_, ref path) => path.segments.last().expect("A path must have at least one segment"),
QPath::TypeRelative(_, ref seg) => seg,
+ QPath::LangItem(..) => panic!("last_path_segment: lang item has no path segments"),
}
}
match *path {
QPath::Resolved(_, ref path) => path.segments.get(0),
QPath::TypeRelative(_, ref seg) => Some(seg),
+ QPath::LangItem(..) => None,
}
}
},
_ => false,
},
+ QPath::LangItem(..) => false,
}
}
pub fn qpath_res(cx: &LateContext<'_>, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res {
match qpath {
hir::QPath::Resolved(_, path) => path.res,
- hir::QPath::TypeRelative(..) => {
+ hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => {
if cx.tcx.has_typeck_results(id.owner.to_def_id()) {
cx.tcx.typeck(id.owner.to_def_id().expect_local()).qpath_res(qpath, id)
} else {
pub const PTR_EQ: [&str; 3] = ["core", "ptr", "eq"];
pub const PTR_NULL: [&str; 2] = ["ptr", "null"];
pub const PTR_NULL_MUT: [&str; 2] = ["ptr", "null_mut"];
-pub const RANGE: [&str; 3] = ["core", "ops", "Range"];
pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["core", "ops", "RangeBounds"];
-pub const RANGE_FROM: [&str; 3] = ["core", "ops", "RangeFrom"];
-pub const RANGE_FROM_STD: [&str; 3] = ["std", "ops", "RangeFrom"];
-pub const RANGE_FULL: [&str; 4] = ["core", "ops", "range", "RangeFull"];
-pub const RANGE_FULL_STD: [&str; 3] = ["std", "ops", "RangeFull"];
-pub const RANGE_INCLUSIVE_NEW: [&str; 4] = ["core", "ops", "RangeInclusive", "new"];
-pub const RANGE_INCLUSIVE_STD_NEW: [&str; 4] = ["std", "ops", "RangeInclusive", "new"];
-pub const RANGE_STD: [&str; 3] = ["std", "ops", "Range"];
-pub const RANGE_TO: [&str; 3] = ["core", "ops", "RangeTo"];
-pub const RANGE_TO_INCLUSIVE: [&str; 3] = ["core", "ops", "RangeToInclusive"];
-pub const RANGE_TO_INCLUSIVE_STD: [&str; 3] = ["std", "ops", "RangeToInclusive"];
-pub const RANGE_TO_STD: [&str; 3] = ["std", "ops", "RangeTo"];
pub const RC: [&str; 3] = ["alloc", "rc", "Rc"];
pub const RC_PTR_EQ: [&str; 4] = ["alloc", "rc", "Rc", "ptr_eq"];
pub const RECEIVER: [&str; 4] = ["std", "sync", "mpsc", "Receiver"];
pub const TO_STRING_METHOD: [&str; 4] = ["alloc", "string", "ToString", "to_string"];
pub const TRANSMUTE: [&str; 4] = ["core", "intrinsics", "", "transmute"];
pub const TRY_FROM: [&str; 4] = ["core", "convert", "TryFrom", "try_from"];
-pub const TRY_INTO_RESULT: [&str; 4] = ["std", "ops", "Try", "into_result"];
pub const TRY_INTO_TRAIT: [&str; 3] = ["core", "convert", "TryInto"];
pub const VEC: [&str; 3] = ["alloc", "vec", "Vec"];
pub const VEC_AS_MUT_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_mut_slice"];
pub fn hir_opt(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Self> {
snippet_opt(cx, expr.span).map(|snippet| {
let snippet = Cow::Owned(snippet);
- Self::hir_from_snippet(cx, expr, snippet)
+ Self::hir_from_snippet(expr, snippet)
})
}
pub fn hir_with_macro_callsite(cx: &LateContext<'_>, expr: &hir::Expr<'_>, default: &'a str) -> Self {
let snippet = snippet_with_macro_callsite(cx, expr.span, default);
- Self::hir_from_snippet(cx, expr, snippet)
+ Self::hir_from_snippet(expr, snippet)
}
/// Generate a suggestion for an expression with the given snippet. This is used by the `hir_*`
/// function variants of `Sugg`, since these use different snippet functions.
- fn hir_from_snippet(cx: &LateContext<'_>, expr: &hir::Expr<'_>, snippet: Cow<'a, str>) -> Self {
- if let Some(range) = higher::range(cx, expr) {
+ fn hir_from_snippet(expr: &hir::Expr<'_>, snippet: Cow<'a, str>) -> Self {
+ if let Some(range) = higher::range(expr) {
let op = match range.limits {
ast::RangeLimits::HalfOpen => AssocOp::DotDot,
ast::RangeLimits::Closed => AssocOp::DotDotEq,
use rustc_span::source_map::Spanned;
use crate::utils::{match_def_path, paths};
-use rustc_ast::ast::LitKind;
+use rustc_ast::LitKind;
use rustc_hir as hir;
declare_clippy_lint! {
if let ExprKind::Match(ref expr1, ref arms, MatchSource::ForLoopDesugar) = expr.kind;
if let ExprKind::Call(ref func, ref args) = expr1.kind;
if let ExprKind::Path(ref path) = func.kind;
- if match_qpath(path, &["{{root}}", "std", "iter", "IntoIterator", "into_iter"]);
+ if matches!(path, QPath::LangItem(LangItem::IntoIterIntoIter, _));
if args.len() == 1;
if let ExprKind::Struct(ref path1, ref fields, None) = args[0].kind;
- if match_qpath(path1, &["{{root}}", "std", "ops", "Range"]);
+ if matches!(path1, QPath::LangItem(LangItem::Range, _));
if fields.len() == 2;
// unimplemented: field checks
if arms.len() == 1;
if let ExprKind::Match(ref expr2, ref arms1, MatchSource::ForLoopDesugar) = e.kind;
if let ExprKind::Call(ref func1, ref args1) = expr2.kind;
if let ExprKind::Path(ref path2) = func1.kind;
- if match_qpath(path2, &["{{root}}", "std", "iter", "Iterator", "next"]);
+ if matches!(path2, QPath::LangItem(LangItem::IteratorNext, _));
if args1.len() == 1;
if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, ref inner) = args1[0].kind;
if let ExprKind::Path(ref path3) = inner.kind;
if match_qpath(path4, &["__next"]);
if let ExprKind::Path(ref path5) = value.kind;
if match_qpath(path5, &["val"]);
- if let PatKind::TupleStruct(ref path6, ref fields1, None) = arms1[0].pat.kind;
- if match_qpath(path6, &["{{root}}", "std", "option", "Option", "Some"]);
+ if let PatKind::Struct(ref path6, ref fields1, false) = arms1[0].pat.kind;
+ if matches!(path6, QPath::LangItem(LangItem::OptionSome, _));
if fields1.len() == 1;
// unimplemented: field checks
if let ExprKind::Break(ref destination, None) = arms1[1].body.kind;
- if let PatKind::Path(ref path7) = arms1[1].pat.kind;
- if match_qpath(path7, &["{{root}}", "std", "option", "Option", "None"]);
+ if let PatKind::Struct(ref path7, ref fields2, false) = arms1[1].pat.kind;
+ if matches!(path7, QPath::LangItem(LangItem::OptionNone, _));
+ if fields2.len() == 0;
+ // unimplemented: field checks
if let StmtKind::Local(ref local1) = body.stmts[2].kind;
if let Some(ref init) = local1.init;
if let ExprKind::Path(ref path8) = init.kind;
-Subproject commit 1bfb26d6cae6f535ac1034877635fc0cef87fe64
+Subproject commit 2d6d73fafe2f087354f7cea37297cd81316cae98
-Subproject commit 942aa2b5d729a63f8b81592ab7b2720b63a884e9
+Subproject commit 48ef96dd00b90d950a122ca180923aba77efaf74
-Subproject commit c9c518e5e9761bf35d466c47c57c3a1358b56b3c
+Subproject commit 0b2b9a5508186c16a2e782f47ce7e0e1c5fb8d33