Skip to content
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
cb9838c
rustdoc: Rename set_back_info to restore_module_data.
aDotInTheVoid Dec 2, 2024
67defd7
update instrumentation
lcnr Dec 3, 2024
8a47b44
closure requirements: don't replace bivariant opaque args
lcnr Dec 3, 2024
65d0b5d
small code cleanup
lcnr Dec 3, 2024
a2eca35
Visit BinOp span in MutVisitor::visit_expr
dtolnay Dec 3, 2024
a3cfe2f
Visit Stmt span in MutVisitor::flat_map_stmt
dtolnay Dec 3, 2024
2e1f25b
Improve code for FileName retrieval in rustdoc
GuillaumeGomez Dec 3, 2024
1c96ddd
closure-requirements: add regression tests
lcnr Dec 3, 2024
7afce4f
Update `NonZero` and `NonNull` to not field-project (per MCP807)
scottmcm Nov 21, 2024
2997ec5
Rename `is_real_and_local` function into `filename_real_and_local`
GuillaumeGomez Dec 3, 2024
3fadb87
bootstrap: `println!` -> `eprintln!`
clubby789 Dec 3, 2024
2372561
compiletest: `println!` -> `eprintln!`
clubby789 Dec 3, 2024
8374f7c
tidy: `println!` -> `eprintln!`
clubby789 Dec 3, 2024
68f8a53
Rollup merge of #133651 - scottmcm:nonnull-nonzero-no-field-projectio…
matthiaskrgr Dec 4, 2024
afffc1a
Rollup merge of #133764 - aDotInTheVoid:rename, r=GuillaumeGomez
matthiaskrgr Dec 4, 2024
45088fd
Rollup merge of #133784 - dtolnay:visitspans, r=compiler-errors
matthiaskrgr Dec 4, 2024
9fd0972
Rollup merge of #133798 - lcnr:nested-bodies-opaques, r=compiler-errors
matthiaskrgr Dec 4, 2024
5530869
Rollup merge of #133804 - GuillaumeGomez:improve-code, r=notriddle
matthiaskrgr Dec 4, 2024
0585134
Rollup merge of #133817 - clubby789:bootstrap-eprintln, r=jieyouxu
matthiaskrgr Dec 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
@@ -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);
vis.visit_span(span);
}
ExprKind::Binary(_binop, lhs, rhs) => {
ExprKind::Binary(binop, lhs, rhs) => {
vis.visit_expr(lhs);
vis.visit_expr(rhs);
vis.visit_span(&mut binop.span);
}
ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs),
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>(
vis: &mut T,
Stmt { kind, mut span, mut id }: Stmt,
Stmt { kind, span, mut id }: Stmt,
) -> SmallVec<[Stmt; 1]> {
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()
.map(|kind| Stmt { id, kind, span })
.collect();
if stmts.len() > 1 {
panic!(
match stmts.len() {
0 => {}
1 => vis.visit_span(&mut stmts[0].span),
2.. => panic!(
"cloning statement `NodeId`s is prohibited by default, \
the visitor should implement custom statement visiting"
);
),
}
vis.visit_span(&mut span);
stmts
}

51 changes: 8 additions & 43 deletions compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
@@ -973,25 +973,20 @@ impl<'tcx> RegionInferenceContext<'tcx> {
propagated_outlives_requirements: &mut Vec<ClosureOutlivesRequirement<'tcx>>,
) -> bool {
let tcx = infcx.tcx;

let TypeTest { generic_kind, lower_bound, span: _, verify_bound: _ } = type_test;
let TypeTest { generic_kind, lower_bound, span: blame_span, ref verify_bound } = *type_test;

let generic_ty = generic_kind.to_ty(tcx);
let Some(subject) = self.try_promote_type_test_subject(infcx, generic_ty) else {
return false;
};

debug!("subject = {:?}", subject);

let r_scc = self.constraint_sccs.scc(*lower_bound);

let r_scc = self.constraint_sccs.scc(lower_bound);
debug!(
"lower_bound = {:?} r_scc={:?} universe={:?}",
lower_bound,
r_scc,
self.constraint_sccs.annotation(r_scc).min_universe()
);

// If the type test requires that `T: 'a` where `'a` is a
// placeholder from another universe, that effectively requires
// `T: 'static`, so we have to propagate that requirement.
@@ -1004,7 +999,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
propagated_outlives_requirements.push(ClosureOutlivesRequirement {
subject,
outlived_free_region: static_r,
blame_span: type_test.span,
blame_span,
category: ConstraintCategory::Boring,
});

@@ -1031,12 +1026,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// where `ur` is a local bound -- we are sometimes in a
// position to prove things that our caller cannot. See
// #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;
}

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`
// 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 {
subject,
outlived_free_region: upper_bound,
blame_span: type_test.span,
blame_span,
category: ConstraintCategory::Boring,
};
debug!("try_promote_type_test: pushing {:#?}", requirement);
debug!(?requirement, "adding closure 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
/// closure signature.
/// 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(
&self,
infcx: &InferCtxt<'tcx>,
ty: Ty<'tcx>,
) -> Option<ClosureOutlivesSubject<'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 ty = fold_regions(tcx, ty, |r, _depth| {
let r_vid = self.to_region_vid(r);
let r_scc = self.constraint_sccs.scc(r_vid);
34 changes: 28 additions & 6 deletions library/core/src/num/nonzero.rs
Original file line number Diff line number Diff line change
@@ -37,6 +37,8 @@ pub unsafe trait ZeroablePrimitive: Sized + Copy + private::Sealed {
macro_rules! impl_zeroable_primitive {
($($NonZeroInner:ident ( $primitive:ty )),+ $(,)?) => {
mod private {
use super::*;

#[unstable(
feature = "nonzero_internals",
reason = "implementation detail which may disappear or be replaced at any time",
@@ -45,7 +47,11 @@ macro_rules! impl_zeroable_primitive {
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)]
#[rustc_layout_scalar_valid_range_start(1)]
#[rustc_nonnull_optimization_guaranteed]
@@ -55,6 +61,16 @@ macro_rules! impl_zeroable_primitive {
issue = "none"
)]
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]
fn clone(&self) -> Self {
Self(self.0)
*self
}
}

@@ -440,15 +456,21 @@ where
#[rustc_const_stable(feature = "const_nonzero_get", since = "1.34.0")]
#[inline]
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
// memory somewhere. If the value of `self` was from by-value argument
// of some not-inlined function, LLVM don't have range metadata
// 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
// of `.0` is such that this transmute is sound.
53 changes: 30 additions & 23 deletions library/core/src/ptr/non_null.rs
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ use crate::pin::PinCoerceUnsized;
use crate::ptr::Unique;
use crate::slice::{self, SliceIndex};
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].
///
@@ -69,6 +69,8 @@ use crate::{fmt, hash, intrinsics, ptr};
#[rustc_nonnull_optimization_guaranteed]
#[rustc_diagnostic_item = "NonNull"]
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,
}

@@ -282,7 +284,7 @@ impl<T: ?Sized> NonNull<T> {
pub fn addr(self) -> NonZero<usize> {
// SAFETY: The pointer is guaranteed by the type to be non-null,
// 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
@@ -296,7 +298,7 @@ impl<T: ?Sized> NonNull<T> {
#[stable(feature = "strict_provenance", since = "1.84.0")]
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.
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
@@ -335,7 +337,12 @@ impl<T: ?Sized> NonNull<T> {
#[must_use]
#[inline(always)]
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`]
@@ -484,7 +491,7 @@ impl<T: ?Sized> NonNull<T> {
// 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
// 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.
@@ -508,7 +515,7 @@ impl<T: ?Sized> NonNull<T> {
// 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
// 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)`).
@@ -560,7 +567,7 @@ impl<T: ?Sized> NonNull<T> {
// 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
// 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)`).
@@ -584,7 +591,7 @@ impl<T: ?Sized> NonNull<T> {
// 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
// `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
@@ -666,7 +673,7 @@ impl<T: ?Sized> NonNull<T> {
// 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
// `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
@@ -763,7 +770,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized,
{
// 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
@@ -781,7 +788,7 @@ impl<T: ?Sized> NonNull<T> {
#[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 {
// 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
@@ -856,7 +863,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized,
{
// 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
@@ -875,7 +882,7 @@ impl<T: ?Sized> NonNull<T> {
#[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
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`.
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
@@ -893,7 +900,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized,
{
// 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
@@ -914,7 +921,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized,
{
// 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
@@ -934,7 +941,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized,
{
// 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
@@ -954,7 +961,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized,
{
// 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
@@ -974,7 +981,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized,
{
// 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
@@ -994,7 +1001,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized,
{
// 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
@@ -1014,7 +1021,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized,
{
// 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.
@@ -1201,7 +1208,7 @@ impl<T: ?Sized> NonNull<T> {

{
// 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
T: Sized,
{
self.pointer.is_aligned()
self.as_ptr().is_aligned()
}

/// Returns whether the pointer is aligned to `align`.
@@ -1266,7 +1273,7 @@ impl<T: ?Sized> NonNull<T> {
#[must_use]
#[unstable(feature = "pointer_is_aligned_to", issue = "96284")]
pub fn is_aligned_to(self, align: usize) -> bool {
self.pointer.is_aligned_to(align)
self.as_ptr().is_aligned_to(align)
}
}

20 changes: 10 additions & 10 deletions src/bootstrap/src/bin/main.rs
Original file line number Diff line number Diff line change
@@ -48,9 +48,9 @@ fn main() {
err => {
drop(err);
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 {
println!("WARNING: build directory locked, waiting for lock");
eprintln!("WARNING: build directory locked, waiting for lock");
}
let mut lock = t!(build_lock.write());
t!(lock.write(process::id().to_string().as_ref()));
@@ -70,13 +70,13 @@ fn main() {
// changelog warning, not the `x.py setup` message.
let suggest_setup = config.config.is_none() && !matches!(config.cmd, Subcommand::Setup { .. });
if suggest_setup {
println!("WARNING: you have not made a `config.toml`");
println!(
eprintln!("WARNING: you have not made a `config.toml`");
eprintln!(
"HELP: consider running `./x.py setup` or copying `config.example.toml` by running \
`cp config.example.toml config.toml`"
);
} else if let Some(suggestion) = &changelog_suggestion {
println!("{suggestion}");
eprintln!("{suggestion}");
}

let pre_commit = config.src.join(".git").join("hooks").join("pre-commit");
@@ -86,13 +86,13 @@ fn main() {
Build::new(config).build();

if suggest_setup {
println!("WARNING: you have not made a `config.toml`");
println!(
eprintln!("WARNING: you have not made a `config.toml`");
eprintln!(
"HELP: consider running `./x.py setup` or copying `config.example.toml` by running \
`cp config.example.toml config.toml`"
);
} 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.
@@ -102,14 +102,14 @@ fn main() {
if fs::read_to_string(pre_commit).is_ok_and(|contents| {
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. \
Consider moving it to .git/hooks/pre-push instead, which runs less often."
);
}

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 {
2 changes: 1 addition & 1 deletion src/bootstrap/src/bin/rustc.rs
Original file line number Diff line number Diff line change
@@ -306,7 +306,7 @@ fn main() {
// should run on success, after this block.
}
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 {
2 changes: 1 addition & 1 deletion src/bootstrap/src/core/build_steps/check.rs
Original file line number Diff line number Diff line change
@@ -287,7 +287,7 @@ impl Step for CodegenBackend {
fn run(self, builder: &Builder<'_>) {
// FIXME: remove once https://github.com/rust-lang/rust/issues/112393 is resolved
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;
}

10 changes: 5 additions & 5 deletions src/bootstrap/src/core/build_steps/compile.rs
Original file line number Diff line number Diff line change
@@ -1611,7 +1611,7 @@ impl Step for Sysroot {
let sysroot = sysroot_dir(compiler.stage);

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);
t!(fs::create_dir_all(&sysroot));

@@ -1681,7 +1681,7 @@ impl Step for Sysroot {
return true;
}
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
} else {
true
@@ -2240,7 +2240,7 @@ pub fn stream_cargo(
cargo.arg(arg);
}

builder.verbose(|| println!("running: {cargo:?}"));
builder.verbose(|| eprintln!("running: {cargo:?}"));

if builder.config.dry_run() {
return true;
@@ -2261,12 +2261,12 @@ pub fn stream_cargo(
Ok(msg) => {
if builder.config.json_output {
// Forward JSON to stdout.
println!("{line}");
eprintln!("{line}");
}
cb(msg)
}
// If this was informational, just print it out and continue
Err(_) => println!("{line}"),
Err(_) => eprintln!("{line}"),
}
}

2 changes: 1 addition & 1 deletion src/bootstrap/src/core/build_steps/dist.rs
Original file line number Diff line number Diff line change
@@ -2080,7 +2080,7 @@ fn maybe_install_llvm(
{
let mut cmd = command(llvm_config);
cmd.arg("--libfiles");
builder.verbose(|| println!("running {cmd:?}"));
builder.verbose(|| eprintln!("running {cmd:?}"));
let files = cmd.run_capture_stdout(builder).stdout();
let build_llvm_out = &builder.llvm_out(builder.config.build);
let target_llvm_out = &builder.llvm_out(target);
6 changes: 3 additions & 3 deletions src/bootstrap/src/core/build_steps/format.rs
Original file line number Diff line number Diff line change
@@ -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 len <= 10 {
for path in paths {
println!("fmt: {verb} {adjective}file {path}");
eprintln!("fmt: {verb} {adjective}file {path}");
}
} 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) {
Ok(Some(files)) => {
if files.is_empty() {
println!("fmt info: No modified files detected for formatting.");
eprintln!("fmt info: No modified files detected for formatting.");
return;
}

40 changes: 20 additions & 20 deletions src/bootstrap/src/core/build_steps/setup.rs
Original file line number Diff line number Diff line change
@@ -134,7 +134,7 @@ impl Step for Profile {
t!(fs::remove_file(path));
}
_ => {
println!("Exiting.");
eprintln!("Exiting.");
crate::exit!(1);
}
}
@@ -184,15 +184,15 @@ pub fn setup(config: &Config, profile: Profile) {
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 {
println!("- `x.py {cmd}`");
eprintln!("- `x.py {cmd}`");
}

if profile != Profile::Dist {
println!(
eprintln!(
"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));

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`
@@ -256,7 +256,7 @@ impl Step for Link {
}

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

@@ -296,7 +296,7 @@ fn attempt_toolchain_link(builder: &Builder<'_>, stage_path: &str) {
}

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"
);
} else {
@@ -321,14 +321,14 @@ fn toolchain_is_linked(builder: &Builder<'_>) -> bool {
return false;
}
// The toolchain has already been linked.
println!(
eprintln!(
"`stage1` toolchain already linked; not attempting to link `stage1` toolchain"
);
}
None => {
// In this case, we don't know if the `stage1` toolchain has been linked;
// but `rustup` failed, so let's not go any further.
println!(
eprintln!(
"`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()
}

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() {
println!("{}) {}: {}", letter, profile, profile.purpose());
eprintln!("{}) {}: {}", letter, profile, profile.purpose());
}
let template = loop {
print!(
@@ -488,15 +488,15 @@ fn install_git_hook_maybe(builder: &Builder<'_>, config: &Config) -> io::Result<
return Ok(());
}

println!(
eprintln!(
"\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
pushing your code to ensure your code is up to par. If you decide later that this behavior is
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) {
println!("Ok, skipping installation!");
eprintln!("Ok, skipping installation!");
return Ok(());
}
if !hooks_dir.exists() {
@@ -513,7 +513,7 @@ undesirable, simply delete the `pre-push` file from .git/hooks."
);
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(())
}
@@ -654,7 +654,7 @@ impl Step for Editor {
if let Some(editor_kind) = editor_kind {
while !t!(create_editor_settings_maybe(config, editor_kind.clone())) {}
} else {
println!("Ok, skipping editor setup!");
eprintln!("Ok, skipping editor setup!");
}
}
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);
}
}
println!(
eprintln!(
"\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::Print) => false,
_ => {
println!("Ok, skipping settings!");
eprintln!("Ok, skipping settings!");
return Ok(true);
}
};
@@ -733,9 +733,9 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu
_ => "Created",
};
fs::write(&settings_path, editor.settings_template())?;
println!("{verb} `{}`", settings_filename);
eprintln!("{verb} `{}`", settings_filename);
} else {
println!("\n{}", editor.settings_template());
eprintln!("\n{}", editor.settings_template());
}
Ok(should_create)
}
2 changes: 1 addition & 1 deletion src/bootstrap/src/core/build_steps/suggest.rs
Original file line number Diff line number Diff line change
@@ -66,6 +66,6 @@ pub fn suggest(builder: &Builder<'_>, run: bool) {
build.build();
}
} 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");
}
}
6 changes: 3 additions & 3 deletions src/bootstrap/src/core/build_steps/test.rs
Original file line number Diff line number Diff line change
@@ -471,11 +471,11 @@ impl Miri {
// We re-use the `cargo` from above.
cargo.arg("--print-sysroot");

builder.verbose(|| println!("running: {cargo:?}"));
builder.verbose(|| eprintln!("running: {cargo:?}"));
let stdout = cargo.run_capture_stdout(builder).stdout();
// Output is "<sysroot>\n".
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)
}
}
@@ -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);
builder.add_rust_test_threads(&mut cmd);
// allow for unstable options such as new editions
2 changes: 1 addition & 1 deletion src/bootstrap/src/core/builder/cargo.rs
Original file line number Diff line number Diff line change
@@ -523,7 +523,7 @@ impl Builder<'_> {

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) {
println!("using sysroot {sysroot_str}");
eprintln!("using sysroot {sysroot_str}");
}

