Auto merge of #133841 - matthiaskrgr:rollup-2snj3hc, r=matthiaskrgr

Rollup of 6 pull requests

Successful merges:

 - #133651 (Update `NonZero` and `NonNull` to not field-project (per MCP#807))
 - #133764 (rustdoc: Rename `set_back_info` to `restore_module_data`.)
 - #133784 (Fix MutVisitor's default implementations to visit Stmt's and BinOp's spans)
 - #133798 (stop replacing bivariant args with `'static` when computing closure requirements)
 - #133804 (Improve code for FileName retrieval in rustdoc)
 - #133817 (Use `eprintln` instead of `println` in bootstrap/compiletest/tidy)

Failed merges:

 - #133810 (remove unnecessary `eval_verify_bound`)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-12-04 07:24:25 +00:00
commit 733616f723
62 changed files with 917 additions and 834 deletions

View File

@ -1625,9 +1625,10 @@ pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, token
visit_thin_exprs(vis, call_args); visit_thin_exprs(vis, call_args);
vis.visit_span(span); vis.visit_span(span);
} }
ExprKind::Binary(_binop, lhs, rhs) => { ExprKind::Binary(binop, lhs, rhs) => {
vis.visit_expr(lhs); vis.visit_expr(lhs);
vis.visit_expr(rhs); vis.visit_expr(rhs);
vis.visit_span(&mut binop.span);
} }
ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs), ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs),
ExprKind::Cast(expr, ty) => { ExprKind::Cast(expr, ty) => {
@ -1785,20 +1786,21 @@ pub fn noop_filter_map_expr<T: MutVisitor>(vis: &mut T, mut e: P<Expr>) -> Optio
pub fn walk_flat_map_stmt<T: MutVisitor>( pub fn walk_flat_map_stmt<T: MutVisitor>(
vis: &mut T, vis: &mut T,
Stmt { kind, mut span, mut id }: Stmt, Stmt { kind, span, mut id }: Stmt,
) -> SmallVec<[Stmt; 1]> { ) -> SmallVec<[Stmt; 1]> {
vis.visit_id(&mut id); vis.visit_id(&mut id);
let stmts: SmallVec<_> = walk_flat_map_stmt_kind(vis, kind) let mut stmts: SmallVec<[Stmt; 1]> = walk_flat_map_stmt_kind(vis, kind)
.into_iter() .into_iter()
.map(|kind| Stmt { id, kind, span }) .map(|kind| Stmt { id, kind, span })
.collect(); .collect();
if stmts.len() > 1 { match stmts.len() {
panic!( 0 => {}
1 => vis.visit_span(&mut stmts[0].span),
2.. => panic!(
"cloning statement `NodeId`s is prohibited by default, \ "cloning statement `NodeId`s is prohibited by default, \
the visitor should implement custom statement visiting" the visitor should implement custom statement visiting"
); ),
} }
vis.visit_span(&mut span);
stmts stmts
} }

View File

@ -973,25 +973,20 @@ impl<'tcx> RegionInferenceContext<'tcx> {
propagated_outlives_requirements: &mut Vec<ClosureOutlivesRequirement<'tcx>>, propagated_outlives_requirements: &mut Vec<ClosureOutlivesRequirement<'tcx>>,
) -> bool { ) -> bool {
let tcx = infcx.tcx; let tcx = infcx.tcx;
let TypeTest { generic_kind, lower_bound, span: blame_span, ref verify_bound } = *type_test;
let TypeTest { generic_kind, lower_bound, span: _, verify_bound: _ } = type_test;
let generic_ty = generic_kind.to_ty(tcx); let generic_ty = generic_kind.to_ty(tcx);
let Some(subject) = self.try_promote_type_test_subject(infcx, generic_ty) else { let Some(subject) = self.try_promote_type_test_subject(infcx, generic_ty) else {
return false; return false;
}; };
debug!("subject = {:?}", subject); let r_scc = self.constraint_sccs.scc(lower_bound);
let r_scc = self.constraint_sccs.scc(*lower_bound);
debug!( debug!(
"lower_bound = {:?} r_scc={:?} universe={:?}", "lower_bound = {:?} r_scc={:?} universe={:?}",
lower_bound, lower_bound,
r_scc, r_scc,
self.constraint_sccs.annotation(r_scc).min_universe() self.constraint_sccs.annotation(r_scc).min_universe()
); );
// If the type test requires that `T: 'a` where `'a` is a // If the type test requires that `T: 'a` where `'a` is a
// placeholder from another universe, that effectively requires // placeholder from another universe, that effectively requires
// `T: 'static`, so we have to propagate that requirement. // `T: 'static`, so we have to propagate that requirement.
@ -1004,7 +999,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
propagated_outlives_requirements.push(ClosureOutlivesRequirement { propagated_outlives_requirements.push(ClosureOutlivesRequirement {
subject, subject,
outlived_free_region: static_r, outlived_free_region: static_r,
blame_span: type_test.span, blame_span,
category: ConstraintCategory::Boring, category: ConstraintCategory::Boring,
}); });
@ -1031,12 +1026,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// where `ur` is a local bound -- we are sometimes in a // where `ur` is a local bound -- we are sometimes in a
// position to prove things that our caller cannot. See // position to prove things that our caller cannot. See
// #53570 for an example. // #53570 for an example.
if self.eval_verify_bound(infcx, generic_ty, ur, &type_test.verify_bound) { if self.eval_verify_bound(infcx, generic_ty, ur, &verify_bound) {
continue; continue;
} }
let non_local_ub = self.universal_region_relations.non_local_upper_bounds(ur); let non_local_ub = self.universal_region_relations.non_local_upper_bounds(ur);
debug!("try_promote_type_test: non_local_ub={:?}", non_local_ub); debug!(?non_local_ub);
// This is slightly too conservative. To show T: '1, given `'2: '1` // This is slightly too conservative. To show T: '1, given `'2: '1`
// and `'3: '1` we only need to prove that T: '2 *or* T: '3, but to // and `'3: '1` we only need to prove that T: '2 *or* T: '3, but to
@ -1049,10 +1044,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let requirement = ClosureOutlivesRequirement { let requirement = ClosureOutlivesRequirement {
subject, subject,
outlived_free_region: upper_bound, outlived_free_region: upper_bound,
blame_span: type_test.span, blame_span,
category: ConstraintCategory::Boring, category: ConstraintCategory::Boring,
}; };
debug!("try_promote_type_test: pushing {:#?}", requirement); debug!(?requirement, "adding closure requirement");
propagated_outlives_requirements.push(requirement); propagated_outlives_requirements.push(requirement);
} }
} }
@ -1063,44 +1058,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// variables in the type `T` with an equal universal region from the /// variables in the type `T` with an equal universal region from the
/// closure signature. /// closure signature.
/// This is not always possible, so this is a fallible process. /// This is not always possible, so this is a fallible process.
#[instrument(level = "debug", skip(self, infcx))] #[instrument(level = "debug", skip(self, infcx), ret)]
fn try_promote_type_test_subject( fn try_promote_type_test_subject(
&self, &self,
infcx: &InferCtxt<'tcx>, infcx: &InferCtxt<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> Option<ClosureOutlivesSubject<'tcx>> { ) -> Option<ClosureOutlivesSubject<'tcx>> {
let tcx = infcx.tcx; let tcx = infcx.tcx;
// Opaque types' args may include useless lifetimes.
// We will replace them with ReStatic.
struct OpaqueFolder<'tcx> {
tcx: TyCtxt<'tcx>,
}
impl<'tcx> ty::TypeFolder<TyCtxt<'tcx>> for OpaqueFolder<'tcx> {
fn cx(&self) -> TyCtxt<'tcx> {
self.tcx
}
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
use ty::TypeSuperFoldable as _;
let tcx = self.tcx;
let &ty::Alias(ty::Opaque, ty::AliasTy { args, def_id, .. }) = t.kind() else {
return t.super_fold_with(self);
};
let args = std::iter::zip(args, tcx.variances_of(def_id)).map(|(arg, v)| {
match (arg.unpack(), v) {
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => {
tcx.lifetimes.re_static.into()
}
_ => arg.fold_with(self),
}
});
Ty::new_opaque(tcx, def_id, tcx.mk_args_from_iter(args))
}
}
let ty = ty.fold_with(&mut OpaqueFolder { tcx });
let mut failed = false; let mut failed = false;
let ty = fold_regions(tcx, ty, |r, _depth| { let ty = fold_regions(tcx, ty, |r, _depth| {
let r_vid = self.to_region_vid(r); let r_vid = self.to_region_vid(r);
let r_scc = self.constraint_sccs.scc(r_vid); let r_scc = self.constraint_sccs.scc(r_vid);

View File

@ -37,6 +37,8 @@ pub unsafe trait ZeroablePrimitive: Sized + Copy + private::Sealed {
macro_rules! impl_zeroable_primitive { macro_rules! impl_zeroable_primitive {
($($NonZeroInner:ident ( $primitive:ty )),+ $(,)?) => { ($($NonZeroInner:ident ( $primitive:ty )),+ $(,)?) => {
mod private { mod private {
use super::*;
#[unstable( #[unstable(
feature = "nonzero_internals", feature = "nonzero_internals",
reason = "implementation detail which may disappear or be replaced at any time", reason = "implementation detail which may disappear or be replaced at any time",
@ -45,7 +47,11 @@ macro_rules! impl_zeroable_primitive {
pub trait Sealed {} pub trait Sealed {}
$( $(
#[derive(Debug, Clone, Copy, PartialEq)] // This inner type is never shown directly, so intentionally does not have Debug
#[expect(missing_debug_implementations)]
// Since this struct is non-generic and derives Copy,
// the derived Clone is `*self` and thus doesn't field-project.
#[derive(Clone, Copy)]
#[repr(transparent)] #[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(1)] #[rustc_layout_scalar_valid_range_start(1)]
#[rustc_nonnull_optimization_guaranteed] #[rustc_nonnull_optimization_guaranteed]
@ -55,6 +61,16 @@ macro_rules! impl_zeroable_primitive {
issue = "none" issue = "none"
)] )]
pub struct $NonZeroInner($primitive); pub struct $NonZeroInner($primitive);
// This is required to allow matching a constant. We don't get it from a derive
// because the derived `PartialEq` would do a field projection, which is banned
// by <https://github.com/rust-lang/compiler-team/issues/807>.
#[unstable(
feature = "nonzero_internals",
reason = "implementation detail which may disappear or be replaced at any time",
issue = "none"
)]
impl StructuralPartialEq for $NonZeroInner {}
)+ )+
} }
@ -172,7 +188,7 @@ where
{ {
#[inline] #[inline]
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self(self.0) *self
} }
} }
@ -440,15 +456,21 @@ where
#[rustc_const_stable(feature = "const_nonzero_get", since = "1.34.0")] #[rustc_const_stable(feature = "const_nonzero_get", since = "1.34.0")]
#[inline] #[inline]
pub const fn get(self) -> T { pub const fn get(self) -> T {
// FIXME: This can be changed to simply `self.0` once LLVM supports `!range` metadata
// for function arguments: https://github.com/llvm/llvm-project/issues/76628
//
// Rustc can set range metadata only if it loads `self` from // Rustc can set range metadata only if it loads `self` from
// memory somewhere. If the value of `self` was from by-value argument // memory somewhere. If the value of `self` was from by-value argument
// of some not-inlined function, LLVM don't have range metadata // of some not-inlined function, LLVM don't have range metadata
// to understand that the value cannot be zero. // to understand that the value cannot be zero.
// //
// For now, using the transmute `assume`s the range at runtime. // Using the transmute `assume`s the range at runtime.
//
// Even once LLVM supports `!range` metadata for function arguments
// (see <https://github.com/llvm/llvm-project/issues/76628>), this can't
// be `.0` because MCP#807 bans field-projecting into `scalar_valid_range`
// types, and it arguably wouldn't want to be anyway because if this is
// MIR-inlined, there's no opportunity to put that argument metadata anywhere.
//
// The good answer here will eventually be pattern types, which will hopefully
// allow it to go back to `.0`, maybe with a cast of some sort.
// //
// SAFETY: `ZeroablePrimitive` guarantees that the size and bit validity // SAFETY: `ZeroablePrimitive` guarantees that the size and bit validity
// of `.0` is such that this transmute is sound. // of `.0` is such that this transmute is sound.

View File

@ -7,7 +7,7 @@ use crate::pin::PinCoerceUnsized;
use crate::ptr::Unique; use crate::ptr::Unique;
use crate::slice::{self, SliceIndex}; use crate::slice::{self, SliceIndex};
use crate::ub_checks::assert_unsafe_precondition; use crate::ub_checks::assert_unsafe_precondition;
use crate::{fmt, hash, intrinsics, ptr}; use crate::{fmt, hash, intrinsics, mem, ptr};
/// `*mut T` but non-zero and [covariant]. /// `*mut T` but non-zero and [covariant].
/// ///
@ -69,6 +69,8 @@ use crate::{fmt, hash, intrinsics, ptr};
#[rustc_nonnull_optimization_guaranteed] #[rustc_nonnull_optimization_guaranteed]
#[rustc_diagnostic_item = "NonNull"] #[rustc_diagnostic_item = "NonNull"]
pub struct NonNull<T: ?Sized> { pub struct NonNull<T: ?Sized> {
// Remember to use `.as_ptr()` instead of `.pointer`, as field projecting to
// this is banned by <https://github.com/rust-lang/compiler-team/issues/807>.
pointer: *const T, pointer: *const T,
} }
@ -282,7 +284,7 @@ impl<T: ?Sized> NonNull<T> {
pub fn addr(self) -> NonZero<usize> { pub fn addr(self) -> NonZero<usize> {
// SAFETY: The pointer is guaranteed by the type to be non-null, // SAFETY: The pointer is guaranteed by the type to be non-null,
// meaning that the address will be non-zero. // meaning that the address will be non-zero.
unsafe { NonZero::new_unchecked(self.pointer.addr()) } unsafe { NonZero::new_unchecked(self.as_ptr().addr()) }
} }
/// Creates a new pointer with the given address and the [provenance][crate::ptr#provenance] of /// Creates a new pointer with the given address and the [provenance][crate::ptr#provenance] of
@ -296,7 +298,7 @@ impl<T: ?Sized> NonNull<T> {
#[stable(feature = "strict_provenance", since = "1.84.0")] #[stable(feature = "strict_provenance", since = "1.84.0")]
pub fn with_addr(self, addr: NonZero<usize>) -> Self { pub fn with_addr(self, addr: NonZero<usize>) -> Self {
// SAFETY: The result of `ptr::from::with_addr` is non-null because `addr` is guaranteed to be non-zero. // SAFETY: The result of `ptr::from::with_addr` is non-null because `addr` is guaranteed to be non-zero.
unsafe { NonNull::new_unchecked(self.pointer.with_addr(addr.get()) as *mut _) } unsafe { NonNull::new_unchecked(self.as_ptr().with_addr(addr.get()) as *mut _) }
} }
/// Creates a new pointer by mapping `self`'s address to a new one, preserving the /// Creates a new pointer by mapping `self`'s address to a new one, preserving the
@ -335,7 +337,12 @@ impl<T: ?Sized> NonNull<T> {
#[must_use] #[must_use]
#[inline(always)] #[inline(always)]
pub const fn as_ptr(self) -> *mut T { pub const fn as_ptr(self) -> *mut T {
self.pointer as *mut T // This is a transmute for the same reasons as `NonZero::get`.
// SAFETY: `NonNull` is `transparent` over a `*const T`, and `*const T`
// and `*mut T` have the same layout, so transitively we can transmute
// our `NonNull` to a `*mut T` directly.
unsafe { mem::transmute::<Self, *mut T>(self) }
} }
/// Returns a shared reference to the value. If the value may be uninitialized, [`as_uninit_ref`] /// Returns a shared reference to the value. If the value may be uninitialized, [`as_uninit_ref`]
@ -484,7 +491,7 @@ impl<T: ?Sized> NonNull<T> {
// Additionally safety contract of `offset` guarantees that the resulting pointer is // Additionally safety contract of `offset` guarantees that the resulting pointer is
// pointing to an allocation, there can't be an allocation at null, thus it's safe to // pointing to an allocation, there can't be an allocation at null, thus it's safe to
// construct `NonNull`. // construct `NonNull`.
unsafe { NonNull { pointer: intrinsics::offset(self.pointer, count) } } unsafe { NonNull { pointer: intrinsics::offset(self.as_ptr(), count) } }
} }
/// Calculates the offset from a pointer in bytes. /// Calculates the offset from a pointer in bytes.
@ -508,7 +515,7 @@ impl<T: ?Sized> NonNull<T> {
// Additionally safety contract of `offset` guarantees that the resulting pointer is // Additionally safety contract of `offset` guarantees that the resulting pointer is
// pointing to an allocation, there can't be an allocation at null, thus it's safe to // pointing to an allocation, there can't be an allocation at null, thus it's safe to
// construct `NonNull`. // construct `NonNull`.
unsafe { NonNull { pointer: self.pointer.byte_offset(count) } } unsafe { NonNull { pointer: self.as_ptr().byte_offset(count) } }
} }
/// Adds an offset to a pointer (convenience for `.offset(count as isize)`). /// Adds an offset to a pointer (convenience for `.offset(count as isize)`).
@ -560,7 +567,7 @@ impl<T: ?Sized> NonNull<T> {
// Additionally safety contract of `offset` guarantees that the resulting pointer is // Additionally safety contract of `offset` guarantees that the resulting pointer is
// pointing to an allocation, there can't be an allocation at null, thus it's safe to // pointing to an allocation, there can't be an allocation at null, thus it's safe to
// construct `NonNull`. // construct `NonNull`.
unsafe { NonNull { pointer: intrinsics::offset(self.pointer, count) } } unsafe { NonNull { pointer: intrinsics::offset(self.as_ptr(), count) } }
} }
/// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`). /// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`).
@ -584,7 +591,7 @@ impl<T: ?Sized> NonNull<T> {
// Additionally safety contract of `add` guarantees that the resulting pointer is pointing // Additionally safety contract of `add` guarantees that the resulting pointer is pointing
// to an allocation, there can't be an allocation at null, thus it's safe to construct // to an allocation, there can't be an allocation at null, thus it's safe to construct
// `NonNull`. // `NonNull`.
unsafe { NonNull { pointer: self.pointer.byte_add(count) } } unsafe { NonNull { pointer: self.as_ptr().byte_add(count) } }
} }
/// Subtracts an offset from a pointer (convenience for /// Subtracts an offset from a pointer (convenience for
@ -666,7 +673,7 @@ impl<T: ?Sized> NonNull<T> {
// Additionally safety contract of `sub` guarantees that the resulting pointer is pointing // Additionally safety contract of `sub` guarantees that the resulting pointer is pointing
// to an allocation, there can't be an allocation at null, thus it's safe to construct // to an allocation, there can't be an allocation at null, thus it's safe to construct
// `NonNull`. // `NonNull`.
unsafe { NonNull { pointer: self.pointer.byte_sub(count) } } unsafe { NonNull { pointer: self.as_ptr().byte_sub(count) } }
} }
/// Calculates the distance between two pointers within the same allocation. The returned value is in /// Calculates the distance between two pointers within the same allocation. The returned value is in
@ -763,7 +770,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized, T: Sized,
{ {
// SAFETY: the caller must uphold the safety contract for `offset_from`. // SAFETY: the caller must uphold the safety contract for `offset_from`.
unsafe { self.pointer.offset_from(origin.pointer) } unsafe { self.as_ptr().offset_from(origin.as_ptr()) }
} }
/// Calculates the distance between two pointers within the same allocation. The returned value is in /// Calculates the distance between two pointers within the same allocation. The returned value is in
@ -781,7 +788,7 @@ impl<T: ?Sized> NonNull<T> {
#[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")] #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")]
pub const unsafe fn byte_offset_from<U: ?Sized>(self, origin: NonNull<U>) -> isize { pub const unsafe fn byte_offset_from<U: ?Sized>(self, origin: NonNull<U>) -> isize {
// SAFETY: the caller must uphold the safety contract for `byte_offset_from`. // SAFETY: the caller must uphold the safety contract for `byte_offset_from`.
unsafe { self.pointer.byte_offset_from(origin.pointer) } unsafe { self.as_ptr().byte_offset_from(origin.as_ptr()) }
} }
// N.B. `wrapping_offset``, `wrapping_add`, etc are not implemented because they can wrap to null // N.B. `wrapping_offset``, `wrapping_add`, etc are not implemented because they can wrap to null
@ -856,7 +863,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized, T: Sized,
{ {
// SAFETY: the caller must uphold the safety contract for `sub_ptr`. // SAFETY: the caller must uphold the safety contract for `sub_ptr`.
unsafe { self.pointer.sub_ptr(subtracted.pointer) } unsafe { self.as_ptr().sub_ptr(subtracted.as_ptr()) }
} }
/// Calculates the distance between two pointers within the same allocation, *where it's known that /// Calculates the distance between two pointers within the same allocation, *where it's known that
@ -875,7 +882,7 @@ impl<T: ?Sized> NonNull<T> {
#[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: NonNull<U>) -> usize { pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: NonNull<U>) -> usize {
// SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`. // SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`.
unsafe { self.pointer.byte_sub_ptr(origin.pointer) } unsafe { self.as_ptr().byte_sub_ptr(origin.as_ptr()) }
} }
/// Reads the value from `self` without moving it. This leaves the /// Reads the value from `self` without moving it. This leaves the
@ -893,7 +900,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized, T: Sized,
{ {
// SAFETY: the caller must uphold the safety contract for `read`. // SAFETY: the caller must uphold the safety contract for `read`.
unsafe { ptr::read(self.pointer) } unsafe { ptr::read(self.as_ptr()) }
} }
/// Performs a volatile read of the value from `self` without moving it. This /// Performs a volatile read of the value from `self` without moving it. This
@ -914,7 +921,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized, T: Sized,
{ {
// SAFETY: the caller must uphold the safety contract for `read_volatile`. // SAFETY: the caller must uphold the safety contract for `read_volatile`.
unsafe { ptr::read_volatile(self.pointer) } unsafe { ptr::read_volatile(self.as_ptr()) }
} }
/// Reads the value from `self` without moving it. This leaves the /// Reads the value from `self` without moving it. This leaves the
@ -934,7 +941,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized, T: Sized,
{ {
// SAFETY: the caller must uphold the safety contract for `read_unaligned`. // SAFETY: the caller must uphold the safety contract for `read_unaligned`.
unsafe { ptr::read_unaligned(self.pointer) } unsafe { ptr::read_unaligned(self.as_ptr()) }
} }
/// Copies `count * size_of<T>` bytes from `self` to `dest`. The source /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
@ -954,7 +961,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized, T: Sized,
{ {
// SAFETY: the caller must uphold the safety contract for `copy`. // SAFETY: the caller must uphold the safety contract for `copy`.
unsafe { ptr::copy(self.pointer, dest.as_ptr(), count) } unsafe { ptr::copy(self.as_ptr(), dest.as_ptr(), count) }
} }
/// Copies `count * size_of<T>` bytes from `self` to `dest`. The source /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
@ -974,7 +981,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized, T: Sized,
{ {
// SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`. // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
unsafe { ptr::copy_nonoverlapping(self.pointer, dest.as_ptr(), count) } unsafe { ptr::copy_nonoverlapping(self.as_ptr(), dest.as_ptr(), count) }
} }
/// Copies `count * size_of<T>` bytes from `src` to `self`. The source /// Copies `count * size_of<T>` bytes from `src` to `self`. The source
@ -994,7 +1001,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized, T: Sized,
{ {
// SAFETY: the caller must uphold the safety contract for `copy`. // SAFETY: the caller must uphold the safety contract for `copy`.
unsafe { ptr::copy(src.pointer, self.as_ptr(), count) } unsafe { ptr::copy(src.as_ptr(), self.as_ptr(), count) }
} }
/// Copies `count * size_of<T>` bytes from `src` to `self`. The source /// Copies `count * size_of<T>` bytes from `src` to `self`. The source
@ -1014,7 +1021,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized, T: Sized,
{ {
// SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`. // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
unsafe { ptr::copy_nonoverlapping(src.pointer, self.as_ptr(), count) } unsafe { ptr::copy_nonoverlapping(src.as_ptr(), self.as_ptr(), count) }
} }
/// Executes the destructor (if any) of the pointed-to value. /// Executes the destructor (if any) of the pointed-to value.
@ -1201,7 +1208,7 @@ impl<T: ?Sized> NonNull<T> {
{ {
// SAFETY: `align` has been checked to be a power of 2 above. // SAFETY: `align` has been checked to be a power of 2 above.
unsafe { ptr::align_offset(self.pointer, align) } unsafe { ptr::align_offset(self.as_ptr(), align) }
} }
} }
@ -1229,7 +1236,7 @@ impl<T: ?Sized> NonNull<T> {
where where
T: Sized, T: Sized,
{ {
self.pointer.is_aligned() self.as_ptr().is_aligned()
} }
/// Returns whether the pointer is aligned to `align`. /// Returns whether the pointer is aligned to `align`.
@ -1266,7 +1273,7 @@ impl<T: ?Sized> NonNull<T> {
#[must_use] #[must_use]
#[unstable(feature = "pointer_is_aligned_to", issue = "96284")] #[unstable(feature = "pointer_is_aligned_to", issue = "96284")]
pub fn is_aligned_to(self, align: usize) -> bool { pub fn is_aligned_to(self, align: usize) -> bool {
self.pointer.is_aligned_to(align) self.as_ptr().is_aligned_to(align)
} }
} }

View File

@ -48,9 +48,9 @@ fn main() {
err => { err => {
drop(err); drop(err);
if let Ok(pid) = pid { if let Ok(pid) = pid {
println!("WARNING: build directory locked by process {pid}, waiting for lock"); eprintln!("WARNING: build directory locked by process {pid}, waiting for lock");
} else { } else {
println!("WARNING: build directory locked, waiting for lock"); eprintln!("WARNING: build directory locked, waiting for lock");
} }
let mut lock = t!(build_lock.write()); let mut lock = t!(build_lock.write());
t!(lock.write(process::id().to_string().as_ref())); t!(lock.write(process::id().to_string().as_ref()));
@ -70,13 +70,13 @@ fn main() {
// changelog warning, not the `x.py setup` message. // changelog warning, not the `x.py setup` message.
let suggest_setup = config.config.is_none() && !matches!(config.cmd, Subcommand::Setup { .. }); let suggest_setup = config.config.is_none() && !matches!(config.cmd, Subcommand::Setup { .. });
if suggest_setup { if suggest_setup {
println!("WARNING: you have not made a `config.toml`"); eprintln!("WARNING: you have not made a `config.toml`");
println!( eprintln!(
"HELP: consider running `./x.py setup` or copying `config.example.toml` by running \ "HELP: consider running `./x.py setup` or copying `config.example.toml` by running \
`cp config.example.toml config.toml`" `cp config.example.toml config.toml`"
); );
} else if let Some(suggestion) = &changelog_suggestion { } else if let Some(suggestion) = &changelog_suggestion {
println!("{suggestion}"); eprintln!("{suggestion}");
} }
let pre_commit = config.src.join(".git").join("hooks").join("pre-commit"); let pre_commit = config.src.join(".git").join("hooks").join("pre-commit");
@ -86,13 +86,13 @@ fn main() {
Build::new(config).build(); Build::new(config).build();
if suggest_setup { if suggest_setup {
println!("WARNING: you have not made a `config.toml`"); eprintln!("WARNING: you have not made a `config.toml`");
println!( eprintln!(
"HELP: consider running `./x.py setup` or copying `config.example.toml` by running \ "HELP: consider running `./x.py setup` or copying `config.example.toml` by running \
`cp config.example.toml config.toml`" `cp config.example.toml config.toml`"
); );
} else if let Some(suggestion) = &changelog_suggestion { } else if let Some(suggestion) = &changelog_suggestion {
println!("{suggestion}"); eprintln!("{suggestion}");
} }
// Give a warning if the pre-commit script is in pre-commit and not pre-push. // Give a warning if the pre-commit script is in pre-commit and not pre-push.
@ -102,14 +102,14 @@ fn main() {
if fs::read_to_string(pre_commit).is_ok_and(|contents| { if fs::read_to_string(pre_commit).is_ok_and(|contents| {
contents.contains("https://github.com/rust-lang/rust/issues/77620#issuecomment-705144570") contents.contains("https://github.com/rust-lang/rust/issues/77620#issuecomment-705144570")
}) { }) {
println!( eprintln!(
"WARNING: You have the pre-push script installed to .git/hooks/pre-commit. \ "WARNING: You have the pre-push script installed to .git/hooks/pre-commit. \
Consider moving it to .git/hooks/pre-push instead, which runs less often." Consider moving it to .git/hooks/pre-push instead, which runs less often."
); );
} }
if suggest_setup || changelog_suggestion.is_some() { if suggest_setup || changelog_suggestion.is_some() {
println!("NOTE: this message was printed twice to make it more likely to be seen"); eprintln!("NOTE: this message was printed twice to make it more likely to be seen");
} }
if dump_bootstrap_shims { if dump_bootstrap_shims {

View File

@ -306,7 +306,7 @@ fn main() {
// should run on success, after this block. // should run on success, after this block.
} }
if verbose > 0 { if verbose > 0 {
println!("\nDid not run successfully: {status}\n{cmd:?}\n-------------"); eprintln!("\nDid not run successfully: {status}\n{cmd:?}\n-------------");
} }
if let Some(mut on_fail) = on_fail { if let Some(mut on_fail) = on_fail {

View File

@ -287,7 +287,7 @@ impl Step for CodegenBackend {
fn run(self, builder: &Builder<'_>) { fn run(self, builder: &Builder<'_>) {
// FIXME: remove once https://github.com/rust-lang/rust/issues/112393 is resolved // FIXME: remove once https://github.com/rust-lang/rust/issues/112393 is resolved
if builder.build.config.vendor && self.backend == "gcc" { if builder.build.config.vendor && self.backend == "gcc" {
println!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled."); eprintln!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled.");
return; return;
} }

View File

@ -1611,7 +1611,7 @@ impl Step for Sysroot {
let sysroot = sysroot_dir(compiler.stage); let sysroot = sysroot_dir(compiler.stage);
builder builder
.verbose(|| println!("Removing sysroot {} to avoid caching bugs", sysroot.display())); .verbose(|| eprintln!("Removing sysroot {} to avoid caching bugs", sysroot.display()));
let _ = fs::remove_dir_all(&sysroot); let _ = fs::remove_dir_all(&sysroot);
t!(fs::create_dir_all(&sysroot)); t!(fs::create_dir_all(&sysroot));
@ -1681,7 +1681,7 @@ impl Step for Sysroot {
return true; return true;
} }
if !filtered_files.iter().all(|f| f != path.file_name().unwrap()) { if !filtered_files.iter().all(|f| f != path.file_name().unwrap()) {
builder.verbose_than(1, || println!("ignoring {}", path.display())); builder.verbose_than(1, || eprintln!("ignoring {}", path.display()));
false false
} else { } else {
true true
@ -2240,7 +2240,7 @@ pub fn stream_cargo(
cargo.arg(arg); cargo.arg(arg);
} }
builder.verbose(|| println!("running: {cargo:?}")); builder.verbose(|| eprintln!("running: {cargo:?}"));
if builder.config.dry_run() { if builder.config.dry_run() {
return true; return true;
@ -2261,12 +2261,12 @@ pub fn stream_cargo(
Ok(msg) => { Ok(msg) => {
if builder.config.json_output { if builder.config.json_output {
// Forward JSON to stdout. // Forward JSON to stdout.
println!("{line}"); eprintln!("{line}");
} }
cb(msg) cb(msg)
} }
// If this was informational, just print it out and continue // If this was informational, just print it out and continue
Err(_) => println!("{line}"), Err(_) => eprintln!("{line}"),
} }
} }

View File

@ -2080,7 +2080,7 @@ fn maybe_install_llvm(
{ {
let mut cmd = command(llvm_config); let mut cmd = command(llvm_config);
cmd.arg("--libfiles"); cmd.arg("--libfiles");
builder.verbose(|| println!("running {cmd:?}")); builder.verbose(|| eprintln!("running {cmd:?}"));
let files = cmd.run_capture_stdout(builder).stdout(); let files = cmd.run_capture_stdout(builder).stdout();
let build_llvm_out = &builder.llvm_out(builder.config.build); let build_llvm_out = &builder.llvm_out(builder.config.build);
let target_llvm_out = &builder.llvm_out(target); let target_llvm_out = &builder.llvm_out(target);

View File

@ -107,10 +107,10 @@ fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) {
if let Some(adjective) = adjective { format!("{adjective} ") } else { String::new() }; if let Some(adjective) = adjective { format!("{adjective} ") } else { String::new() };
if len <= 10 { if len <= 10 {
for path in paths { for path in paths {
println!("fmt: {verb} {adjective}file {path}"); eprintln!("fmt: {verb} {adjective}file {path}");
} }
} else { } else {
println!("fmt: {verb} {len} {adjective}files"); eprintln!("fmt: {verb} {len} {adjective}files");
} }
} }
@ -199,7 +199,7 @@ pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) {
match get_modified_rs_files(build) { match get_modified_rs_files(build) {
Ok(Some(files)) => { Ok(Some(files)) => {
if files.is_empty() { if files.is_empty() {
println!("fmt info: No modified files detected for formatting."); eprintln!("fmt info: No modified files detected for formatting.");
return; return;
} }

View File

@ -134,7 +134,7 @@ impl Step for Profile {
t!(fs::remove_file(path)); t!(fs::remove_file(path));
} }
_ => { _ => {
println!("Exiting."); eprintln!("Exiting.");
crate::exit!(1); crate::exit!(1);
} }
} }
@ -184,15 +184,15 @@ pub fn setup(config: &Config, profile: Profile) {
Profile::Dist => &["dist", "build"], Profile::Dist => &["dist", "build"],
}; };
println!(); eprintln!();
println!("To get started, try one of the following commands:"); eprintln!("To get started, try one of the following commands:");
for cmd in suggestions { for cmd in suggestions {
println!("- `x.py {cmd}`"); eprintln!("- `x.py {cmd}`");
} }
if profile != Profile::Dist { if profile != Profile::Dist {
println!( eprintln!(
"For more suggestions, see https://rustc-dev-guide.rust-lang.org/building/suggested.html" "For more suggestions, see https://rustc-dev-guide.rust-lang.org/building/suggested.html"
); );
} }
@ -224,7 +224,7 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) {
t!(fs::write(path, settings)); t!(fs::write(path, settings));
let include_path = profile.include_path(&config.src); let include_path = profile.include_path(&config.src);
println!("`x.py` will now use the configuration at {}", include_path.display()); eprintln!("`x.py` will now use the configuration at {}", include_path.display());
} }
/// Creates a toolchain link for stage1 using `rustup` /// Creates a toolchain link for stage1 using `rustup`
@ -256,7 +256,7 @@ impl Step for Link {
} }
if !rustup_installed(builder) { if !rustup_installed(builder) {
println!("WARNING: `rustup` is not installed; Skipping `stage1` toolchain linking."); eprintln!("WARNING: `rustup` is not installed; Skipping `stage1` toolchain linking.");
return; return;
} }
@ -296,7 +296,7 @@ fn attempt_toolchain_link(builder: &Builder<'_>, stage_path: &str) {
} }
if try_link_toolchain(builder, stage_path) { if try_link_toolchain(builder, stage_path) {
println!( eprintln!(
"Added `stage1` rustup toolchain; try `cargo +stage1 build` on a separate rust project to run a newly-built toolchain" "Added `stage1` rustup toolchain; try `cargo +stage1 build` on a separate rust project to run a newly-built toolchain"
); );
} else { } else {
@ -321,14 +321,14 @@ fn toolchain_is_linked(builder: &Builder<'_>) -> bool {
return false; return false;
} }
// The toolchain has already been linked. // The toolchain has already been linked.
println!( eprintln!(
"`stage1` toolchain already linked; not attempting to link `stage1` toolchain" "`stage1` toolchain already linked; not attempting to link `stage1` toolchain"
); );
} }
None => { None => {
// In this case, we don't know if the `stage1` toolchain has been linked; // In this case, we don't know if the `stage1` toolchain has been linked;
// but `rustup` failed, so let's not go any further. // but `rustup` failed, so let's not go any further.
println!( eprintln!(
"`rustup` failed to list current toolchains; not attempting to link `stage1` toolchain" "`rustup` failed to list current toolchains; not attempting to link `stage1` toolchain"
); );
} }
@ -389,9 +389,9 @@ pub fn interactive_path() -> io::Result<Profile> {
input.parse() input.parse()
} }
println!("Welcome to the Rust project! What do you want to do with x.py?"); eprintln!("Welcome to the Rust project! What do you want to do with x.py?");
for ((letter, _), profile) in abbrev_all() { for ((letter, _), profile) in abbrev_all() {
println!("{}) {}: {}", letter, profile, profile.purpose()); eprintln!("{}) {}: {}", letter, profile, profile.purpose());
} }
let template = loop { let template = loop {
print!( print!(
@ -488,7 +488,7 @@ fn install_git_hook_maybe(builder: &Builder<'_>, config: &Config) -> io::Result<
return Ok(()); return Ok(());
} }
println!( eprintln!(
"\nRust's CI will automatically fail if it doesn't pass `tidy`, the internal tool for ensuring code quality. "\nRust's CI will automatically fail if it doesn't pass `tidy`, the internal tool for ensuring code quality.
If you'd like, x.py can install a git hook for you that will automatically run `test tidy` before If you'd like, x.py can install a git hook for you that will automatically run `test tidy` before
pushing your code to ensure your code is up to par. If you decide later that this behavior is pushing your code to ensure your code is up to par. If you decide later that this behavior is
@ -496,7 +496,7 @@ undesirable, simply delete the `pre-push` file from .git/hooks."
); );
if prompt_user("Would you like to install the git hook?: [y/N]")? != Some(PromptResult::Yes) { if prompt_user("Would you like to install the git hook?: [y/N]")? != Some(PromptResult::Yes) {
println!("Ok, skipping installation!"); eprintln!("Ok, skipping installation!");
return Ok(()); return Ok(());
} }
if !hooks_dir.exists() { if !hooks_dir.exists() {
@ -513,7 +513,7 @@ undesirable, simply delete the `pre-push` file from .git/hooks."
); );
return Err(e); return Err(e);
} }
Ok(_) => println!("Linked `src/etc/pre-push.sh` to `.git/hooks/pre-push`"), Ok(_) => eprintln!("Linked `src/etc/pre-push.sh` to `.git/hooks/pre-push`"),
}; };
Ok(()) Ok(())
} }
@ -654,7 +654,7 @@ impl Step for Editor {
if let Some(editor_kind) = editor_kind { if let Some(editor_kind) = editor_kind {
while !t!(create_editor_settings_maybe(config, editor_kind.clone())) {} while !t!(create_editor_settings_maybe(config, editor_kind.clone())) {}
} else { } else {
println!("Ok, skipping editor setup!"); eprintln!("Ok, skipping editor setup!");
} }
} }
Err(e) => eprintln!("Could not determine the editor: {e}"), Err(e) => eprintln!("Could not determine the editor: {e}"),
@ -687,7 +687,7 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu
mismatched_settings = Some(false); mismatched_settings = Some(false);
} }
} }
println!( eprintln!(
"\nx.py can automatically install the recommended `{settings_filename}` file for rustc development" "\nx.py can automatically install the recommended `{settings_filename}` file for rustc development"
); );
@ -706,7 +706,7 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu
Some(PromptResult::Yes) => true, Some(PromptResult::Yes) => true,
Some(PromptResult::Print) => false, Some(PromptResult::Print) => false,
_ => { _ => {
println!("Ok, skipping settings!"); eprintln!("Ok, skipping settings!");
return Ok(true); return Ok(true);
} }
}; };
@ -733,9 +733,9 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu
_ => "Created", _ => "Created",
}; };
fs::write(&settings_path, editor.settings_template())?; fs::write(&settings_path, editor.settings_template())?;
println!("{verb} `{}`", settings_filename); eprintln!("{verb} `{}`", settings_filename);
} else { } else {
println!("\n{}", editor.settings_template()); eprintln!("\n{}", editor.settings_template());
} }
Ok(should_create) Ok(should_create)
} }

