Auto merge of #134223 - matthiaskrgr:rollup-qy69vqb, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #133122 (Add unpolished, experimental support for AFIDT (async fn in dyn trait))
 - #133249 (ABI checks: add support for loongarch)
 - #134089 (Use newly added exceptions to non default branch warning)
 - #134188 (Bump Fuchsia)
 - #134204 (Fix our `llvm::Bool` typedef to be signed, to match `LLVMBool`)
 - #134207 (Revert "bootstrap: print{ln}! -> eprint{ln}! (take 2) #134040")
 - #134214 (rustdoc: fix self cmp)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors
2024-12-12 18:53:32 +00:00
60 changed files with 847 additions and 251 deletions
+3 -1
View File
@@ -17,7 +17,9 @@
DebugEmissionKind, DebugNameTableKind,
};
pub type Bool = c_uint;
/// In the LLVM-C API, boolean values are passed as `typedef int LLVMBool`,
/// which has a different ABI from Rust or C++ `bool`.
pub type Bool = c_int;
pub const True: Bool = 1 as Bool;
pub const False: Bool = 0 as Bool;
+2
View File
@@ -390,6 +390,8 @@ pub fn internal(&self, feature: Symbol) -> bool {
(unstable, associated_type_defaults, "1.2.0", Some(29661)),
/// Allows `async || body` closures.
(unstable, async_closure, "1.37.0", Some(62290)),
/// Allows async functions to be called from `dyn Trait`.
(incomplete, async_fn_in_dyn_trait, "CURRENT_RUSTC_VERSION", Some(133119)),
/// Allows `#[track_caller]` on async functions.
(unstable, async_fn_track_caller, "1.73.0", Some(110011)),
/// Allows `for await` loops.
+20 -17
View File
@@ -677,23 +677,26 @@ pub fn expect_resolve_for_vtable(
//
// 1) The underlying method expects a caller location parameter
// in the ABI
if resolved.def.requires_caller_location(tcx)
// 2) The caller location parameter comes from having `#[track_caller]`
// on the implementation, and *not* on the trait method.
&& !tcx.should_inherit_track_caller(def)
// If the method implementation comes from the trait definition itself
// (e.g. `trait Foo { #[track_caller] my_fn() { /* impl */ } }`),
// then we don't need to generate a shim. This check is needed because
// `should_inherit_track_caller` returns `false` if our method
// implementation comes from the trait block, and not an impl block
&& !matches!(
tcx.opt_associated_item(def),
Some(ty::AssocItem {
container: ty::AssocItemContainer::Trait,
..
})
)
{
let needs_track_caller_shim = resolved.def.requires_caller_location(tcx)
// 2) The caller location parameter comes from having `#[track_caller]`
// on the implementation, and *not* on the trait method.
&& !tcx.should_inherit_track_caller(def)
// If the method implementation comes from the trait definition itself
// (e.g. `trait Foo { #[track_caller] my_fn() { /* impl */ } }`),
// then we don't need to generate a shim. This check is needed because
// `should_inherit_track_caller` returns `false` if our method
// implementation comes from the trait block, and not an impl block
&& !matches!(
tcx.opt_associated_item(def),
Some(ty::AssocItem {
container: ty::AssocItemContainer::Trait,
..
})
);
// We also need to generate a shim if this is an AFIT.
let needs_rpitit_shim =
tcx.return_position_impl_trait_in_trait_shim_data(def).is_some();
if needs_track_caller_shim || needs_rpitit_shim {
if tcx.is_closure_like(def) {
debug!(
" => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}",
+1
View File
@@ -146,6 +146,7 @@
mod parameterized;
mod predicate;
mod region;
mod return_position_impl_trait_in_trait;
mod rvalue_scopes;
mod structural_impls;
#[allow(hidden_glob_reexports)]
@@ -0,0 +1,95 @@
use rustc_hir::def_id::DefId;
use crate::ty::{self, ExistentialPredicateStableCmpExt, TyCtxt};
impl<'tcx> TyCtxt<'tcx> {
/// Given a `def_id` of a trait or impl method, compute whether that method needs to
/// have an RPITIT shim applied to it for it to be object safe. If so, return the
/// `def_id` of the RPITIT, and also the args of trait method that returns the RPITIT.
///
/// NOTE that these args are not, in general, the same as than the RPITIT's args. They
/// are a subset of those args, since they do not include the late-bound lifetimes of
/// the RPITIT. Depending on the context, these will need to be dealt with in different
/// ways -- in codegen, it's okay to fill them with ReErased.
pub fn return_position_impl_trait_in_trait_shim_data(
self,
def_id: DefId,
) -> Option<(DefId, ty::EarlyBinder<'tcx, ty::GenericArgsRef<'tcx>>)> {
let assoc_item = self.opt_associated_item(def_id)?;
let (trait_item_def_id, opt_impl_def_id) = match assoc_item.container {
ty::AssocItemContainer::Impl => {
(assoc_item.trait_item_def_id?, Some(self.parent(def_id)))
}
ty::AssocItemContainer::Trait => (def_id, None),
};
let sig = self.fn_sig(trait_item_def_id);
// Check if the trait returns an RPITIT.
let ty::Alias(ty::Projection, ty::AliasTy { def_id, .. }) =
*sig.skip_binder().skip_binder().output().kind()
else {
return None;
};
if !self.is_impl_trait_in_trait(def_id) {
return None;
}
let args = if let Some(impl_def_id) = opt_impl_def_id {
// Rebase the args from the RPITIT onto the impl trait ref, so we can later
// substitute them with the method args of the *impl* method, since that's
// the instance we're building a vtable shim for.
ty::GenericArgs::identity_for_item(self, trait_item_def_id).rebase_onto(
self,
self.parent(trait_item_def_id),
self.impl_trait_ref(impl_def_id)
.expect("expected impl trait ref from parent of impl item")
.instantiate_identity()
.args,
)
} else {
// This is when we have a default trait implementation.
ty::GenericArgs::identity_for_item(self, trait_item_def_id)
};
Some((def_id, ty::EarlyBinder::bind(args)))
}
/// Given a `DefId` of an RPITIT and its args, return the existential predicates
/// that corresponds to the RPITIT's bounds with the self type erased.
pub fn item_bounds_to_existential_predicates(
self,
def_id: DefId,
args: ty::GenericArgsRef<'tcx>,
) -> &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
let mut bounds: Vec<_> = self
.item_super_predicates(def_id)
.iter_instantiated(self, args)
.filter_map(|clause| {
clause
.kind()
.map_bound(|clause| match clause {
ty::ClauseKind::Trait(trait_pred) => Some(ty::ExistentialPredicate::Trait(
ty::ExistentialTraitRef::erase_self_ty(self, trait_pred.trait_ref),
)),
ty::ClauseKind::Projection(projection_pred) => {
Some(ty::ExistentialPredicate::Projection(
ty::ExistentialProjection::erase_self_ty(self, projection_pred),
))
}
ty::ClauseKind::TypeOutlives(_) => {
// Type outlives bounds don't really turn into anything,
// since we must use an intersection region for the `dyn*`'s
// region anyways.
None
}
_ => unreachable!("unexpected clause in item bounds: {clause:?}"),
})
.transpose()
})
.collect();
bounds.sort_by(|a, b| a.skip_binder().stable_cmp(self, &b.skip_binder()));
self.mk_poly_existential_predicates(&bounds)
}
}
+53 -3
View File
@@ -9,6 +9,7 @@
use rustc_middle::mir::patch::MirPatch;
use rustc_middle::mir::*;
use rustc_middle::query::Providers;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::{
self, CoroutineArgs, CoroutineArgsExt, EarlyBinder, GenericArgs, Ty, TyCtxt,
};
@@ -710,6 +711,13 @@ fn build_call_shim<'tcx>(
};
let def_id = instance.def_id();
let rpitit_shim = if let ty::InstanceKind::ReifyShim(..) = instance {
tcx.return_position_impl_trait_in_trait_shim_data(def_id)
} else {
None
};
let sig = tcx.fn_sig(def_id);
let sig = sig.map_bound(|sig| tcx.instantiate_bound_regions_with_erased(sig));
@@ -765,9 +773,34 @@ fn build_call_shim<'tcx>(
let mut local_decls = local_decls_for_sig(&sig, span);
let source_info = SourceInfo::outermost(span);
let mut destination = Place::return_place();
if let Some((rpitit_def_id, fn_args)) = rpitit_shim {
let rpitit_args =
fn_args.instantiate_identity().extend_to(tcx, rpitit_def_id, |param, _| {
match param.kind {
ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
ty::GenericParamDefKind::Type { .. }
| ty::GenericParamDefKind::Const { .. } => {
unreachable!("rpitit should have no addition ty/ct")
}
}
});
let dyn_star_ty = Ty::new_dynamic(
tcx,
tcx.item_bounds_to_existential_predicates(rpitit_def_id, rpitit_args),
tcx.lifetimes.re_erased,
ty::DynStar,
);
destination = local_decls.push(local_decls[RETURN_PLACE].clone()).into();
local_decls[RETURN_PLACE].ty = dyn_star_ty;
let mut inputs_and_output = sig.inputs_and_output.to_vec();
*inputs_and_output.last_mut().unwrap() = dyn_star_ty;
sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
}
let rcvr_place = || {
assert!(rcvr_adjustment.is_some());
Place::from(Local::new(1 + 0))
Place::from(Local::new(1))
};
let mut statements = vec![];
@@ -854,7 +887,7 @@ fn build_call_shim<'tcx>(
TerminatorKind::Call {
func: callee,
args,
destination: Place::return_place(),
destination,
target: Some(BasicBlock::new(1)),
unwind: if let Some(Adjustment::RefMut) = rcvr_adjustment {
UnwindAction::Cleanup(BasicBlock::new(3))
@@ -882,7 +915,24 @@ fn build_call_shim<'tcx>(
);
}
// BB #1/#2 - return
block(&mut blocks, vec![], TerminatorKind::Return, false);
// NOTE: If this is an RPITIT in dyn, we also want to coerce
// the return type of the function into a `dyn*`.
let stmts = if rpitit_shim.is_some() {
vec![Statement {
source_info,
kind: StatementKind::Assign(Box::new((
Place::return_place(),
Rvalue::Cast(
CastKind::PointerCoercion(PointerCoercion::DynStar, CoercionSource::Implicit),
Operand::Move(destination),
sig.output(),
),
))),
}]
} else {
vec![]
};
block(&mut blocks, stmts, TerminatorKind::Return, false);
if let Some(Adjustment::RefMut) = rcvr_adjustment {
// BB #3 - drop if closure panics
block(
+4 -1
View File
@@ -42,7 +42,10 @@ fn custom_coerce_unsize_info<'tcx>(
..
})) => Ok(tcx.coerce_unsized_info(impl_def_id)?.custom_kind.unwrap()),
impl_source => {
bug!("invalid `CoerceUnsized` impl_source: {:?}", impl_source);
bug!(
"invalid `CoerceUnsized` from {source_ty} to {target_ty}: impl_source: {:?}",
impl_source
);
}
}
}
+1
View File
@@ -461,6 +461,7 @@
async_drop_slice,
async_drop_surface_drop_in_place,
async_fn,
async_fn_in_dyn_trait,
async_fn_in_trait,
async_fn_kind_helper,
async_fn_kind_upvars,
+3 -1
View File
@@ -611,6 +611,8 @@ pub fn all_rust_features() -> impl Iterator<Item = (&'static str, Stability)> {
&[/*(512, "hvx-length64b"),*/ (1024, "hvx-length128b")];
const MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "msa")];
const CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vdspv1")];
const LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
&[(128, "lsx"), (256, "lasx")];
impl super::spec::Target {
pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] {
@@ -638,7 +640,7 @@ pub fn features_for_correct_vector_abi(&self) -> &'static [(u64, &'static str)]
"aarch64" | "arm64ec" => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI,
"arm" => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI,
"powerpc" | "powerpc64" => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI,
"loongarch64" => &[], // on-stack ABI, so we complain about all by-val vectors
"loongarch64" => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI,
"riscv32" | "riscv64" => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI,
"wasm32" | "wasm64" => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI,
"s390x" => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI,
@@ -11,6 +11,7 @@
use rustc_errors::FatalError;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_middle::bug;
use rustc_middle::query::Providers;
use rustc_middle::ty::{
self, EarlyBinder, ExistentialPredicateStableCmpExt as _, GenericArgs, Ty, TyCtxt,
@@ -901,23 +902,59 @@ fn contains_illegal_impl_trait_in_trait<'tcx>(
fn_def_id: DefId,
ty: ty::Binder<'tcx, Ty<'tcx>>,
) -> Option<MethodViolationCode> {
// This would be caught below, but rendering the error as a separate
// `async-specific` message is better.
if tcx.asyncness(fn_def_id).is_async() {
return Some(MethodViolationCode::AsyncFn);
}
let ty = tcx.liberate_late_bound_regions(fn_def_id, ty);
if tcx.asyncness(fn_def_id).is_async() {
// FIXME(async_fn_in_dyn_trait): Think of a better way to unify these code paths
// to issue an appropriate feature suggestion when users try to use AFIDT.
// Obviously we must only do this once AFIDT is finished enough to actually be usable.
if tcx.features().async_fn_in_dyn_trait() {
let ty::Alias(ty::Projection, proj) = *ty.kind() else {
bug!("expected async fn in trait to return an RPITIT");
};
assert!(tcx.is_impl_trait_in_trait(proj.def_id));
// FIXME(async_fn_in_dyn_trait): We should check that this bound is legal too,
// and stop relying on `async fn` in the definition.
for bound in tcx.item_bounds(proj.def_id).instantiate(tcx, proj.args) {
if let Some(violation) = bound
.visit_with(&mut IllegalRpititVisitor { tcx, allowed: Some(proj) })
.break_value()
{
return Some(violation);
}
}
// FIXME(RPITIT): Perhaps we should use a visitor here?
ty.skip_binder().walk().find_map(|arg| {
if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Alias(ty::Projection, proj) = ty.kind()
&& tcx.is_impl_trait_in_trait(proj.def_id)
{
Some(MethodViolationCode::ReferencesImplTraitInTrait(tcx.def_span(proj.def_id)))
} else {
None
} else {
// Rendering the error as a separate `async-specific` message is better.
Some(MethodViolationCode::AsyncFn)
}
})
} else {
ty.visit_with(&mut IllegalRpititVisitor { tcx, allowed: None }).break_value()
}
}
struct IllegalRpititVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
allowed: Option<ty::AliasTy<'tcx>>,
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IllegalRpititVisitor<'tcx> {
type Result = ControlFlow<MethodViolationCode>;
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
if let ty::Alias(ty::Projection, proj) = *ty.kind()
&& Some(proj) != self.allowed
&& self.tcx.is_impl_trait_in_trait(proj.def_id)
{
ControlFlow::Break(MethodViolationCode::ReferencesImplTraitInTrait(
self.tcx.def_span(proj.def_id),
))
} else {
ty.super_visit_with(self)
}
}
}
pub(crate) fn provide(providers: &mut Providers) {
@@ -7,8 +7,8 @@
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::DefKind;
use rustc_hir::lang_items::LangItem;
use rustc_infer::infer::DefineOpaqueTypes;
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
use rustc_infer::infer::{DefineOpaqueTypes, RegionVariableOrigin};
use rustc_infer::traits::{ObligationCauseCode, PredicateObligations};
use rustc_middle::traits::select::OverflowError;
use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData};
@@ -18,6 +18,7 @@
use rustc_middle::ty::{self, Term, Ty, TyCtxt, TypingMode, Upcast};
use rustc_middle::{bug, span_bug};
use rustc_span::symbol::sym;
use thin_vec::thin_vec;
use tracing::{debug, instrument};
use super::{
@@ -61,6 +62,9 @@ enum ProjectionCandidate<'tcx> {
/// Bounds specified on an object type
Object(ty::PolyProjectionPredicate<'tcx>),
/// Built-in bound for a dyn async fn in trait
ObjectRpitit,
/// From an "impl" (or a "pseudo-impl" returned by select)
Select(Selection<'tcx>),
}
@@ -827,6 +831,17 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
env_predicates,
false,
);
// `dyn Trait` automagically project their AFITs to `dyn* Future`.
if tcx.is_impl_trait_in_trait(obligation.predicate.def_id)
&& let Some(out_trait_def_id) = data.principal_def_id()
&& let rpitit_trait_def_id = tcx.parent(obligation.predicate.def_id)
&& tcx
.supertrait_def_ids(out_trait_def_id)
.any(|trait_def_id| trait_def_id == rpitit_trait_def_id)
{
candidate_set.push_candidate(ProjectionCandidate::ObjectRpitit);
}
}
#[instrument(
@@ -1247,6 +1262,8 @@ fn confirm_candidate<'cx, 'tcx>(
ProjectionCandidate::Select(impl_source) => {
confirm_select_candidate(selcx, obligation, impl_source)
}
ProjectionCandidate::ObjectRpitit => confirm_object_rpitit_candidate(selcx, obligation),
};
// When checking for cycle during evaluation, we compare predicates with
@@ -2034,6 +2051,45 @@ fn confirm_impl_candidate<'cx, 'tcx>(
}
}
fn confirm_object_rpitit_candidate<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionTermObligation<'tcx>,
) -> Progress<'tcx> {
let tcx = selcx.tcx();
let mut obligations = thin_vec![];
// Compute an intersection lifetime for all the input components of this GAT.
let intersection =
selcx.infcx.next_region_var(RegionVariableOrigin::MiscVariable(obligation.cause.span));
for component in obligation.predicate.args {
match component.unpack() {
ty::GenericArgKind::Lifetime(lt) => {
obligations.push(obligation.with(tcx, ty::OutlivesPredicate(lt, intersection)));
}
ty::GenericArgKind::Type(ty) => {
obligations.push(obligation.with(tcx, ty::OutlivesPredicate(ty, intersection)));
}
ty::GenericArgKind::Const(_ct) => {
// Consts have no outlives...
}
}
}
Progress {
term: Ty::new_dynamic(
tcx,
tcx.item_bounds_to_existential_predicates(
obligation.predicate.def_id,
obligation.predicate.args,
),
intersection,
ty::DynStar,
)
.into(),
obligations,
}
}
// Get obligations corresponding to the predicates from the where-clause of the
// associated type itself.
fn assoc_ty_own_obligations<'cx, 'tcx>(
@@ -19,6 +19,7 @@
use rustc_middle::ty::{self, GenericArgsRef, ToPolyTraitRef, Ty, TyCtxt, Upcast};
use rustc_middle::{bug, span_bug};
use rustc_span::def_id::DefId;
use rustc_type_ir::elaborate;
use tracing::{debug, instrument};
use super::SelectionCandidate::{self, *};
@@ -624,6 +625,12 @@ fn confirm_object_candidate(
for assoc_type in assoc_types {
let defs: &ty::Generics = tcx.generics_of(assoc_type);
// When `async_fn_in_dyn_trait` is enabled, we don't need to check the
// RPITIT for compatibility, since it's not provided by the user.
if tcx.features().async_fn_in_dyn_trait() && tcx.is_impl_trait_in_trait(assoc_type) {
continue;
}
if !defs.own_params.is_empty() {
tcx.dcx().span_delayed_bug(
obligation.cause.span,
@@ -1175,6 +1182,38 @@ fn confirm_builtin_unsize_candidate(
ty::ClauseKind::TypeOutlives(outlives).upcast(tcx),
));
// Require that all AFIT will return something that can be coerced into `dyn*`
// -- a shim will be responsible for doing the actual coercion to `dyn*`.
if let Some(principal) = data.principal() {
for supertrait in
elaborate::supertraits(tcx, principal.with_self_ty(tcx, source))
{
if tcx.is_trait_alias(supertrait.def_id()) {
continue;
}
for &assoc_item in tcx.associated_item_def_ids(supertrait.def_id()) {
if !tcx.is_impl_trait_in_trait(assoc_item) {
continue;
}
// RPITITs with `Self: Sized` don't need to be checked.
if tcx.generics_require_sized_self(assoc_item) {
continue;
}
let pointer_like_goal = pointer_like_goal_for_rpitit(
tcx,
supertrait,
assoc_item,
&obligation.cause,
);
nested.push(predicate_to_obligation(pointer_like_goal.upcast(tcx)));
}
}
}
ImplSource::Builtin(BuiltinImplSource::Misc, nested)
}
@@ -1280,3 +1319,43 @@ fn confirm_builtin_unsize_candidate(
})
}
}
/// Compute a goal that some RPITIT (right now, only RPITITs corresponding to Futures)
/// implements the `PointerLike` trait, which is a requirement for the RPITIT to be
/// coercible to `dyn* Future`, which is itself a requirement for the RPITIT's parent
/// trait to be coercible to `dyn Trait`.
///
/// We do this given a supertrait's substitutions, and then augment the substitutions
/// with bound variables to compute the goal universally. Given that `PointerLike` has
/// no region requirements (at least for the built-in pointer types), this shouldn't
/// *really* matter, but it is the best choice for soundness.
fn pointer_like_goal_for_rpitit<'tcx>(
tcx: TyCtxt<'tcx>,
supertrait: ty::PolyTraitRef<'tcx>,
rpitit_item: DefId,
cause: &ObligationCause<'tcx>,
) -> ty::PolyTraitRef<'tcx> {
let mut bound_vars = supertrait.bound_vars().to_vec();
let args = supertrait.skip_binder().args.extend_to(tcx, rpitit_item, |arg, _| match arg.kind {
ty::GenericParamDefKind::Lifetime => {
let kind = ty::BoundRegionKind::Named(arg.def_id, tcx.item_name(arg.def_id));
bound_vars.push(ty::BoundVariableKind::Region(kind));
ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion {
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
kind,
})
.into()
}
ty::GenericParamDefKind::Type { .. } | ty::GenericParamDefKind::Const { .. } => {
unreachable!()
}
});
ty::Binder::bind_with_vars(
ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::PointerLike, Some(cause.span)), [
Ty::new_projection_from_args(tcx, rpitit_item, args),
]),
tcx.mk_bound_variable_kinds(&bound_vars),
)
}
+26
View File
@@ -48,12 +48,38 @@ fn fn_sig_for_fn_abi<'tcx>(
let mut sig = tcx
.instantiate_bound_regions_with_erased(tcx.fn_sig(def_id).instantiate(tcx, args));
// Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`.
if let ty::InstanceKind::VTableShim(..) = instance.def {
let mut inputs_and_output = sig.inputs_and_output.to_vec();
inputs_and_output[0] = Ty::new_mut_ptr(tcx, inputs_and_output[0]);
sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
}
// Modify `fn() -> impl Future` to `fn() -> dyn* Future`.
if let ty::InstanceKind::ReifyShim(def_id, _) = instance.def
&& let Some((rpitit_def_id, fn_args)) =
tcx.return_position_impl_trait_in_trait_shim_data(def_id)
{
let fn_args = fn_args.instantiate(tcx, args);
let rpitit_args =
fn_args.extend_to(tcx, rpitit_def_id, |param, _| match param.kind {
ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
ty::GenericParamDefKind::Type { .. }
| ty::GenericParamDefKind::Const { .. } => {
unreachable!("rpitit should have no addition ty/ct")
}
});
let dyn_star_ty = Ty::new_dynamic(
tcx,
tcx.item_bounds_to_existential_predicates(rpitit_def_id, rpitit_args),
tcx.lifetimes.re_erased,
ty::DynStar,
);
let mut inputs_and_output = sig.inputs_and_output.to_vec();
*inputs_and_output.last_mut().unwrap() = dyn_star_ty;
sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
}
sig
}
ty::Closure(def_id, args) => {
+10 -10
View File
@@ -48,9 +48,9 @@ fn main() {
err => {
drop(err);
if let Ok(pid) = pid {
eprintln!("WARNING: build directory locked by process {pid}, waiting for lock");
println!("WARNING: build directory locked by process {pid}, waiting for lock");
} else {
eprintln!("WARNING: build directory locked, waiting for lock");
println!("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 {
eprintln!("WARNING: you have not made a `config.toml`");
eprintln!(
println!("WARNING: you have not made a `config.toml`");
println!(
"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 {
eprintln!("{suggestion}");
println!("{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 {
eprintln!("WARNING: you have not made a `config.toml`");
eprintln!(
println!("WARNING: you have not made a `config.toml`");
println!(
"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 {
eprintln!("{suggestion}");
println!("{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")
}) {
eprintln!(
println!(
"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() {
eprintln!("NOTE: this message was printed twice to make it more likely to be seen");
println!("NOTE: this message was printed twice to make it more likely to be seen");
}
if dump_bootstrap_shims {
+1 -1
View File
@@ -306,7 +306,7 @@ fn main() {
// should run on success, after this block.
}
if verbose > 0 {
eprintln!("\nDid not run successfully: {status}\n{cmd:?}\n-------------");
println!("\nDid not run successfully: {status}\n{cmd:?}\n-------------");
}
if let Some(mut on_fail) = on_fail {
+1 -1
View File
@@ -287,7 +287,7 @@ fn make_run(run: RunConfig<'_>) {
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" {
eprintln!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled.");
println!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled.");
return;
}
@@ -1611,7 +1611,7 @@ fn run(self, builder: &Builder<'_>) -> PathBuf {
let sysroot = sysroot_dir(compiler.stage);
builder
.verbose(|| eprintln!("Removing sysroot {} to avoid caching bugs", sysroot.display()));
.verbose(|| println!("Removing sysroot {} to avoid caching bugs", sysroot.display()));
let _ = fs::remove_dir_all(&sysroot);
t!(fs::create_dir_all(&sysroot));
@@ -1681,7 +1681,7 @@ fn run(self, builder: &Builder<'_>) -> PathBuf {
return true;
}
if !filtered_files.iter().all(|f| f != path.file_name().unwrap()) {
builder.verbose_than(1, || eprintln!("ignoring {}", path.display()));
builder.verbose_than(1, || println!("ignoring {}", path.display()));
false
} else {
true
@@ -2240,7 +2240,7 @@ pub fn stream_cargo(
cargo.arg(arg);
}
builder.verbose(|| eprintln!("running: {cargo:?}"));
builder.verbose(|| println!("running: {cargo:?}"));
if builder.config.dry_run() {
return true;
@@ -2266,7 +2266,7 @@ pub fn stream_cargo(
cb(msg)
}
// If this was informational, just print it out and continue
Err(_) => eprintln!("{line}"),
Err(_) => println!("{line}"),
}
}
+1 -1
View File
@@ -2080,7 +2080,7 @@ fn maybe_install_llvm(
{
let mut cmd = command(llvm_config);
cmd.arg("--libfiles");
builder.verbose(|| eprintln!("running {cmd:?}"));
builder.verbose(|| println!("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);
+3 -3
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 len <= 10 {
for path in paths {
eprintln!("fmt: {verb} {adjective}file {path}");
println!("fmt: {verb} {adjective}file {path}");
}
} else {
eprintln!("fmt: {verb} {len} {adjective}files");
println!("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() {
eprintln!("fmt info: No modified files detected for formatting.");
println!("fmt info: No modified files detected for formatting.");
return;
}
+23 -23
View File
@@ -134,7 +134,7 @@ fn make_run(run: RunConfig<'_>) {
t!(fs::remove_file(path));
}
_ => {
eprintln!("Exiting.");
println!("Exiting.");
crate::exit!(1);
}
}
@@ -184,15 +184,15 @@ pub fn setup(config: &Config, profile: Profile) {
Profile::Dist => &["dist", "build"],
};
eprintln!();
println!();
eprintln!("To get started, try one of the following commands:");
println!("To get started, try one of the following commands:");
for cmd in suggestions {
eprintln!("- `x.py {cmd}`");
println!("- `x.py {cmd}`");
}
if profile != Profile::Dist {
eprintln!(
println!(
"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);
eprintln!("`x.py` will now use the configuration at {}", include_path.display());
println!("`x.py` will now use the configuration at {}", include_path.display());
}
/// Creates a toolchain link for stage1 using `rustup`
@@ -256,7 +256,7 @@ fn run(self, builder: &Builder<'_>) -> Self::Output {
}
if !rustup_installed(builder) {
eprintln!("WARNING: `rustup` is not installed; Skipping `stage1` toolchain linking.");
println!("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) {
eprintln!(
println!(
"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.
eprintln!(
println!(
"`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.
eprintln!(
println!(
"`rustup` failed to list current toolchains; not attempting to link `stage1` toolchain"
);
}
@@ -389,12 +389,12 @@ fn parse_with_abbrev(input: &str) -> Result<Profile, String> {
input.parse()
}
eprintln!("Welcome to the Rust project! What do you want to do with x.py?");
println!("Welcome to the Rust project! What do you want to do with x.py?");
for ((letter, _), profile) in abbrev_all() {
eprintln!("{}) {}: {}", letter, profile, profile.purpose());
println!("{}) {}: {}", letter, profile, profile.purpose());
}
let template = loop {
eprint!(
print!(
"Please choose one ({}): ",
abbrev_all().map(|((l, _), _)| l).collect::<Vec<_>>().join("/")
);
@@ -428,7 +428,7 @@ enum PromptResult {
fn prompt_user(prompt: &str) -> io::Result<Option<PromptResult>> {
let mut input = String::new();
loop {
eprint!("{prompt} ");
print!("{prompt} ");
io::stdout().flush()?;
input.clear();
io::stdin().read_line(&mut input)?;
@@ -490,7 +490,7 @@ fn install_git_hook_maybe(builder: &Builder<'_>, config: &Config) -> io::Result<
return Ok(());
}
eprintln!(
println!(
"\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
@@ -498,7 +498,7 @@ fn install_git_hook_maybe(builder: &Builder<'_>, config: &Config) -> io::Result<
);
if prompt_user("Would you like to install the git hook?: [y/N]")? != Some(PromptResult::Yes) {
eprintln!("Ok, skipping installation!");
println!("Ok, skipping installation!");
return Ok(());
}
if !hooks_dir.exists() {
@@ -515,7 +515,7 @@ fn install_git_hook_maybe(builder: &Builder<'_>, config: &Config) -> io::Result<
);
return Err(e);
}
Ok(_) => eprintln!("Linked `src/etc/pre-push.sh` to `.git/hooks/pre-push`"),
Ok(_) => println!("Linked `src/etc/pre-push.sh` to `.git/hooks/pre-push`"),
};
Ok(())
}
@@ -541,7 +541,7 @@ fn prompt_user() -> io::Result<Option<EditorKind>> {
let mut input = String::new();
loop {
eprint!("{}", prompt_str);
print!("{}", prompt_str);
io::stdout().flush()?;
input.clear();
io::stdin().read_line(&mut input)?;
@@ -656,7 +656,7 @@ fn run(self, builder: &Builder<'_>) -> Self::Output {
if let Some(editor_kind) = editor_kind {
while !t!(create_editor_settings_maybe(config, editor_kind.clone())) {}
} else {
eprintln!("Ok, skipping editor setup!");
println!("Ok, skipping editor setup!");
}
}
Err(e) => eprintln!("Could not determine the editor: {e}"),
@@ -689,7 +689,7 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu
mismatched_settings = Some(false);
}
}
eprintln!(
println!(
"\nx.py can automatically install the recommended `{settings_filename}` file for rustc development"
);
@@ -708,7 +708,7 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu
Some(PromptResult::Yes) => true,
Some(PromptResult::Print) => false,
_ => {
eprintln!("Ok, skipping settings!");
println!("Ok, skipping settings!");
return Ok(true);
}
};
@@ -735,9 +735,9 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu
_ => "Created",
};
fs::write(&settings_path, editor.settings_template())?;
eprintln!("{verb} `{}`", settings_filename);
println!("{verb} `{}`", settings_filename);
} else {
eprintln!("\n{}", editor.settings_template());
println!("\n{}", editor.settings_template());
}
Ok(should_create)
}
@@ -66,6 +66,6 @@ pub fn suggest(builder: &Builder<'_>, run: bool) {
build.build();
}
} else {
eprintln!("HELP: consider using the `--run` flag to automatically run suggested tests");
println!("HELP: consider using the `--run` flag to automatically run suggested tests");
}
}
+3 -3
View File
@@ -471,11 +471,11 @@ pub fn build_miri_sysroot(
// We re-use the `cargo` from above.
cargo.arg("--print-sysroot");
builder.verbose(|| eprintln!("running: {cargo:?}"));
builder.verbose(|| println!("running: {cargo:?}"));
let stdout = cargo.run_capture_stdout(builder).stdout();
// Output is "<sysroot>\n".
let sysroot = stdout.trim_end();
builder.verbose(|| eprintln!("`cargo miri setup --print-sysroot` said: {sysroot:?}"));
builder.verbose(|| println!("`cargo miri setup --print-sysroot` said: {sysroot:?}"));
PathBuf::from(sysroot)
}
}
@@ -2488,7 +2488,7 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) ->
}
}
builder.verbose(|| eprintln!("doc tests for: {}", markdown.display()));
builder.verbose(|| println!("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
+1 -1
View File
@@ -523,7 +523,7 @@ fn cargo(
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) {
eprintln!("using sysroot {sysroot_str}");
println!("using sysroot {sysroot_str}");
}
let mut rustflags = Rustflags::new(target);
+6 -8
View File
@@ -392,14 +392,14 @@ fn maybe_run(&self, builder: &Builder<'_>, mut pathsets: Vec<PathSet>) {
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) {
eprintln!("Skipping {pathset:?} because it is excluded");
println!("Skipping {pathset:?} because it is excluded");
}
return true;
}
if !builder.config.skip.is_empty() && !matches!(builder.config.dry_run, DryRun::SelfCheck) {
builder.verbose(|| {
eprintln!(
println!(
"{:?} not skipped for {:?} -- not in {:?}",
pathset, self.name, builder.config.skip
)
@@ -1437,11 +1437,11 @@ pub fn ensure<S: Step>(&'a self, step: S) -> S::Output {
panic!("{}", out);
}
if let Some(out) = self.cache.get(&step) {
self.verbose_than(1, || eprintln!("{}c {:?}", " ".repeat(stack.len()), step));
self.verbose_than(1, || println!("{}c {:?}", " ".repeat(stack.len()), step));
return out;
}
self.verbose_than(1, || eprintln!("{}> {:?}", " ".repeat(stack.len()), step));
self.verbose_than(1, || println!("{}> {:?}", " ".repeat(stack.len()), step));
stack.push(Box::new(step.clone()));
}
@@ -1462,7 +1462,7 @@ pub fn ensure<S: Step>(&'a self, step: S) -> S::Output {
let step_string = format!("{step:?}");
let brace_index = step_string.find('{').unwrap_or(0);
let type_string = type_name::<S>();
eprintln!(
println!(
"[TIMING] {} {} -- {}.{:03}",
&type_string.strip_prefix("bootstrap::").unwrap_or(type_string),
&step_string[brace_index..],
@@ -1479,9 +1479,7 @@ pub fn ensure<S: Step>(&'a self, step: S) -> S::Output {
let cur_step = stack.pop().expect("step stack empty");
assert_eq!(cur_step.downcast_ref(), Some(&step));
}
self.verbose_than(1, || {
eprintln!("{}< {:?}", " ".repeat(self.stack.borrow().len()), step)
});
self.verbose_than(1, || println!("{}< {:?}", " ".repeat(self.stack.borrow().len()), step));
self.cache.put(step, out.clone());
out
}
+30 -30
View File
@@ -1299,7 +1299,7 @@ pub(crate) fn get_toml(file: &Path) -> Result<TomlConfig, toml::de::Error> {
.map(|change_id| change_id.inner.map(crate::find_recent_config_change_ids))
{
if !changes.is_empty() {
eprintln!(
println!(
"WARNING: There have been changes to x.py since you last updated:\n{}",
crate::human_readable_changes(&changes)
);
@@ -1565,7 +1565,7 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
}
if cargo_clippy.is_some() && rustc.is_none() {
eprintln!(
println!(
"WARNING: Using `build.cargo-clippy` without `build.rustc` usually fails due to toolchain conflict."
);
}
@@ -1852,7 +1852,7 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
// FIXME: Remove this option at the end of 2024.
if parallel_compiler.is_some() {
eprintln!(
println!(
"WARNING: The `rust.parallel-compiler` option is deprecated and does nothing. The parallel compiler (with one thread) is now the default"
);
}
@@ -1884,7 +1884,7 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
if available_backends.contains(&backend) {
panic!("Invalid value '{s}' for 'rust.codegen-backends'. Instead, please use '{backend}'.");
} else {
eprintln!("HELP: '{s}' for 'rust.codegen-backends' might fail. \
println!("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}'.");
}
@@ -1913,7 +1913,7 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
// 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 {
eprintln!(
println!(
"WARNING: `rust.download-rustc` is enabled. The `rust.channel` option will be overridden by the CI rustc's channel."
);
@@ -2003,10 +2003,10 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
if config.llvm_from_ci {
let warn = |option: &str| {
eprintln!(
println!(
"WARNING: `{option}` will only be used on `compiler/rustc_llvm` build, not for the LLVM build."
);
eprintln!(
println!(
"HELP: To use `{option}` for LLVM builds, set `download-ci-llvm` option to false."
);
};
@@ -2025,12 +2025,12 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
// if they've chosen a different value.
if libzstd.is_some() {
eprintln!(
println!(
"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."
);
eprintln!(
println!(
"HELP: To use `llvm.libzstd` for LLVM/LLD builds, set `download-ci-llvm` option to false."
);
}
@@ -2099,7 +2099,7 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
if available_backends.contains(&backend) {
panic!("Invalid value '{s}' for 'target.{triple}.codegen-backends'. Instead, please use '{backend}'.");
} else {
eprintln!("HELP: '{s}' for 'target.{triple}.codegen-backends' might fail. \
println!("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}'.");
}
@@ -2315,7 +2315,7 @@ pub(crate) fn try_run(&self, cmd: &mut Command) -> Result<(), ()> {
if self.dry_run() {
return Ok(());
}
self.verbose(|| eprintln!("running: {cmd:?}"));
self.verbose(|| println!("running: {cmd:?}"));
build_helper::util::try_run(cmd, self.is_verbose())
}
@@ -2490,7 +2490,7 @@ pub(crate) fn download_rustc_commit(&self) -> Option<&str> {
// 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() {
eprintln!("WARNING: LLVM submodule has changes, `download-rustc` will be disabled.");
println!("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.");
@@ -2501,8 +2501,8 @@ pub(crate) fn download_rustc_commit(&self) -> Option<&str> {
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") => {
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.");
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.");
return None;
},
Err(e) => {
@@ -2527,7 +2527,7 @@ pub(crate) fn download_rustc_commit(&self) -> Option<&str> {
.is_some_and(|s| s == "1" || s == "true");
if disable_ci_rustc_if_incompatible && res.is_err() {
eprintln!("WARNING: download-rustc is disabled with `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` env.");
println!("WARNING: download-rustc is disabled with `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` env.");
return None;
}
@@ -2712,7 +2712,7 @@ pub(crate) fn update_submodule(&self, relative_path: &str) {
return;
}
eprintln!("Updating submodule {relative_path}");
println!("Updating submodule {relative_path}");
self.check_run(
helpers::git(Some(&self.src))
.run_always()
@@ -2835,7 +2835,7 @@ fn download_ci_rustc_commit(
Some(StringOrBool::Bool(true)) => false,
Some(StringOrBool::String(s)) if s == "if-unchanged" => {
if !self.rust_info.is_managed_git_subrepository() {
eprintln!(
println!(
"ERROR: `download-rustc=if-unchanged` is only compatible with Git managed sources."
);
crate::exit!(1);
@@ -2868,10 +2868,10 @@ fn download_ci_rustc_commit(
if if_unchanged {
return None;
}
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");
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");
crate::exit!(1);
}
};
@@ -2910,7 +2910,7 @@ fn parse_download_ci_llvm(
let if_unchanged = || {
if self.rust_info.is_from_tarball() {
// Git is needed for running "if-unchanged" logic.
eprintln!(
println!(
"WARNING: 'if-unchanged' has no effect on tarball sources; ignoring `download-ci-llvm`."
);
return false;
@@ -2959,10 +2959,10 @@ pub fn last_modified_commit(
// 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() {
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");
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");
crate::exit!(1);
}
@@ -2974,14 +2974,14 @@ pub fn last_modified_commit(
if has_changes {
if if_unchanged {
if self.is_verbose() {
eprintln!(
println!(
"warning: saw changes to one of {modified_paths:?} since {commit}; \
ignoring `{option_name}`"
);
}
return None;
}
eprintln!(
println!(
"warning: `{option_name}` is enabled, but there are changes to one of {modified_paths:?}"
);
}
@@ -3018,7 +3018,7 @@ macro_rules! warn {
($current:expr, $expected:expr) => {
if let Some(current) = &$current {
if Some(current) != $expected.as_ref() {
eprintln!(
println!(
"WARNING: `llvm.{}` has no effect with `llvm.download-ci-llvm`. \
Current value: {:?}, Expected value(s): {}{:?}",
stringify!($expected).replace("_", "-"),
@@ -3123,7 +3123,7 @@ macro_rules! warn {
($current:expr, $expected:expr, $config_section:expr) => {
if let Some(current) = &$current {
if Some(current) != $expected.as_ref() {
eprintln!(
println!(
"WARNING: `{}` has no effect with `rust.download-rustc`. \
Current value: {:?}, Expected value(s): {}{:?}",
format!("{}.{}", $config_section, stringify!($expected).replace("_", "-")),
+2 -2
View File
@@ -196,12 +196,12 @@ struct HelpVerboseOnly {
if let Ok(HelpVerboseOnly { help: true, verbose: 1.., cmd: subcommand }) =
HelpVerboseOnly::try_parse_from(normalize_args(args))
{
eprintln!("NOTE: updating submodules before printing available paths");
println!("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 {
eprintln!("{s}");
println!("{s}");
} else {
panic!("No paths available for subcommand `{}`", subcommand.as_str());
}
+13 -13
View File
@@ -77,7 +77,7 @@ pub(crate) fn check_run(&self, cmd: &mut BootstrapCommand) -> bool {
if self.dry_run() && !cmd.run_always {
return true;
}
self.verbose(|| eprintln!("running: {cmd:?}"));
self.verbose(|| println!("running: {cmd:?}"));
check_run(cmd, self.is_verbose())
}
@@ -144,7 +144,7 @@ fn should_fix_bins_and_dylibs(&self) -> bool {
/// 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));
eprintln!("attempting to patch {}", fname.display());
println!("attempting to patch {}", fname.display());
// Only build `.nix-deps` once.
static NIX_DEPS_DIR: OnceLock<PathBuf> = OnceLock::new();
@@ -206,7 +206,7 @@ fn fix_bin_or_dylib(&self, fname: &Path) {
}
fn download_file(&self, url: &str, dest_path: &Path, help_on_error: &str) {
self.verbose(|| eprintln!("download {url}"));
self.verbose(|| println!("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 @@ fn download_file(&self, url: &str, dest_path: &Path, help_on_error: &str) {
}
fn download_http_with_retries(&self, tempfile: &Path, url: &str, help_on_error: &str) {
eprintln!("downloading {url}");
println!("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 @@ fn unpack(&self, tarball: &Path, dst: &Path, pattern: &str) {
short_path = short_path.strip_prefix(pattern).unwrap_or(short_path);
let dst_path = dst.join(short_path);
self.verbose(|| {
eprintln!("extracting {} to {}", original_path.display(), dst.display())
println!("extracting {} to {}", original_path.display(), dst.display())
});
if !t!(member.unpack_in(dst)) {
panic!("path traversal attack ??");
@@ -365,7 +365,7 @@ fn unpack(&self, tarball: &Path, dst: &Path, pattern: &str) {
pub(crate) fn verify(&self, path: &Path, expected: &str) -> bool {
use sha2::Digest;
self.verbose(|| eprintln!("verifying {}", path.display()));
self.verbose(|| println!("verifying {}", path.display()));
if self.dry_run() {
return false;
@@ -391,7 +391,7 @@ pub(crate) fn verify(&self, path: &Path, expected: &str) -> bool {
let verified = checksum == expected;
if !verified {
eprintln!(
println!(
"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(|| eprintln!("downloading stage0 clippy artifacts"));
self.verbose(|| println!("downloading stage0 clippy artifacts"));
let date = &self.stage0_metadata.compiler.date;
let version = &self.stage0_metadata.compiler.version;
@@ -518,7 +518,7 @@ fn ci_component_contents(&self, stamp_file: &str) -> Vec<String> {
}
pub(crate) fn download_ci_rustc(&self, commit: &str) {
self.verbose(|| eprintln!("using downloaded stage2 artifacts from CI (commit {commit})"));
self.verbose(|| println!("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 @@ pub(crate) fn download_beta_toolchain(&self) {}
#[cfg(not(feature = "bootstrap-self-test"))]
pub(crate) fn download_beta_toolchain(&self) {
self.verbose(|| eprintln!("downloading stage0 beta artifacts"));
self.verbose(|| println!("downloading stage0 beta artifacts"));
let date = &self.stage0_metadata.compiler.date;
let version = &self.stage0_metadata.compiler.version;
@@ -677,7 +677,7 @@ fn download_component(
return;
} else {
self.verbose(|| {
eprintln!(
println!(
"ignoring cached file {} due to failed verification",
tarball.display()
)
@@ -776,10 +776,10 @@ pub(crate) fn maybe_download_ci_llvm(&self) {
t!(check_incompatible_options_for_ci_llvm(current_config_toml, ci_config_toml));
}
Err(e) if e.to_string().contains("unknown field") => {
eprintln!(
println!(
"WARNING: CI LLVM has some fields that are no longer supported in bootstrap; download-ci-llvm will be disabled."
);
eprintln!("HELP: Consider rebasing to a newer commit if available.");
println!("HELP: Consider rebasing to a newer commit if available.");
}
Err(e) => {
eprintln!("ERROR: Failed to parse CI LLVM config.toml: {e}");
+2 -2
View File
@@ -237,11 +237,11 @@ pub fn check(build: &mut Build) {
stage0_supported_target_list.intersection(&missing_targets_hashset).collect();
if !duplicated_targets.is_empty() {
eprintln!(
println!(
"Following targets supported from the stage0 compiler, please remove them from STAGE0_MISSING_TARGETS list."
);
for duplicated_target in duplicated_targets {
eprintln!(" {duplicated_target}");
println!(" {duplicated_target}");
}
std::process::exit(1);
}
+14 -14
View File
@@ -406,11 +406,11 @@ pub fn new(mut config: Config) -> Build {
.unwrap()
.trim();
if local_release.split('.').take(2).eq(version.split('.').take(2)) {
build.verbose(|| eprintln!("auto-detected local-rebuild {local_release}"));
build.verbose(|| println!("auto-detected local-rebuild {local_release}"));
build.local_rebuild = true;
}
build.verbose(|| eprintln!("finding compilers"));
build.verbose(|| println!("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
@@ -418,7 +418,7 @@ pub fn new(mut config: Config) -> Build {
//
// Similarly, for `setup` we don't actually need submodules or cargo metadata.
if !matches!(build.config.cmd, Subcommand::Setup { .. }) {
build.verbose(|| eprintln!("running sanity check"));
build.verbose(|| println!("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 @@ pub fn new(mut config: Config) -> Build {
// Now, update all existing submodules.
build.update_existing_submodules();
build.verbose(|| eprintln!("learning about cargo"));
build.verbose(|| println!("learning about cargo"));
crate::core::metadata::build(&mut build);
}
@@ -605,7 +605,7 @@ fn clear_if_dirty(&self, dir: &Path, input: &Path) -> bool {
let stamp = dir.join(".stamp");
let mut cleared = false;
if mtime(&stamp) < mtime(input) {
self.verbose(|| eprintln!("Dirty - {}", dir.display()));
self.verbose(|| println!("Dirty - {}", dir.display()));
let _ = fs::remove_dir_all(dir);
cleared = true;
} else if stamp.exists() {
@@ -890,7 +890,7 @@ fn run(
let executed_at = std::panic::Location::caller();
self.verbose(|| {
eprintln!("running: {command:?} (created at {created_at}, executed at {executed_at})")
println!("running: {command:?} (created at {created_at}, executed at {executed_at})")
});
let cmd = command.as_command_mut();
@@ -947,7 +947,7 @@ fn run(
let fail = |message: &str, output: CommandOutput| -> ! {
if self.is_verbose() {
eprintln!("{message}");
println!("{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 @@ fn run(
if let Some(stdout) =
output.stdout_if_present().take_if(|s| !s.trim().is_empty())
{
eprintln!("STDOUT:\n{stdout}\n");
println!("STDOUT:\n{stdout}\n");
}
if let Some(stderr) =
output.stderr_if_present().take_if(|s| !s.trim().is_empty())
{
eprintln!("STDERR:\n{stderr}\n");
println!("STDERR:\n{stderr}\n");
}
eprintln!("Command {command:?} has failed. Rerun with -v to see more details.");
println!("Command {command:?} has failed. Rerun with -v to see more details.");
} else {
eprintln!("Command has failed. Rerun with -v to see more details.");
println!("Command has failed. Rerun with -v to see more details.");
}
}
exit!(1);
@@ -1011,7 +1011,7 @@ fn info(&self, msg: &str) {
match self.config.dry_run {
DryRun::SelfCheck => (),
DryRun::Disabled | DryRun::UserSelected => {
eprintln!("{msg}");
println!("{msg}");
}
}
}
@@ -1666,7 +1666,7 @@ fn copy_link_internal(&self, src: &Path, dst: &Path, dereference_symlinks: bool)
if self.config.dry_run() {
return;
}
self.verbose_than(1, || eprintln!("Copy/Link {src:?} to {dst:?}"));
self.verbose_than(1, || println!("Copy/Link {src:?} to {dst:?}"));
if src == dst {
return;
}
@@ -1775,7 +1775,7 @@ fn install(&self, src: &Path, dstdir: &Path, perms: u32) {
return;
}
let dst = dstdir.join(src.file_name().unwrap());
self.verbose_than(1, || eprintln!("Install {src:?} to {dst:?}"));
self.verbose_than(1, || println!("Install {src:?} to {dst:?}"));
t!(fs::create_dir_all(dstdir));
if !src.exists() {
panic!("ERROR: File \"{}\" not found!", src.display());
+5 -5
View File
@@ -155,15 +155,15 @@ pub fn find_target(build: &Build, target: TargetSelection) {
build.cxx.borrow_mut().insert(target, compiler);
}
build.verbose(|| eprintln!("CC_{} = {:?}", target.triple, build.cc(target)));
build.verbose(|| eprintln!("CFLAGS_{} = {cflags:?}", target.triple));
build.verbose(|| println!("CC_{} = {:?}", target.triple, build.cc(target)));
build.verbose(|| println!("CFLAGS_{} = {cflags:?}", target.triple));
if let Ok(cxx) = build.cxx(target) {
let cxxflags = build.cflags(target, GitRepo::Rustc, CLang::Cxx);
build.verbose(|| eprintln!("CXX_{} = {cxx:?}", target.triple));
build.verbose(|| eprintln!("CXXFLAGS_{} = {cxxflags:?}", target.triple));
build.verbose(|| println!("CXX_{} = {cxx:?}", target.triple));
build.verbose(|| println!("CXXFLAGS_{} = {cxxflags:?}", target.triple));
}
if let Some(ar) = ar {
build.verbose(|| eprintln!("AR_{} = {ar:?}", target.triple));
build.verbose(|| println!("AR_{} = {ar:?}", target.triple));
build.ar.borrow_mut().insert(target, ar);
}
+3 -3
View File
@@ -135,7 +135,7 @@ impl Drop for TimeIt {
fn drop(&mut self) {
let time = self.1.elapsed();
if !self.0 {
eprintln!("\tfinished in {}.{:03} seconds", time.as_secs(), time.subsec_millis());
println!("\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) => {
eprintln!("failed to execute command: {cmd:?}\nERROR: {e}");
println!("failed to execute command: {cmd:?}\nERROR: {e}");
return false;
}
};
if !status.success() && print_cmd_on_fail {
eprintln!(
println!(
"\n\ncommand did not execute successfully: {cmd:?}\n\
expected success, got: {status}\n\n"
);
+1 -1
View File
@@ -185,7 +185,7 @@ pub(crate) fn persist(&self, build: &Build) {
if version.format_version == CURRENT_FORMAT_VERSION {
t!(serde_json::from_slice::<JsonRoot>(&contents)).invocations
} else {
eprintln!(
println!(
"WARNING: overriding existing build/metrics.json, as it's not \
compatible with build metrics format version {CURRENT_FORMAT_VERSION}."
);
+24 -26
View File
@@ -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(|| eprintln!("running: {cmd:?}"));
builder.verbose(|| println!("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() {
eprintln!(
println!(
"\n\ncommand did not execute successfully: {cmd:?}\n\
expected success, got: {}",
result.status
@@ -135,9 +135,7 @@ fn render_all(mut self) {
if self.up_to_date_tests > 0 {
let n = self.up_to_date_tests;
let s = if n > 1 { "s" } else { "" };
eprintln!(
"help: ignored {n} up-to-date test{s}; use `--force-rerun` to prevent this\n"
);
println!("help: ignored {n} up-to-date test{s}; use `--force-rerun` to prevent this\n");
}
}
@@ -187,12 +185,12 @@ fn render_test_outcome(&mut self, outcome: Outcome<'_>, test: &TestOutcome) {
}
fn render_test_outcome_verbose(&self, outcome: Outcome<'_>, test: &TestOutcome) {
eprint!("test {} ... ", test.name);
self.builder.colored_stderr(|stdout| outcome.write_long(stdout)).unwrap();
print!("test {} ... ", test.name);
self.builder.colored_stdout(|stdout| outcome.write_long(stdout)).unwrap();
if let Some(exec_time) = test.exec_time {
eprint!(" ({exec_time:.2?})");
print!(" ({exec_time:.2?})");
}
eprintln!();
println!();
}
fn render_test_outcome_terse(&mut self, outcome: Outcome<'_>, test: &TestOutcome) {
@@ -200,45 +198,45 @@ fn render_test_outcome_terse(&mut self, outcome: Outcome<'_>, test: &TestOutcome
if let Some(total) = self.tests_count {
let total = total.to_string();
let executed = format!("{:>width$}", self.executed_tests - 1, width = total.len());
eprint!(" {executed}/{total}");
print!(" {executed}/{total}");
}
eprintln!();
println!();
self.terse_tests_in_line = 0;
}
self.terse_tests_in_line += 1;
self.builder.colored_stderr(|stdout| outcome.write_short(stdout, &test.name)).unwrap();
self.builder.colored_stdout(|stdout| outcome.write_short(stdout, &test.name)).unwrap();
let _ = std::io::stdout().flush();
}
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 {
eprintln!();
println!();
}
if !self.failures.is_empty() {
eprintln!("\nfailures:\n");
println!("\nfailures:\n");
for failure in &self.failures {
if failure.stdout.is_some() || failure.message.is_some() {
eprintln!("---- {} stdout ----", failure.name);
println!("---- {} stdout ----", failure.name);
if let Some(stdout) = &failure.stdout {
eprintln!("{stdout}");
println!("{stdout}");
}
if let Some(message) = &failure.message {
eprintln!("NOTE: {message}");
println!("NOTE: {message}");
}
}
}
eprintln!("\nfailures:");
println!("\nfailures:");
for failure in &self.failures {
eprintln!(" {}", failure.name);
println!(" {}", failure.name);
}
}
if !self.benches.is_empty() {
eprintln!("\nbenchmarks:");
println!("\nbenchmarks:");
let mut rows = Vec::new();
for bench in &self.benches {
@@ -253,13 +251,13 @@ fn render_suite_outcome(&self, outcome: Outcome<'_>, suite: &SuiteOutcome) {
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 {
eprintln!(" {:<max_0$} {:>max_1$} {:>max_2$}", row.0, row.1, row.2);
println!(" {:<max_0$} {:>max_1$} {:>max_2$}", row.0, row.1, row.2);
}
}
eprint!("\ntest result: ");
self.builder.colored_stderr(|stdout| outcome.write_long(stdout)).unwrap();
eprintln!(
print!("\ntest result: ");
self.builder.colored_stdout(|stdout| outcome.write_long(stdout)).unwrap();
println!(
". {} passed; {} failed; {} ignored; {} measured; {} filtered out{time}\n",
suite.passed,
suite.failed,
@@ -276,7 +274,7 @@ fn render_suite_outcome(&self, outcome: Outcome<'_>, suite: &SuiteOutcome) {
fn render_message(&mut self, message: Message) {
match message {
Message::Suite(SuiteMessage::Started { test_count }) => {
eprintln!("\nrunning {test_count} tests");
println!("\nrunning {test_count} tests");
self.executed_tests = 0;
self.terse_tests_in_line = 0;
self.tests_count = Some(test_count);
@@ -316,7 +314,7 @@ fn render_message(&mut self, message: Message) {
self.failures.push(outcome);
}
Message::Test(TestMessage::Timeout { name }) => {
eprintln!("test {name} has been running for a long time");
println!("test {name} has been running for a long time");
}
Message::Test(TestMessage::Started) => {} // Not useful
}
+1 -1
View File
@@ -344,7 +344,7 @@ fn run(self, build_cli: impl FnOnce(&Tarball<'a>, &mut BootstrapCommand)) -> Gen
// 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(|| {
eprintln!("Forcing dist.compression-profile = 'no-op' for `x install`.")
println!("Forcing dist.compression-profile = 'no-op' for `x install`.")
});
// "no-op" indicates that the rust-installer won't produce compressed tarball sources.
"no-op"
@@ -35,7 +35,7 @@ PICK_REFS=()
# commit hash of fuchsia.git and some other repos in the "monorepo" checkout, in
# addition to versions of prebuilts. It should be bumped regularly by the
# Fuchsia team  we aim for every 1-2 months.
INTEGRATION_SHA=9f632bb7446d5a6af2998f1a0ebdb4b8ea2f4511
INTEGRATION_SHA=bb38af4e3d45e490531b71fc52a460003141d032
checkout=fuchsia
jiri=.jiri_root/bin/jiri
+1 -1
View File
@@ -201,7 +201,7 @@ fn convert_render_type_id(
// exported from this same module). It's also likely to Do
// What I Mean, since if a re-export changes the name, it might
// also be a change in semantic meaning.
.filter(|fqp| fqp.last() == fqp.last());
.filter(|this_fqp| this_fqp.last() == fqp.last());
Some(insert_into_map(
itemid_to_pathid,
ItemId::DefId(defid),
+1 -1
View File
@@ -144,7 +144,7 @@ pub(crate) fn write_filtered_diff<Filter>(
}
if !wrote_data {
eprintln!("note: diff is identical to nightly rustdoc");
println!("note: diff is identical to nightly rustdoc");
assert!(diff_output.metadata().unwrap().len() == 0);
return false;
} else if verbose {
+3 -3
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") {
eprintln!(
println!(
"WARNING: debuginfo tests are not available when \
testing with remote"
);
@@ -28,7 +28,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
}
if config.target.contains("android") {
eprintln!(
println!(
"{} 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 {
eprintln!(
println!(
"WARNING: The used version of LLDB (350) has a \
known issue that breaks debuginfo tests. See \
issue #32520 for more information. Skipping all \
+5 -5
View File
@@ -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);
eprintln!("{}", opts.usage(&message));
eprintln!();
println!("{}", opts.usage(&message));
println!();
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);
eprintln!("{}", opts.usage(&message));
eprintln!();
println!("{}", opts.usage(&message));
println!();
panic!()
}
@@ -508,7 +508,7 @@ pub fn run_tests(config: Arc<Config>) {
// easy to miss which tests failed, and as such fail to reproduce
// the failure locally.
eprintln!(
println!(
"Some tests failed in compiletest suite={}{} mode={} host={} target={}",
config.suite,
config
+26 -26
View File
@@ -131,7 +131,7 @@ pub fn run(config: Arc<Config>, testpaths: &TestPaths, revision: Option<&str>) {
if config.verbose {
// We're going to be dumping a lot of info. Start on a new line.
eprintln!("\n");
print!("\n\n");
}
debug!("running {:?}", testpaths.file.display());
let mut props = TestProps::from_file(&testpaths.file, revision, &config);
@@ -353,7 +353,7 @@ fn check_if_test_should_compile(
{
self.error(&format!("{} test did not emit an error", self.config.mode));
if self.config.mode == crate::common::Mode::Ui {
eprintln!("note: by default, ui tests are expected not to compile");
println!("note: by default, ui tests are expected not to compile");
}
proc_res.fatal(None, || ());
};
@@ -774,20 +774,20 @@ fn check_expected_errors(&self, expected_errors: Vec<errors::Error>, proc_res: &
unexpected.len(),
not_found.len()
));
eprintln!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline);
println!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline);
if !unexpected.is_empty() {
eprintln!("{}", "--- unexpected errors (from JSON output) ---".green());
println!("{}", "--- unexpected errors (from JSON output) ---".green());
for error in &unexpected {
eprintln!("{}", error.render_for_expected());
println!("{}", error.render_for_expected());
}
eprintln!("{}", "---".green());
println!("{}", "---".green());
}
if !not_found.is_empty() {
eprintln!("{}", "--- not found errors (from test file) ---".red());
println!("{}", "--- not found errors (from test file) ---".red());
for error in &not_found {
eprintln!("{}", error.render_for_expected());
println!("{}", error.render_for_expected());
}
eprintln!("{}", "---\n".red());
println!("{}", "---\n".red());
}
panic!("errors differ from expected");
}
@@ -1876,18 +1876,18 @@ fn output_base_name(&self) -> PathBuf {
fn maybe_dump_to_stdout(&self, out: &str, err: &str) {
if self.config.verbose {
eprintln!("------stdout------------------------------");
eprintln!("{}", out);
eprintln!("------stderr------------------------------");
eprintln!("{}", err);
eprintln!("------------------------------------------");
println!("------stdout------------------------------");
println!("{}", out);
println!("------stderr------------------------------");
println!("{}", err);
println!("------------------------------------------");
}
}
fn error(&self, err: &str) {
match self.revision {
Some(rev) => eprintln!("\nerror in revision `{}`: {}", rev, err),
None => eprintln!("\nerror: {}", err),
Some(rev) => println!("\nerror in revision `{}`: {}", rev, err),
None => println!("\nerror: {}", err),
}
}
@@ -1972,7 +1972,7 @@ fn compare_to_default_rustdoc(&mut self, out_dir: &Path) {
if !self.config.has_html_tidy {
return;
}
eprintln!("info: generating a diff against nightly rustdoc");
println!("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 @@ fn compare_to_default_rustdoc(&mut self, out_dir: &Path) {
.output()
.unwrap();
assert!(output.status.success());
eprintln!("{}", String::from_utf8_lossy(&output.stdout));
println!("{}", String::from_utf8_lossy(&output.stdout));
eprintln!("{}", String::from_utf8_lossy(&output.stderr));
} else {
use colored::Colorize;
@@ -2496,7 +2496,7 @@ fn normalize_platform_differences(output: &str) -> String {
)"#
)
.replace_all(&output, |caps: &Captures<'_>| {
eprintln!("{}", &caps[0]);
println!("{}", &caps[0]);
caps[0].replace(r"\", "/")
})
.replace("\r\n", "\n")
@@ -2601,14 +2601,14 @@ fn compare_output(
if let Err(err) = fs::write(&actual_path, &actual) {
self.fatal(&format!("failed to write {stream} to `{actual_path:?}`: {err}",));
}
eprintln!("Saved the actual {stream} to {actual_path:?}");
println!("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() {
eprintln!("normalized {}:\n{}\n", stream, actual);
println!("normalized {}:\n{}\n", stream, actual);
} else {
self.show_diff(
stream,
@@ -2631,10 +2631,10 @@ fn compare_output(
if let Err(err) = fs::write(&expected_path, &actual) {
self.fatal(&format!("failed to write {stream} to `{expected_path:?}`: {err}"));
}
eprintln!("Blessing the {stream} of {test_name} in {expected_path:?}");
println!("Blessing the {stream} of {test_name} in {expected_path:?}");
}
eprintln!("\nThe actual {0} differed from the expected {0}.", stream);
println!("\nThe actual {0} differed from the expected {0}.", stream);
if self.config.bless { 0 } else { 1 }
}
@@ -2783,7 +2783,7 @@ fn init_incremental_test(&self) {
fs::create_dir_all(&incremental_dir).unwrap();
if self.config.verbose {
eprintln!("init_incremental_test: incremental_dir={}", incremental_dir.display());
println!("init_incremental_test: incremental_dir={}", incremental_dir.display());
}
}
@@ -2841,7 +2841,7 @@ fn render(name: &str, contents: &str) -> String {
}
}
eprintln!(
println!(
"status: {}\ncommand: {}\n{}\n{}\n",
self.status,
self.cmdline,
@@ -2852,7 +2852,7 @@ fn render(name: &str, contents: &str) -> String {
pub fn fatal(&self, err: Option<&str>, on_failure: impl FnOnce()) -> ! {
if let Some(e) = err {
eprintln!("\nerror: {}", e);
println!("\nerror: {}", e);
}
self.print_info();
on_failure();
@@ -64,13 +64,13 @@ pub(super) fn run_codegen_units_test(&self) {
if !missing.is_empty() {
missing.sort();
eprintln!("\nThese items should have been contained but were not:\n");
println!("\nThese items should have been contained but were not:\n");
for item in &missing {
eprintln!("{}", item);
println!("{}", item);
}
eprintln!("\n");
println!("\n");
}
if !unexpected.is_empty() {
@@ -80,24 +80,24 @@ pub(super) fn run_codegen_units_test(&self) {
sorted
};
eprintln!("\nThese items were contained but should not have been:\n");
println!("\nThese items were contained but should not have been:\n");
for item in sorted {
eprintln!("{}", item);
println!("{}", item);
}
eprintln!("\n");
println!("\n");
}
if !wrong_cgus.is_empty() {
wrong_cgus.sort_by_key(|pair| pair.0.name.clone());
eprintln!("\nThe following items were assigned to wrong codegen units:\n");
println!("\nThe following items were assigned to wrong codegen units:\n");
for &(ref expected_item, ref actual_item) in &wrong_cgus {
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!();
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!();
}
}
@@ -260,7 +260,7 @@ fn run_debuginfo_gdb_test_no_opt(&self) {
cmdline,
};
if adb.kill().is_err() {
eprintln!("Adb process is already finished.");
println!("Adb process is already finished.");
}
} else {
let rust_src_root =
@@ -275,7 +275,7 @@ fn run_debuginfo_gdb_test_no_opt(&self) {
match self.config.gdb_version {
Some(version) => {
eprintln!("NOTE: compiletest thinks it is using GDB version {}", version);
println!("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 @@ fn run_debuginfo_gdb_test_no_opt(&self) {
}
}
_ => {
eprintln!(
println!(
"NOTE: compiletest does not know which version of \
GDB it is using"
);
@@ -392,10 +392,10 @@ fn run_debuginfo_lldb_test_no_opt(&self) {
match self.config.lldb_version {
Some(ref version) => {
eprintln!("NOTE: compiletest thinks it is using LLDB version {}", version);
println!("NOTE: compiletest thinks it is using LLDB version {}", version);
}
_ => {
eprintln!(
println!(
"NOTE: compiletest does not know which version of \
LLDB it is using"
);
@@ -30,7 +30,7 @@ pub(super) fn run_incremental_test(&self) {
assert!(incremental_dir.exists(), "init_incremental_test failed to create incremental dir");
if self.config.verbose {
eprint!("revision={:?} props={:#?}", revision, self.props);
print!("revision={:?} props={:#?}", revision, self.props);
}
if revision.starts_with("cpass") {
+1 -1
View File
@@ -89,7 +89,7 @@ fn check_mir_dump(&self, test_info: MiroptTest) {
}
let expected_string = fs::read_to_string(&expected_file).unwrap();
if dumped_string != expected_string {
eprint!("{}", write_diff(&expected_string, &dumped_string, 3));
print!("{}", write_diff(&expected_string, &dumped_string, 3));
panic!(
"Actual MIR output differs from expected MIR output {}",
expected_file.display()
@@ -29,7 +29,7 @@ pub(super) fn run_rustdoc_json_test(&self) {
if !res.status.success() {
self.fatal_proc_rec_with_ctx("jsondocck failed!", &res, |_| {
eprintln!("Rustdoc Output:");
println!("Rustdoc Output:");
proc_res.print_info();
})
}
+2 -2
View File
@@ -109,10 +109,10 @@ pub(super) fn run_ui_test(&self) {
}
if errors > 0 {
eprintln!("To update references, rerun the tests and pass the `--bless` flag");
println!("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());
eprintln!(
println!(
"To only update this specific test, also pass `--test-args {}`",
relative_path_to_file.display(),
);
+1 -1
View File
@@ -30,7 +30,7 @@ fn path_div() -> &'static str {
pub fn logv(config: &Config, s: String) {
debug!("{}", s);
if config.verbose {
eprintln!("{}", s);
println!("{}", s);
}
}
@@ -0,0 +1,20 @@
//@ edition: 2021
#![feature(async_closure, noop_waker)]
use std::future::Future;
use std::pin::pin;
use std::task::*;
pub fn block_on<T>(fut: impl Future<Output = T>) -> T {
let mut fut = pin!(fut);
// Poll loop, just to test the future...
let ctx = &mut Context::from_waker(Waker::noop());
loop {
match unsafe { fut.as_mut().poll(ctx) } {
Poll::Pending => {}
Poll::Ready(t) => break t,
}
}
}
@@ -0,0 +1,40 @@
//@ aux-build:block-on.rs
//@ edition: 2021
//@ run-pass
//@ check-run-results
#![allow(refining_impl_trait)]
#![feature(async_fn_in_dyn_trait)]
//~^ WARN the feature `async_fn_in_dyn_trait` is incomplete
extern crate block_on;
use std::future::Future;
use std::pin::Pin;
trait AsyncTrait {
type Output;
async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output;
}
impl<F> AsyncTrait for F
where
F: Future,
{
type Output = F::Output;
fn async_dispatch(self: Pin<&mut Self>) -> Pin<&mut Self> {
self
}
}
fn main() {
block_on::block_on(async {
let f = std::pin::pin!(async {
println!("hello, world");
});
let x: Pin<&mut dyn AsyncTrait<Output = ()>> = f;
x.async_dispatch().await;
});
}
@@ -0,0 +1 @@
hello, world
@@ -0,0 +1,11 @@
warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/mut-is-pointer-like.rs:7:12
|
LL | #![feature(async_fn_in_dyn_trait)]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #133119 <https://github.com/rust-lang/rust/issues/133119> for more information
= note: `#[warn(incomplete_features)]` on by default
warning: 1 warning emitted
+32
View File
@@ -0,0 +1,32 @@
//@ aux-build:block-on.rs
//@ edition: 2021
//@ run-pass
//@ check-run-results
#![allow(refining_impl_trait)]
#![feature(async_fn_in_dyn_trait)]
//~^ WARN the feature `async_fn_in_dyn_trait` is incomplete
extern crate block_on;
use std::pin::Pin;
use std::future::Future;
trait AsyncTrait {
async fn async_dispatch(&self);
}
impl AsyncTrait for &'static str {
fn async_dispatch(&self) -> Pin<Box<impl Future<Output = ()>>> {
Box::pin(async move {
println!("message from the aether: {self}");
})
}
}
fn main() {
block_on::block_on(async {
let x: &dyn AsyncTrait = &"hello, world!";
x.async_dispatch().await;
});
}
@@ -0,0 +1 @@
message from the aether: hello, world!
+11
View File
@@ -0,0 +1,11 @@
warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/works.rs:7:12
|
LL | #![feature(async_fn_in_dyn_trait)]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #133119 <https://github.com/rust-lang/rust/issues/133119> for more information
= note: `#[warn(incomplete_features)]` on by default
warning: 1 warning emitted
+23
View File
@@ -0,0 +1,23 @@
//@ edition: 2021
#![feature(async_fn_in_dyn_trait)]
//~^ WARN the feature `async_fn_in_dyn_trait` is incomplete
use std::future::Future;
trait AsyncTrait {
async fn async_dispatch(&self);
}
impl AsyncTrait for &'static str {
fn async_dispatch(&self) -> impl Future<Output = ()> {
async move {
// The implementor must box the future...
}
}
}
fn main() {
let x: &dyn AsyncTrait = &"hello, world!";
//~^ ERROR `impl Future<Output = ()>` needs to have the same ABI as a pointer
}
@@ -0,0 +1,21 @@
warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/wrong-size.rs:3:12
|
LL | #![feature(async_fn_in_dyn_trait)]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #133119 <https://github.com/rust-lang/rust/issues/133119> for more information
= note: `#[warn(incomplete_features)]` on by default
error[E0277]: `impl Future<Output = ()>` needs to have the same ABI as a pointer
--> $DIR/wrong-size.rs:21:30
|
LL | let x: &dyn AsyncTrait = &"hello, world!";
| ^^^^^^^^^^^^^^^^ `impl Future<Output = ()>` needs to be a pointer-like type
|
= help: the trait `for<'a> PointerLike` is not implemented for `impl Future<Output = ()>`
= note: required for the cast from `&&'static str` to `&dyn AsyncTrait`
error: aborting due to 1 previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0277`.
@@ -0,0 +1,14 @@
//@ edition: 2021
trait Foo {
async fn bar(&self);
}
async fn takes_dyn_trait(x: &dyn Foo) {
//~^ ERROR the trait `Foo` cannot be made into an object
x.bar().await;
//~^ ERROR the trait `Foo` cannot be made into an object
//~| ERROR the trait `Foo` cannot be made into an object
}
fn main() {}
@@ -0,0 +1,48 @@
error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/feature-gate-async-fn-in-dyn-trait.rs:7:30
|
LL | async fn takes_dyn_trait(x: &dyn Foo) {
| ^^^^^^^ `Foo` cannot be made into an object
|
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/feature-gate-async-fn-in-dyn-trait.rs:4:14
|
LL | trait Foo {
| --- this trait cannot be made into an object...
LL | async fn bar(&self);
| ^^^ ...because method `bar` is `async`
= help: consider moving `bar` to another trait
error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/feature-gate-async-fn-in-dyn-trait.rs:9:7
|
LL | x.bar().await;
| ^^^ `Foo` cannot be made into an object
|
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/feature-gate-async-fn-in-dyn-trait.rs:4:14
|
LL | trait Foo {
| --- this trait cannot be made into an object...
LL | async fn bar(&self);
| ^^^ ...because method `bar` is `async`
= help: consider moving `bar` to another trait
error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/feature-gate-async-fn-in-dyn-trait.rs:9:5
|
LL | x.bar().await;
| ^^^^^^^ `Foo` cannot be made into an object
|
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/feature-gate-async-fn-in-dyn-trait.rs:4:14
|
LL | trait Foo {
| --- this trait cannot be made into an object...
LL | async fn bar(&self);
| ^^^ ...because method `bar` is `async`
= help: consider moving `bar` to another trait
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0038`.
@@ -0,0 +1,13 @@
//@ check-pass
// Make sure that we don't enforce that an RPIT that has `where Self: Sized` is pointer-like.
trait Foo {
fn foo() -> impl Sized where Self: Sized {}
}
impl Foo for () {}
fn main() {
let x: &dyn Foo = &();
}
+9 -1
View File
@@ -991,13 +991,21 @@ https://github.com/rust-lang/reference/blob/HEAD/src/identifiers.md.
cc = ["@ehuss"]
[assign]
warn_non_default_branch = true
warn_non_default_branch.enable = true
contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
users_on_vacation = [
"jyn514",
"celinval",
]
[[assign.warn_non_default_branch.exceptions]]
title = "[beta"
branch = "beta"
[[assign.warn_non_default_branch.exceptions]]
title = "[stable"
branch = "stable"
[assign.adhoc_groups]
compiler = [
"@BoxyUwU",