let mut rustflags = Rustflags::new(target);
14 changes: 8 additions & 6 deletions src/bootstrap/src/core/builder/mod.rs
Original file line number Diff line number Diff line change
@@ -392,14 +392,14 @@ impl StepDescription {
fn is_excluded(&self, builder: &Builder<'_>, pathset: &PathSet) -> bool {
if builder.config.skip.iter().any(|e| pathset.has(e, builder.kind)) {
if !matches!(builder.config.dry_run, DryRun::SelfCheck) {
println!("Skipping {pathset:?} because it is excluded");
eprintln!("Skipping {pathset:?} because it is excluded");
}
return true;
}

if !builder.config.skip.is_empty() && !matches!(builder.config.dry_run, DryRun::SelfCheck) {
builder.verbose(|| {
println!(
eprintln!(
"{:?} not skipped for {:?} -- not in {:?}",
pathset, self.name, builder.config.skip
)
@@ -1437,11 +1437,11 @@ impl<'a> Builder<'a> {
panic!("{}", out);
}
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;
}
self.verbose_than(1, || println!("{}> {:?}", " ".repeat(stack.len()), step));
self.verbose_than(1, || eprintln!("{}> {:?}", " ".repeat(stack.len()), step));
stack.push(Box::new(step.clone()));
}

@@ -1462,7 +1462,7 @@ impl<'a> Builder<'a> {
let step_string = format!("{step:?}");
let brace_index = step_string.find('{').unwrap_or(0);
let type_string = type_name::<S>();
println!(
eprintln!(
"[TIMING] {} {} -- {}.{:03}",
&type_string.strip_prefix("bootstrap::").unwrap_or(type_string),
&step_string[brace_index..],
@@ -1479,7 +1479,9 @@ impl<'a> Builder<'a> {
let cur_step = stack.pop().expect("step stack empty");
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());
out
}
60 changes: 30 additions & 30 deletions src/bootstrap/src/core/config/config.rs
Original file line number Diff line number Diff line change
@@ -1293,7 +1293,7 @@ impl Config {
.map(|change_id| change_id.inner.map(crate::find_recent_config_change_ids))
{
if !changes.is_empty() {
println!(
eprintln!(
"WARNING: There have been changes to x.py since you last updated:\n{}",
crate::human_readable_changes(&changes)
);
@@ -1559,7 +1559,7 @@ impl Config {
}

if cargo_clippy.is_some() && rustc.is_none() {
println!(
eprintln!(
"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.
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"
);
}
@@ -1873,7 +1873,7 @@ impl Config {
if available_backends.contains(&backend) {
panic!("Invalid value '{s}' for 'rust.codegen-backends'. Instead, please use '{backend}'.");
} 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. \
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.
if let Some(commit) = &config.download_rustc_commit {
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."
);

@@ -1992,10 +1992,10 @@ impl Config {

if config.llvm_from_ci {
let warn = |option: &str| {
println!(
eprintln!(
"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."
);
};
@@ -2014,12 +2014,12 @@ impl Config {
// if they've chosen a different value.

if libzstd.is_some() {
println!(
eprintln!(
"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 \
artifacts builder config."
);
println!(
eprintln!(
"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) {
panic!("Invalid value '{s}' for 'target.{triple}.codegen-backends'. Instead, please use '{backend}'.");
} 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. \
In this case, it would be referred to as '{backend}'.");
}
@@ -2304,7 +2304,7 @@ impl Config {
if self.dry_run() {
return Ok(());
}
self.verbose(|| println!("running: {cmd:?}"));
self.verbose(|| eprintln!("running: {cmd:?}"));
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
// to not break CI. For non-CI environments, we should return an error.
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;
} else {
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") {
Ok(ci_config_toml) => ci_config_toml,
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.");
println!("HELP: Consider rebasing to a newer commit if available.");
eprintln!("WARNING: CI rustc has some fields that are no longer supported in bootstrap; download-rustc will be disabled.");
eprintln!("HELP: Consider rebasing to a newer commit if available.");
return None;
},
Err(e) => {
@@ -2516,7 +2516,7 @@ impl Config {
.is_some_and(|s| s == "1" || s == "true");

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

@@ -2701,7 +2701,7 @@ impl Config {
return;
}

println!("Updating submodule {relative_path}");
eprintln!("Updating submodule {relative_path}");
self.check_run(
helpers::git(Some(&self.src))
.run_always()
@@ -2824,7 +2824,7 @@ impl Config {
Some(StringOrBool::Bool(true)) => false,
Some(StringOrBool::String(s)) if s == "if-unchanged" => {
if !self.rust_info.is_managed_git_subrepository() {
println!(
eprintln!(
"ERROR: `download-rustc=if-unchanged` is only compatible with Git managed sources."
);
crate::exit!(1);
@@ -2857,10 +2857,10 @@ impl Config {
if if_unchanged {
return None;
}
println!("ERROR: could not find commit hash for downloading rustc");
println!("HELP: maybe your repository history is too shallow?");
println!("HELP: consider setting `rust.download-rustc=false` in config.toml");
println!("HELP: or fetch enough history to include one upstream commit");
eprintln!("ERROR: could not find commit hash for downloading rustc");
eprintln!("HELP: maybe your repository history is too shallow?");
eprintln!("HELP: consider setting `rust.download-rustc=false` in config.toml");
eprintln!("HELP: or fetch enough history to include one upstream commit");
crate::exit!(1);
}
};
@@ -2899,7 +2899,7 @@ impl Config {
let if_unchanged = || {
if self.rust_info.is_from_tarball() {
// Git is needed for running "if-unchanged" logic.
println!(
eprintln!(
"WARNING: 'if-unchanged' has no effect on tarball sources; ignoring `download-ci-llvm`."
);
return false;
@@ -2948,10 +2948,10 @@ impl Config {
// Only commits merged by bors will have CI artifacts.
let commit = get_closest_merge_commit(Some(&self.src), &self.git_config(), &[]).unwrap();
if commit.is_empty() {
println!("error: could not find commit hash for downloading components from CI");
println!("help: maybe your repository history is too shallow?");
println!("help: consider disabling `{option_name}`");
println!("help: or fetch enough history to include one upstream commit");
eprintln!("error: could not find commit hash for downloading components from CI");
eprintln!("help: maybe your repository history is too shallow?");
eprintln!("help: consider disabling `{option_name}`");
eprintln!("help: or fetch enough history to include one upstream commit");
crate::exit!(1);
}

@@ -2963,14 +2963,14 @@ impl Config {
if has_changes {
if if_unchanged {
if self.is_verbose() {
println!(
eprintln!(
"warning: saw changes to one of {modified_paths:?} since {commit}; \
ignoring `{option_name}`"
);
}
return None;
}
println!(
eprintln!(
"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) => {
if let Some(current) = &$current {
if Some(current) != $expected.as_ref() {
println!(
eprintln!(
"WARNING: `llvm.{}` has no effect with `llvm.download-ci-llvm`. \
Current value: {:?}, Expected value(s): {}{:?}",
stringify!($expected).replace("_", "-"),
@@ -3112,7 +3112,7 @@ fn check_incompatible_options_for_ci_rustc(
($current:expr, $expected:expr, $config_section:expr) => {
if let Some(current) = &$current {
if Some(current) != $expected.as_ref() {
println!(
eprintln!(
"WARNING: `{}` has no effect with `rust.download-rustc`. \
Current value: {:?}, Expected value(s): {}{:?}",
format!("{}.{}", $config_section, stringify!($expected).replace("_", "-")),
4 changes: 2 additions & 2 deletions src/bootstrap/src/core/config/flags.rs
Original file line number Diff line number Diff line change
@@ -196,12 +196,12 @@ impl Flags {
if let Ok(HelpVerboseOnly { help: true, verbose: 1.., cmd: subcommand }) =
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 build = Build::new(config);
let paths = Builder::get_help(&build, subcommand);
if let Some(s) = paths {
println!("{s}");
eprintln!("{s}");
} else {
panic!("No paths available for subcommand `{}`", subcommand.as_str());
}
26 changes: 13 additions & 13 deletions src/bootstrap/src/core/download.rs
Original file line number Diff line number Diff line change
@@ -77,7 +77,7 @@ impl Config {
if self.dry_run() && !cmd.run_always {
return true;
}
self.verbose(|| println!("running: {cmd:?}"));
self.verbose(|| eprintln!("running: {cmd:?}"));
check_run(cmd, self.is_verbose())
}

@@ -144,7 +144,7 @@ impl Config {
/// Please see <https://nixos.org/patchelf.html> for more information
fn fix_bin_or_dylib(&self, fname: &Path) {
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.
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) {
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/.
let tempfile = self.tempdir().join(dest_path.file_name().unwrap());
// 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) {
println!("downloading {url}");
eprintln!("downloading {url}");
// Try curl. If that fails and we are on windows, fallback to PowerShell.
// options should be kept in sync with
// src/bootstrap/src/core/download.rs
@@ -341,7 +341,7 @@ impl Config {
short_path = short_path.strip_prefix(pattern).unwrap_or(short_path);
let dst_path = dst.join(short_path);
self.verbose(|| {
println!("extracting {} to {}", original_path.display(), dst.display())
eprintln!("extracting {} to {}", original_path.display(), dst.display())
});
if !t!(member.unpack_in(dst)) {
panic!("path traversal attack ??");
@@ -365,7 +365,7 @@ impl Config {
pub(crate) fn verify(&self, path: &Path, expected: &str) -> bool {
use sha2::Digest;

self.verbose(|| println!("verifying {}", path.display()));
self.verbose(|| eprintln!("verifying {}", path.display()));

if self.dry_run() {
return false;
@@ -391,7 +391,7 @@ impl Config {
let verified = checksum == expected;

if !verified {
println!(
eprintln!(
"invalid checksum: \n\
found: {checksum}\n\
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.
impl Config {
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 version = &self.stage0_metadata.compiler.version;
@@ -518,7 +518,7 @@ impl Config {
}

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);
// 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"))]
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 version = &self.stage0_metadata.compiler.version;
@@ -677,7 +677,7 @@ impl Config {
return;
} else {
self.verbose(|| {
println!(
eprintln!(
"ignoring cached file {} due to failed verification",
tarball.display()
)
@@ -776,10 +776,10 @@ download-rustc = false
t!(check_incompatible_options_for_ci_llvm(current_config_toml, ci_config_toml));
}
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."
);
println!("HELP: Consider rebasing to a newer commit if available.");
eprintln!("HELP: Consider rebasing to a newer commit if available.");
}
Err(e) => {
eprintln!("ERROR: Failed to parse CI LLVM config.toml: {e}");
4 changes: 2 additions & 2 deletions src/bootstrap/src/core/sanity.rs
Original file line number Diff line number Diff line change
@@ -237,11 +237,11 @@ than building it.
stage0_supported_target_list.intersection(&missing_targets_hashset).collect();

if !duplicated_targets.is_empty() {
println!(
eprintln!(
"Following targets supported from the stage0 compiler, please remove them from STAGE0_MISSING_TARGETS list."
);
for duplicated_target in duplicated_targets {
println!(" {duplicated_target}");
eprintln!(" {duplicated_target}");
}
std::process::exit(1);
}
28 changes: 14 additions & 14 deletions src/bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
@@ -406,19 +406,19 @@ impl Build {
.unwrap()
.trim();
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.verbose(|| println!("finding compilers"));
build.verbose(|| eprintln!("finding compilers"));
utils::cc_detect::find(&build);
// 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
// run. This is ok because `setup` never runs any build commands, so it won't fail if commands are missing.
//
// Similarly, for `setup` we don't actually need submodules or cargo metadata.
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);

// 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.
build.update_existing_submodules();

build.verbose(|| println!("learning about cargo"));
build.verbose(|| eprintln!("learning about cargo"));
crate::core::metadata::build(&mut build);
}

@@ -605,7 +605,7 @@ impl Build {
let stamp = dir.join(".stamp");
let mut cleared = false;
if mtime(&stamp) < mtime(input) {
self.verbose(|| println!("Dirty - {}", dir.display()));
self.verbose(|| eprintln!("Dirty - {}", dir.display()));
let _ = fs::remove_dir_all(dir);
cleared = true;
} else if stamp.exists() {
@@ -890,7 +890,7 @@ impl Build {
let executed_at = std::panic::Location::caller();

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();
@@ -947,7 +947,7 @@ Executed at: {executed_at}"#,

let fail = |message: &str, output: CommandOutput| -> ! {
if self.is_verbose() {
println!("{message}");
eprintln!("{message}");
} else {
let (stdout, stderr) = (output.stdout_if_present(), output.stderr_if_present());
// 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) =
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) =
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 {
println!("Command has failed. Rerun with -v to see more details.");
eprintln!("Command has failed. Rerun with -v to see more details.");
}
}
exit!(1);
@@ -1011,7 +1011,7 @@ Executed at: {executed_at}"#,
match self.config.dry_run {
DryRun::SelfCheck => (),
DryRun::Disabled | DryRun::UserSelected => {
println!("{msg}");
eprintln!("{msg}");
}
}
}
@@ -1666,7 +1666,7 @@ Executed at: {executed_at}"#,
if self.config.dry_run() {
return;
}
self.verbose_than(1, || println!("Copy/Link {src:?} to {dst:?}"));
self.verbose_than(1, || eprintln!("Copy/Link {src:?} to {dst:?}"));
if src == dst {
return;
}
@@ -1775,7 +1775,7 @@ Executed at: {executed_at}"#,
return;
}
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));
if !src.exists() {
panic!("ERROR: File \"{}\" not found!", src.display());
10 changes: 5 additions & 5 deletions src/bootstrap/src/utils/cc_detect.rs
Original file line number Diff line number Diff line change
@@ -155,15 +155,15 @@ pub fn find_target(build: &Build, target: TargetSelection) {
build.cxx.borrow_mut().insert(target, compiler);
}

build.verbose(|| println!("CC_{} = {:?}", target.triple, build.cc(target)));
build.verbose(|| println!("CFLAGS_{} = {cflags:?}", target.triple));
build.verbose(|| eprintln!("CC_{} = {:?}", target.triple, build.cc(target)));
build.verbose(|| eprintln!("CFLAGS_{} = {cflags:?}", target.triple));
if let Ok(cxx) = build.cxx(target) {
let cxxflags = build.cflags(target, GitRepo::Rustc, CLang::Cxx);
build.verbose(|| println!("CXX_{} = {cxx:?}", target.triple));
build.verbose(|| println!("CXXFLAGS_{} = {cxxflags:?}", target.triple));
build.verbose(|| eprintln!("CXX_{} = {cxx:?}", target.triple));
build.verbose(|| eprintln!("CXXFLAGS_{} = {cxxflags:?}", target.triple));
}
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);
}

6 changes: 3 additions & 3 deletions src/bootstrap/src/utils/helpers.rs
Original file line number Diff line number Diff line change
@@ -135,7 +135,7 @@ impl Drop for TimeIt {
fn drop(&mut self) {
let time = self.1.elapsed();
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() {
Ok(status) => status,
Err(e) => {
println!("failed to execute command: {cmd:?}\nERROR: {e}");
eprintln!("failed to execute command: {cmd:?}\nERROR: {e}");
return false;
}
};
if !status.success() && print_cmd_on_fail {
println!(
eprintln!(
"\n\ncommand did not execute successfully: {cmd:?}\n\
expected success, got: {status}\n\n"
);
2 changes: 1 addition & 1 deletion src/bootstrap/src/utils/metrics.rs
Original file line number Diff line number Diff line change
@@ -184,7 +184,7 @@ impl BuildMetrics {
if version.format_version == CURRENT_FORMAT_VERSION {
t!(serde_json::from_slice::<JsonRoot>(&contents)).invocations
} else {
println!(
eprintln!(
"WARNING: overriding existing build/metrics.json, as it's not \
compatible with build metrics format version {CURRENT_FORMAT_VERSION}."
);
36 changes: 19 additions & 17 deletions src/bootstrap/src/utils/render_tests.rs
Original file line number Diff line number Diff line change
@@ -56,7 +56,7 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut BootstrapCommand, stream: bool) ->
let cmd = cmd.as_command_mut();
cmd.stdout(Stdio::piped());

builder.verbose(|| println!("running: {cmd:?}"));
builder.verbose(|| eprintln!("running: {cmd:?}"));

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();
if !result.status.success() && builder.is_verbose() {
println!(
eprintln!(
"\n\ncommand did not execute successfully: {cmd:?}\n\
expected success, got: {}",
result.status
@@ -135,7 +135,9 @@ impl<'a> Renderer<'a> {
if self.up_to_date_tests > 0 {
let n = self.up_to_date_tests;
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 {
print!(" ({exec_time:.2?})");
}
println!();
eprintln!();
}

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());
print!(" {executed}/{total}");
}
println!();
eprintln!();
self.terse_tests_in_line = 0;
}

@@ -212,31 +214,31 @@ impl<'a> Renderer<'a> {
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.
if !self.builder.config.verbose_tests {
println!();
eprintln!();
}

if !self.failures.is_empty() {
println!("\nfailures:\n");
eprintln!("\nfailures:\n");
for failure in &self.failures {
if failure.stdout.is_some() || failure.message.is_some() {
println!("---- {} stdout ----", failure.name);
eprintln!("---- {} stdout ----", failure.name);
if let Some(stdout) = &failure.stdout {
println!("{stdout}");
eprintln!("{stdout}");
}
if let Some(message) = &failure.message {
println!("NOTE: {message}");
eprintln!("NOTE: {message}");
}
}
}

println!("\nfailures:");
eprintln!("\nfailures:");
for failure in &self.failures {
println!(" {}", failure.name);
eprintln!(" {}", failure.name);
}
}

if !self.benches.is_empty() {
println!("\nbenchmarks:");
eprintln!("\nbenchmarks:");

let mut rows = Vec::new();
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_2 = rows.iter().map(|r| r.2.len()).max().unwrap_or(0);
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: ");
self.builder.colored_stdout(|stdout| outcome.write_long(stdout)).unwrap();
println!(
eprintln!(
". {} passed; {} failed; {} ignored; {} measured; {} filtered out{time}\n",
suite.passed,
suite.failed,
@@ -274,7 +276,7 @@ impl<'a> Renderer<'a> {
fn render_message(&mut self, message: Message) {
match message {
Message::Suite(SuiteMessage::Started { test_count }) => {
println!("\nrunning {test_count} tests");
eprintln!("\nrunning {test_count} tests");
self.executed_tests = 0;
self.terse_tests_in_line = 0;
self.tests_count = Some(test_count);
@@ -314,7 +316,7 @@ impl<'a> Renderer<'a> {
self.failures.push(outcome);
}
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
}
2 changes: 1 addition & 1 deletion src/bootstrap/src/utils/tarball.rs
Original file line number Diff line number Diff line change
@@ -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.
let compression_profile = if self.builder.kind == Kind::Install {
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"
25 changes: 13 additions & 12 deletions src/librustdoc/formats/renderer.rs
Original file line number Diff line number Diff line change
@@ -17,17 +17,18 @@ pub(crate) trait FormatRenderer<'tcx>: Sized {
///
/// This is true for html, and false for json. See #80664
const RUN_ON_MODULE: bool;

/// 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:
///
/// 1. save_module_data
/// 2. item
/// 3. set_back_info
/// 1. `save_module_data`
/// 2. `item`
/// 3. `restore_module_data`
///
/// However,the `item` method might update information in `self` (for example if the child is
/// a module). To prevent it to impact the other children of the current module, we need to
/// reset the information between each call to `item` by using `set_back_info`.
/// This is because the `item` method might update information in `self` (for example if the child
/// 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 `restore_module_data`.
type ModuleData;

/// 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
/// 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:
///
/// ```ignore (not valid code)
/// let reset_data = type.save_module_data();
/// type.item(item)?;
/// type.set_back_info(reset_data);
/// let reset_data = renderer.save_module_data();
/// renderer.item(item)?;
/// renderer.restore_module_data(reset_data);
/// ```
fn save_module_data(&mut self) -> Self::ModuleData;
/// 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.
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 {
let info = cx.save_module_data();
run_format_inner(cx, it, prof)?;
cx.set_back_info(info);
cx.restore_module_data(info);
}

cx.mod_item_out()?;
2 changes: 1 addition & 1 deletion src/librustdoc/html/render/context.rs
Original file line number Diff line number Diff line change
@@ -601,7 +601,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
self.info
}

fn set_back_info(&mut self, info: Self::ModuleData) {
fn restore_module_data(&mut self, info: Self::ModuleData) {
self.info = info;
}

50 changes: 22 additions & 28 deletions src/librustdoc/html/sources.rs
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use rustc_span::{FileName, sym};
use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, sym};
use tracing::info;

use crate::clean;
@@ -50,8 +50,14 @@ struct LocalSourcesCollector<'a, 'tcx> {
src_root: &'a Path,
}

fn is_real_and_local(span: clean::Span, sess: &Session) -> bool {
span.cnum(sess) == LOCAL_CRATE && span.filename(sess).is_real()
fn filename_real_and_local(span: clean::Span, sess: &Session) -> Option<RealFileName> {
if span.cnum(sess) == LOCAL_CRATE
&& let FileName::Real(file) = span.filename(sess)
{
Some(file)
} else {
None
}
}

impl LocalSourcesCollector<'_, '_> {
@@ -60,16 +66,8 @@ impl LocalSourcesCollector<'_, '_> {
let span = item.span(self.tcx);
let Some(span) = span else { return };
// skip all synthetic "files"
if !is_real_and_local(span, sess) {
return;
}
let filename = span.filename(sess);
let p = if let FileName::Real(file) = filename {
match file.into_local_path() {
Some(p) => p,
None => return,
}
} else {
let Some(p) = filename_real_and_local(span, sess).and_then(|file| file.into_local_path())
else {
return;
};
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 including source files, and we haven't seen this file yet,
// then we need to render it out to the filesystem.
if is_real_and_local(span, sess) {
let filename = span.filename(sess);
if let Some(filename) = filename_real_and_local(span, sess) {
let span = span.inner();
let pos = sess.source_map().lookup_source_file(span.lo());
let file_span = span.with_lo(pos.start_pos).with_hi(pos.end_position());
@@ -152,7 +149,7 @@ impl DocVisitor<'_> for SourceCollector<'_, '_> {
span,
format!(
"failed to render source code for `{filename}`: {e}",
filename = filename.prefer_local(),
filename = filename.to_string_lossy(FileNameDisplayPreference::Local),
),
);
false
@@ -168,18 +165,13 @@ impl SourceCollector<'_, '_> {
/// Renders the given filename into its corresponding HTML source file.
fn emit_source(
&mut self,
filename: &FileName,
file: &RealFileName,
file_span: rustc_span::Span,
) -> Result<(), Error> {
let p = match *filename {
FileName::Real(ref file) => {
if let Some(local_path) = file.local_path() {
local_path.to_path_buf()
} else {
unreachable!("only the current crate should have sources emitted");
}
}
_ => return Ok(()),
let p = if let Some(local_path) = file.local_path() {
local_path.to_path_buf()
} else {
unreachable!("only the current crate should have sources emitted");
};
if self.emitted_local_sources.contains(&*p) {
// We've already emitted this source
@@ -233,8 +225,10 @@ impl SourceCollector<'_, '_> {
cur.push(&fname);

let title = format!("{} - source", src_fname.to_string_lossy());
let desc =
format!("Source of the Rust file `{}`.", filename.prefer_remapped_unconditionaly());
let desc = format!(
"Source of the Rust file `{}`.",
file.to_string_lossy(FileNameDisplayPreference::Remapped)
);
let page = layout::Page {
title: &title,
css_class: "src",
9 changes: 4 additions & 5 deletions src/librustdoc/json/mod.rs
Original file line number Diff line number Diff line change
@@ -163,11 +163,10 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
}

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 set_back_info(&mut self, _info: Self::ModuleData) {
unreachable!("RUN_ON_MODULE = false should never call set_back_info")
fn restore_module_data(&mut self, _info: Self::ModuleData) {
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
@@ -248,7 +247,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
}

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> {
2 changes: 1 addition & 1 deletion src/tools/compiletest/src/compute_diff.rs
Original file line number Diff line number Diff line change
@@ -144,7 +144,7 @@ where
}

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);
return false;
} else if verbose {
6 changes: 3 additions & 3 deletions src/tools/compiletest/src/debuggers.rs
Original file line number Diff line number Diff line change
@@ -20,15 +20,15 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
}

if config.remote_test_client.is_some() && !config.target.contains("android") {
println!(
eprintln!(
"WARNING: debuginfo tests are not available when \
testing with remote"
);
return None;
}

if config.target.contains("android") {
println!(
eprintln!(
"{} debug-info test uses tcp 5039 port.\
please reserve it",
config.target
@@ -50,7 +50,7 @@ pub(crate) fn configure_lldb(config: &Config) -> Option<Arc<Config>> {
config.lldb_python_dir.as_ref()?;

if let Some(350) = config.lldb_version {
println!(
eprintln!(
"WARNING: The used version of LLDB (350) has a \
known issue that breaks debuginfo tests. See \
issue #32520 for more information. Skipping all \
10 changes: 5 additions & 5 deletions src/tools/compiletest/src/lib.rs
Original file line number Diff line number Diff line change
@@ -188,8 +188,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
let (argv0, args_) = args.split_first().unwrap();
if args.len() == 1 || args[1] == "-h" || args[1] == "--help" {
let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
println!("{}", opts.usage(&message));
println!();
eprintln!("{}", opts.usage(&message));
eprintln!();
panic!()
}

@@ -200,8 +200,8 @@ pub fn parse_config(args: Vec<String>) -> Config {

if matches.opt_present("h") || matches.opt_present("help") {
let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
println!("{}", opts.usage(&message));
println!();
eprintln!("{}", opts.usage(&message));
eprintln!();
panic!()
}

@@ -501,7 +501,7 @@ pub fn run_tests(config: Arc<Config>) {
// easy to miss which tests failed, and as such fail to reproduce
// the failure locally.

println!(
eprintln!(
"Some tests failed in compiletest suite={}{} mode={} host={} target={}",
config.suite,
config
50 changes: 25 additions & 25 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
@@ -774,20 +774,20 @@ impl<'test> TestCx<'test> {
unexpected.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() {
println!("{}", "--- unexpected errors (from JSON output) ---".green());
eprintln!("{}", "--- unexpected errors (from JSON output) ---".green());
for error in &unexpected {
println!("{}", error.render_for_expected());
eprintln!("{}", error.render_for_expected());
}
println!("{}", "---".green());
eprintln!("{}", "---".green());
}
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 {
println!("{}", error.render_for_expected());
eprintln!("{}", error.render_for_expected());
}
println!("{}", "---\n".red());
eprintln!("{}", "---\n".red());
}
panic!("errors differ from expected");
}
@@ -1876,18 +1876,18 @@ impl<'test> TestCx<'test> {

fn maybe_dump_to_stdout(&self, out: &str, err: &str) {
if self.config.verbose {
println!("------stdout------------------------------");
println!("{}", out);
println!("------stderr------------------------------");
println!("{}", err);
println!("------------------------------------------");
eprintln!("------stdout------------------------------");
eprintln!("{}", out);
eprintln!("------stderr------------------------------");
eprintln!("{}", err);
eprintln!("------------------------------------------");
}
}

fn error(&self, err: &str) {
match self.revision {
Some(rev) => println!("\nerror in revision `{}`: {}", rev, err),
None => println!("\nerror: {}", err),
Some(rev) => eprintln!("\nerror in revision `{}`: {}", rev, err),
None => eprintln!("\nerror: {}", err),
}
}

@@ -1972,7 +1972,7 @@ impl<'test> TestCx<'test> {
if !self.config.has_html_tidy {
return;
}
println!("info: generating a diff against nightly rustdoc");
eprintln!("info: generating a diff against nightly rustdoc");

let suffix =
self.safe_revision().map_or("nightly".into(), |path| path.to_owned() + "-nightly");
@@ -2082,7 +2082,7 @@ impl<'test> TestCx<'test> {
.output()
.unwrap();
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));
} else {
use colored::Colorize;
@@ -2482,7 +2482,7 @@ impl<'test> TestCx<'test> {
)"#
)
.replace_all(&output, |caps: &Captures<'_>| {
println!("{}", &caps[0]);
eprintln!("{}", &caps[0]);
caps[0].replace(r"\", "/")
})
.replace("\r\n", "\n")
@@ -2581,16 +2581,16 @@ impl<'test> TestCx<'test> {
if let Err(err) = fs::write(&actual_path, &actual) {
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 =
expected_output_path(self.testpaths, self.revision, &self.config.compare_mode, stream);

if !self.config.bless {
if expected.is_empty() {
println!("normalized {}:\n{}\n", stream, actual);
eprintln!("normalized {}:\n{}\n", stream, actual);
} else {
println!("diff of {stream}:\n");
eprintln!("diff of {stream}:\n");
if let Some(diff_command) = self.config.diff_command.as_deref() {
let mut args = diff_command.split_whitespace();
let name = args.next().unwrap();
@@ -2625,10 +2625,10 @@ impl<'test> TestCx<'test> {
if let Err(err) = fs::write(&expected_path, &actual) {
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 }
}
@@ -2707,7 +2707,7 @@ impl<'test> TestCx<'test> {
fs::create_dir_all(&incremental_dir).unwrap();

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",
self.status,
self.cmdline,
@@ -2776,7 +2776,7 @@ impl ProcRes {

pub fn fatal(&self, err: Option<&str>, on_failure: impl FnOnce()) -> ! {
if let Some(e) = err {
println!("\nerror: {}", e);
eprintln!("\nerror: {}", e);
}
self.print_info();
on_failure();
22 changes: 11 additions & 11 deletions src/tools/compiletest/src/runtest/codegen_units.rs
Original file line number Diff line number Diff line change
@@ -64,13 +64,13 @@ impl TestCx<'_> {
if !missing.is_empty() {
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 {
println!("{}", item);
eprintln!("{}", item);
}

println!("\n");
eprintln!("\n");
}

if !unexpected.is_empty() {
@@ -80,24 +80,24 @@ impl TestCx<'_> {
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 {
println!("{}", item);
eprintln!("{}", item);
}

println!("\n");
eprintln!("\n");
}

if !wrong_cgus.is_empty() {
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 {
println!("{}", expected_item.name);
println!(" expected: {}", codegen_units_to_str(&expected_item.codegen_units));
println!(" actual: {}", codegen_units_to_str(&actual_item.codegen_units));
println!();
eprintln!("{}", expected_item.name);
eprintln!(" expected: {}", codegen_units_to_str(&expected_item.codegen_units));
eprintln!(" actual: {}", codegen_units_to_str(&actual_item.codegen_units));
eprintln!();
}
}

10 changes: 5 additions & 5 deletions src/tools/compiletest/src/runtest/debuginfo.rs
Original file line number Diff line number Diff line change
@@ -260,7 +260,7 @@ impl TestCx<'_> {
cmdline,
};
if adb.kill().is_err() {
println!("Adb process is already finished.");
eprintln!("Adb process is already finished.");
}
} else {
let rust_src_root =
@@ -275,7 +275,7 @@ impl TestCx<'_> {

match self.config.gdb_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() {
// Add the directory containing the pretty printers to
@@ -297,7 +297,7 @@ impl TestCx<'_> {
}
}
_ => {
println!(
eprintln!(
"NOTE: compiletest does not know which version of \
GDB it is using"
);
@@ -392,10 +392,10 @@ impl TestCx<'_> {

match self.config.lldb_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 \
LLDB it is using"
);
2 changes: 1 addition & 1 deletion src/tools/compiletest/src/runtest/rustdoc_json.rs
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@ impl TestCx<'_> {

if !res.status.success() {
self.fatal_proc_rec_with_ctx("jsondocck failed!", &res, |_| {
println!("Rustdoc Output:");
eprintln!("Rustdoc Output:");
proc_res.print_info();
})
}
4 changes: 2 additions & 2 deletions src/tools/compiletest/src/runtest/ui.rs
Original file line number Diff line number Diff line change
@@ -109,10 +109,10 @@ impl TestCx<'_> {
}

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 =
self.testpaths.relative_dir.join(self.testpaths.file.file_name().unwrap());
println!(
eprintln!(
"To only update this specific test, also pass `--test-args {}`",
relative_path_to_file.display(),
);
2 changes: 1 addition & 1 deletion src/tools/compiletest/src/util.rs
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ fn path_div() -> &'static str {
pub fn logv(config: &Config, s: String) {
debug!("{}", s);
if config.verbose {
println!("{}", s);
eprintln!("{}", s);
}
}

6 changes: 3 additions & 3 deletions src/tools/tidy/src/error_codes.rs
Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@ const IGNORE_UI_TEST_CHECK: &[&str] =
macro_rules! verbose_print {
($verbose:expr, $($fmt:tt)*) => {
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
let error_codes = extract_error_codes(root_path, &mut errors);
if verbose {
println!("Found {} error codes", error_codes.len());
println!("Highest error code: `{}`", error_codes.iter().max().unwrap());
eprintln!("Found {} error codes", error_codes.len());
eprintln!("Highest error code: `{}`", error_codes.iter().max().unwrap());
}

// Stage 2: check list has docs
8 changes: 4 additions & 4 deletions src/tools/tidy/src/features.rs
Original file line number Diff line number Diff line change
@@ -158,14 +158,14 @@ pub fn check(
.collect::<Vec<_>>();

for &(name, _) in gate_untested.iter() {
println!("Expected a gate test for the feature '{name}'.");
println!(
eprintln!("Expected a gate test for the feature '{name}'.");
eprintln!(
"Hint: create a failing test file named 'tests/ui/feature-gates/feature-gate-{}.rs',\
\n with its failures due to missing usage of `#![feature({})]`.",
name.replace("_", "-"),
name
);
println!(
eprintln!(
"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.",
name
@@ -218,7 +218,7 @@ pub fn check(

lines.sort();
for line in lines {
println!("* {line}");
eprintln!("* {line}");
}
}

8 changes: 4 additions & 4 deletions src/tools/tidy/src/unstable_book.rs
Original file line number Diff line number Diff line change
@@ -118,16 +118,16 @@ pub fn check(path: &Path, features: CollectedFeatures, bad: &mut bool) {
// List unstable features that don't have Unstable Book sections.
// 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 -
&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-
&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);
}
// */
}
2 changes: 1 addition & 1 deletion src/tools/tidy/src/x_version.rs
Original file line number Diff line number Diff line change
@@ -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 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`"
);
}
Original file line number Diff line number Diff line change
@@ -31,7 +31,6 @@
}
}
scope 9 (inlined NonNull::<[u8]>::as_ptr) {
let mut _17: *const [u8];
}
}
scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) {
@@ -102,16 +101,9 @@
StorageDead(_16);
StorageDead(_12);
StorageDead(_6);
- StorageLive(_17);
+ nop;
_17 = copy (_5.0: *const [u8]);
- _4 = move _17 as *mut [u8] (PtrToPtr);
- StorageDead(_17);
+ _4 = copy _17 as *mut [u8] (PtrToPtr);
+ nop;
_4 = copy _5 as *mut [u8] (Transmute);
StorageDead(_5);
- _3 = move _4 as *mut u8 (PtrToPtr);
+ _3 = copy _17 as *mut u8 (PtrToPtr);
_3 = move _4 as *mut u8 (PtrToPtr);
StorageDead(_4);
StorageDead(_3);
- StorageDead(_1);
Original file line number Diff line number Diff line change
@@ -20,7 +20,6 @@
scope 5 (inlined <std::alloc::Global as Allocator>::allocate) {
}
scope 6 (inlined NonNull::<[u8]>::as_ptr) {
let mut _12: *const [u8];
}
}
scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) {
@@ -45,16 +44,9 @@

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

bb1: {
StorageDead(_6);
- StorageLive(_12);
+ nop;
_12 = copy (_5.0: *const [u8]);
- _4 = move _12 as *mut [u8] (PtrToPtr);
- StorageDead(_12);
+ _4 = copy _12 as *mut [u8] (PtrToPtr);
+ nop;
_4 = copy _5 as *mut [u8] (Transmute);
StorageDead(_5);
- _3 = move _4 as *mut u8 (PtrToPtr);
+ _3 = copy _12 as *mut u8 (PtrToPtr);
_3 = move _4 as *mut u8 (PtrToPtr);
StorageDead(_4);
StorageDead(_3);
- StorageDead(_1);
Original file line number Diff line number Diff line change
@@ -4,28 +4,28 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
debug slice => _1;
debug f => _2;
let mut _0: ();
let mut _11: std::slice::Iter<'_, T>;
let mut _12: std::iter::Enumerate<std::slice::Iter<'_, T>>;
let mut _13: std::iter::Enumerate<std::slice::Iter<'_, T>>;
let mut _21: std::option::Option<(usize, &T)>;
let mut _24: &impl Fn(usize, &T);
let mut _25: (usize, &T);
let _26: ();
let mut _13: std::slice::Iter<'_, T>;
let mut _14: std::iter::Enumerate<std::slice::Iter<'_, T>>;
let mut _15: std::iter::Enumerate<std::slice::Iter<'_, T>>;
let mut _23: std::option::Option<(usize, &T)>;
let mut _26: &impl Fn(usize, &T);
let mut _27: (usize, &T);
let _28: ();
scope 1 {
debug iter => _13;
let _22: usize;
let _23: &T;
debug iter => _15;
let _24: usize;
let _25: &T;
scope 2 {
debug i => _22;
debug x => _23;
debug i => _24;
debug x => _25;
}
scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
let mut _14: &mut std::slice::Iter<'_, T>;
let mut _15: std::option::Option<&T>;
let mut _19: (usize, bool);
let mut _20: (usize, &T);
let mut _16: &mut std::slice::Iter<'_, T>;
let mut _17: std::option::Option<&T>;
let mut _21: (usize, bool);
let mut _22: (usize, &T);
scope 19 {
let _18: usize;
let _20: usize;
scope 24 {
}
}
@@ -40,8 +40,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
}
}
scope 25 (inlined <Option<&T> as Try>::branch) {
let mut _16: isize;
let _17: &T;
let mut _18: isize;
let _19: &T;
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 4 (inlined std::slice::Iter::<'_, T>::new) {
let _3: usize;
let mut _7: *mut T;
let mut _8: *mut T;
let mut _10: *const T;
let mut _5: std::ptr::NonNull<[T]>;
let mut _9: *mut T;
let mut _10: *mut T;
let mut _12: *const T;
scope 5 {
let _6: std::ptr::NonNull<T>;
let _8: std::ptr::NonNull<T>;
scope 6 {
let _9: *const T;
let _11: *const T;
scope 7 {
}
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>) {
let mut _5: *const T;
let mut _6: *mut [T];
let mut _7: *const T;
scope 11 (inlined NonNull::<[T]>::as_ptr) {
}
}
@@ -87,76 +89,82 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
}

bb0: {
StorageLive(_11);
StorageLive(_13);
StorageLive(_3);
StorageLive(_6);
StorageLive(_4);
StorageLive(_5);
StorageLive(_8);
_3 = PtrMetadata(copy _1);
StorageLive(_5);
StorageLive(_4);
_4 = &raw const (*_1);
_5 = copy _4 as *const T (PtrToPtr);
_6 = NonNull::<T> { pointer: copy _5 };
StorageLive(_9);
_5 = NonNull::<[T]> { pointer: move _4 };
StorageDead(_4);
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];
}

bb1: {
StorageLive(_8);
StorageLive(_7);
_7 = copy _4 as *mut T (PtrToPtr);
_8 = Offset(copy _7, copy _3);
StorageDead(_7);
_9 = move _8 as *const T (PtrToPtr);
StorageDead(_8);
StorageLive(_10);
StorageLive(_9);
_9 = copy _8 as *mut T (Transmute);
_10 = Offset(copy _9, copy _3);
StorageDead(_9);
_11 = move _10 as *const T (PtrToPtr);
StorageDead(_10);
goto -> bb3;
}

bb2: {
_9 = copy _3 as *const T (Transmute);
_11 = copy _3 as *const T (Transmute);
goto -> 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);
_12 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _11, count: const 0_usize };
StorageLive(_12);
_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);
StorageLive(_13);
_13 = copy _12;
StorageDead(_8);
StorageDead(_3);
_14 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _13, count: const 0_usize };
StorageDead(_13);
StorageLive(_15);
_15 = copy _14;
goto -> bb4;
}

bb4: {
StorageLive(_23);
StorageLive(_20);
StorageLive(_21);
StorageLive(_18);
StorageLive(_19);
StorageLive(_15);
StorageLive(_14);
_14 = &mut (_13.0: std::slice::Iter<'_, T>);
_15 = <std::slice::Iter<'_, T> as Iterator>::next(move _14) -> [return: bb5, unwind unreachable];
StorageLive(_17);
StorageLive(_16);
_16 = &mut (_15.0: std::slice::Iter<'_, T>);
_17 = <std::slice::Iter<'_, T> as Iterator>::next(move _16) -> [return: bb5, unwind unreachable];
}

bb5: {
StorageDead(_14);
StorageLive(_16);
_16 = discriminant(_15);
switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb11];
StorageDead(_16);
StorageLive(_18);
_18 = discriminant(_17);
switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb11];
}

bb6: {
StorageDead(_16);
StorageDead(_15);
StorageDead(_19);
StorageDead(_18);
StorageDead(_17);
StorageDead(_21);
StorageDead(_13);
StorageDead(_20);
StorageDead(_23);
StorageDead(_15);
drop(_2) -> [return: bb7, unwind unreachable];
}

@@ -165,35 +173,35 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
}

bb8: {
_17 = move ((_15 as Some).0: &T);
StorageDead(_16);
StorageDead(_15);
_18 = copy (_13.1: usize);
_19 = AddWithOverflow(copy (_13.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];
_19 = move ((_17 as Some).0: &T);
StorageDead(_18);
StorageDead(_17);
_20 = copy (_15.1: usize);
_21 = AddWithOverflow(copy (_15.1: usize), const 1_usize);
assert(!move (_21.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_15.1: usize), const 1_usize) -> [success: bb9, unwind unreachable];
}

bb9: {
(_13.1: usize) = move (_19.0: usize);
StorageLive(_20);
_20 = (copy _18, copy _17);
_21 = Option::<(usize, &T)>::Some(move _20);
(_15.1: usize) = move (_21.0: usize);
StorageLive(_22);
_22 = (copy _20, copy _19);
_23 = Option::<(usize, &T)>::Some(move _22);
StorageDead(_22);
StorageDead(_21);
StorageDead(_20);
StorageDead(_19);
StorageDead(_18);
_22 = copy (((_21 as Some).0: (usize, &T)).0: usize);
_23 = copy (((_21 as Some).0: (usize, &T)).1: &T);
StorageLive(_24);
_24 = &_2;
StorageLive(_25);
_25 = (copy _22, copy _23);
_26 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _24, move _25) -> [return: bb10, unwind unreachable];
_24 = copy (((_23 as Some).0: (usize, &T)).0: usize);
_25 = copy (((_23 as Some).0: (usize, &T)).1: &T);
StorageLive(_26);
_26 = &_2;
StorageLive(_27);
_27 = (copy _24, copy _25);
_28 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _26, move _27) -> [return: bb10, unwind unreachable];
}

bb10: {
StorageDead(_25);
StorageDead(_24);
StorageDead(_21);
StorageDead(_27);
StorageDead(_26);
StorageDead(_23);
goto -> bb4;
}

Loading