View File

@ -66,6 +66,6 @@ pub fn suggest(builder: &Builder<'_>, run: bool) {
build.build(); build.build();
} }
} else { } else {
println!("HELP: consider using the `--run` flag to automatically run suggested tests"); eprintln!("HELP: consider using the `--run` flag to automatically run suggested tests");
} }
} }

View File

@ -471,11 +471,11 @@ impl Miri {
// We re-use the `cargo` from above. // We re-use the `cargo` from above.
cargo.arg("--print-sysroot"); cargo.arg("--print-sysroot");
builder.verbose(|| println!("running: {cargo:?}")); builder.verbose(|| eprintln!("running: {cargo:?}"));
let stdout = cargo.run_capture_stdout(builder).stdout(); let stdout = cargo.run_capture_stdout(builder).stdout();
// Output is "<sysroot>\n". // Output is "<sysroot>\n".
let sysroot = stdout.trim_end(); let sysroot = stdout.trim_end();
builder.verbose(|| println!("`cargo miri setup --print-sysroot` said: {sysroot:?}")); builder.verbose(|| eprintln!("`cargo miri setup --print-sysroot` said: {sysroot:?}"));
PathBuf::from(sysroot) PathBuf::from(sysroot)
} }
} }
@ -2478,7 +2478,7 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) ->
} }
} }
builder.verbose(|| println!("doc tests for: {}", markdown.display())); builder.verbose(|| eprintln!("doc tests for: {}", markdown.display()));
let mut cmd = builder.rustdoc_cmd(compiler); let mut cmd = builder.rustdoc_cmd(compiler);
builder.add_rust_test_threads(&mut cmd); builder.add_rust_test_threads(&mut cmd);
// allow for unstable options such as new editions // allow for unstable options such as new editions

View File

@ -523,7 +523,7 @@ impl Builder<'_> {
let sysroot_str = sysroot.as_os_str().to_str().expect("sysroot should be UTF-8"); let sysroot_str = sysroot.as_os_str().to_str().expect("sysroot should be UTF-8");
if self.is_verbose() && !matches!(self.config.dry_run, DryRun::SelfCheck) { if self.is_verbose() && !matches!(self.config.dry_run, DryRun::SelfCheck) {
println!("using sysroot {sysroot_str}"); eprintln!("using sysroot {sysroot_str}");
} }
let mut rustflags = Rustflags::new(target); let mut rustflags = Rustflags::new(target);

View File

@ -392,14 +392,14 @@ impl StepDescription {
fn is_excluded(&self, builder: &Builder<'_>, pathset: &PathSet) -> bool { fn is_excluded(&self, builder: &Builder<'_>, pathset: &PathSet) -> bool {
if builder.config.skip.iter().any(|e| pathset.has(e, builder.kind)) { if builder.config.skip.iter().any(|e| pathset.has(e, builder.kind)) {
if !matches!(builder.config.dry_run, DryRun::SelfCheck) { if !matches!(builder.config.dry_run, DryRun::SelfCheck) {
println!("Skipping {pathset:?} because it is excluded"); eprintln!("Skipping {pathset:?} because it is excluded");
} }
return true; return true;
} }
if !builder.config.skip.is_empty() && !matches!(builder.config.dry_run, DryRun::SelfCheck) { if !builder.config.skip.is_empty() && !matches!(builder.config.dry_run, DryRun::SelfCheck) {
builder.verbose(|| { builder.verbose(|| {
println!( eprintln!(
"{:?} not skipped for {:?} -- not in {:?}", "{:?} not skipped for {:?} -- not in {:?}",
pathset, self.name, builder.config.skip pathset, self.name, builder.config.skip
) )
@ -1437,11 +1437,11 @@ impl<'a> Builder<'a> {
panic!("{}", out); panic!("{}", out);
} }
if let Some(out) = self.cache.get(&step) { if let Some(out) = self.cache.get(&step) {
self.verbose_than(1, || println!("{}c {:?}", " ".repeat(stack.len()), step)); self.verbose_than(1, || eprintln!("{}c {:?}", " ".repeat(stack.len()), step));
return out; return out;
} }
self.verbose_than(1, || println!("{}> {:?}", " ".repeat(stack.len()), step)); self.verbose_than(1, || eprintln!("{}> {:?}", " ".repeat(stack.len()), step));
stack.push(Box::new(step.clone())); stack.push(Box::new(step.clone()));
} }
@ -1462,7 +1462,7 @@ impl<'a> Builder<'a> {
let step_string = format!("{step:?}"); let step_string = format!("{step:?}");
let brace_index = step_string.find('{').unwrap_or(0); let brace_index = step_string.find('{').unwrap_or(0);
let type_string = type_name::<S>(); let type_string = type_name::<S>();
println!( eprintln!(
"[TIMING] {} {} -- {}.{:03}", "[TIMING] {} {} -- {}.{:03}",
&type_string.strip_prefix("bootstrap::").unwrap_or(type_string), &type_string.strip_prefix("bootstrap::").unwrap_or(type_string),
&step_string[brace_index..], &step_string[brace_index..],
@ -1479,7 +1479,9 @@ impl<'a> Builder<'a> {
let cur_step = stack.pop().expect("step stack empty"); let cur_step = stack.pop().expect("step stack empty");
assert_eq!(cur_step.downcast_ref(), Some(&step)); assert_eq!(cur_step.downcast_ref(), Some(&step));
} }
self.verbose_than(1, || println!("{}< {:?}", " ".repeat(self.stack.borrow().len()), step)); self.verbose_than(1, || {
eprintln!("{}< {:?}", " ".repeat(self.stack.borrow().len()), step)
});
self.cache.put(step, out.clone()); self.cache.put(step, out.clone());
out out
} }

View File

@ -1293,7 +1293,7 @@ impl Config {
.map(|change_id| change_id.inner.map(crate::find_recent_config_change_ids)) .map(|change_id| change_id.inner.map(crate::find_recent_config_change_ids))
{ {
if !changes.is_empty() { if !changes.is_empty() {
println!( eprintln!(
"WARNING: There have been changes to x.py since you last updated:\n{}", "WARNING: There have been changes to x.py since you last updated:\n{}",
crate::human_readable_changes(&changes) crate::human_readable_changes(&changes)
); );
@ -1559,7 +1559,7 @@ impl Config {
} }
if cargo_clippy.is_some() && rustc.is_none() { if cargo_clippy.is_some() && rustc.is_none() {
println!( eprintln!(
"WARNING: Using `build.cargo-clippy` without `build.rustc` usually fails due to toolchain conflict." "WARNING: Using `build.cargo-clippy` without `build.rustc` usually fails due to toolchain conflict."
); );
} }
@ -1841,7 +1841,7 @@ impl Config {
// FIXME: Remove this option at the end of 2024. // FIXME: Remove this option at the end of 2024.
if parallel_compiler.is_some() { if parallel_compiler.is_some() {
println!( eprintln!(
"WARNING: The `rust.parallel-compiler` option is deprecated and does nothing. The parallel compiler (with one thread) is now the default" "WARNING: The `rust.parallel-compiler` option is deprecated and does nothing. The parallel compiler (with one thread) is now the default"
); );
} }
@ -1873,7 +1873,7 @@ impl Config {
if available_backends.contains(&backend) { if available_backends.contains(&backend) {
panic!("Invalid value '{s}' for 'rust.codegen-backends'. Instead, please use '{backend}'."); panic!("Invalid value '{s}' for 'rust.codegen-backends'. Instead, please use '{backend}'.");
} else { } else {
println!("HELP: '{s}' for 'rust.codegen-backends' might fail. \ eprintln!("HELP: '{s}' for 'rust.codegen-backends' might fail. \
Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \ Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \
In this case, it would be referred to as '{backend}'."); In this case, it would be referred to as '{backend}'.");
} }
@ -1902,7 +1902,7 @@ impl Config {
// tests may fail due to using a different channel than the one used by the compiler during tests. // tests may fail due to using a different channel than the one used by the compiler during tests.
if let Some(commit) = &config.download_rustc_commit { if let Some(commit) = &config.download_rustc_commit {
if is_user_configured_rust_channel { if is_user_configured_rust_channel {
println!( eprintln!(
"WARNING: `rust.download-rustc` is enabled. The `rust.channel` option will be overridden by the CI rustc's channel." "WARNING: `rust.download-rustc` is enabled. The `rust.channel` option will be overridden by the CI rustc's channel."
); );
@ -1992,10 +1992,10 @@ impl Config {
if config.llvm_from_ci { if config.llvm_from_ci {
let warn = |option: &str| { let warn = |option: &str| {
println!( eprintln!(
"WARNING: `{option}` will only be used on `compiler/rustc_llvm` build, not for the LLVM build." "WARNING: `{option}` will only be used on `compiler/rustc_llvm` build, not for the LLVM build."
); );
println!( eprintln!(
"HELP: To use `{option}` for LLVM builds, set `download-ci-llvm` option to false." "HELP: To use `{option}` for LLVM builds, set `download-ci-llvm` option to false."
); );
}; };
@ -2014,12 +2014,12 @@ impl Config {
// if they've chosen a different value. // if they've chosen a different value.
if libzstd.is_some() { if libzstd.is_some() {
println!( eprintln!(
"WARNING: when using `download-ci-llvm`, the local `llvm.libzstd` option, \ "WARNING: when using `download-ci-llvm`, the local `llvm.libzstd` option, \
like almost all `llvm.*` options, will be ignored and set by the LLVM CI \ like almost all `llvm.*` options, will be ignored and set by the LLVM CI \
artifacts builder config." artifacts builder config."
); );
println!( eprintln!(
"HELP: To use `llvm.libzstd` for LLVM/LLD builds, set `download-ci-llvm` option to false." "HELP: To use `llvm.libzstd` for LLVM/LLD builds, set `download-ci-llvm` option to false."
); );
} }
@ -2088,7 +2088,7 @@ impl Config {
if available_backends.contains(&backend) { if available_backends.contains(&backend) {
panic!("Invalid value '{s}' for 'target.{triple}.codegen-backends'. Instead, please use '{backend}'."); panic!("Invalid value '{s}' for 'target.{triple}.codegen-backends'. Instead, please use '{backend}'.");
} else { } else {
println!("HELP: '{s}' for 'target.{triple}.codegen-backends' might fail. \ eprintln!("HELP: '{s}' for 'target.{triple}.codegen-backends' might fail. \
Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \ Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \
In this case, it would be referred to as '{backend}'."); In this case, it would be referred to as '{backend}'.");
} }
@ -2304,7 +2304,7 @@ impl Config {
if self.dry_run() { if self.dry_run() {
return Ok(()); return Ok(());
} }
self.verbose(|| println!("running: {cmd:?}")); self.verbose(|| eprintln!("running: {cmd:?}"));
build_helper::util::try_run(cmd, self.is_verbose()) build_helper::util::try_run(cmd, self.is_verbose())
} }
@ -2479,7 +2479,7 @@ impl Config {
// This happens when LLVM submodule is updated in CI, we should disable ci-rustc without an error // This happens when LLVM submodule is updated in CI, we should disable ci-rustc without an error
// to not break CI. For non-CI environments, we should return an error. // to not break CI. For non-CI environments, we should return an error.
if CiEnv::is_ci() { if CiEnv::is_ci() {
println!("WARNING: LLVM submodule has changes, `download-rustc` will be disabled."); eprintln!("WARNING: LLVM submodule has changes, `download-rustc` will be disabled.");
return None; return None;
} else { } else {
panic!("ERROR: LLVM submodule has changes, `download-rustc` can't be used."); panic!("ERROR: LLVM submodule has changes, `download-rustc` can't be used.");
@ -2490,8 +2490,8 @@ impl Config {
let ci_config_toml = match self.get_builder_toml("ci-rustc") { let ci_config_toml = match self.get_builder_toml("ci-rustc") {
Ok(ci_config_toml) => ci_config_toml, Ok(ci_config_toml) => ci_config_toml,
Err(e) if e.to_string().contains("unknown field") => { Err(e) if e.to_string().contains("unknown field") => {
println!("WARNING: CI rustc has some fields that are no longer supported in bootstrap; download-rustc will be disabled."); eprintln!("WARNING: CI rustc has some fields that are no longer supported in bootstrap; download-rustc will be disabled.");
println!("HELP: Consider rebasing to a newer commit if available."); eprintln!("HELP: Consider rebasing to a newer commit if available.");
return None; return None;
}, },
Err(e) => { Err(e) => {
@ -2516,7 +2516,7 @@ impl Config {
.is_some_and(|s| s == "1" || s == "true"); .is_some_and(|s| s == "1" || s == "true");
if disable_ci_rustc_if_incompatible && res.is_err() { if disable_ci_rustc_if_incompatible && res.is_err() {
println!("WARNING: download-rustc is disabled with `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` env."); eprintln!("WARNING: download-rustc is disabled with `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` env.");
return None; return None;
} }
@ -2701,7 +2701,7 @@ impl Config {
return; return;
} }
println!("Updating submodule {relative_path}"); eprintln!("Updating submodule {relative_path}");
self.check_run( self.check_run(
helpers::git(Some(&self.src)) helpers::git(Some(&self.src))
.run_always() .run_always()
@ -2824,7 +2824,7 @@ impl Config {
Some(StringOrBool::Bool(true)) => false, Some(StringOrBool::Bool(true)) => false,
Some(StringOrBool::String(s)) if s == "if-unchanged" => { Some(StringOrBool::String(s)) if s == "if-unchanged" => {
if !self.rust_info.is_managed_git_subrepository() { if !self.rust_info.is_managed_git_subrepository() {
println!( eprintln!(
"ERROR: `download-rustc=if-unchanged` is only compatible with Git managed sources." "ERROR: `download-rustc=if-unchanged` is only compatible with Git managed sources."
); );
crate::exit!(1); crate::exit!(1);
@ -2857,10 +2857,10 @@ impl Config {
if if_unchanged { if if_unchanged {
return None; return None;
} }
println!("ERROR: could not find commit hash for downloading rustc"); eprintln!("ERROR: could not find commit hash for downloading rustc");
println!("HELP: maybe your repository history is too shallow?"); eprintln!("HELP: maybe your repository history is too shallow?");
println!("HELP: consider setting `rust.download-rustc=false` in config.toml"); eprintln!("HELP: consider setting `rust.download-rustc=false` in config.toml");
println!("HELP: or fetch enough history to include one upstream commit"); eprintln!("HELP: or fetch enough history to include one upstream commit");
crate::exit!(1); crate::exit!(1);
} }
}; };
@ -2899,7 +2899,7 @@ impl Config {
let if_unchanged = || { let if_unchanged = || {
if self.rust_info.is_from_tarball() { if self.rust_info.is_from_tarball() {
// Git is needed for running "if-unchanged" logic. // Git is needed for running "if-unchanged" logic.
println!( eprintln!(
"WARNING: 'if-unchanged' has no effect on tarball sources; ignoring `download-ci-llvm`." "WARNING: 'if-unchanged' has no effect on tarball sources; ignoring `download-ci-llvm`."
); );
return false; return false;
@ -2948,10 +2948,10 @@ impl Config {
// Only commits merged by bors will have CI artifacts. // Only commits merged by bors will have CI artifacts.
let commit = get_closest_merge_commit(Some(&self.src), &self.git_config(), &[]).unwrap(); let commit = get_closest_merge_commit(Some(&self.src), &self.git_config(), &[]).unwrap();
if commit.is_empty() { if commit.is_empty() {
println!("error: could not find commit hash for downloading components from CI"); eprintln!("error: could not find commit hash for downloading components from CI");
println!("help: maybe your repository history is too shallow?"); eprintln!("help: maybe your repository history is too shallow?");
println!("help: consider disabling `{option_name}`"); eprintln!("help: consider disabling `{option_name}`");
println!("help: or fetch enough history to include one upstream commit"); eprintln!("help: or fetch enough history to include one upstream commit");
crate::exit!(1); crate::exit!(1);
} }
@ -2963,14 +2963,14 @@ impl Config {
if has_changes { if has_changes {
if if_unchanged { if if_unchanged {
if self.is_verbose() { if self.is_verbose() {
println!( eprintln!(
"warning: saw changes to one of {modified_paths:?} since {commit}; \ "warning: saw changes to one of {modified_paths:?} since {commit}; \
ignoring `{option_name}`" ignoring `{option_name}`"
); );
} }
return None; return None;
} }
println!( eprintln!(
"warning: `{option_name}` is enabled, but there are changes to one of {modified_paths:?}" "warning: `{option_name}` is enabled, but there are changes to one of {modified_paths:?}"
); );
} }
@ -3007,7 +3007,7 @@ pub(crate) fn check_incompatible_options_for_ci_llvm(
($current:expr, $expected:expr) => { ($current:expr, $expected:expr) => {
if let Some(current) = &$current { if let Some(current) = &$current {
if Some(current) != $expected.as_ref() { if Some(current) != $expected.as_ref() {
println!( eprintln!(
"WARNING: `llvm.{}` has no effect with `llvm.download-ci-llvm`. \ "WARNING: `llvm.{}` has no effect with `llvm.download-ci-llvm`. \
Current value: {:?}, Expected value(s): {}{:?}", Current value: {:?}, Expected value(s): {}{:?}",
stringify!($expected).replace("_", "-"), stringify!($expected).replace("_", "-"),
@ -3112,7 +3112,7 @@ fn check_incompatible_options_for_ci_rustc(
($current:expr, $expected:expr, $config_section:expr) => { ($current:expr, $expected:expr, $config_section:expr) => {
if let Some(current) = &$current { if let Some(current) = &$current {
if Some(current) != $expected.as_ref() { if Some(current) != $expected.as_ref() {
println!( eprintln!(
"WARNING: `{}` has no effect with `rust.download-rustc`. \ "WARNING: `{}` has no effect with `rust.download-rustc`. \
Current value: {:?}, Expected value(s): {}{:?}", Current value: {:?}, Expected value(s): {}{:?}",
format!("{}.{}", $config_section, stringify!($expected).replace("_", "-")), format!("{}.{}", $config_section, stringify!($expected).replace("_", "-")),

View File

@ -196,12 +196,12 @@ impl Flags {
if let Ok(HelpVerboseOnly { help: true, verbose: 1.., cmd: subcommand }) = if let Ok(HelpVerboseOnly { help: true, verbose: 1.., cmd: subcommand }) =
HelpVerboseOnly::try_parse_from(normalize_args(args)) HelpVerboseOnly::try_parse_from(normalize_args(args))
{ {
println!("NOTE: updating submodules before printing available paths"); eprintln!("NOTE: updating submodules before printing available paths");
let config = Config::parse(Self::parse(&[String::from("build")])); let config = Config::parse(Self::parse(&[String::from("build")]));
let build = Build::new(config); let build = Build::new(config);
let paths = Builder::get_help(&build, subcommand); let paths = Builder::get_help(&build, subcommand);
if let Some(s) = paths { if let Some(s) = paths {
println!("{s}"); eprintln!("{s}");
} else { } else {
panic!("No paths available for subcommand `{}`", subcommand.as_str()); panic!("No paths available for subcommand `{}`", subcommand.as_str());
} }

View File

@ -77,7 +77,7 @@ impl Config {
if self.dry_run() && !cmd.run_always { if self.dry_run() && !cmd.run_always {
return true; return true;
} }
self.verbose(|| println!("running: {cmd:?}")); self.verbose(|| eprintln!("running: {cmd:?}"));
check_run(cmd, self.is_verbose()) check_run(cmd, self.is_verbose())
} }
@ -144,7 +144,7 @@ impl Config {
/// Please see <https://nixos.org/patchelf.html> for more information /// Please see <https://nixos.org/patchelf.html> for more information
fn fix_bin_or_dylib(&self, fname: &Path) { fn fix_bin_or_dylib(&self, fname: &Path) {
assert_eq!(SHOULD_FIX_BINS_AND_DYLIBS.get(), Some(&true)); assert_eq!(SHOULD_FIX_BINS_AND_DYLIBS.get(), Some(&true));
println!("attempting to patch {}", fname.display()); eprintln!("attempting to patch {}", fname.display());
// Only build `.nix-deps` once. // Only build `.nix-deps` once.
static NIX_DEPS_DIR: OnceLock<PathBuf> = OnceLock::new(); static NIX_DEPS_DIR: OnceLock<PathBuf> = OnceLock::new();
@ -206,7 +206,7 @@ impl Config {
} }
fn download_file(&self, url: &str, dest_path: &Path, help_on_error: &str) { fn download_file(&self, url: &str, dest_path: &Path, help_on_error: &str) {
self.verbose(|| println!("download {url}")); self.verbose(|| eprintln!("download {url}"));
// Use a temporary file in case we crash while downloading, to avoid a corrupt download in cache/. // Use a temporary file in case we crash while downloading, to avoid a corrupt download in cache/.
let tempfile = self.tempdir().join(dest_path.file_name().unwrap()); let tempfile = self.tempdir().join(dest_path.file_name().unwrap());
// While bootstrap itself only supports http and https downloads, downstream forks might // While bootstrap itself only supports http and https downloads, downstream forks might
@ -226,7 +226,7 @@ impl Config {
} }
fn download_http_with_retries(&self, tempfile: &Path, url: &str, help_on_error: &str) { fn download_http_with_retries(&self, tempfile: &Path, url: &str, help_on_error: &str) {
println!("downloading {url}"); eprintln!("downloading {url}");
// Try curl. If that fails and we are on windows, fallback to PowerShell. // Try curl. If that fails and we are on windows, fallback to PowerShell.
// options should be kept in sync with // options should be kept in sync with
// src/bootstrap/src/core/download.rs // src/bootstrap/src/core/download.rs
@ -341,7 +341,7 @@ impl Config {
short_path = short_path.strip_prefix(pattern).unwrap_or(short_path); short_path = short_path.strip_prefix(pattern).unwrap_or(short_path);
let dst_path = dst.join(short_path); let dst_path = dst.join(short_path);
self.verbose(|| { self.verbose(|| {
println!("extracting {} to {}", original_path.display(), dst.display()) eprintln!("extracting {} to {}", original_path.display(), dst.display())
}); });
if !t!(member.unpack_in(dst)) { if !t!(member.unpack_in(dst)) {
panic!("path traversal attack ??"); panic!("path traversal attack ??");
@ -365,7 +365,7 @@ impl Config {
pub(crate) fn verify(&self, path: &Path, expected: &str) -> bool { pub(crate) fn verify(&self, path: &Path, expected: &str) -> bool {
use sha2::Digest; use sha2::Digest;
self.verbose(|| println!("verifying {}", path.display())); self.verbose(|| eprintln!("verifying {}", path.display()));
if self.dry_run() { if self.dry_run() {
return false; return false;
@ -391,7 +391,7 @@ impl Config {
let verified = checksum == expected; let verified = checksum == expected;
if !verified { if !verified {
println!( eprintln!(
"invalid checksum: \n\ "invalid checksum: \n\
found: {checksum}\n\ found: {checksum}\n\
expected: {expected}", expected: {expected}",
@ -421,7 +421,7 @@ enum DownloadSource {
/// Functions that are only ever called once, but named for clarify and to avoid thousand-line functions. /// Functions that are only ever called once, but named for clarify and to avoid thousand-line functions.
impl Config { impl Config {
pub(crate) fn download_clippy(&self) -> PathBuf { pub(crate) fn download_clippy(&self) -> PathBuf {
self.verbose(|| println!("downloading stage0 clippy artifacts")); self.verbose(|| eprintln!("downloading stage0 clippy artifacts"));
let date = &self.stage0_metadata.compiler.date; let date = &self.stage0_metadata.compiler.date;
let version = &self.stage0_metadata.compiler.version; let version = &self.stage0_metadata.compiler.version;
@ -518,7 +518,7 @@ impl Config {
} }
pub(crate) fn download_ci_rustc(&self, commit: &str) { pub(crate) fn download_ci_rustc(&self, commit: &str) {
self.verbose(|| println!("using downloaded stage2 artifacts from CI (commit {commit})")); self.verbose(|| eprintln!("using downloaded stage2 artifacts from CI (commit {commit})"));
let version = self.artifact_version_part(commit); let version = self.artifact_version_part(commit);
// download-rustc doesn't need its own cargo, it can just use beta's. But it does need the // download-rustc doesn't need its own cargo, it can just use beta's. But it does need the
@ -539,7 +539,7 @@ impl Config {
#[cfg(not(feature = "bootstrap-self-test"))] #[cfg(not(feature = "bootstrap-self-test"))]
pub(crate) fn download_beta_toolchain(&self) { pub(crate) fn download_beta_toolchain(&self) {
self.verbose(|| println!("downloading stage0 beta artifacts")); self.verbose(|| eprintln!("downloading stage0 beta artifacts"));
let date = &self.stage0_metadata.compiler.date; let date = &self.stage0_metadata.compiler.date;
let version = &self.stage0_metadata.compiler.version; let version = &self.stage0_metadata.compiler.version;
@ -677,7 +677,7 @@ impl Config {
return; return;
} else { } else {
self.verbose(|| { self.verbose(|| {
println!( eprintln!(
"ignoring cached file {} due to failed verification", "ignoring cached file {} due to failed verification",
tarball.display() tarball.display()
) )
@ -776,10 +776,10 @@ download-rustc = false
t!(check_incompatible_options_for_ci_llvm(current_config_toml, ci_config_toml)); t!(check_incompatible_options_for_ci_llvm(current_config_toml, ci_config_toml));
} }
Err(e) if e.to_string().contains("unknown field") => { Err(e) if e.to_string().contains("unknown field") => {
println!( eprintln!(
"WARNING: CI LLVM has some fields that are no longer supported in bootstrap; download-ci-llvm will be disabled." "WARNING: CI LLVM has some fields that are no longer supported in bootstrap; download-ci-llvm will be disabled."
); );
println!("HELP: Consider rebasing to a newer commit if available."); eprintln!("HELP: Consider rebasing to a newer commit if available.");
} }
Err(e) => { Err(e) => {
eprintln!("ERROR: Failed to parse CI LLVM config.toml: {e}"); eprintln!("ERROR: Failed to parse CI LLVM config.toml: {e}");

View File

@ -237,11 +237,11 @@ than building it.
stage0_supported_target_list.intersection(&missing_targets_hashset).collect(); stage0_supported_target_list.intersection(&missing_targets_hashset).collect();
if !duplicated_targets.is_empty() { if !duplicated_targets.is_empty() {
println!( eprintln!(
"Following targets supported from the stage0 compiler, please remove them from STAGE0_MISSING_TARGETS list." "Following targets supported from the stage0 compiler, please remove them from STAGE0_MISSING_TARGETS list."
); );
for duplicated_target in duplicated_targets { for duplicated_target in duplicated_targets {
println!(" {duplicated_target}"); eprintln!(" {duplicated_target}");
} }
std::process::exit(1); std::process::exit(1);
} }

View File

@ -406,11 +406,11 @@ impl Build {
.unwrap() .unwrap()
.trim(); .trim();
if local_release.split('.').take(2).eq(version.split('.').take(2)) { if local_release.split('.').take(2).eq(version.split('.').take(2)) {
build.verbose(|| println!("auto-detected local-rebuild {local_release}")); build.verbose(|| eprintln!("auto-detected local-rebuild {local_release}"));
build.local_rebuild = true; build.local_rebuild = true;
} }
build.verbose(|| println!("finding compilers")); build.verbose(|| eprintln!("finding compilers"));
utils::cc_detect::find(&build); utils::cc_detect::find(&build);
// When running `setup`, the profile is about to change, so any requirements we have now may // When running `setup`, the profile is about to change, so any requirements we have now may
// be different on the next invocation. Don't check for them until the next time x.py is // be different on the next invocation. Don't check for them until the next time x.py is
@ -418,7 +418,7 @@ impl Build {
// //
// Similarly, for `setup` we don't actually need submodules or cargo metadata. // Similarly, for `setup` we don't actually need submodules or cargo metadata.
if !matches!(build.config.cmd, Subcommand::Setup { .. }) { if !matches!(build.config.cmd, Subcommand::Setup { .. }) {
build.verbose(|| println!("running sanity check")); build.verbose(|| eprintln!("running sanity check"));
crate::core::sanity::check(&mut build); crate::core::sanity::check(&mut build);
// Make sure we update these before gathering metadata so we don't get an error about missing // Make sure we update these before gathering metadata so we don't get an error about missing
@ -436,7 +436,7 @@ impl Build {
// Now, update all existing submodules. // Now, update all existing submodules.
build.update_existing_submodules(); build.update_existing_submodules();
build.verbose(|| println!("learning about cargo")); build.verbose(|| eprintln!("learning about cargo"));
crate::core::metadata::build(&mut build); crate::core::metadata::build(&mut build);
} }
@ -605,7 +605,7 @@ impl Build {
let stamp = dir.join(".stamp"); let stamp = dir.join(".stamp");
let mut cleared = false; let mut cleared = false;
if mtime(&stamp) < mtime(input) { if mtime(&stamp) < mtime(input) {
self.verbose(|| println!("Dirty - {}", dir.display())); self.verbose(|| eprintln!("Dirty - {}", dir.display()));
let _ = fs::remove_dir_all(dir); let _ = fs::remove_dir_all(dir);
cleared = true; cleared = true;
} else if stamp.exists() { } else if stamp.exists() {
@ -890,7 +890,7 @@ impl Build {
let executed_at = std::panic::Location::caller(); let executed_at = std::panic::Location::caller();
self.verbose(|| { self.verbose(|| {
println!("running: {command:?} (created at {created_at}, executed at {executed_at})") eprintln!("running: {command:?} (created at {created_at}, executed at {executed_at})")
}); });
let cmd = command.as_command_mut(); let cmd = command.as_command_mut();
@ -947,7 +947,7 @@ Executed at: {executed_at}"#,
let fail = |message: &str, output: CommandOutput| -> ! { let fail = |message: &str, output: CommandOutput| -> ! {
if self.is_verbose() { if self.is_verbose() {
println!("{message}"); eprintln!("{message}");
} else { } else {
let (stdout, stderr) = (output.stdout_if_present(), output.stderr_if_present()); let (stdout, stderr) = (output.stdout_if_present(), output.stderr_if_present());
// If the command captures output, the user would not see any indication that // If the command captures output, the user would not see any indication that
@ -957,16 +957,16 @@ Executed at: {executed_at}"#,
if let Some(stdout) = if let Some(stdout) =
output.stdout_if_present().take_if(|s| !s.trim().is_empty()) output.stdout_if_present().take_if(|s| !s.trim().is_empty())
{ {
println!("STDOUT:\n{stdout}\n"); eprintln!("STDOUT:\n{stdout}\n");
} }
if let Some(stderr) = if let Some(stderr) =
output.stderr_if_present().take_if(|s| !s.trim().is_empty()) output.stderr_if_present().take_if(|s| !s.trim().is_empty())
{ {
println!("STDERR:\n{stderr}\n"); eprintln!("STDERR:\n{stderr}\n");
} }
println!("Command {command:?} has failed. Rerun with -v to see more details."); eprintln!("Command {command:?} has failed. Rerun with -v to see more details.");
} else { } else {
println!("Command has failed. Rerun with -v to see more details."); eprintln!("Command has failed. Rerun with -v to see more details.");
} }
} }
exit!(1); exit!(1);
@ -1011,7 +1011,7 @@ Executed at: {executed_at}"#,
match self.config.dry_run { match self.config.dry_run {
DryRun::SelfCheck => (), DryRun::SelfCheck => (),
DryRun::Disabled | DryRun::UserSelected => { DryRun::Disabled | DryRun::UserSelected => {
println!("{msg}"); eprintln!("{msg}");
} }
} }
} }
@ -1666,7 +1666,7 @@ Executed at: {executed_at}"#,
if self.config.dry_run() { if self.config.dry_run() {
return; return;
} }
self.verbose_than(1, || println!("Copy/Link {src:?} to {dst:?}")); self.verbose_than(1, || eprintln!("Copy/Link {src:?} to {dst:?}"));
if src == dst { if src == dst {
return; return;
} }
@ -1775,7 +1775,7 @@ Executed at: {executed_at}"#,
return; return;
} }
let dst = dstdir.join(src.file_name().unwrap()); let dst = dstdir.join(src.file_name().unwrap());
self.verbose_than(1, || println!("Install {src:?} to {dst:?}")); self.verbose_than(1, || eprintln!("Install {src:?} to {dst:?}"));
t!(fs::create_dir_all(dstdir)); t!(fs::create_dir_all(dstdir));
if !src.exists() { if !src.exists() {
panic!("ERROR: File \"{}\" not found!", src.display()); panic!("ERROR: File \"{}\" not found!", src.display());

View File

@ -155,15 +155,15 @@ pub fn find_target(build: &Build, target: TargetSelection) {
build.cxx.borrow_mut().insert(target, compiler); build.cxx.borrow_mut().insert(target, compiler);
} }
build.verbose(|| println!("CC_{} = {:?}", target.triple, build.cc(target))); build.verbose(|| eprintln!("CC_{} = {:?}", target.triple, build.cc(target)));
build.verbose(|| println!("CFLAGS_{} = {cflags:?}", target.triple)); build.verbose(|| eprintln!("CFLAGS_{} = {cflags:?}", target.triple));
if let Ok(cxx) = build.cxx(target) { if let Ok(cxx) = build.cxx(target) {
let cxxflags = build.cflags(target, GitRepo::Rustc, CLang::Cxx); let cxxflags = build.cflags(target, GitRepo::Rustc, CLang::Cxx);
build.verbose(|| println!("CXX_{} = {cxx:?}", target.triple)); build.verbose(|| eprintln!("CXX_{} = {cxx:?}", target.triple));
build.verbose(|| println!("CXXFLAGS_{} = {cxxflags:?}", target.triple)); build.verbose(|| eprintln!("CXXFLAGS_{} = {cxxflags:?}", target.triple));
} }
if let Some(ar) = ar { if let Some(ar) = ar {
build.verbose(|| println!("AR_{} = {ar:?}", target.triple)); build.verbose(|| eprintln!("AR_{} = {ar:?}", target.triple));
build.ar.borrow_mut().insert(target, ar); build.ar.borrow_mut().insert(target, ar);
} }

View File

@ -135,7 +135,7 @@ impl Drop for TimeIt {
fn drop(&mut self) { fn drop(&mut self) {
let time = self.1.elapsed(); let time = self.1.elapsed();
if !self.0 { if !self.0 {
println!("\tfinished in {}.{:03} seconds", time.as_secs(), time.subsec_millis()); eprintln!("\tfinished in {}.{:03} seconds", time.as_secs(), time.subsec_millis());
} }
} }
} }
@ -267,12 +267,12 @@ pub fn check_run(cmd: &mut BootstrapCommand, print_cmd_on_fail: bool) -> bool {
let status = match cmd.as_command_mut().status() { let status = match cmd.as_command_mut().status() {
Ok(status) => status, Ok(status) => status,
Err(e) => { Err(e) => {
println!("failed to execute command: {cmd:?}\nERROR: {e}"); eprintln!("failed to execute command: {cmd:?}\nERROR: {e}");
return false; return false;
} }
}; };
if !status.success() && print_cmd_on_fail { if !status.success() && print_cmd_on_fail {
println!( eprintln!(
"\n\ncommand did not execute successfully: {cmd:?}\n\ "\n\ncommand did not execute successfully: {cmd:?}\n\
expected success, got: {status}\n\n" expected success, got: {status}\n\n"
); );

View File

@ -184,7 +184,7 @@ impl BuildMetrics {
if version.format_version == CURRENT_FORMAT_VERSION { if version.format_version == CURRENT_FORMAT_VERSION {
t!(serde_json::from_slice::<JsonRoot>(&contents)).invocations t!(serde_json::from_slice::<JsonRoot>(&contents)).invocations
} else { } else {
println!( eprintln!(
"WARNING: overriding existing build/metrics.json, as it's not \ "WARNING: overriding existing build/metrics.json, as it's not \
compatible with build metrics format version {CURRENT_FORMAT_VERSION}." compatible with build metrics format version {CURRENT_FORMAT_VERSION}."
); );

View File

@ -56,7 +56,7 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut BootstrapCommand, stream: bool) ->
let cmd = cmd.as_command_mut(); let cmd = cmd.as_command_mut();
cmd.stdout(Stdio::piped()); cmd.stdout(Stdio::piped());
builder.verbose(|| println!("running: {cmd:?}")); builder.verbose(|| eprintln!("running: {cmd:?}"));
let mut process = cmd.spawn().unwrap(); let mut process = cmd.spawn().unwrap();
@ -71,7 +71,7 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut BootstrapCommand, stream: bool) ->
let result = process.wait_with_output().unwrap(); let result = process.wait_with_output().unwrap();
if !result.status.success() && builder.is_verbose() { if !result.status.success() && builder.is_verbose() {
println!( eprintln!(
"\n\ncommand did not execute successfully: {cmd:?}\n\ "\n\ncommand did not execute successfully: {cmd:?}\n\
expected success, got: {}", expected success, got: {}",
result.status result.status
@ -135,7 +135,9 @@ impl<'a> Renderer<'a> {
if self.up_to_date_tests > 0 { if self.up_to_date_tests > 0 {
let n = self.up_to_date_tests; let n = self.up_to_date_tests;
let s = if n > 1 { "s" } else { "" }; let s = if n > 1 { "s" } else { "" };
println!("help: ignored {n} up-to-date test{s}; use `--force-rerun` to prevent this\n"); eprintln!(
"help: ignored {n} up-to-date test{s}; use `--force-rerun` to prevent this\n"
);
} }
} }
@ -190,7 +192,7 @@ impl<'a> Renderer<'a> {
if let Some(exec_time) = test.exec_time { if let Some(exec_time) = test.exec_time {
print!(" ({exec_time:.2?})"); print!(" ({exec_time:.2?})");
} }
println!(); eprintln!();
} }
fn render_test_outcome_terse(&mut self, outcome: Outcome<'_>, test: &TestOutcome) { fn render_test_outcome_terse(&mut self, outcome: Outcome<'_>, test: &TestOutcome) {
@ -200,7 +202,7 @@ impl<'a> Renderer<'a> {
let executed = format!("{:>width$}", self.executed_tests - 1, width = total.len()); let executed = format!("{:>width$}", self.executed_tests - 1, width = total.len());
print!(" {executed}/{total}"); print!(" {executed}/{total}");
} }
println!(); eprintln!();
self.terse_tests_in_line = 0; self.terse_tests_in_line = 0;
} }
@ -212,31 +214,31 @@ impl<'a> Renderer<'a> {
fn render_suite_outcome(&self, outcome: Outcome<'_>, suite: &SuiteOutcome) { fn render_suite_outcome(&self, outcome: Outcome<'_>, suite: &SuiteOutcome) {
// The terse output doesn't end with a newline, so we need to add it ourselves. // The terse output doesn't end with a newline, so we need to add it ourselves.
if !self.builder.config.verbose_tests { if !self.builder.config.verbose_tests {
println!(); eprintln!();
} }
if !self.failures.is_empty() { if !self.failures.is_empty() {
println!("\nfailures:\n"); eprintln!("\nfailures:\n");
for failure in &self.failures { for failure in &self.failures {
if failure.stdout.is_some() || failure.message.is_some() { if failure.stdout.is_some() || failure.message.is_some() {
println!("---- {} stdout ----", failure.name); eprintln!("---- {} stdout ----", failure.name);
if let Some(stdout) = &failure.stdout { if let Some(stdout) = &failure.stdout {
println!("{stdout}"); eprintln!("{stdout}");
} }
if let Some(message) = &failure.message { if let Some(message) = &failure.message {
println!("NOTE: {message}"); eprintln!("NOTE: {message}");
} }
} }
} }
println!("\nfailures:"); eprintln!("\nfailures:");
for failure in &self.failures { for failure in &self.failures {
println!(" {}", failure.name); eprintln!(" {}", failure.name);
} }
} }
if !self.benches.is_empty() { if !self.benches.is_empty() {
println!("\nbenchmarks:"); eprintln!("\nbenchmarks:");
let mut rows = Vec::new(); let mut rows = Vec::new();
for bench in &self.benches { for bench in &self.benches {
@ -251,13 +253,13 @@ impl<'a> Renderer<'a> {
let max_1 = rows.iter().map(|r| r.1.len()).max().unwrap_or(0); let max_1 = rows.iter().map(|r| r.1.len()).max().unwrap_or(0);
let max_2 = rows.iter().map(|r| r.2.len()).max().unwrap_or(0); let max_2 = rows.iter().map(|r| r.2.len()).max().unwrap_or(0);
for row in &rows { for row in &rows {
println!(" {:<max_0$} {:>max_1$} {:>max_2$}", row.0, row.1, row.2); eprintln!(" {:<max_0$} {:>max_1$} {:>max_2$}", row.0, row.1, row.2);
} }
} }
print!("\ntest result: "); print!("\ntest result: ");
self.builder.colored_stdout(|stdout| outcome.write_long(stdout)).unwrap(); self.builder.colored_stdout(|stdout| outcome.write_long(stdout)).unwrap();
println!( eprintln!(
". {} passed; {} failed; {} ignored; {} measured; {} filtered out{time}\n", ". {} passed; {} failed; {} ignored; {} measured; {} filtered out{time}\n",
suite.passed, suite.passed,
suite.failed, suite.failed,
@ -274,7 +276,7 @@ impl<'a> Renderer<'a> {
fn render_message(&mut self, message: Message) { fn render_message(&mut self, message: Message) {
match message { match message {
Message::Suite(SuiteMessage::Started { test_count }) => { Message::Suite(SuiteMessage::Started { test_count }) => {
println!("\nrunning {test_count} tests"); eprintln!("\nrunning {test_count} tests");
self.executed_tests = 0; self.executed_tests = 0;
self.terse_tests_in_line = 0; self.terse_tests_in_line = 0;
self.tests_count = Some(test_count); self.tests_count = Some(test_count);
@ -314,7 +316,7 @@ impl<'a> Renderer<'a> {
self.failures.push(outcome); self.failures.push(outcome);
} }
Message::Test(TestMessage::Timeout { name }) => { Message::Test(TestMessage::Timeout { name }) => {
println!("test {name} has been running for a long time"); eprintln!("test {name} has been running for a long time");
} }
Message::Test(TestMessage::Started) => {} // Not useful Message::Test(TestMessage::Started) => {} // Not useful
} }

View File

@ -344,7 +344,7 @@ impl<'a> Tarball<'a> {
// For `x install` tarball files aren't needed, so we can speed up the process by not producing them. // For `x install` tarball files aren't needed, so we can speed up the process by not producing them.
let compression_profile = if self.builder.kind == Kind::Install { let compression_profile = if self.builder.kind == Kind::Install {
self.builder.verbose(|| { self.builder.verbose(|| {
println!("Forcing dist.compression-profile = 'no-op' for `x install`.") eprintln!("Forcing dist.compression-profile = 'no-op' for `x install`.")
}); });
// "no-op" indicates that the rust-installer won't produce compressed tarball sources. // "no-op" indicates that the rust-installer won't produce compressed tarball sources.
"no-op" "no-op"

View File

@ -17,17 +17,18 @@ pub(crate) trait FormatRenderer<'tcx>: Sized {
/// ///
/// This is true for html, and false for json. See #80664 /// This is true for html, and false for json. See #80664
const RUN_ON_MODULE: bool; const RUN_ON_MODULE: bool;
/// This associated type is the type where the current module information is stored. /// This associated type is the type where the current module information is stored.
/// ///
/// For each module, we go through their items by calling for each item: /// For each module, we go through their items by calling for each item:
/// ///
/// 1. save_module_data /// 1. `save_module_data`
/// 2. item /// 2. `item`
/// 3. set_back_info /// 3. `restore_module_data`
/// ///
/// However,the `item` method might update information in `self` (for example if the child is /// This is because the `item` method might update information in `self` (for example if the child
/// a module). To prevent it to impact the other children of the current module, we need to /// is a module). To prevent it from impacting the other children of the current module, we need to
/// reset the information between each call to `item` by using `set_back_info`. /// reset the information between each call to `item` by using `restore_module_data`.
type ModuleData; type ModuleData;
/// Sets up any state required for the renderer. When this is called the cache has already been /// Sets up any state required for the renderer. When this is called the cache has already been
@ -41,18 +42,18 @@ pub(crate) trait FormatRenderer<'tcx>: Sized {
/// This method is called right before call [`Self::item`]. This method returns a type /// This method is called right before call [`Self::item`]. This method returns a type
/// containing information that needs to be reset after the [`Self::item`] method has been /// containing information that needs to be reset after the [`Self::item`] method has been
/// called with the [`Self::set_back_info`] method. /// called with the [`Self::restore_module_data`] method.
/// ///
/// In short it goes like this: /// In short it goes like this:
/// ///
/// ```ignore (not valid code) /// ```ignore (not valid code)
/// let reset_data = type.save_module_data(); /// let reset_data = renderer.save_module_data();
/// type.item(item)?; /// renderer.item(item)?;
/// type.set_back_info(reset_data); /// renderer.restore_module_data(reset_data);
/// ``` /// ```
fn save_module_data(&mut self) -> Self::ModuleData; fn save_module_data(&mut self) -> Self::ModuleData;
/// Used to reset current module's information. /// Used to reset current module's information.
fn set_back_info(&mut self, info: Self::ModuleData); fn restore_module_data(&mut self, info: Self::ModuleData);
/// Renders a single non-module item. This means no recursive sub-item rendering is required. /// Renders a single non-module item. This means no recursive sub-item rendering is required.
fn item(&mut self, item: clean::Item) -> Result<(), Error>; fn item(&mut self, item: clean::Item) -> Result<(), Error>;
@ -91,7 +92,7 @@ fn run_format_inner<'tcx, T: FormatRenderer<'tcx>>(
for it in module.items { for it in module.items {
let info = cx.save_module_data(); let info = cx.save_module_data();
run_format_inner(cx, it, prof)?; run_format_inner(cx, it, prof)?;
cx.set_back_info(info); cx.restore_module_data(info);
} }
cx.mod_item_out()?; cx.mod_item_out()?;

View File

@ -601,7 +601,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
self.info self.info
} }
fn set_back_info(&mut self, info: Self::ModuleData) { fn restore_module_data(&mut self, info: Self::ModuleData) {
self.info = info; self.info = info;
} }

View File

@ -9,7 +9,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_hir::def_id::LOCAL_CRATE; use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_session::Session; use rustc_session::Session;
use rustc_span::{FileName, sym}; use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, sym};
use tracing::info; use tracing::info;
use crate::clean; use crate::clean;
@ -50,8 +50,14 @@ struct LocalSourcesCollector<'a, 'tcx> {
src_root: &'a Path, src_root: &'a Path,
} }
fn is_real_and_local(span: clean::Span, sess: &Session) -> bool { fn filename_real_and_local(span: clean::Span, sess: &Session) -> Option<RealFileName> {
span.cnum(sess) == LOCAL_CRATE && span.filename(sess).is_real() if span.cnum(sess) == LOCAL_CRATE
&& let FileName::Real(file) = span.filename(sess)
{
Some(file)
} else {
None
}
} }
impl LocalSourcesCollector<'_, '_> { impl LocalSourcesCollector<'_, '_> {
@ -60,16 +66,8 @@ impl LocalSourcesCollector<'_, '_> {
let span = item.span(self.tcx); let span = item.span(self.tcx);
let Some(span) = span else { return }; let Some(span) = span else { return };
// skip all synthetic "files" // skip all synthetic "files"
if !is_real_and_local(span, sess) { let Some(p) = filename_real_and_local(span, sess).and_then(|file| file.into_local_path())
return; else {
}
let filename = span.filename(sess);
let p = if let FileName::Real(file) = filename {
match file.into_local_path() {
Some(p) => p,
None => return,
}
} else {
return; return;
}; };
if self.local_sources.contains_key(&*p) { if self.local_sources.contains_key(&*p) {
@ -135,8 +133,7 @@ impl DocVisitor<'_> for SourceCollector<'_, '_> {
// If we're not rendering sources, there's nothing to do. // If we're not rendering sources, there's nothing to do.
// If we're including source files, and we haven't seen this file yet, // If we're including source files, and we haven't seen this file yet,
// then we need to render it out to the filesystem. // then we need to render it out to the filesystem.
if is_real_and_local(span, sess) { if let Some(filename) = filename_real_and_local(span, sess) {
let filename = span.filename(sess);
let span = span.inner(); let span = span.inner();
let pos = sess.source_map().lookup_source_file(span.lo()); let pos = sess.source_map().lookup_source_file(span.lo());
let file_span = span.with_lo(pos.start_pos).with_hi(pos.end_position()); let file_span = span.with_lo(pos.start_pos).with_hi(pos.end_position());
@ -152,7 +149,7 @@ impl DocVisitor<'_> for SourceCollector<'_, '_> {
span, span,
format!( format!(
"failed to render source code for `{filename}`: {e}", "failed to render source code for `{filename}`: {e}",
filename = filename.prefer_local(), filename = filename.to_string_lossy(FileNameDisplayPreference::Local),
), ),
); );
false false
@ -168,18 +165,13 @@ impl SourceCollector<'_, '_> {
/// Renders the given filename into its corresponding HTML source file. /// Renders the given filename into its corresponding HTML source file.
fn emit_source( fn emit_source(
&mut self, &mut self,
filename: &FileName, file: &RealFileName,
file_span: rustc_span::Span, file_span: rustc_span::Span,
) -> Result<(), Error> { ) -> Result<(), Error> {
let p = match *filename { let p = if let Some(local_path) = file.local_path() {
FileName::Real(ref file) => { local_path.to_path_buf()
if let Some(local_path) = file.local_path() { } else {
local_path.to_path_buf() unreachable!("only the current crate should have sources emitted");
} else {
unreachable!("only the current crate should have sources emitted");
}
}
_ => return Ok(()),
}; };
if self.emitted_local_sources.contains(&*p) { if self.emitted_local_sources.contains(&*p) {
// We've already emitted this source // We've already emitted this source
@ -233,8 +225,10 @@ impl SourceCollector<'_, '_> {
cur.push(&fname); cur.push(&fname);
let title = format!("{} - source", src_fname.to_string_lossy()); let title = format!("{} - source", src_fname.to_string_lossy());
let desc = let desc = format!(
format!("Source of the Rust file `{}`.", filename.prefer_remapped_unconditionaly()); "Source of the Rust file `{}`.",
file.to_string_lossy(FileNameDisplayPreference::Remapped)
);
let page = layout::Page { let page = layout::Page {
title: &title, title: &title,
css_class: "src", css_class: "src",

View File

@ -163,11 +163,10 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
} }
fn save_module_data(&mut self) -> Self::ModuleData { fn save_module_data(&mut self) -> Self::ModuleData {
unreachable!("RUN_ON_MODULE = false should never call save_module_data") unreachable!("RUN_ON_MODULE = false, should never call save_module_data")
} }
fn restore_module_data(&mut self, _info: Self::ModuleData) {
fn set_back_info(&mut self, _info: Self::ModuleData) { unreachable!("RUN_ON_MODULE = false, should never call set_back_info")
unreachable!("RUN_ON_MODULE = false should never call set_back_info")
} }
/// Inserts an item into the index. This should be used rather than directly calling insert on /// Inserts an item into the index. This should be used rather than directly calling insert on
@ -248,7 +247,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
} }
fn mod_item_in(&mut self, _item: &clean::Item) -> Result<(), Error> { fn mod_item_in(&mut self, _item: &clean::Item) -> Result<(), Error> {
unreachable!("RUN_ON_MODULE = false should never call mod_item_in") unreachable!("RUN_ON_MODULE = false, should never call mod_item_in")
} }
fn after_krate(&mut self) -> Result<(), Error> { fn after_krate(&mut self) -> Result<(), Error> {

View File

@ -144,7 +144,7 @@ where
} }
if !wrote_data { if !wrote_data {
println!("note: diff is identical to nightly rustdoc"); eprintln!("note: diff is identical to nightly rustdoc");
assert!(diff_output.metadata().unwrap().len() == 0); assert!(diff_output.metadata().unwrap().len() == 0);
return false; return false;
} else if verbose { } else if verbose {

View File

@ -20,7 +20,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
} }
if config.remote_test_client.is_some() && !config.target.contains("android") { if config.remote_test_client.is_some() && !config.target.contains("android") {
println!( eprintln!(
"WARNING: debuginfo tests are not available when \ "WARNING: debuginfo tests are not available when \
testing with remote" testing with remote"
); );
@ -28,7 +28,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
} }
if config.target.contains("android") { if config.target.contains("android") {
println!( eprintln!(
"{} debug-info test uses tcp 5039 port.\ "{} debug-info test uses tcp 5039 port.\
please reserve it", please reserve it",
config.target config.target
@ -50,7 +50,7 @@ pub(crate) fn configure_lldb(config: &Config) -> Option<Arc<Config>> {
config.lldb_python_dir.as_ref()?; config.lldb_python_dir.as_ref()?;
if let Some(350) = config.lldb_version { if let Some(350) = config.lldb_version {
println!( eprintln!(
"WARNING: The used version of LLDB (350) has a \ "WARNING: The used version of LLDB (350) has a \
known issue that breaks debuginfo tests. See \ known issue that breaks debuginfo tests. See \
issue #32520 for more information. Skipping all \ issue #32520 for more information. Skipping all \

View File

@ -188,8 +188,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
let (argv0, args_) = args.split_first().unwrap(); let (argv0, args_) = args.split_first().unwrap();
if args.len() == 1 || args[1] == "-h" || args[1] == "--help" { if args.len() == 1 || args[1] == "-h" || args[1] == "--help" {
let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0); let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
println!("{}", opts.usage(&message)); eprintln!("{}", opts.usage(&message));
println!(); eprintln!();
panic!() panic!()
} }
@ -200,8 +200,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
if matches.opt_present("h") || matches.opt_present("help") { if matches.opt_present("h") || matches.opt_present("help") {
let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0); let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
println!("{}", opts.usage(&message)); eprintln!("{}", opts.usage(&message));
println!(); eprintln!();
panic!() panic!()
} }
@ -501,7 +501,7 @@ pub fn run_tests(config: Arc<Config>) {
// easy to miss which tests failed, and as such fail to reproduce // easy to miss which tests failed, and as such fail to reproduce
// the failure locally. // the failure locally.
println!( eprintln!(
"Some tests failed in compiletest suite={}{} mode={} host={} target={}", "Some tests failed in compiletest suite={}{} mode={} host={} target={}",
config.suite, config.suite,
config config

View File

@ -774,20 +774,20 @@ impl<'test> TestCx<'test> {
unexpected.len(), unexpected.len(),
not_found.len() not_found.len()
)); ));
println!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline); eprintln!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline);
if !unexpected.is_empty() { if !unexpected.is_empty() {
println!("{}", "--- unexpected errors (from JSON output) ---".green()); eprintln!("{}", "--- unexpected errors (from JSON output) ---".green());
for error in &unexpected { for error in &unexpected {
println!("{}", error.render_for_expected()); eprintln!("{}", error.render_for_expected());
} }
println!("{}", "---".green()); eprintln!("{}", "---".green());
} }
if !not_found.is_empty() { if !not_found.is_empty() {
println!("{}", "--- not found errors (from test file) ---".red()); eprintln!("{}", "--- not found errors (from test file) ---".red());
for error in &not_found { for error in &not_found {
println!("{}", error.render_for_expected()); eprintln!("{}", error.render_for_expected());
} }
println!("{}", "---\n".red()); eprintln!("{}", "---\n".red());
} }
panic!("errors differ from expected"); panic!("errors differ from expected");
} }
@ -1876,18 +1876,18 @@ impl<'test> TestCx<'test> {
fn maybe_dump_to_stdout(&self, out: &str, err: &str) { fn maybe_dump_to_stdout(&self, out: &str, err: &str) {
if self.config.verbose { if self.config.verbose {
println!("------stdout------------------------------"); eprintln!("------stdout------------------------------");
println!("{}", out); eprintln!("{}", out);
println!("------stderr------------------------------"); eprintln!("------stderr------------------------------");
println!("{}", err); eprintln!("{}", err);
println!("------------------------------------------"); eprintln!("------------------------------------------");
} }
} }
fn error(&self, err: &str) { fn error(&self, err: &str) {
match self.revision { match self.revision {
Some(rev) => println!("\nerror in revision `{}`: {}", rev, err), Some(rev) => eprintln!("\nerror in revision `{}`: {}", rev, err),
None => println!("\nerror: {}", err), None => eprintln!("\nerror: {}", err),
} }
} }
@ -1972,7 +1972,7 @@ impl<'test> TestCx<'test> {
if !self.config.has_html_tidy { if !self.config.has_html_tidy {
return; return;
} }
println!("info: generating a diff against nightly rustdoc"); eprintln!("info: generating a diff against nightly rustdoc");
let suffix = let suffix =
self.safe_revision().map_or("nightly".into(), |path| path.to_owned() + "-nightly"); self.safe_revision().map_or("nightly".into(), |path| path.to_owned() + "-nightly");
@ -2082,7 +2082,7 @@ impl<'test> TestCx<'test> {
.output() .output()
.unwrap(); .unwrap();
assert!(output.status.success()); assert!(output.status.success());
println!("{}", String::from_utf8_lossy(&output.stdout)); eprintln!("{}", String::from_utf8_lossy(&output.stdout));
eprintln!("{}", String::from_utf8_lossy(&output.stderr)); eprintln!("{}", String::from_utf8_lossy(&output.stderr));
} else { } else {
use colored::Colorize; use colored::Colorize;
@ -2482,7 +2482,7 @@ impl<'test> TestCx<'test> {
)"# )"#
) )
.replace_all(&output, |caps: &Captures<'_>| { .replace_all(&output, |caps: &Captures<'_>| {
println!("{}", &caps[0]); eprintln!("{}", &caps[0]);
caps[0].replace(r"\", "/") caps[0].replace(r"\", "/")
}) })
.replace("\r\n", "\n") .replace("\r\n", "\n")
@ -2581,16 +2581,16 @@ impl<'test> TestCx<'test> {
if let Err(err) = fs::write(&actual_path, &actual) { if let Err(err) = fs::write(&actual_path, &actual) {
self.fatal(&format!("failed to write {stream} to `{actual_path:?}`: {err}",)); self.fatal(&format!("failed to write {stream} to `{actual_path:?}`: {err}",));
} }
println!("Saved the actual {stream} to {actual_path:?}"); eprintln!("Saved the actual {stream} to {actual_path:?}");
let expected_path = let expected_path =
expected_output_path(self.testpaths, self.revision, &self.config.compare_mode, stream); expected_output_path(self.testpaths, self.revision, &self.config.compare_mode, stream);
if !self.config.bless { if !self.config.bless {
if expected.is_empty() { if expected.is_empty() {
println!("normalized {}:\n{}\n", stream, actual); eprintln!("normalized {}:\n{}\n", stream, actual);
} else { } else {
println!("diff of {stream}:\n"); eprintln!("diff of {stream}:\n");
if let Some(diff_command) = self.config.diff_command.as_deref() { if let Some(diff_command) = self.config.diff_command.as_deref() {
let mut args = diff_command.split_whitespace(); let mut args = diff_command.split_whitespace();
let name = args.next().unwrap(); let name = args.next().unwrap();
@ -2625,10 +2625,10 @@ impl<'test> TestCx<'test> {
if let Err(err) = fs::write(&expected_path, &actual) { if let Err(err) = fs::write(&expected_path, &actual) {
self.fatal(&format!("failed to write {stream} to `{expected_path:?}`: {err}")); self.fatal(&format!("failed to write {stream} to `{expected_path:?}`: {err}"));
} }
println!("Blessing the {stream} of {test_name} in {expected_path:?}"); eprintln!("Blessing the {stream} of {test_name} in {expected_path:?}");
} }
println!("\nThe actual {0} differed from the expected {0}.", stream); eprintln!("\nThe actual {0} differed from the expected {0}.", stream);
if self.config.bless { 0 } else { 1 } if self.config.bless { 0 } else { 1 }
} }
@ -2707,7 +2707,7 @@ impl<'test> TestCx<'test> {
fs::create_dir_all(&incremental_dir).unwrap(); fs::create_dir_all(&incremental_dir).unwrap();
if self.config.verbose { if self.config.verbose {
println!("init_incremental_test: incremental_dir={}", incremental_dir.display()); eprintln!("init_incremental_test: incremental_dir={}", incremental_dir.display());
} }
} }
@ -2765,7 +2765,7 @@ impl ProcRes {
} }
} }
println!( eprintln!(
"status: {}\ncommand: {}\n{}\n{}\n", "status: {}\ncommand: {}\n{}\n{}\n",
self.status, self.status,
self.cmdline, self.cmdline,
@ -2776,7 +2776,7 @@ impl ProcRes {
pub fn fatal(&self, err: Option<&str>, on_failure: impl FnOnce()) -> ! { pub fn fatal(&self, err: Option<&str>, on_failure: impl FnOnce()) -> ! {
if let Some(e) = err { if let Some(e) = err {
println!("\nerror: {}", e); eprintln!("\nerror: {}", e);
} }
self.print_info(); self.print_info();
on_failure(); on_failure();

View File

@ -64,13 +64,13 @@ impl TestCx<'_> {
if !missing.is_empty() { if !missing.is_empty() {
missing.sort(); missing.sort();
println!("\nThese items should have been contained but were not:\n"); eprintln!("\nThese items should have been contained but were not:\n");
for item in &missing { for item in &missing {
println!("{}", item); eprintln!("{}", item);
} }
println!("\n"); eprintln!("\n");
} }
if !unexpected.is_empty() { if !unexpected.is_empty() {
@ -80,24 +80,24 @@ impl TestCx<'_> {
sorted sorted
}; };
println!("\nThese items were contained but should not have been:\n"); eprintln!("\nThese items were contained but should not have been:\n");
for item in sorted { for item in sorted {
println!("{}", item); eprintln!("{}", item);
} }
println!("\n"); eprintln!("\n");
} }
if !wrong_cgus.is_empty() { if !wrong_cgus.is_empty() {
wrong_cgus.sort_by_key(|pair| pair.0.name.clone()); wrong_cgus.sort_by_key(|pair| pair.0.name.clone());
println!("\nThe following items were assigned to wrong codegen units:\n"); eprintln!("\nThe following items were assigned to wrong codegen units:\n");
for &(ref expected_item, ref actual_item) in &wrong_cgus { for &(ref expected_item, ref actual_item) in &wrong_cgus {
println!("{}", expected_item.name); eprintln!("{}", expected_item.name);
println!(" expected: {}", codegen_units_to_str(&expected_item.codegen_units)); eprintln!(" expected: {}", codegen_units_to_str(&expected_item.codegen_units));
println!(" actual: {}", codegen_units_to_str(&actual_item.codegen_units)); eprintln!(" actual: {}", codegen_units_to_str(&actual_item.codegen_units));
println!(); eprintln!();
} }
} }

View File

@ -260,7 +260,7 @@ impl TestCx<'_> {
cmdline, cmdline,
}; };
if adb.kill().is_err() { if adb.kill().is_err() {
println!("Adb process is already finished."); eprintln!("Adb process is already finished.");
} }
} else { } else {
let rust_src_root = let rust_src_root =
@ -275,7 +275,7 @@ impl TestCx<'_> {
match self.config.gdb_version { match self.config.gdb_version {
Some(version) => { Some(version) => {
println!("NOTE: compiletest thinks it is using GDB version {}", version); eprintln!("NOTE: compiletest thinks it is using GDB version {}", version);
if version > extract_gdb_version("7.4").unwrap() { if version > extract_gdb_version("7.4").unwrap() {
// Add the directory containing the pretty printers to // Add the directory containing the pretty printers to
@ -297,7 +297,7 @@ impl TestCx<'_> {
} }
} }
_ => { _ => {
println!( eprintln!(
"NOTE: compiletest does not know which version of \ "NOTE: compiletest does not know which version of \
GDB it is using" GDB it is using"
); );
@ -392,10 +392,10 @@ impl TestCx<'_> {
match self.config.lldb_version { match self.config.lldb_version {
Some(ref version) => { Some(ref version) => {
println!("NOTE: compiletest thinks it is using LLDB version {}", version); eprintln!("NOTE: compiletest thinks it is using LLDB version {}", version);
} }
_ => { _ => {
println!( eprintln!(
"NOTE: compiletest does not know which version of \ "NOTE: compiletest does not know which version of \
LLDB it is using" LLDB it is using"
); );

View File

@ -29,7 +29,7 @@ impl TestCx<'_> {
if !res.status.success() { if !res.status.success() {
self.fatal_proc_rec_with_ctx("jsondocck failed!", &res, |_| { self.fatal_proc_rec_with_ctx("jsondocck failed!", &res, |_| {
println!("Rustdoc Output:"); eprintln!("Rustdoc Output:");
proc_res.print_info(); proc_res.print_info();
}) })
} }

View File

@ -109,10 +109,10 @@ impl TestCx<'_> {
} }
if errors > 0 { if errors > 0 {
println!("To update references, rerun the tests and pass the `--bless` flag"); eprintln!("To update references, rerun the tests and pass the `--bless` flag");
let relative_path_to_file = let relative_path_to_file =
self.testpaths.relative_dir.join(self.testpaths.file.file_name().unwrap()); self.testpaths.relative_dir.join(self.testpaths.file.file_name().unwrap());
println!( eprintln!(
"To only update this specific test, also pass `--test-args {}`", "To only update this specific test, also pass `--test-args {}`",
relative_path_to_file.display(), relative_path_to_file.display(),
); );

View File

@ -30,7 +30,7 @@ fn path_div() -> &'static str {
pub fn logv(config: &Config, s: String) { pub fn logv(config: &Config, s: String) {
debug!("{}", s); debug!("{}", s);
if config.verbose { if config.verbose {
println!("{}", s); eprintln!("{}", s);
} }
} }

View File

@ -38,7 +38,7 @@ const IGNORE_UI_TEST_CHECK: &[&str] =
macro_rules! verbose_print { macro_rules! verbose_print {
($verbose:expr, $($fmt:tt)*) => { ($verbose:expr, $($fmt:tt)*) => {
if $verbose { if $verbose {
println!("{}", format_args!($($fmt)*)); eprintln!("{}", format_args!($($fmt)*));
} }
}; };
} }
@ -49,8 +49,8 @@ pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut
// Stage 1: create list // Stage 1: create list
let error_codes = extract_error_codes(root_path, &mut errors); let error_codes = extract_error_codes(root_path, &mut errors);
if verbose { if verbose {
println!("Found {} error codes", error_codes.len()); eprintln!("Found {} error codes", error_codes.len());
println!("Highest error code: `{}`", error_codes.iter().max().unwrap()); eprintln!("Highest error code: `{}`", error_codes.iter().max().unwrap());
} }
// Stage 2: check list has docs // Stage 2: check list has docs

View File

@ -158,14 +158,14 @@ pub fn check(
.collect::<Vec<_>>(); .collect::<Vec<_>>();
for &(name, _) in gate_untested.iter() { for &(name, _) in gate_untested.iter() {
println!("Expected a gate test for the feature '{name}'."); eprintln!("Expected a gate test for the feature '{name}'.");
println!( eprintln!(
"Hint: create a failing test file named 'tests/ui/feature-gates/feature-gate-{}.rs',\ "Hint: create a failing test file named 'tests/ui/feature-gates/feature-gate-{}.rs',\
\n with its failures due to missing usage of `#![feature({})]`.", \n with its failures due to missing usage of `#![feature({})]`.",
name.replace("_", "-"), name.replace("_", "-"),
name name
); );
println!( eprintln!(
"Hint: If you already have such a test and don't want to rename it,\ "Hint: If you already have such a test and don't want to rename it,\
\n you can also add a // gate-test-{} line to the test file.", \n you can also add a // gate-test-{} line to the test file.",
name name
@ -218,7 +218,7 @@ pub fn check(
lines.sort(); lines.sort();
for line in lines { for line in lines {
println!("* {line}"); eprintln!("* {line}");
} }
} }

View File

@ -118,16 +118,16 @@ pub fn check(path: &Path, features: CollectedFeatures, bad: &mut bool) {
// List unstable features that don't have Unstable Book sections. // List unstable features that don't have Unstable Book sections.
// Remove the comment marker if you want the list printed. // Remove the comment marker if you want the list printed.
/* /*
println!("Lib features without unstable book sections:"); eprintln!("Lib features without unstable book sections:");
for feature_name in &unstable_lang_feature_names - for feature_name in &unstable_lang_feature_names -
&unstable_book_lang_features_section_file_names { &unstable_book_lang_features_section_file_names {
println!(" * {} {:?}", feature_name, lib_features[&feature_name].tracking_issue); eprintln!(" * {} {:?}", feature_name, lib_features[&feature_name].tracking_issue);
} }
println!("Lang features without unstable book sections:"); eprintln!("Lang features without unstable book sections:");
for feature_name in &unstable_lib_feature_names- for feature_name in &unstable_lib_feature_names-
&unstable_book_lib_features_section_file_names { &unstable_book_lib_features_section_file_names {
println!(" * {} {:?}", feature_name, lang_features[&feature_name].tracking_issue); eprintln!(" * {} {:?}", feature_name, lang_features[&feature_name].tracking_issue);
} }
// */ // */
} }

View File

@ -42,7 +42,7 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) {
if let Some(expected) = get_x_wrapper_version(root, cargo) { if let Some(expected) = get_x_wrapper_version(root, cargo) {
if installed < expected { if installed < expected {
return println!( return eprintln!(
"Current version of x is {installed}, but the latest version is {expected}\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`" "Current version of x is {installed}, but the latest version is {expected}\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`"
); );
} }

View File

@ -31,7 +31,6 @@
} }
} }
scope 9 (inlined NonNull::<[u8]>::as_ptr) { scope 9 (inlined NonNull::<[u8]>::as_ptr) {
let mut _17: *const [u8];
} }
} }
scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) { scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) {
@ -102,16 +101,9 @@
StorageDead(_16); StorageDead(_16);
StorageDead(_12); StorageDead(_12);
StorageDead(_6); StorageDead(_6);
- StorageLive(_17); _4 = copy _5 as *mut [u8] (Transmute);
+ nop;
_17 = copy (_5.0: *const [u8]);
- _4 = move _17 as *mut [u8] (PtrToPtr);
- StorageDead(_17);
+ _4 = copy _17 as *mut [u8] (PtrToPtr);
+ nop;
StorageDead(_5); StorageDead(_5);
- _3 = move _4 as *mut u8 (PtrToPtr); _3 = move _4 as *mut u8 (PtrToPtr);
+ _3 = copy _17 as *mut u8 (PtrToPtr);
StorageDead(_4); StorageDead(_4);
StorageDead(_3); StorageDead(_3);
- StorageDead(_1); - StorageDead(_1);

View File

@ -20,7 +20,6 @@
scope 5 (inlined <std::alloc::Global as Allocator>::allocate) { scope 5 (inlined <std::alloc::Global as Allocator>::allocate) {
} }
scope 6 (inlined NonNull::<[u8]>::as_ptr) { scope 6 (inlined NonNull::<[u8]>::as_ptr) {
let mut _12: *const [u8];
} }
} }
scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) { scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) {
@ -45,16 +44,9 @@
bb1: { bb1: {
StorageDead(_6); StorageDead(_6);
- StorageLive(_12); _4 = copy _5 as *mut [u8] (Transmute);
+ nop;
_12 = copy (_5.0: *const [u8]);
- _4 = move _12 as *mut [u8] (PtrToPtr);
- StorageDead(_12);
+ _4 = copy _12 as *mut [u8] (PtrToPtr);
+ nop;
StorageDead(_5); StorageDead(_5);
- _3 = move _4 as *mut u8 (PtrToPtr); _3 = move _4 as *mut u8 (PtrToPtr);
+ _3 = copy _12 as *mut u8 (PtrToPtr);
StorageDead(_4); StorageDead(_4);
StorageDead(_3); StorageDead(_3);
- StorageDead(_1); - StorageDead(_1);

View File

@ -31,7 +31,6 @@
} }
} }
scope 9 (inlined NonNull::<[u8]>::as_ptr) { scope 9 (inlined NonNull::<[u8]>::as_ptr) {
let mut _17: *const [u8];
} }
} }
scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) { scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) {
@ -102,16 +101,9 @@
StorageDead(_16); StorageDead(_16);
StorageDead(_12); StorageDead(_12);
StorageDead(_6); StorageDead(_6);
- StorageLive(_17); _4 = copy _5 as *mut [u8] (Transmute);
+ nop;
_17 = copy (_5.0: *const [u8]);
- _4 = move _17 as *mut [u8] (PtrToPtr);
- StorageDead(_17);
+ _4 = copy _17 as *mut [u8] (PtrToPtr);
+ nop;
StorageDead(_5); StorageDead(_5);
- _3 = move _4 as *mut u8 (PtrToPtr); _3 = move _4 as *mut u8 (PtrToPtr);
+ _3 = copy _17 as *mut u8 (PtrToPtr);
StorageDead(_4); StorageDead(_4);
StorageDead(_3); StorageDead(_3);
- StorageDead(_1); - StorageDead(_1);

View File

@ -20,7 +20,6 @@
scope 5 (inlined <std::alloc::Global as Allocator>::allocate) { scope 5 (inlined <std::alloc::Global as Allocator>::allocate) {
} }
scope 6 (inlined NonNull::<[u8]>::as_ptr) { scope 6 (inlined NonNull::<[u8]>::as_ptr) {
let mut _12: *const [u8];
} }
} }
scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) { scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) {
@ -45,16 +44,9 @@
bb1: { bb1: {
StorageDead(_6); StorageDead(_6);
- StorageLive(_12); _4 = copy _5 as *mut [u8] (Transmute);
+ nop;
_12 = copy (_5.0: *const [u8]);
- _4 = move _12 as *mut [u8] (PtrToPtr);
- StorageDead(_12);
+ _4 = copy _12 as *mut [u8] (PtrToPtr);
+ nop;
StorageDead(_5); StorageDead(_5);
- _3 = move _4 as *mut u8 (PtrToPtr); _3 = move _4 as *mut u8 (PtrToPtr);
+ _3 = copy _12 as *mut u8 (PtrToPtr);
StorageDead(_4); StorageDead(_4);
StorageDead(_3); StorageDead(_3);
- StorageDead(_1); - StorageDead(_1);

View File

@ -4,28 +4,28 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
debug slice => _1; debug slice => _1;
debug f => _2; debug f => _2;
let mut _0: (); let mut _0: ();
let mut _11: std::slice::Iter<'_, T>; let mut _13: std::slice::Iter<'_, T>;
let mut _12: std::iter::Enumerate<std::slice::Iter<'_, T>>; let mut _14: std::iter::Enumerate<std::slice::Iter<'_, T>>;
let mut _13: std::iter::Enumerate<std::slice::Iter<'_, T>>; let mut _15: std::iter::Enumerate<std::slice::Iter<'_, T>>;
let mut _21: std::option::Option<(usize, &T)>; let mut _23: std::option::Option<(usize, &T)>;
let mut _24: &impl Fn(usize, &T); let mut _26: &impl Fn(usize, &T);
let mut _25: (usize, &T); let mut _27: (usize, &T);
let _26: (); let _28: ();
scope 1 { scope 1 {
debug iter => _13; debug iter => _15;
let _22: usize; let _24: usize;
let _23: &T; let _25: &T;
scope 2 { scope 2 {
debug i => _22; debug i => _24;
debug x => _23; debug x => _25;
} }
scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) { scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
let mut _14: &mut std::slice::Iter<'_, T>; let mut _16: &mut std::slice::Iter<'_, T>;
let mut _15: std::option::Option<&T>; let mut _17: std::option::Option<&T>;
let mut _19: (usize, bool); let mut _21: (usize, bool);
let mut _20: (usize, &T); let mut _22: (usize, &T);
scope 19 { scope 19 {
let _18: usize; let _20: usize;
scope 24 { scope 24 {
} }
} }
@ -40,8 +40,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
} }
} }
scope 25 (inlined <Option<&T> as Try>::branch) { scope 25 (inlined <Option<&T> as Try>::branch) {
let mut _16: isize; let mut _18: isize;
let _17: &T; let _19: &T;
scope 26 { scope 26 {
} }
} }
@ -50,13 +50,14 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
scope 3 (inlined core::slice::<impl [T]>::iter) { scope 3 (inlined core::slice::<impl [T]>::iter) {
scope 4 (inlined std::slice::Iter::<'_, T>::new) { scope 4 (inlined std::slice::Iter::<'_, T>::new) {
let _3: usize; let _3: usize;
let mut _7: *mut T; let mut _5: std::ptr::NonNull<[T]>;
let mut _8: *mut T; let mut _9: *mut T;
let mut _10: *const T; let mut _10: *mut T;
let mut _12: *const T;
scope 5 { scope 5 {
let _6: std::ptr::NonNull<T>; let _8: std::ptr::NonNull<T>;
scope 6 { scope 6 {
let _9: *const T; let _11: *const T;
scope 7 { scope 7 {
} }
scope 12 (inlined without_provenance::<T>) { scope 12 (inlined without_provenance::<T>) {
@ -72,7 +73,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
} }
} }
scope 10 (inlined NonNull::<[T]>::cast::<T>) { scope 10 (inlined NonNull::<[T]>::cast::<T>) {
let mut _5: *const T; let mut _6: *mut [T];
let mut _7: *const T;
scope 11 (inlined NonNull::<[T]>::as_ptr) { scope 11 (inlined NonNull::<[T]>::as_ptr) {
} }
} }
@ -87,76 +89,82 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
} }
bb0: { bb0: {
StorageLive(_11); StorageLive(_13);
StorageLive(_3); StorageLive(_3);
StorageLive(_6); StorageLive(_8);
StorageLive(_4);
StorageLive(_5);
_3 = PtrMetadata(copy _1); _3 = PtrMetadata(copy _1);
StorageLive(_5);
StorageLive(_4);
_4 = &raw const (*_1); _4 = &raw const (*_1);
_5 = copy _4 as *const T (PtrToPtr); _5 = NonNull::<[T]> { pointer: move _4 };
_6 = NonNull::<T> { pointer: copy _5 }; StorageDead(_4);
StorageLive(_9); StorageLive(_6);
StorageLive(_7);
_6 = copy _5 as *mut [T] (Transmute);
_7 = copy _6 as *const T (PtrToPtr);
_8 = NonNull::<T> { pointer: move _7 };
StorageDead(_7);
StorageDead(_6);
StorageDead(_5);
StorageLive(_11);
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2]; switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
} }
bb1: { bb1: {
StorageLive(_8); StorageLive(_10);
StorageLive(_7); StorageLive(_9);
_7 = copy _4 as *mut T (PtrToPtr); _9 = copy _8 as *mut T (Transmute);
_8 = Offset(copy _7, copy _3); _10 = Offset(copy _9, copy _3);
StorageDead(_7); StorageDead(_9);
_9 = move _8 as *const T (PtrToPtr); _11 = move _10 as *const T (PtrToPtr);
StorageDead(_8); StorageDead(_10);
goto -> bb3; goto -> bb3;
} }
bb2: { bb2: {
_9 = copy _3 as *const T (Transmute); _11 = copy _3 as *const T (Transmute);
goto -> bb3; goto -> bb3;
} }
bb3: { bb3: {
StorageLive(_10); StorageLive(_12);
_10 = copy _9; _12 = copy _11;
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
StorageDead(_10); StorageDead(_12);
StorageDead(_9);
StorageDead(_5);
StorageDead(_4);
StorageDead(_6);
StorageDead(_3);
_12 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _11, count: const 0_usize };
StorageDead(_11); StorageDead(_11);
StorageLive(_13); StorageDead(_8);
_13 = copy _12; StorageDead(_3);
_14 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _13, count: const 0_usize };
StorageDead(_13);
StorageLive(_15);
_15 = copy _14;
goto -> bb4; goto -> bb4;
} }
bb4: { bb4: {
StorageLive(_23);
StorageLive(_20);
StorageLive(_21); StorageLive(_21);
StorageLive(_18); StorageLive(_17);
StorageLive(_19); StorageLive(_16);
StorageLive(_15); _16 = &mut (_15.0: std::slice::Iter<'_, T>);
StorageLive(_14); _17 = <std::slice::Iter<'_, T> as Iterator>::next(move _16) -> [return: bb5, unwind unreachable];
_14 = &mut (_13.0: std::slice::Iter<'_, T>);
_15 = <std::slice::Iter<'_, T> as Iterator>::next(move _14) -> [return: bb5, unwind unreachable];
} }
bb5: { bb5: {
StorageDead(_14); StorageDead(_16);
StorageLive(_16); StorageLive(_18);
_16 = discriminant(_15); _18 = discriminant(_17);
switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb11]; switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb11];
} }
bb6: { bb6: {
StorageDead(_16);
StorageDead(_15);
StorageDead(_19);
StorageDead(_18); StorageDead(_18);
StorageDead(_17);
StorageDead(_21); StorageDead(_21);
StorageDead(_13); StorageDead(_20);
StorageDead(_23);
StorageDead(_15);
drop(_2) -> [return: bb7, unwind unreachable]; drop(_2) -> [return: bb7, unwind unreachable];
} }
@ -165,35 +173,35 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
} }
bb8: { bb8: {
_17 = move ((_15 as Some).0: &T); _19 = move ((_17 as Some).0: &T);
StorageDead(_16); StorageDead(_18);
StorageDead(_15); StorageDead(_17);
_18 = copy (_13.1: usize); _20 = copy (_15.1: usize);
_19 = AddWithOverflow(copy (_13.1: usize), const 1_usize); _21 = AddWithOverflow(copy (_15.1: usize), const 1_usize);
assert(!move (_19.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_13.1: usize), const 1_usize) -> [success: bb9, unwind unreachable]; assert(!move (_21.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_15.1: usize), const 1_usize) -> [success: bb9, unwind unreachable];
} }
bb9: { bb9: {
(_13.1: usize) = move (_19.0: usize); (_15.1: usize) = move (_21.0: usize);
StorageLive(_20); StorageLive(_22);
_20 = (copy _18, copy _17); _22 = (copy _20, copy _19);
_21 = Option::<(usize, &T)>::Some(move _20); _23 = Option::<(usize, &T)>::Some(move _22);
StorageDead(_22);
StorageDead(_21);
StorageDead(_20); StorageDead(_20);
StorageDead(_19); _24 = copy (((_23 as Some).0: (usize, &T)).0: usize);
StorageDead(_18); _25 = copy (((_23 as Some).0: (usize, &T)).1: &T);
_22 = copy (((_21 as Some).0: (usize, &T)).0: usize); StorageLive(_26);
_23 = copy (((_21 as Some).0: (usize, &T)).1: &T); _26 = &_2;
StorageLive(_24); StorageLive(_27);
_24 = &_2; _27 = (copy _24, copy _25);
StorageLive(_25); _28 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _26, move _27) -> [return: bb10, unwind unreachable];
_25 = (copy _22, copy _23);
_26 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _24, move _25) -> [return: bb10, unwind unreachable];
} }
bb10: { bb10: {
StorageDead(_25); StorageDead(_27);
StorageDead(_24); StorageDead(_26);
StorageDead(_21); StorageDead(_23);
goto -> bb4; goto -> bb4;
} }

View File

@ -4,34 +4,35 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
debug slice => _1; debug slice => _1;
debug f => _2; debug f => _2;
let mut _0: (); let mut _0: ();
let mut _11: std::slice::Iter<'_, T>; let mut _13: std::slice::Iter<'_, T>;
let mut _12: std::iter::Enumerate<std::slice::Iter<'_, T>>; let mut _14: std::iter::Enumerate<std::slice::Iter<'_, T>>;
let mut _13: std::iter::Enumerate<std::slice::Iter<'_, T>>; let mut _15: std::iter::Enumerate<std::slice::Iter<'_, T>>;
let mut _14: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>; let mut _16: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
let mut _15: std::option::Option<(usize, &T)>; let mut _17: std::option::Option<(usize, &T)>;
let mut _16: isize; let mut _18: isize;
let mut _19: &impl Fn(usize, &T); let mut _21: &impl Fn(usize, &T);
let mut _20: (usize, &T); let mut _22: (usize, &T);
let _21: (); let _23: ();
scope 1 { scope 1 {
debug iter => _13; debug iter => _15;
let _17: usize; let _19: usize;
let _18: &T; let _20: &T;
scope 2 { scope 2 {
debug i => _17; debug i => _19;
debug x => _18; debug x => _20;
} }
} }
scope 3 (inlined core::slice::<impl [T]>::iter) { scope 3 (inlined core::slice::<impl [T]>::iter) {
scope 4 (inlined std::slice::Iter::<'_, T>::new) { scope 4 (inlined std::slice::Iter::<'_, T>::new) {
let _3: usize; let _3: usize;
let mut _7: *mut T; let mut _5: std::ptr::NonNull<[T]>;
let mut _8: *mut T; let mut _9: *mut T;
let mut _10: *const T; let mut _10: *mut T;
let mut _12: *const T;
scope 5 { scope 5 {
let _6: std::ptr::NonNull<T>; let _8: std::ptr::NonNull<T>;
scope 6 { scope 6 {
let _9: *const T; let _11: *const T;
scope 7 { scope 7 {
} }
scope 12 (inlined without_provenance::<T>) { scope 12 (inlined without_provenance::<T>) {
@ -47,7 +48,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
} }
} }
scope 10 (inlined NonNull::<[T]>::cast::<T>) { scope 10 (inlined NonNull::<[T]>::cast::<T>) {
let mut _5: *const T; let mut _6: *mut [T];
let mut _7: *const T;
scope 11 (inlined NonNull::<[T]>::as_ptr) { scope 11 (inlined NonNull::<[T]>::as_ptr) {
} }
} }
@ -62,66 +64,72 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
} }
bb0: { bb0: {
StorageLive(_11); StorageLive(_13);
StorageLive(_3); StorageLive(_3);
StorageLive(_6); StorageLive(_8);
StorageLive(_4);
StorageLive(_5);
_3 = PtrMetadata(copy _1); _3 = PtrMetadata(copy _1);
StorageLive(_5);
StorageLive(_4);
_4 = &raw const (*_1); _4 = &raw const (*_1);
_5 = copy _4 as *const T (PtrToPtr); _5 = NonNull::<[T]> { pointer: move _4 };
_6 = NonNull::<T> { pointer: copy _5 }; StorageDead(_4);
StorageLive(_9); StorageLive(_6);
StorageLive(_7);
_6 = copy _5 as *mut [T] (Transmute);
_7 = copy _6 as *const T (PtrToPtr);
_8 = NonNull::<T> { pointer: move _7 };
StorageDead(_7);
StorageDead(_6);
StorageDead(_5);
StorageLive(_11);
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2]; switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
} }
bb1: { bb1: {
StorageLive(_8); StorageLive(_10);
StorageLive(_7); StorageLive(_9);
_7 = copy _4 as *mut T (PtrToPtr); _9 = copy _8 as *mut T (Transmute);
_8 = Offset(copy _7, copy _3); _10 = Offset(copy _9, copy _3);
StorageDead(_7); StorageDead(_9);
_9 = move _8 as *const T (PtrToPtr); _11 = move _10 as *const T (PtrToPtr);
StorageDead(_8); StorageDead(_10);
goto -> bb3; goto -> bb3;
} }
bb2: { bb2: {
_9 = copy _3 as *const T (Transmute); _11 = copy _3 as *const T (Transmute);
goto -> bb3; goto -> bb3;
} }
bb3: { bb3: {
StorageLive(_10); StorageLive(_12);
_10 = copy _9; _12 = copy _11;
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
StorageDead(_10); StorageDead(_12);
StorageDead(_9);
StorageDead(_5);
StorageDead(_4);
StorageDead(_6);
StorageDead(_3);
_12 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _11, count: const 0_usize };
StorageDead(_11); StorageDead(_11);
StorageLive(_13); StorageDead(_8);
_13 = copy _12; StorageDead(_3);
_14 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _13, count: const 0_usize };
StorageDead(_13);
StorageLive(_15);
_15 = copy _14;
goto -> bb4; goto -> bb4;
} }
bb4: { bb4: {
StorageLive(_15); StorageLive(_17);
_14 = &mut _13; _16 = &mut _15;
_15 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _14) -> [return: bb5, unwind: bb11]; _17 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _16) -> [return: bb5, unwind: bb11];
} }
bb5: { bb5: {
_16 = discriminant(_15); _18 = discriminant(_17);
switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
} }
bb6: { bb6: {
StorageDead(_17);
StorageDead(_15); StorageDead(_15);
StorageDead(_13);
drop(_2) -> [return: bb7, unwind continue]; drop(_2) -> [return: bb7, unwind continue];
} }
@ -130,19 +138,19 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
} }
bb8: { bb8: {
_17 = copy (((_15 as Some).0: (usize, &T)).0: usize); _19 = copy (((_17 as Some).0: (usize, &T)).0: usize);
_18 = copy (((_15 as Some).0: (usize, &T)).1: &T); _20 = copy (((_17 as Some).0: (usize, &T)).1: &T);
StorageLive(_19); StorageLive(_21);
_19 = &_2; _21 = &_2;
StorageLive(_20); StorageLive(_22);
_20 = (copy _17, copy _18); _22 = (copy _19, copy _20);
_21 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _19, move _20) -> [return: bb9, unwind: bb11]; _23 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _21, move _22) -> [return: bb9, unwind: bb11];
} }
bb9: { bb9: {
StorageDead(_20); StorageDead(_22);
StorageDead(_19); StorageDead(_21);
StorageDead(_15); StorageDead(_17);
goto -> bb4; goto -> bb4;
} }

View File

@ -4,31 +4,32 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
debug slice => _1; debug slice => _1;
debug f => _2; debug f => _2;
let mut _0: (); let mut _0: ();
let mut _11: std::slice::Iter<'_, T>; let mut _13: std::slice::Iter<'_, T>;
let mut _12: std::slice::Iter<'_, T>; let mut _14: std::slice::Iter<'_, T>;
let mut _13: &mut std::slice::Iter<'_, T>; let mut _15: &mut std::slice::Iter<'_, T>;
let mut _14: std::option::Option<&T>; let mut _16: std::option::Option<&T>;
let mut _15: isize; let mut _17: isize;
let mut _17: &impl Fn(&T); let mut _19: &impl Fn(&T);
let mut _18: (&T,); let mut _20: (&T,);
let _19: (); let _21: ();
scope 1 { scope 1 {
debug iter => _12; debug iter => _14;
let _16: &T; let _18: &T;
scope 2 { scope 2 {
debug x => _16; debug x => _18;
} }
} }
scope 3 (inlined core::slice::<impl [T]>::iter) { scope 3 (inlined core::slice::<impl [T]>::iter) {
scope 4 (inlined std::slice::Iter::<'_, T>::new) { scope 4 (inlined std::slice::Iter::<'_, T>::new) {
let _3: usize; let _3: usize;
let mut _7: *mut T; let mut _5: std::ptr::NonNull<[T]>;
let mut _8: *mut T; let mut _9: *mut T;
let mut _10: *const T; let mut _10: *mut T;
let mut _12: *const T;
scope 5 { scope 5 {
let _6: std::ptr::NonNull<T>; let _8: std::ptr::NonNull<T>;
scope 6 { scope 6 {
let _9: *const T; let _11: *const T;
scope 7 { scope 7 {
} }
scope 12 (inlined without_provenance::<T>) { scope 12 (inlined without_provenance::<T>) {
@ -44,7 +45,8 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
} }
} }
scope 10 (inlined NonNull::<[T]>::cast::<T>) { scope 10 (inlined NonNull::<[T]>::cast::<T>) {
let mut _5: *const T; let mut _6: *mut [T];
let mut _7: *const T;
scope 11 (inlined NonNull::<[T]>::as_ptr) { scope 11 (inlined NonNull::<[T]>::as_ptr) {
} }
} }
@ -56,62 +58,68 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
bb0: { bb0: {
StorageLive(_3); StorageLive(_3);
StorageLive(_6); StorageLive(_8);
StorageLive(_4);
StorageLive(_5);
_3 = PtrMetadata(copy _1); _3 = PtrMetadata(copy _1);
StorageLive(_5);
StorageLive(_4);
_4 = &raw const (*_1); _4 = &raw const (*_1);
_5 = copy _4 as *const T (PtrToPtr); _5 = NonNull::<[T]> { pointer: move _4 };
_6 = NonNull::<T> { pointer: copy _5 }; StorageDead(_4);
StorageLive(_9); StorageLive(_6);
StorageLive(_7);
_6 = copy _5 as *mut [T] (Transmute);
_7 = copy _6 as *const T (PtrToPtr);
_8 = NonNull::<T> { pointer: move _7 };
StorageDead(_7);
StorageDead(_6);
StorageDead(_5);
StorageLive(_11);
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2]; switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
} }
bb1: { bb1: {
StorageLive(_8); StorageLive(_10);
StorageLive(_7); StorageLive(_9);
_7 = copy _4 as *mut T (PtrToPtr); _9 = copy _8 as *mut T (Transmute);
_8 = Offset(copy _7, copy _3); _10 = Offset(copy _9, copy _3);
StorageDead(_7); StorageDead(_9);
_9 = move _8 as *const T (PtrToPtr); _11 = move _10 as *const T (PtrToPtr);
StorageDead(_8); StorageDead(_10);
goto -> bb3; goto -> bb3;
} }
bb2: { bb2: {
_9 = copy _3 as *const T (Transmute); _11 = copy _3 as *const T (Transmute);
goto -> bb3; goto -> bb3;
} }
bb3: { bb3: {
StorageLive(_10);
_10 = copy _9;
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
StorageDead(_10);
StorageDead(_9);
StorageDead(_5);
StorageDead(_4);
StorageDead(_6);
StorageDead(_3);
StorageLive(_12); StorageLive(_12);
_12 = copy _11; _12 = copy _11;
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
StorageDead(_12);
StorageDead(_11);
StorageDead(_8);
StorageDead(_3);
StorageLive(_14);
_14 = copy _13;
goto -> bb4; goto -> bb4;
} }
bb4: { bb4: {
StorageLive(_14); StorageLive(_16);
_13 = &mut _12; _15 = &mut _14;
_14 = <std::slice::Iter<'_, T> as Iterator>::next(move _13) -> [return: bb5, unwind unreachable]; _16 = <std::slice::Iter<'_, T> as Iterator>::next(move _15) -> [return: bb5, unwind unreachable];
} }
bb5: { bb5: {
_15 = discriminant(_14); _17 = discriminant(_16);
switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10];
} }
bb6: { bb6: {
StorageDead(_16);
StorageDead(_14); StorageDead(_14);
StorageDead(_12);
drop(_2) -> [return: bb7, unwind unreachable]; drop(_2) -> [return: bb7, unwind unreachable];
} }
@ -120,18 +128,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
} }
bb8: { bb8: {
_16 = copy ((_14 as Some).0: &T); _18 = copy ((_16 as Some).0: &T);
StorageLive(_17); StorageLive(_19);
_17 = &_2; _19 = &_2;
StorageLive(_18); StorageLive(_20);
_18 = (copy _16,); _20 = (copy _18,);
_19 = <impl Fn(&T) as Fn<(&T,)>>::call(move _17, move _18) -> [return: bb9, unwind unreachable]; _21 = <impl Fn(&T) as Fn<(&T,)>>::call(move _19, move _20) -> [return: bb9, unwind unreachable];
} }
bb9: { bb9: {
StorageDead(_18); StorageDead(_20);
StorageDead(_17); StorageDead(_19);
StorageDead(_14); StorageDead(_16);
goto -> bb4; goto -> bb4;
} }

View File

@ -4,31 +4,32 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
debug slice => _1; debug slice => _1;
debug f => _2; debug f => _2;
let mut _0: (); let mut _0: ();
let mut _11: std::slice::Iter<'_, T>; let mut _13: std::slice::Iter<'_, T>;
let mut _12: std::slice::Iter<'_, T>; let mut _14: std::slice::Iter<'_, T>;
let mut _13: &mut std::slice::Iter<'_, T>; let mut _15: &mut std::slice::Iter<'_, T>;
let mut _14: std::option::Option<&T>; let mut _16: std::option::Option<&T>;
let mut _15: isize; let mut _17: isize;
let mut _17: &impl Fn(&T); let mut _19: &impl Fn(&T);
let mut _18: (&T,); let mut _20: (&T,);
let _19: (); let _21: ();
scope 1 { scope 1 {
debug iter => _12; debug iter => _14;
let _16: &T; let _18: &T;
scope 2 { scope 2 {
debug x => _16; debug x => _18;
} }
} }
scope 3 (inlined core::slice::<impl [T]>::iter) { scope 3 (inlined core::slice::<impl [T]>::iter) {
scope 4 (inlined std::slice::Iter::<'_, T>::new) { scope 4 (inlined std::slice::Iter::<'_, T>::new) {
let _3: usize; let _3: usize;
let mut _7: *mut T; let mut _5: std::ptr::NonNull<[T]>;
let mut _8: *mut T; let mut _9: *mut T;
let mut _10: *const T; let mut _10: *mut T;
let mut _12: *const T;
scope 5 { scope 5 {
let _6: std::ptr::NonNull<T>; let _8: std::ptr::NonNull<T>;
scope 6 { scope 6 {
let _9: *const T; let _11: *const T;
scope 7 { scope 7 {
} }
scope 12 (inlined without_provenance::<T>) { scope 12 (inlined without_provenance::<T>) {
@ -44,7 +45,8 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
} }
} }
scope 10 (inlined NonNull::<[T]>::cast::<T>) { scope 10 (inlined NonNull::<[T]>::cast::<T>) {
let mut _5: *const T; let mut _6: *mut [T];
let mut _7: *const T;
scope 11 (inlined NonNull::<[T]>::as_ptr) { scope 11 (inlined NonNull::<[T]>::as_ptr) {
} }
} }
@ -56,62 +58,68 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
bb0: { bb0: {
StorageLive(_3); StorageLive(_3);
StorageLive(_6); StorageLive(_8);
StorageLive(_4);
StorageLive(_5);
_3 = PtrMetadata(copy _1); _3 = PtrMetadata(copy _1);
StorageLive(_5);
StorageLive(_4);
_4 = &raw const (*_1); _4 = &raw const (*_1);
_5 = copy _4 as *const T (PtrToPtr); _5 = NonNull::<[T]> { pointer: move _4 };
_6 = NonNull::<T> { pointer: copy _5 }; StorageDead(_4);
StorageLive(_9); StorageLive(_6);
StorageLive(_7);
_6 = copy _5 as *mut [T] (Transmute);
_7 = copy _6 as *const T (PtrToPtr);
_8 = NonNull::<T> { pointer: move _7 };
StorageDead(_7);
StorageDead(_6);
StorageDead(_5);
StorageLive(_11);
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2]; switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
} }
bb1: { bb1: {
StorageLive(_8); StorageLive(_10);
StorageLive(_7); StorageLive(_9);
_7 = copy _4 as *mut T (PtrToPtr); _9 = copy _8 as *mut T (Transmute);
_8 = Offset(copy _7, copy _3); _10 = Offset(copy _9, copy _3);
StorageDead(_7); StorageDead(_9);
_9 = move _8 as *const T (PtrToPtr); _11 = move _10 as *const T (PtrToPtr);
StorageDead(_8); StorageDead(_10);
goto -> bb3; goto -> bb3;
} }
bb2: { bb2: {
_9 = copy _3 as *const T (Transmute); _11 = copy _3 as *const T (Transmute);
goto -> bb3; goto -> bb3;
} }
bb3: { bb3: {
StorageLive(_10);
_10 = copy _9;
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
StorageDead(_10);
StorageDead(_9);
StorageDead(_5);
StorageDead(_4);
StorageDead(_6);
StorageDead(_3);
StorageLive(_12); StorageLive(_12);
_12 = copy _11; _12 = copy _11;
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
StorageDead(_12);
StorageDead(_11);
StorageDead(_8);
StorageDead(_3);
StorageLive(_14);
_14 = copy _13;
goto -> bb4; goto -> bb4;
} }
bb4: { bb4: {
StorageLive(_14); StorageLive(_16);
_13 = &mut _12; _15 = &mut _14;
_14 = <std::slice::Iter<'_, T> as Iterator>::next(move _13) -> [return: bb5, unwind: bb11]; _16 = <std::slice::Iter<'_, T> as Iterator>::next(move _15) -> [return: bb5, unwind: bb11];
} }
bb5: { bb5: {
_15 = discriminant(_14); _17 = discriminant(_16);
switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10];
} }
bb6: { bb6: {
StorageDead(_16);
StorageDead(_14); StorageDead(_14);
StorageDead(_12);
drop(_2) -> [return: bb7, unwind continue]; drop(_2) -> [return: bb7, unwind continue];
} }
@ -120,18 +128,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
} }
bb8: { bb8: {
_16 = copy ((_14 as Some).0: &T); _18 = copy ((_16 as Some).0: &T);
StorageLive(_17); StorageLive(_19);
_17 = &_2; _19 = &_2;
StorageLive(_18); StorageLive(_20);
_18 = (copy _16,); _20 = (copy _18,);
_19 = <impl Fn(&T) as Fn<(&T,)>>::call(move _17, move _18) -> [return: bb9, unwind: bb11]; _21 = <impl Fn(&T) as Fn<(&T,)>>::call(move _19, move _20) -> [return: bb9, unwind: bb11];
} }
bb9: { bb9: {
StorageDead(_18); StorageDead(_20);
StorageDead(_17); StorageDead(_19);
StorageDead(_14); StorageDead(_16);
goto -> bb4; goto -> bb4;
} }

View File

@ -4,34 +4,35 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
debug slice => _1; debug slice => _1;
debug f => _2; debug f => _2;
let mut _0: (); let mut _0: ();
let mut _11: std::slice::Iter<'_, T>; let mut _13: std::slice::Iter<'_, T>;
let mut _12: std::iter::Rev<std::slice::Iter<'_, T>>; let mut _14: std::iter::Rev<std::slice::Iter<'_, T>>;
let mut _13: std::iter::Rev<std::slice::Iter<'_, T>>; let mut _15: std::iter::Rev<std::slice::Iter<'_, T>>;
let mut _15: std::option::Option<&T>; let mut _17: std::option::Option<&T>;
let mut _16: isize; let mut _18: isize;
let mut _18: &impl Fn(&T); let mut _20: &impl Fn(&T);
let mut _19: (&T,); let mut _21: (&T,);
let _20: (); let _22: ();
scope 1 { scope 1 {
debug iter => _13; debug iter => _15;
let _17: &T; let _19: &T;
scope 2 { scope 2 {
debug x => _17; debug x => _19;
} }
scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) { scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
let mut _14: &mut std::slice::Iter<'_, T>; let mut _16: &mut std::slice::Iter<'_, T>;
} }
} }
scope 3 (inlined core::slice::<impl [T]>::iter) { scope 3 (inlined core::slice::<impl [T]>::iter) {
scope 4 (inlined std::slice::Iter::<'_, T>::new) { scope 4 (inlined std::slice::Iter::<'_, T>::new) {
let _3: usize; let _3: usize;
let mut _7: *mut T; let mut _5: std::ptr::NonNull<[T]>;
let mut _8: *mut T; let mut _9: *mut T;
let mut _10: *const T; let mut _10: *mut T;
let mut _12: *const T;
scope 5 { scope 5 {
let _6: std::ptr::NonNull<T>; let _8: std::ptr::NonNull<T>;
scope 6 { scope 6 {
let _9: *const T; let _11: *const T;
scope 7 { scope 7 {
} }
scope 12 (inlined without_provenance::<T>) { scope 12 (inlined without_provenance::<T>) {
@ -47,7 +48,8 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
} }
} }
scope 10 (inlined NonNull::<[T]>::cast::<T>) { scope 10 (inlined NonNull::<[T]>::cast::<T>) {
let mut _5: *const T; let mut _6: *mut [T];
let mut _7: *const T;
scope 11 (inlined NonNull::<[T]>::as_ptr) { scope 11 (inlined NonNull::<[T]>::as_ptr) {
} }
} }
@ -62,68 +64,74 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
} }
bb0: { bb0: {
StorageLive(_11); StorageLive(_13);
StorageLive(_3); StorageLive(_3);
StorageLive(_6); StorageLive(_8);
StorageLive(_4);
StorageLive(_5);
_3 = PtrMetadata(copy _1); _3 = PtrMetadata(copy _1);
StorageLive(_5);
StorageLive(_4);
_4 = &raw const (*_1); _4 = &raw const (*_1);
_5 = copy _4 as *const T (PtrToPtr); _5 = NonNull::<[T]> { pointer: move _4 };
_6 = NonNull::<T> { pointer: copy _5 }; StorageDead(_4);
StorageLive(_9); StorageLive(_6);
StorageLive(_7);
_6 = copy _5 as *mut [T] (Transmute);
_7 = copy _6 as *const T (PtrToPtr);
_8 = NonNull::<T> { pointer: move _7 };
StorageDead(_7);
StorageDead(_6);
StorageDead(_5);
StorageLive(_11);
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2]; switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
} }
bb1: { bb1: {
StorageLive(_8); StorageLive(_10);
StorageLive(_7); StorageLive(_9);
_7 = copy _4 as *mut T (PtrToPtr); _9 = copy _8 as *mut T (Transmute);
_8 = Offset(copy _7, copy _3); _10 = Offset(copy _9, copy _3);
StorageDead(_7); StorageDead(_9);
_9 = move _8 as *const T (PtrToPtr); _11 = move _10 as *const T (PtrToPtr);
StorageDead(_8); StorageDead(_10);
goto -> bb3; goto -> bb3;
} }
bb2: { bb2: {
_9 = copy _3 as *const T (Transmute); _11 = copy _3 as *const T (Transmute);
goto -> bb3; goto -> bb3;
} }
bb3: { bb3: {
StorageLive(_10); StorageLive(_12);
_10 = copy _9; _12 = copy _11;
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
StorageDead(_10); StorageDead(_12);
StorageDead(_9);
StorageDead(_5);
StorageDead(_4);
StorageDead(_6);
StorageDead(_3);
_12 = Rev::<std::slice::Iter<'_, T>> { iter: copy _11 };
StorageDead(_11); StorageDead(_11);
StorageLive(_13); StorageDead(_8);
_13 = copy _12; StorageDead(_3);
_14 = Rev::<std::slice::Iter<'_, T>> { iter: copy _13 };
StorageDead(_13);
StorageLive(_15);
_15 = copy _14;
goto -> bb4; goto -> bb4;
} }
bb4: { bb4: {
StorageLive(_15); StorageLive(_17);
StorageLive(_14); StorageLive(_16);
_14 = &mut (_13.0: std::slice::Iter<'_, T>); _16 = &mut (_15.0: std::slice::Iter<'_, T>);
_15 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind unreachable]; _17 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _16) -> [return: bb5, unwind unreachable];
} }
bb5: { bb5: {
StorageDead(_14); StorageDead(_16);
_16 = discriminant(_15); _18 = discriminant(_17);
switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
} }
bb6: { bb6: {
StorageDead(_17);
StorageDead(_15); StorageDead(_15);
StorageDead(_13);
drop(_2) -> [return: bb7, unwind unreachable]; drop(_2) -> [return: bb7, unwind unreachable];
} }
@ -132,18 +140,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
} }
bb8: { bb8: {
_17 = copy ((_15 as Some).0: &T); _19 = copy ((_17 as Some).0: &T);
StorageLive(_18); StorageLive(_20);
_18 = &_2; _20 = &_2;
StorageLive(_19); StorageLive(_21);
_19 = (copy _17,); _21 = (copy _19,);
_20 = <impl Fn(&T) as Fn<(&T,)>>::call(move _18, move _19) -> [return: bb9, unwind unreachable]; _22 = <impl Fn(&T) as Fn<(&T,)>>::call(move _20, move _21) -> [return: bb9, unwind unreachable];
} }
bb9: { bb9: {
StorageDead(_19); StorageDead(_21);
StorageDead(_18); StorageDead(_20);
StorageDead(_15); StorageDead(_17);
goto -> bb4; goto -> bb4;
} }

View File

@ -4,34 +4,35 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
debug slice => _1; debug slice => _1;
debug f => _2; debug f => _2;
let mut _0: (); let mut _0: ();
let mut _11: std::slice::Iter<'_, T>; let mut _13: std::slice::Iter<'_, T>;
let mut _12: std::iter::Rev<std::slice::Iter<'_, T>>; let mut _14: std::iter::Rev<std::slice::Iter<'_, T>>;
let mut _13: std::iter::Rev<std::slice::Iter<'_, T>>; let mut _15: std::iter::Rev<std::slice::Iter<'_, T>>;
let mut _15: std::option::Option<&T>; let mut _17: std::option::Option<&T>;
let mut _16: isize; let mut _18: isize;
let mut _18: &impl Fn(&T); let mut _20: &impl Fn(&T);
let mut _19: (&T,); let mut _21: (&T,);
let _20: (); let _22: ();
scope 1 { scope 1 {
debug iter => _13; debug iter => _15;
let _17: &T; let _19: &T;
scope 2 { scope 2 {
debug x => _17; debug x => _19;
} }
scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) { scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
let mut _14: &mut std::slice::Iter<'_, T>; let mut _16: &mut std::slice::Iter<'_, T>;
} }
} }
scope 3 (inlined core::slice::<impl [T]>::iter) { scope 3 (inlined core::slice::<impl [T]>::iter) {
scope 4 (inlined std::slice::Iter::<'_, T>::new) { scope 4 (inlined std::slice::Iter::<'_, T>::new) {
let _3: usize; let _3: usize;
let mut _7: *mut T; let mut _5: std::ptr::NonNull<[T]>;
let mut _8: *mut T; let mut _9: *mut T;
let mut _10: *const T; let mut _10: *mut T;
let mut _12: *const T;
scope 5 { scope 5 {
let _6: std::ptr::NonNull<T>; let _8: std::ptr::NonNull<T>;
scope 6 { scope 6 {
let _9: *const T; let _11: *const T;
scope 7 { scope 7 {
} }
scope 12 (inlined without_provenance::<T>) { scope 12 (inlined without_provenance::<T>) {
@ -47,7 +48,8 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
} }
} }
scope 10 (inlined NonNull::<[T]>::cast::<T>) { scope 10 (inlined NonNull::<[T]>::cast::<T>) {
let mut _5: *const T; let mut _6: *mut [T];
let mut _7: *const T;
scope 11 (inlined NonNull::<[T]>::as_ptr) { scope 11 (inlined NonNull::<[T]>::as_ptr) {
} }
} }
@ -62,68 +64,74 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
} }
bb0: { bb0: {
StorageLive(_11); StorageLive(_13);
StorageLive(_3); StorageLive(_3);
StorageLive(_6); StorageLive(_8);
StorageLive(_4);
StorageLive(_5);
_3 = PtrMetadata(copy _1); _3 = PtrMetadata(copy _1);
StorageLive(_5);
StorageLive(_4);
_4 = &raw const (*_1); _4 = &raw const (*_1);
_5 = copy _4 as *const T (PtrToPtr); _5 = NonNull::<[T]> { pointer: move _4 };
_6 = NonNull::<T> { pointer: copy _5 }; StorageDead(_4);
StorageLive(_9); StorageLive(_6);
StorageLive(_7);
_6 = copy _5 as *mut [T] (Transmute);
_7 = copy _6 as *const T (PtrToPtr);
_8 = NonNull::<T> { pointer: move _7 };
StorageDead(_7);
StorageDead(_6);
StorageDead(_5);
StorageLive(_11);
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2]; switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
} }
bb1: { bb1: {
StorageLive(_8); StorageLive(_10);
StorageLive(_7); StorageLive(_9);
_7 = copy _4 as *mut T (PtrToPtr); _9 = copy _8 as *mut T (Transmute);
_8 = Offset(copy _7, copy _3); _10 = Offset(copy _9, copy _3);
StorageDead(_7); StorageDead(_9);
_9 = move _8 as *const T (PtrToPtr); _11 = move _10 as *const T (PtrToPtr);
StorageDead(_8); StorageDead(_10);
goto -> bb3; goto -> bb3;
} }
bb2: { bb2: {
_9 = copy _3 as *const T (Transmute); _11 = copy _3 as *const T (Transmute);
goto -> bb3; goto -> bb3;
} }
bb3: { bb3: {
StorageLive(_10); StorageLive(_12);
_10 = copy _9; _12 = copy _11;
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
StorageDead(_10); StorageDead(_12);
StorageDead(_9);
StorageDead(_5);
StorageDead(_4);
StorageDead(_6);
StorageDead(_3);
_12 = Rev::<std::slice::Iter<'_, T>> { iter: copy _11 };
StorageDead(_11); StorageDead(_11);
StorageLive(_13); StorageDead(_8);
_13 = copy _12; StorageDead(_3);
_14 = Rev::<std::slice::Iter<'_, T>> { iter: copy _13 };
StorageDead(_13);
StorageLive(_15);
_15 = copy _14;
goto -> bb4; goto -> bb4;
} }
bb4: { bb4: {
StorageLive(_15); StorageLive(_17);
StorageLive(_14); StorageLive(_16);
_14 = &mut (_13.0: std::slice::Iter<'_, T>); _16 = &mut (_15.0: std::slice::Iter<'_, T>);
_15 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind: bb11]; _17 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _16) -> [return: bb5, unwind: bb11];
} }
bb5: { bb5: {
StorageDead(_14); StorageDead(_16);
_16 = discriminant(_15); _18 = discriminant(_17);
switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
} }
bb6: { bb6: {
StorageDead(_17);
StorageDead(_15); StorageDead(_15);
StorageDead(_13);
drop(_2) -> [return: bb7, unwind continue]; drop(_2) -> [return: bb7, unwind continue];
} }
@ -132,18 +140,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
} }
bb8: { bb8: {
_17 = copy ((_15 as Some).0: &T); _19 = copy ((_17 as Some).0: &T);
StorageLive(_18); StorageLive(_20);
_18 = &_2; _20 = &_2;
StorageLive(_19); StorageLive(_21);
_19 = (copy _17,); _21 = (copy _19,);
_20 = <impl Fn(&T) as Fn<(&T,)>>::call(move _18, move _19) -> [return: bb9, unwind: bb11]; _22 = <impl Fn(&T) as Fn<(&T,)>>::call(move _20, move _21) -> [return: bb9, unwind: bb11];
} }
bb9: { bb9: {
StorageDead(_19); StorageDead(_21);
StorageDead(_18); StorageDead(_20);
StorageDead(_15); StorageDead(_17);
goto -> bb4; goto -> bb4;
} }

View File

@ -15,11 +15,11 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
scope 4 { scope 4 {
scope 8 (inlined <NonNull<T> as PartialEq>::eq) { scope 8 (inlined <NonNull<T> as PartialEq>::eq) {
let mut _5: std::ptr::NonNull<T>; let mut _5: std::ptr::NonNull<T>;
let mut _6: *mut T;
let mut _7: *mut T;
scope 9 (inlined NonNull::<T>::as_ptr) { scope 9 (inlined NonNull::<T>::as_ptr) {
let mut _6: *const T;
} }
scope 10 (inlined NonNull::<T>::as_ptr) { scope 10 (inlined NonNull::<T>::as_ptr) {
let mut _7: *const T;
} }
} }
} }
@ -48,13 +48,13 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
_4 = copy (*_3); _4 = copy (*_3);
StorageDead(_3); StorageDead(_3);
StorageLive(_6); StorageLive(_6);
StorageLive(_7);
StorageLive(_5); StorageLive(_5);
_5 = copy ((*_1).0: std::ptr::NonNull<T>); _5 = copy ((*_1).0: std::ptr::NonNull<T>);
_6 = copy (_5.0: *const T); _6 = copy _5 as *mut T (Transmute);
StorageDead(_5); StorageDead(_5);
_7 = copy (_4.0: *const T); StorageLive(_7);
_0 = Eq(copy _6, copy _7); _7 = copy _4 as *mut T (Transmute);
_0 = Eq(move _6, move _7);
StorageDead(_7); StorageDead(_7);
StorageDead(_6); StorageDead(_6);
goto -> bb3; goto -> bb3;

View File

@ -15,11 +15,11 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
scope 4 { scope 4 {
scope 8 (inlined <NonNull<T> as PartialEq>::eq) { scope 8 (inlined <NonNull<T> as PartialEq>::eq) {
let mut _5: std::ptr::NonNull<T>; let mut _5: std::ptr::NonNull<T>;
let mut _6: *mut T;
let mut _7: *mut T;
scope 9 (inlined NonNull::<T>::as_ptr) { scope 9 (inlined NonNull::<T>::as_ptr) {
let mut _6: *const T;
} }
scope 10 (inlined NonNull::<T>::as_ptr) { scope 10 (inlined NonNull::<T>::as_ptr) {
let mut _7: *const T;
} }
} }
} }
@ -48,13 +48,13 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
_4 = copy (*_3); _4 = copy (*_3);
StorageDead(_3); StorageDead(_3);
StorageLive(_6); StorageLive(_6);
StorageLive(_7);
StorageLive(_5); StorageLive(_5);
_5 = copy ((*_1).0: std::ptr::NonNull<T>); _5 = copy ((*_1).0: std::ptr::NonNull<T>);
_6 = copy (_5.0: *const T); _6 = copy _5 as *mut T (Transmute);
StorageDead(_5); StorageDead(_5);
_7 = copy (_4.0: *const T); StorageLive(_7);
_0 = Eq(copy _6, copy _7); _7 = copy _4 as *mut T (Transmute);
_0 = Eq(move _6, move _7);
StorageDead(_7); StorageDead(_7);
StorageDead(_6); StorageDead(_6);
goto -> bb3; goto -> bb3;

View File

@ -7,16 +7,18 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
debug self => _1; debug self => _1;
scope 2 (inlined Vec::<u8>::as_slice) { scope 2 (inlined Vec::<u8>::as_slice) {
debug self => _1; debug self => _1;
let mut _7: usize; let mut _9: *const u8;
let mut _10: usize;
scope 3 (inlined Vec::<u8>::as_ptr) { scope 3 (inlined Vec::<u8>::as_ptr) {
debug self => _1; debug self => _1;
let mut _2: &alloc::raw_vec::RawVec<u8>; let mut _2: &alloc::raw_vec::RawVec<u8>;
let mut _8: *mut u8;
scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) { scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
debug self => _2; debug self => _2;
let mut _3: &alloc::raw_vec::RawVecInner; let mut _3: &alloc::raw_vec::RawVecInner;
scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) { scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
debug self => _3; debug self => _3;
let mut _6: std::ptr::NonNull<u8>; let mut _7: std::ptr::NonNull<u8>;
scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) { scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
debug self => _3; debug self => _3;
let mut _4: std::ptr::NonNull<u8>; let mut _4: std::ptr::NonNull<u8>;
@ -25,27 +27,28 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>; debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
scope 8 (inlined NonNull::<u8>::cast::<u8>) { scope 8 (inlined NonNull::<u8>::cast::<u8>) {
debug self => _4; debug self => _4;
let mut _5: *mut u8;
let mut _6: *const u8;
scope 9 (inlined NonNull::<u8>::as_ptr) { scope 9 (inlined NonNull::<u8>::as_ptr) {
debug self => _4; debug self => _4;
let mut _5: *const u8;
} }
} }
} }
scope 10 (inlined Unique::<u8>::as_non_null_ptr) { scope 10 (inlined Unique::<u8>::as_non_null_ptr) {
debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _6; debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _7;
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>; debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
} }
} }
scope 11 (inlined NonNull::<u8>::as_ptr) { scope 11 (inlined NonNull::<u8>::as_ptr) {
debug self => _6; debug self => _7;
} }
} }
} }
} }
scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) { scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
debug data => _5; debug data => _9;
debug len => _7; debug len => _10;
let _8: *const [u8]; let _11: *const [u8];
scope 13 (inlined core::ub_checks::check_language_ub) { scope 13 (inlined core::ub_checks::check_language_ub) {
scope 14 (inlined core::ub_checks::check_language_ub::runtime) { scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
} }
@ -55,11 +58,11 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
scope 16 (inlined align_of::<u8>) { scope 16 (inlined align_of::<u8>) {
} }
scope 17 (inlined slice_from_raw_parts::<u8>) { scope 17 (inlined slice_from_raw_parts::<u8>) {
debug data => _5; debug data => _9;
debug len => _7; debug len => _10;
scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) { scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
debug data_pointer => _5; debug data_pointer => _9;
debug metadata => _7; debug metadata => _10;
} }
} }
} }
@ -67,26 +70,37 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
} }
bb0: { bb0: {
StorageLive(_8);
StorageLive(_9);
StorageLive(_2); StorageLive(_2);
_2 = &((*_1).0: alloc::raw_vec::RawVec<u8>); _2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
StorageLive(_3); StorageLive(_3);
_3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner); _3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner);
StorageLive(_6); StorageLive(_7);
StorageLive(_4); StorageLive(_4);
_4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>); _4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
_5 = copy (_4.0: *const u8); StorageLive(_5);
_6 = NonNull::<u8> { pointer: copy _5 }; StorageLive(_6);
StorageDead(_4); _5 = copy _4 as *mut u8 (Transmute);
_6 = copy _5 as *const u8 (PtrToPtr);
_7 = NonNull::<u8> { pointer: move _6 };
StorageDead(_6); StorageDead(_6);
StorageDead(_3); StorageDead(_5);
StorageDead(_2); StorageDead(_4);
StorageLive(_7); _8 = copy _7 as *mut u8 (Transmute);
_7 = copy ((*_1).1: usize);
StorageLive(_8);
_8 = *const [u8] from (copy _5, copy _7);
_0 = &(*_8);
StorageDead(_8);
StorageDead(_7); StorageDead(_7);
StorageDead(_3);
_9 = copy _8 as *const u8 (PtrToPtr);
StorageDead(_2);
StorageLive(_10);
_10 = copy ((*_1).1: usize);
StorageLive(_11);
_11 = *const [u8] from (copy _9, copy _10);
_0 = &(*_11);
StorageDead(_11);
StorageDead(_10);
StorageDead(_9);
StorageDead(_8);
return; return;
} }
} }

View File

@ -7,16 +7,18 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
debug self => _1; debug self => _1;
scope 2 (inlined Vec::<u8>::as_slice) { scope 2 (inlined Vec::<u8>::as_slice) {
debug self => _1; debug self => _1;
let mut _7: usize; let mut _9: *const u8;
let mut _10: usize;
scope 3 (inlined Vec::<u8>::as_ptr) { scope 3 (inlined Vec::<u8>::as_ptr) {
debug self => _1; debug self => _1;
let mut _2: &alloc::raw_vec::RawVec<u8>; let mut _2: &alloc::raw_vec::RawVec<u8>;
let mut _8: *mut u8;
scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) { scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
debug self => _2; debug self => _2;
let mut _3: &alloc::raw_vec::RawVecInner; let mut _3: &alloc::raw_vec::RawVecInner;
scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) { scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
debug self => _3; debug self => _3;
let mut _6: std::ptr::NonNull<u8>; let mut _7: std::ptr::NonNull<u8>;
scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) { scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
debug self => _3; debug self => _3;
let mut _4: std::ptr::NonNull<u8>; let mut _4: std::ptr::NonNull<u8>;
@ -25,27 +27,28 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>; debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
scope 8 (inlined NonNull::<u8>::cast::<u8>) { scope 8 (inlined NonNull::<u8>::cast::<u8>) {
debug self => _4; debug self => _4;
let mut _5: *mut u8;
let mut _6: *const u8;
scope 9 (inlined NonNull::<u8>::as_ptr) { scope 9 (inlined NonNull::<u8>::as_ptr) {
debug self => _4; debug self => _4;
let mut _5: *const u8;
} }
} }
} }
scope 10 (inlined Unique::<u8>::as_non_null_ptr) { scope 10 (inlined Unique::<u8>::as_non_null_ptr) {
debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _6; debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _7;
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>; debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
} }
} }
scope 11 (inlined NonNull::<u8>::as_ptr) { scope 11 (inlined NonNull::<u8>::as_ptr) {
debug self => _6; debug self => _7;
} }
} }
} }
} }
scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) { scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
debug data => _5; debug data => _9;
debug len => _7; debug len => _10;
let _8: *const [u8]; let _11: *const [u8];
scope 13 (inlined core::ub_checks::check_language_ub) { scope 13 (inlined core::ub_checks::check_language_ub) {
scope 14 (inlined core::ub_checks::check_language_ub::runtime) { scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
} }
@ -55,11 +58,11 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
scope 16 (inlined align_of::<u8>) { scope 16 (inlined align_of::<u8>) {
} }
scope 17 (inlined slice_from_raw_parts::<u8>) { scope 17 (inlined slice_from_raw_parts::<u8>) {
debug data => _5; debug data => _9;
debug len => _7; debug len => _10;
scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) { scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
debug data_pointer => _5; debug data_pointer => _9;
debug metadata => _7; debug metadata => _10;
} }
} }
} }
@ -67,26 +70,37 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
} }
bb0: { bb0: {
StorageLive(_8);
StorageLive(_9);
StorageLive(_2); StorageLive(_2);
_2 = &((*_1).0: alloc::raw_vec::RawVec<u8>); _2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
StorageLive(_3); StorageLive(_3);
_3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner); _3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner);
StorageLive(_6); StorageLive(_7);
StorageLive(_4); StorageLive(_4);
_4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>); _4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
_5 = copy (_4.0: *const u8); StorageLive(_5);
_6 = NonNull::<u8> { pointer: copy _5 }; StorageLive(_6);
StorageDead(_4); _5 = copy _4 as *mut u8 (Transmute);
_6 = copy _5 as *const u8 (PtrToPtr);
_7 = NonNull::<u8> { pointer: move _6 };
StorageDead(_6); StorageDead(_6);
StorageDead(_3); StorageDead(_5);
StorageDead(_2); StorageDead(_4);
StorageLive(_7); _8 = copy _7 as *mut u8 (Transmute);
_7 = copy ((*_1).1: usize);
StorageLive(_8);
_8 = *const [u8] from (copy _5, copy _7);
_0 = &(*_8);
StorageDead(_8);
StorageDead(_7); StorageDead(_7);
StorageDead(_3);
_9 = copy _8 as *const u8 (PtrToPtr);
StorageDead(_2);
StorageLive(_10);
_10 = copy ((*_1).1: usize);
StorageLive(_11);
_11 = *const [u8] from (copy _9, copy _10);
_0 = &(*_11);
StorageDead(_11);
StorageDead(_10);
StorageDead(_9);
StorageDead(_8);
return; return;
} }
} }

View File

@ -36,12 +36,11 @@ extern crate rustc_errors;
extern crate rustc_parse; extern crate rustc_parse;
extern crate rustc_session; extern crate rustc_session;
extern crate rustc_span; extern crate rustc_span;
extern crate smallvec;
use std::mem; use std::mem;
use std::process::ExitCode; use std::process::ExitCode;
use rustc_ast::ast::{DUMMY_NODE_ID, Expr, ExprKind, Stmt}; use rustc_ast::ast::{DUMMY_NODE_ID, Expr, ExprKind};
use rustc_ast::mut_visit::{self, DummyAstNode as _, MutVisitor}; use rustc_ast::mut_visit::{self, DummyAstNode as _, MutVisitor};
use rustc_ast::node_id::NodeId; use rustc_ast::node_id::NodeId;
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
@ -50,7 +49,6 @@ use rustc_errors::Diag;
use rustc_parse::parser::Recovery; use rustc_parse::parser::Recovery;
use rustc_session::parse::ParseSess; use rustc_session::parse::ParseSess;
use rustc_span::{DUMMY_SP, FileName, Span}; use rustc_span::{DUMMY_SP, FileName, Span};
use smallvec::SmallVec;
// Every parenthesis in the following expressions is re-inserted by the // Every parenthesis in the following expressions is re-inserted by the
// pretty-printer. // pretty-printer.
@ -164,18 +162,6 @@ impl MutVisitor for Normalize {
fn visit_span(&mut self, span: &mut Span) { fn visit_span(&mut self, span: &mut Span) {
*span = DUMMY_SP; *span = DUMMY_SP;
} }
fn visit_expr(&mut self, expr: &mut P<Expr>) {
if let ExprKind::Binary(binop, _left, _right) = &mut expr.kind {
self.visit_span(&mut binop.span);
}
mut_visit::walk_expr(self, expr);
}
fn flat_map_stmt(&mut self, mut stmt: Stmt) -> SmallVec<[Stmt; 1]> {
self.visit_span(&mut stmt.span);
mut_visit::walk_flat_map_stmt(self, stmt)
}
} }
fn parse_expr(psess: &ParseSess, source_code: &str) -> Option<P<Expr>> { fn parse_expr(psess: &ParseSess, source_code: &str) -> Option<P<Expr>> {

View File

@ -0,0 +1,23 @@
// This example broke while refactoring the way closure
// requirements are handled. The setup here matches
// `thread::scope`.
//@ check-pass
struct Outlives<'hr, 'scope: 'hr>(*mut (&'scope (), &'hr ()));
impl<'hr, 'scope> Outlives<'hr, 'scope> {
fn outlives_hr<T: 'hr>(self) {}
}
fn takes_closure_implied_bound<'scope>(f: impl for<'hr> FnOnce(Outlives<'hr, 'scope>)) {}
fn requires_external_outlives_hr<T>() {
// implied bounds:
// - `T: 'scope` as `'scope` is local to this function
// - `'scope: 'hr` as it's an implied bound of `Outlives`
//
// need to prove `T: 'hr` :>
takes_closure_implied_bound(|proof| proof.outlives_hr::<T>());
}
fn main() {}

View File

@ -0,0 +1,21 @@
// This example incorrectly compiled while refactoring the way
// closure requirements are handled.
struct Outlives<'hr: 'scope, 'scope>(*mut (&'scope (), &'hr ()));
impl<'hr, 'scope> Outlives<'hr, 'scope> {
fn outlives_hr<T: 'hr>(self) {}
}
fn takes_closure_implied_bound<'scope>(f: impl for<'hr> FnOnce(Outlives<'hr, 'scope>)) {}
fn requires_external_outlives_hr<T>() {
// implied bounds:
// - `T: 'scope` as `'scope` is local to this function
// - `'hr: 'scope` as it's an implied bound of `Outlives`
//
// need to prove `T: 'hr` :<
takes_closure_implied_bound(|proof| proof.outlives_hr::<T>());
//~^ ERROR the parameter type `T` may not live long enough
}
fn main() {}

View File

@ -0,0 +1,17 @@
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/thread_scope_incorrect_implied_bound.rs:17:47
|
LL | takes_closure_implied_bound(|proof| proof.outlives_hr::<T>());
| ^^^^^^^^^^^
| |
| the parameter type `T` must be valid for the static lifetime...
| ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound
|
LL | fn requires_external_outlives_hr<T: 'static>() {
| +++++++++
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0310`.

View File

@ -1,8 +1,6 @@
// Test that we can deduce when projections like `T::Item` outlive the // Test that we can deduce when projections like `T::Item` outlive the
// function body. Test that this does not imply that `T: 'a` holds. // function body. Test that this does not imply that `T: 'a` holds.
//@ compile-flags:-Zverbose-internals
use std::cell::Cell; use std::cell::Cell;
fn twice<F, T>(mut value: T, mut f: F) fn twice<F, T>(mut value: T, mut f: F)

View File

@ -1,5 +1,5 @@
error[E0310]: the parameter type `T` may not live long enough error[E0310]: the parameter type `T` may not live long enough
--> $DIR/projection-implied-bounds.rs:30:36 --> $DIR/projection-implied-bounds.rs:28:36
| |
LL | twice(value, |value_ref, item| invoke2(value_ref, item)); LL | twice(value, |value_ref, item| invoke2(value_ref, item));
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^