diff --git a/Cargo.lock b/Cargo.lock index e37e8614af2cd..0b74d71fd8929 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1640,9 +1640,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.6" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" dependencies = [ "compiler_builtins", "rustc-std-workspace-alloc", diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 75613a2c55555..733e2f93b2535 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -37,7 +37,11 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<' } ty::InstanceDef::FnPtrShim(def_id, ty) => { let trait_ = tcx.trait_of_item(def_id).unwrap(); - let adjustment = match tcx.fn_trait_kind_from_def_id(trait_) { + // Supports `Fn` or `async Fn` traits. + let adjustment = match tcx + .fn_trait_kind_from_def_id(trait_) + .or_else(|| tcx.async_fn_trait_kind_from_def_id(trait_)) + { Some(ty::ClosureKind::FnOnce) => Adjustment::Identity, Some(ty::ClosureKind::Fn) => Adjustment::Deref { source: DerefSource::ImmRef }, Some(ty::ClosureKind::FnMut) => Adjustment::Deref { source: DerefSource::MutRef }, diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index e4298a981292a..6b45db7ba8323 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1585,9 +1585,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { { // When the suggested binding change would be from `x` to `_x`, suggest changing the // original binding definition instead. (#60164) - (span, snippet, ", consider changing it") + let post = format!(", consider renaming `{}` into `{snippet}`", suggestion.candidate); + (span, snippet, post) } else { - (span, suggestion.candidate.to_string(), "") + (span, suggestion.candidate.to_string(), String::new()) }; let msg = match suggestion.target { SuggestionTarget::SimilarlyNamed => format!( diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index 0d7b9afab5ee4..42d9b519c147f 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -546,8 +546,20 @@ fn encode_ty<'tcx>( if let Some(cfi_encoding) = tcx.get_attr(def_id, sym::cfi_encoding) { // Use user-defined CFI encoding for type if let Some(value_str) = cfi_encoding.value_str() { - if !value_str.to_string().trim().is_empty() { - s.push_str(value_str.to_string().trim()); + let value_str = value_str.to_string(); + let str = value_str.trim(); + if !str.is_empty() { + s.push_str(str); + // Don't compress user-defined builtin types (see + // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-builtin and + // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-compression). + let builtin_types = [ + "v", "w", "b", "c", "a", "h", "s", "t", "i", "j", "l", "m", "x", "y", + "n", "o", "f", "d", "e", "g", "z", + ]; + if !builtin_types.contains(&str) { + compress(dict, DictKey::Ty(ty, TyQ::None), &mut s); + } } else { #[allow( rustc::diagnostic_outside_of_impl, @@ -563,7 +575,6 @@ fn encode_ty<'tcx>( } else { bug!("encode_ty: invalid `cfi_encoding` for `{:?}`", ty.kind()); } - compress(dict, DictKey::Ty(ty, TyQ::None), &mut s); } else if options.contains(EncodeTyOptions::GENERALIZE_REPR_C) && adt_def.repr().c() { // For cross-language LLVM CFI support, the encoding must be compatible at the FFI // boundary. For instance: diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs index 3b902dd80f59b..af533d8db7149 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -281,7 +281,58 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<'tcx>( } // Coroutine-closures don't implement `Fn` traits the normal way. - ty::CoroutineClosure(..) => Err(NoSolution), + // Instead, they always implement `FnOnce`, but only implement + // `FnMut`/`Fn` if they capture no upvars, since those may borrow + // from the closure. + ty::CoroutineClosure(def_id, args) => { + let args = args.as_coroutine_closure(); + let kind_ty = args.kind_ty(); + let sig = args.coroutine_closure_sig().skip_binder(); + + let coroutine_ty = if let Some(closure_kind) = kind_ty.to_opt_closure_kind() { + if !closure_kind.extends(goal_kind) { + return Err(NoSolution); + } + + // If `Fn`/`FnMut`, we only implement this goal if we + // have no captures. + let no_borrows = match args.tupled_upvars_ty().kind() { + ty::Tuple(tys) => tys.is_empty(), + ty::Error(_) => false, + _ => bug!("tuple_fields called on non-tuple"), + }; + if closure_kind != ty::ClosureKind::FnOnce && !no_borrows { + return Err(NoSolution); + } + + coroutine_closure_to_certain_coroutine( + tcx, + goal_kind, + // No captures by ref, so this doesn't matter. + tcx.lifetimes.re_static, + def_id, + args, + sig, + ) + } else { + // Closure kind is not yet determined, so we return ambiguity unless + // the expected kind is `FnOnce` as that is always implemented. + if goal_kind != ty::ClosureKind::FnOnce { + return Ok(None); + } + + coroutine_closure_to_ambiguous_coroutine( + tcx, + goal_kind, // No captures by ref, so this doesn't matter. + tcx.lifetimes.re_static, + def_id, + args, + sig, + ) + }; + + Ok(Some(args.coroutine_closure_sig().rebind((sig.tupled_inputs_ty, coroutine_ty)))) + } ty::Bool | ty::Char @@ -313,6 +364,19 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<'tcx>( } } +/// Relevant types for an async callable, including its inputs, output, +/// and the return type you get from awaiting the output. +#[derive(Copy, Clone, Debug, TypeVisitable, TypeFoldable)] +pub(in crate::solve) struct AsyncCallableRelevantTypes<'tcx> { + pub tupled_inputs_ty: Ty<'tcx>, + /// Type returned by calling the closure + /// i.e. `f()`. + pub output_coroutine_ty: Ty<'tcx>, + /// Type returned by `await`ing the output + /// i.e. `f().await`. + pub coroutine_return_ty: Ty<'tcx>, +} + // Returns a binder of the tupled inputs types, output type, and coroutine type // from a builtin coroutine-closure type. If we don't yet know the closure kind of // the coroutine-closure, emit an additional trait predicate for `AsyncFnKindHelper` @@ -323,8 +387,10 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc self_ty: Ty<'tcx>, goal_kind: ty::ClosureKind, env_region: ty::Region<'tcx>, -) -> Result<(ty::Binder<'tcx, (Ty<'tcx>, Ty<'tcx>, Ty<'tcx>)>, Vec>), NoSolution> -{ +) -> Result< + (ty::Binder<'tcx, AsyncCallableRelevantTypes<'tcx>>, Vec>), + NoSolution, +> { match *self_ty.kind() { ty::CoroutineClosure(def_id, args) => { let args = args.as_coroutine_closure(); @@ -335,24 +401,11 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc if !closure_kind.extends(goal_kind) { return Err(NoSolution); } - sig.to_coroutine_given_kind_and_upvars( - tcx, - args.parent_args(), - tcx.coroutine_for_closure(def_id), - goal_kind, - env_region, - args.tupled_upvars_ty(), - args.coroutine_captures_by_ref_ty(), + + coroutine_closure_to_certain_coroutine( + tcx, goal_kind, env_region, def_id, args, sig, ) } else { - let async_fn_kind_trait_def_id = - tcx.require_lang_item(LangItem::AsyncFnKindHelper, None); - let upvars_projection_def_id = tcx - .associated_items(async_fn_kind_trait_def_id) - .filter_by_name_unhygienic(sym::Upvars) - .next() - .unwrap() - .def_id; // When we don't know the closure kind (and therefore also the closure's upvars, // which are computed at the same time), we must delay the computation of the // generator's upvars. We do this using the `AsyncFnKindHelper`, which as a trait @@ -363,38 +416,23 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc nested.push( ty::TraitRef::new( tcx, - async_fn_kind_trait_def_id, + tcx.require_lang_item(LangItem::AsyncFnKindHelper, None), [kind_ty, Ty::from_closure_kind(tcx, goal_kind)], ) .to_predicate(tcx), ); - let tupled_upvars_ty = Ty::new_projection( - tcx, - upvars_projection_def_id, - [ - ty::GenericArg::from(kind_ty), - Ty::from_closure_kind(tcx, goal_kind).into(), - env_region.into(), - sig.tupled_inputs_ty.into(), - args.tupled_upvars_ty().into(), - args.coroutine_captures_by_ref_ty().into(), - ], - ); - sig.to_coroutine( - tcx, - args.parent_args(), - Ty::from_closure_kind(tcx, goal_kind), - tcx.coroutine_for_closure(def_id), - tupled_upvars_ty, + + coroutine_closure_to_ambiguous_coroutine( + tcx, goal_kind, env_region, def_id, args, sig, ) }; Ok(( - args.coroutine_closure_sig().rebind(( - sig.tupled_inputs_ty, - sig.return_ty, - coroutine_ty, - )), + args.coroutine_closure_sig().rebind(AsyncCallableRelevantTypes { + tupled_inputs_ty: sig.tupled_inputs_ty, + output_coroutine_ty: coroutine_ty, + coroutine_return_ty: sig.return_ty, + }), nested, )) } @@ -418,7 +456,11 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc .def_id; let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]); Ok(( - bound_sig.rebind((Ty::new_tup(tcx, sig.inputs()), sig.output(), future_output_ty)), + bound_sig.rebind(AsyncCallableRelevantTypes { + tupled_inputs_ty: Ty::new_tup(tcx, sig.inputs()), + output_coroutine_ty: sig.output(), + coroutine_return_ty: future_output_ty, + }), nested, )) } @@ -469,7 +511,14 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc .unwrap() .def_id; let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]); - Ok((bound_sig.rebind((sig.inputs()[0], sig.output(), future_output_ty)), nested)) + Ok(( + bound_sig.rebind(AsyncCallableRelevantTypes { + tupled_inputs_ty: sig.inputs()[0], + output_coroutine_ty: sig.output(), + coroutine_return_ty: future_output_ty, + }), + nested, + )) } ty::Bool @@ -502,6 +551,68 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc } } +/// Given a coroutine-closure, project to its returned coroutine when we are *certain* +/// that the closure's kind is compatible with the goal. +fn coroutine_closure_to_certain_coroutine<'tcx>( + tcx: TyCtxt<'tcx>, + goal_kind: ty::ClosureKind, + goal_region: ty::Region<'tcx>, + def_id: DefId, + args: ty::CoroutineClosureArgs<'tcx>, + sig: ty::CoroutineClosureSignature<'tcx>, +) -> Ty<'tcx> { + sig.to_coroutine_given_kind_and_upvars( + tcx, + args.parent_args(), + tcx.coroutine_for_closure(def_id), + goal_kind, + goal_region, + args.tupled_upvars_ty(), + args.coroutine_captures_by_ref_ty(), + ) +} + +/// Given a coroutine-closure, project to its returned coroutine when we are *not certain* +/// that the closure's kind is compatible with the goal, and therefore also don't know +/// yet what the closure's upvars are. +/// +/// Note that we do not also push a `AsyncFnKindHelper` goal here. +fn coroutine_closure_to_ambiguous_coroutine<'tcx>( + tcx: TyCtxt<'tcx>, + goal_kind: ty::ClosureKind, + goal_region: ty::Region<'tcx>, + def_id: DefId, + args: ty::CoroutineClosureArgs<'tcx>, + sig: ty::CoroutineClosureSignature<'tcx>, +) -> Ty<'tcx> { + let async_fn_kind_trait_def_id = tcx.require_lang_item(LangItem::AsyncFnKindHelper, None); + let upvars_projection_def_id = tcx + .associated_items(async_fn_kind_trait_def_id) + .filter_by_name_unhygienic(sym::Upvars) + .next() + .unwrap() + .def_id; + let tupled_upvars_ty = Ty::new_projection( + tcx, + upvars_projection_def_id, + [ + ty::GenericArg::from(args.kind_ty()), + Ty::from_closure_kind(tcx, goal_kind).into(), + goal_region.into(), + sig.tupled_inputs_ty.into(), + args.tupled_upvars_ty().into(), + args.coroutine_captures_by_ref_ty().into(), + ], + ); + sig.to_coroutine( + tcx, + args.parent_args(), + Ty::from_closure_kind(tcx, goal_kind), + tcx.coroutine_for_closure(def_id), + tupled_upvars_ty, + ) +} + /// Assemble a list of predicates that would be present on a theoretical /// user impl for an object type. These predicates must be checked any time /// we assemble a built-in object candidate for an object type, since they diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index aa8cc3667cd7b..3aba5c85abc3a 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -1,5 +1,6 @@ use crate::traits::{check_args_compatible, specialization_graph}; +use super::assembly::structural_traits::AsyncCallableRelevantTypes; use super::assembly::{self, structural_traits, Candidate}; use super::{EvalCtxt, GoalSource}; use rustc_hir::def::DefKind; @@ -392,46 +393,56 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { goal_kind, env_region, )?; - let output_is_sized_pred = - tupled_inputs_and_output_and_coroutine.map_bound(|(_, output, _)| { - ty::TraitRef::from_lang_item(tcx, LangItem::Sized, DUMMY_SP, [output]) - }); + let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound( + |AsyncCallableRelevantTypes { output_coroutine_ty: output_ty, .. }| { + ty::TraitRef::from_lang_item(tcx, LangItem::Sized, DUMMY_SP, [output_ty]) + }, + ); let pred = tupled_inputs_and_output_and_coroutine - .map_bound(|(inputs, output, coroutine)| { - let (projection_ty, term) = match tcx.item_name(goal.predicate.def_id()) { - sym::CallOnceFuture => ( - ty::AliasTy::new( - tcx, - goal.predicate.def_id(), - [goal.predicate.self_ty(), inputs], + .map_bound( + |AsyncCallableRelevantTypes { + tupled_inputs_ty, + output_coroutine_ty, + coroutine_return_ty, + }| { + let (projection_ty, term) = match tcx.item_name(goal.predicate.def_id()) { + sym::CallOnceFuture => ( + ty::AliasTy::new( + tcx, + goal.predicate.def_id(), + [goal.predicate.self_ty(), tupled_inputs_ty], + ), + output_coroutine_ty.into(), ), - coroutine.into(), - ), - sym::CallMutFuture | sym::CallFuture => ( - ty::AliasTy::new( - tcx, - goal.predicate.def_id(), - [ - ty::GenericArg::from(goal.predicate.self_ty()), - inputs.into(), - env_region.into(), - ], + sym::CallMutFuture | sym::CallFuture => ( + ty::AliasTy::new( + tcx, + goal.predicate.def_id(), + [ + ty::GenericArg::from(goal.predicate.self_ty()), + tupled_inputs_ty.into(), + env_region.into(), + ], + ), + output_coroutine_ty.into(), ), - coroutine.into(), - ), - sym::Output => ( - ty::AliasTy::new( - tcx, - goal.predicate.def_id(), - [ty::GenericArg::from(goal.predicate.self_ty()), inputs.into()], + sym::Output => ( + ty::AliasTy::new( + tcx, + goal.predicate.def_id(), + [ + ty::GenericArg::from(goal.predicate.self_ty()), + tupled_inputs_ty.into(), + ], + ), + coroutine_return_ty.into(), ), - output.into(), - ), - name => bug!("no such associated type: {name}"), - }; - ty::ProjectionPredicate { projection_ty, term } - }) + name => bug!("no such associated type: {name}"), + }; + ty::ProjectionPredicate { projection_ty, term } + }, + ) .to_predicate(tcx); // A built-in `AsyncFn` impl only holds if the output is sized. diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 73bf66f66890f..eba6ba3f7b062 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -2,6 +2,7 @@ use crate::traits::supertrait_def_ids; +use super::assembly::structural_traits::AsyncCallableRelevantTypes; use super::assembly::{self, structural_traits, Candidate}; use super::{EvalCtxt, GoalSource, SolverMode}; use rustc_data_structures::fx::FxIndexSet; @@ -327,14 +328,19 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // This region doesn't matter because we're throwing away the coroutine type tcx.lifetimes.re_static, )?; - let output_is_sized_pred = - tupled_inputs_and_output_and_coroutine.map_bound(|(_, output, _)| { - ty::TraitRef::from_lang_item(tcx, LangItem::Sized, DUMMY_SP, [output]) - }); + let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound( + |AsyncCallableRelevantTypes { output_coroutine_ty, .. }| { + ty::TraitRef::from_lang_item(tcx, LangItem::Sized, DUMMY_SP, [output_coroutine_ty]) + }, + ); let pred = tupled_inputs_and_output_and_coroutine - .map_bound(|(inputs, _, _)| { - ty::TraitRef::new(tcx, goal.predicate.def_id(), [goal.predicate.self_ty(), inputs]) + .map_bound(|AsyncCallableRelevantTypes { tupled_inputs_ty, .. }| { + ty::TraitRef::new( + tcx, + goal.predicate.def_id(), + [goal.predicate.self_ty(), tupled_inputs_ty], + ) }) .to_predicate(tcx); // A built-in `AsyncFn` impl only holds if the output is sized. diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index d316149731e14..b8733bab27b21 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -923,14 +923,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { [self_ty, Ty::new_tup(tcx, sig.inputs())], ) }); + // We must additionally check that the return type impls `Future`. + + // FIXME(async_closures): Investigate this before stabilization. + // We instantiate this binder eagerly because the `confirm_future_candidate` + // method doesn't support higher-ranked futures, which the `AsyncFn` + // traits expressly allow the user to write. To fix this correctly, + // we'd need to instantiate trait bounds before we get to selection, + // like the new trait solver does. let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None); + let placeholder_output_ty = self.infcx.enter_forall_and_leak_universe(sig.output()); nested.push(obligation.with( tcx, - sig.map_bound(|sig| { - ty::TraitRef::new(tcx, future_trait_def_id, [sig.output()]) - }), + ty::TraitRef::new(tcx, future_trait_def_id, [placeholder_output_ty]), )); + (trait_ref, Ty::from_closure_kind(tcx, ty::ClosureKind::Fn)) } ty::Closure(_, args) => { @@ -943,14 +951,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { [self_ty, sig.inputs()[0]], ) }); + // We must additionally check that the return type impls `Future`. + // See FIXME in last branch for why we instantiate the binder eagerly. let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None); + let placeholder_output_ty = self.infcx.enter_forall_and_leak_universe(sig.output()); nested.push(obligation.with( tcx, - sig.map_bound(|sig| { - ty::TraitRef::new(tcx, future_trait_def_id, [sig.output()]) - }), + ty::TraitRef::new(tcx, future_trait_def_id, [placeholder_output_ty]), )); + (trait_ref, args.kind_ty()) } _ => bug!("expected callable type for AsyncFn candidate"), diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 20f4310603a05..d2804b4d20af3 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -48,7 +48,7 @@ dlmalloc = { version = "0.2.4", features = ['rustc-dep-of-std'] } fortanix-sgx-abi = { version = "0.5.0", features = ['rustc-dep-of-std'], public = true } [target.'cfg(target_os = "hermit")'.dependencies] -hermit-abi = { version = "0.3.2", features = ['rustc-dep-of-std'], public = true } +hermit-abi = { version = "0.3.9", features = ['rustc-dep-of-std'], public = true } [target.'cfg(target_os = "wasi")'.dependencies] wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false } diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index b60d7a724112d..6ec389400ae81 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -31,6 +31,8 @@ pub use core::f32::{ impl f32 { /// Returns the largest integer less than or equal to `self`. /// + /// This function always returns the precise result. + /// /// # Examples /// /// ``` @@ -52,6 +54,8 @@ impl f32 { /// Returns the smallest integer greater than or equal to `self`. /// + /// This function always returns the precise result. + /// /// # Examples /// /// ``` @@ -73,6 +77,8 @@ impl f32 { /// Returns the nearest integer to `self`. If a value is half-way between two /// integers, round away from `0.0`. /// + /// This function always returns the precise result. + /// /// # Examples /// /// ``` @@ -99,6 +105,8 @@ impl f32 { /// Returns the nearest integer to a number. Rounds half-way cases to the number /// with an even least significant digit. /// + /// This function always returns the precise result. + /// /// # Examples /// /// ``` @@ -123,6 +131,8 @@ impl f32 { /// Returns the integer part of `self`. /// This means that non-integer numbers are always truncated towards zero. /// + /// This function always returns the precise result. + /// /// # Examples /// /// ``` @@ -145,6 +155,8 @@ impl f32 { /// Returns the fractional part of `self`. /// + /// This function always returns the precise result. + /// /// # Examples /// /// ``` @@ -166,6 +178,8 @@ impl f32 { /// Computes the absolute value of `self`. /// + /// This function always returns the precise result. + /// /// # Examples /// /// ``` @@ -249,6 +263,12 @@ impl f32 { /// this is not always true, and will be heavily dependant on designing /// algorithms with specific target hardware in mind. /// + /// # Precision + /// + /// The result of this operation is guaranteed to be the rounded + /// infinite-precision result. It is specified by IEEE 754 as + /// `fusedMultiplyAdd` and guaranteed not to change. + /// /// # Examples /// /// ``` @@ -276,6 +296,11 @@ impl f32 { /// In other words, the result is `self / rhs` rounded to the integer `n` /// such that `self >= n * rhs`. /// + /// # Precision + /// + /// The result of this operation is guaranteed to be the rounded + /// infinite-precision result. + /// /// # Examples /// /// ``` @@ -309,6 +334,11 @@ impl f32 { /// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)` /// approximately. /// + /// # Precision + /// + /// The result of this operation is guaranteed to be the rounded + /// infinite-precision result. + /// /// # Examples /// /// ``` @@ -337,6 +367,10 @@ impl f32 { /// It might have a different sequence of rounding operations than `powf`, /// so the results are not guaranteed to agree. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -355,6 +389,10 @@ impl f32 { /// Raises a number to a floating point power. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -375,6 +413,12 @@ impl f32 { /// /// Returns NaN if `self` is a negative number other than `-0.0`. /// + /// # Precision + /// + /// The result of this operation is guaranteed to be the rounded + /// infinite-precision result. It is specified by IEEE 754 as `squareRoot` + /// and guaranteed not to change. + /// /// # Examples /// /// ``` @@ -398,6 +442,10 @@ impl f32 { /// Returns `e^(self)`, (the exponential function). /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -420,6 +468,10 @@ impl f32 { /// Returns `2^(self)`. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -440,6 +492,10 @@ impl f32 { /// Returns the natural logarithm of the number. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -466,6 +522,10 @@ impl f32 { /// `self.log2()` can produce more accurate results for base 2, and /// `self.log10()` can produce more accurate results for base 10. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -486,6 +546,10 @@ impl f32 { /// Returns the base 2 logarithm of the number. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -506,6 +570,10 @@ impl f32 { /// Returns the base 10 logarithm of the number. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -529,6 +597,12 @@ impl f32 { /// * If `self <= other`: `0.0` /// * Else: `self - other` /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `fdimf` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -561,6 +635,12 @@ impl f32 { /// Returns the cube root of a number. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `cbrtf` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -584,6 +664,12 @@ impl f32 { /// right-angle triangle with other sides having length `x.abs()` and /// `y.abs()`. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `hypotf` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -605,6 +691,10 @@ impl f32 { /// Computes the sine of a number (in radians). /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -624,6 +714,10 @@ impl f32 { /// Computes the cosine of a number (in radians). /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -643,6 +737,12 @@ impl f32 { /// Computes the tangent of a number (in radians). /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `tanf` from libc on Unix and + /// Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -663,6 +763,12 @@ impl f32 { /// the range [-pi/2, pi/2] or NaN if the number is outside the range /// [-1, 1]. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `asinf` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -686,6 +792,12 @@ impl f32 { /// the range [0, pi] or NaN if the number is outside the range /// [-1, 1]. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `acosf` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -708,6 +820,12 @@ impl f32 { /// Computes the arctangent of a number. Return value is in radians in the /// range [-pi/2, pi/2]; /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `atanf` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -734,6 +852,12 @@ impl f32 { /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]` /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)` /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `atan2f` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -764,6 +888,12 @@ impl f32 { /// Simultaneously computes the sine and cosine of the number, `x`. Returns /// `(sin(x), cos(x))`. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `(f32::sin(x), + /// f32::cos(x))`. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -787,6 +917,12 @@ impl f32 { /// Returns `e^(self) - 1` in a way that is accurate even if the /// number is close to zero. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `expm1f` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -809,6 +945,12 @@ impl f32 { /// Returns `ln(1+n)` (natural logarithm) more accurately than if /// the operations were performed separately. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `log1pf` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -831,6 +973,12 @@ impl f32 { /// Hyperbolic sine function. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `sinhf` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -854,6 +1002,12 @@ impl f32 { /// Hyperbolic cosine function. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `coshf` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -877,6 +1031,12 @@ impl f32 { /// Hyperbolic tangent function. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `tanhf` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -900,6 +1060,10 @@ impl f32 { /// Inverse hyperbolic sine function. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -923,6 +1087,10 @@ impl f32 { /// Inverse hyperbolic cosine function. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -948,6 +1116,10 @@ impl f32 { /// Inverse hyperbolic tangent function. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -969,6 +1141,12 @@ impl f32 { /// Gamma function. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `tgammaf` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -991,6 +1169,12 @@ impl f32 { /// /// The integer part of the tuple indicates the sign of the gamma function. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `lgamma_r` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index 88f992b3957af..7385576c33717 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -31,6 +31,8 @@ pub use core::f64::{ impl f64 { /// Returns the largest integer less than or equal to `self`. /// + /// This function always returns the precise result. + /// /// # Examples /// /// ``` @@ -52,6 +54,8 @@ impl f64 { /// Returns the smallest integer greater than or equal to `self`. /// + /// This function always returns the precise result. + /// /// # Examples /// /// ``` @@ -73,6 +77,8 @@ impl f64 { /// Returns the nearest integer to `self`. If a value is half-way between two /// integers, round away from `0.0`. /// + /// This function always returns the precise result. + /// /// # Examples /// /// ``` @@ -99,6 +105,8 @@ impl f64 { /// Returns the nearest integer to a number. Rounds half-way cases to the number /// with an even least significant digit. /// + /// This function always returns the precise result. + /// /// # Examples /// /// ``` @@ -123,6 +131,8 @@ impl f64 { /// Returns the integer part of `self`. /// This means that non-integer numbers are always truncated towards zero. /// + /// This function always returns the precise result. + /// /// # Examples /// /// ``` @@ -145,6 +155,8 @@ impl f64 { /// Returns the fractional part of `self`. /// + /// This function always returns the precise result. + /// /// # Examples /// /// ``` @@ -166,6 +178,8 @@ impl f64 { /// Computes the absolute value of `self`. /// + /// This function always returns the precise result. + /// /// # Examples /// /// ``` @@ -249,6 +263,12 @@ impl f64 { /// this is not always true, and will be heavily dependant on designing /// algorithms with specific target hardware in mind. /// + /// # Precision + /// + /// The result of this operation is guaranteed to be the rounded + /// infinite-precision result. It is specified by IEEE 754 as + /// `fusedMultiplyAdd` and guaranteed not to change. + /// /// # Examples /// /// ``` @@ -276,6 +296,11 @@ impl f64 { /// In other words, the result is `self / rhs` rounded to the integer `n` /// such that `self >= n * rhs`. /// + /// # Precision + /// + /// The result of this operation is guaranteed to be the rounded + /// infinite-precision result. + /// /// # Examples /// /// ``` @@ -309,6 +334,11 @@ impl f64 { /// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)` /// approximately. /// + /// # Precision + /// + /// The result of this operation is guaranteed to be the rounded + /// infinite-precision result. + /// /// # Examples /// /// ``` @@ -337,6 +367,10 @@ impl f64 { /// It might have a different sequence of rounding operations than `powf`, /// so the results are not guaranteed to agree. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -355,6 +389,10 @@ impl f64 { /// Raises a number to a floating point power. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -375,6 +413,12 @@ impl f64 { /// /// Returns NaN if `self` is a negative number other than `-0.0`. /// + /// # Precision + /// + /// The result of this operation is guaranteed to be the rounded + /// infinite-precision result. It is specified by IEEE 754 as `squareRoot` + /// and guaranteed not to change. + /// /// # Examples /// /// ``` @@ -398,6 +442,10 @@ impl f64 { /// Returns `e^(self)`, (the exponential function). /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -420,6 +468,10 @@ impl f64 { /// Returns `2^(self)`. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -440,6 +492,10 @@ impl f64 { /// Returns the natural logarithm of the number. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -466,6 +522,10 @@ impl f64 { /// `self.log2()` can produce more accurate results for base 2, and /// `self.log10()` can produce more accurate results for base 10. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -486,6 +546,10 @@ impl f64 { /// Returns the base 2 logarithm of the number. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -506,6 +570,10 @@ impl f64 { /// Returns the base 10 logarithm of the number. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -529,6 +597,12 @@ impl f64 { /// * If `self <= other`: `0.0` /// * Else: `self - other` /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `fdim` from libc on Unix and + /// Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -561,6 +635,12 @@ impl f64 { /// Returns the cube root of a number. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `cbrt` from libc on Unix and + /// Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -584,6 +664,12 @@ impl f64 { /// right-angle triangle with other sides having length `x.abs()` and /// `y.abs()`. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `hypot` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -605,6 +691,10 @@ impl f64 { /// Computes the sine of a number (in radians). /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -624,6 +714,10 @@ impl f64 { /// Computes the cosine of a number (in radians). /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -643,6 +737,12 @@ impl f64 { /// Computes the tangent of a number (in radians). /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `tan` from libc on Unix and + /// Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -663,6 +763,12 @@ impl f64 { /// the range [-pi/2, pi/2] or NaN if the number is outside the range /// [-1, 1]. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `asin` from libc on Unix and + /// Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -686,6 +792,12 @@ impl f64 { /// the range [0, pi] or NaN if the number is outside the range /// [-1, 1]. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `acos` from libc on Unix and + /// Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -708,6 +820,12 @@ impl f64 { /// Computes the arctangent of a number. Return value is in radians in the /// range [-pi/2, pi/2]; /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `atan` from libc on Unix and + /// Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -734,6 +852,12 @@ impl f64 { /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]` /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)` /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `atan2` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -764,6 +888,12 @@ impl f64 { /// Simultaneously computes the sine and cosine of the number, `x`. Returns /// `(sin(x), cos(x))`. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `(f64::sin(x), + /// f64::cos(x))`. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -787,6 +917,12 @@ impl f64 { /// Returns `e^(self) - 1` in a way that is accurate even if the /// number is close to zero. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `expm1` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -809,6 +945,12 @@ impl f64 { /// Returns `ln(1+n)` (natural logarithm) more accurately than if /// the operations were performed separately. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `log1p` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -831,6 +973,12 @@ impl f64 { /// Hyperbolic sine function. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `sinh` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -854,6 +1002,12 @@ impl f64 { /// Hyperbolic cosine function. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `cosh` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -877,6 +1031,12 @@ impl f64 { /// Hyperbolic tangent function. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `tanh` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -900,6 +1060,10 @@ impl f64 { /// Inverse hyperbolic sine function. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -923,6 +1087,10 @@ impl f64 { /// Inverse hyperbolic cosine function. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -948,6 +1116,10 @@ impl f64 { /// Inverse hyperbolic tangent function. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// /// # Examples /// /// ``` @@ -969,6 +1141,12 @@ impl f64 { /// Gamma function. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `tgamma` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` @@ -991,6 +1169,12 @@ impl f64 { /// /// The integer part of the tuple indicates the sign of the gamma function. /// + /// # Platform-specific precision + /// + /// The precision of this function varies by platform and Rust version. + /// This function currently corresponds to the `lgamma_r` from libc on Unix + /// and Windows. Note that this might change in the future. + /// /// # Examples /// /// ``` diff --git a/library/std/src/sys/pal/hermit/os.rs b/library/std/src/sys/pal/hermit/os.rs index a54536aecb8b2..645f0dc1e311e 100644 --- a/library/std/src/sys/pal/hermit/os.rs +++ b/library/std/src/sys/pal/hermit/os.rs @@ -14,15 +14,15 @@ use crate::sys::unsupported; use crate::vec; pub fn errno() -> i32 { - 0 + unsafe { abi::get_errno() } } -pub fn error_string(_errno: i32) -> String { - "operation successful".to_string() +pub fn error_string(errno: i32) -> String { + abi::error_string(errno).to_string() } pub fn getcwd() -> io::Result { - unsupported() + Ok(PathBuf::from("/")) } pub fn chdir(_: &path::Path) -> io::Result<()> { @@ -188,7 +188,7 @@ pub fn unsetenv(k: &OsStr) -> io::Result<()> { } pub fn temp_dir() -> PathBuf { - panic!("no filesystem on hermit") + PathBuf::from("/tmp") } pub fn home_dir() -> Option { diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs index 69c8792b03148..700c3ee4fdacf 100644 --- a/src/bootstrap/src/core/build_steps/format.rs +++ b/src/bootstrap/src/core/build_steps/format.rs @@ -279,8 +279,8 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { let thread = std::thread::spawn(move || { let mut children = VecDeque::new(); while let Ok(path) = rx.recv() { - // try getting a few more paths from the channel to amortize the overhead of spawning processes - let paths: Vec<_> = rx.try_iter().take(7).chain(std::iter::once(path)).collect(); + // try getting more paths from the channel to amortize the overhead of spawning processes + let paths: Vec<_> = rx.try_iter().take(63).chain(std::iter::once(path)).collect(); let child = rustfmt(&src, &rustfmt_path, paths.as_slice(), check); children.push_back(child); diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index e169cba3c13ae..8223a80c93107 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -642,22 +642,22 @@ impl<'a> ShouldRun<'a> { #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] pub enum Kind { - #[clap(alias = "b")] + #[value(alias = "b")] Build, - #[clap(alias = "c")] + #[value(alias = "c")] Check, Clippy, Fix, Format, - #[clap(alias = "t")] + #[value(alias = "t")] Test, Bench, - #[clap(alias = "d")] + #[value(alias = "d")] Doc, Clean, Dist, Install, - #[clap(alias = "r")] + #[value(alias = "r")] Run, Setup, Suggest, diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index 8af454001a64a..7262b785ee00a 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -31,7 +31,7 @@ pub enum Warnings { /// Deserialized version of all flags for this compile. #[derive(Debug, Parser)] -#[clap( +#[command( override_usage = "x.py [options] [...]", disable_help_subcommand(true), about = "", @@ -118,7 +118,7 @@ pub struct Flags { // This overrides the deny-warnings configuration option, // which passes -Dwarnings to the compiler invocations. #[arg(global(true), long)] - #[clap(value_enum, default_value_t=Warnings::Default, value_name = "deny|warn")] + #[arg(value_enum, default_value_t=Warnings::Default, value_name = "deny|warn")] /// if value is deny, will deny warnings /// if value is warn, will emit warnings /// otherwise, use the default configured behaviour @@ -132,7 +132,7 @@ pub struct Flags { pub json_output: bool, #[arg(global(true), long, value_name = "STYLE")] - #[clap(value_enum, default_value_t = Color::Auto)] + #[arg(value_enum, default_value_t = Color::Auto)] /// whether to use color in cargo and rustc output pub color: Color, @@ -188,7 +188,7 @@ impl Flags { let it = std::iter::once(&first).chain(args.iter()); // We need to check for ` -h -v`, in which case we list the paths #[derive(Parser)] - #[clap(disable_help_flag(true))] + #[command(disable_help_flag(true))] struct HelpVerboseOnly { #[arg(short, long)] help: bool, @@ -218,7 +218,7 @@ impl Flags { #[derive(Debug, Clone, Default, clap::Subcommand)] pub enum Subcommand { - #[clap(aliases = ["b"], long_about = "\n + #[command(aliases = ["b"], long_about = "\n Arguments: This subcommand accepts a number of paths to directories to the crates and/or artifacts to compile. For example, for a quick build of a usable @@ -233,7 +233,7 @@ pub enum Subcommand { /// Compile either the compiler or libraries #[default] Build, - #[clap(aliases = ["c"], long_about = "\n + #[command(aliases = ["c"], long_about = "\n Arguments: This subcommand accepts a number of paths to directories to the crates and/or artifacts to compile. For example: @@ -246,7 +246,7 @@ pub enum Subcommand { all_targets: bool, }, /// Run Clippy (uses rustup/cargo-installed clippy binary) - #[clap(long_about = "\n + #[command(long_about = "\n Arguments: This subcommand accepts a number of paths to directories to the crates and/or artifacts to run clippy against. For example: @@ -273,14 +273,14 @@ pub enum Subcommand { forbid: Vec, }, /// Run cargo fix - #[clap(long_about = "\n + #[command(long_about = "\n Arguments: This subcommand accepts a number of paths to directories to the crates and/or artifacts to run `cargo fix` against. For example: ./x.py fix library/core ./x.py fix library/core library/proc_macro")] Fix, - #[clap( + #[command( name = "fmt", long_about = "\n Arguments: @@ -295,7 +295,7 @@ pub enum Subcommand { #[arg(long)] check: bool, }, - #[clap(aliases = ["d"], long_about = "\n + #[command(aliases = ["d"], long_about = "\n Arguments: This subcommand accepts a number of paths to directories of documentation to build. For example: @@ -316,7 +316,7 @@ pub enum Subcommand { /// render the documentation in JSON format in addition to the usual HTML format json: bool, }, - #[clap(aliases = ["t"], long_about = "\n + #[command(aliases = ["t"], long_about = "\n Arguments: This subcommand accepts a number of paths to test directories that should be compiled and run. For example: @@ -400,7 +400,7 @@ pub enum Subcommand { Dist, /// Install distribution artifacts Install, - #[clap(aliases = ["r"], long_about = "\n + #[command(aliases = ["r"], long_about = "\n Arguments: This subcommand accepts a number of paths to tools to build and run. For example: @@ -413,7 +413,7 @@ pub enum Subcommand { args: Vec, }, /// Set up the environment for development - #[clap(long_about = format!( + #[command(long_about = format!( "\n x.py setup creates a `config.toml` which changes the defaults for x.py itself, as well as setting up a git pre-push hook, VS Code config and toolchain link. @@ -434,7 +434,7 @@ Arguments: profile: Option, }, /// Suggest a subset of tests to run, based on modified files - #[clap(long_about = "\n")] + #[command(long_about = "\n")] Suggest { /// run suggested tests #[arg(long)] diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index d4ca91977a636..90ac97f35f679 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -39,6 +39,7 @@ - [\*-unknown-fuchsia](platform-support/fuchsia.md) - [\*-kmc-solid_\*](platform-support/kmc-solid.md) - [csky-unknown-linux-gnuabiv2\*](platform-support/csky-unknown-linux-gnuabiv2.md) + - [hexagon-unknown-linux-musl](platform-support/hexagon-unknown-linux-musl.md) - [hexagon-unknown-none-elf](platform-support/hexagon-unknown-none-elf.md) - [loongarch\*-unknown-linux-\*](platform-support/loongarch-linux.md) - [loongarch\*-unknown-none\*](platform-support/loongarch-none.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 984cb13f790ca..f1e3ad81b8528 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -286,8 +286,8 @@ target | std | host | notes `bpfel-unknown-none` | * | | BPF (little endian) `csky-unknown-linux-gnuabiv2` | ✓ | | C-SKY abiv2 Linux (little endian) `csky-unknown-linux-gnuabiv2hf` | ✓ | | C-SKY abiv2 Linux, hardfloat (little endian) -[`hexagon-unknown-none-elf`](platform-support/hexagon-unknown-none-elf.md)| * | Bare Hexagon (v60+, HVX) -`hexagon-unknown-linux-musl` | ? | | +[`hexagon-unknown-none-elf`](platform-support/hexagon-unknown-none-elf.md)| * | | Bare Hexagon (v60+, HVX) +[`hexagon-unknown-linux-musl`](platform-support/hexagon-unknown-linux-musl.md) | ✓ | | Hexagon Linux `i386-apple-ios` | ✓ | | 32-bit x86 iOS [^x86_32-floats-return-ABI] [`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS [^x86_32-floats-return-ABI] [`i586-unknown-netbsd`](platform-support/netbsd.md) | ✓ | | 32-bit x86, restricted to Pentium diff --git a/src/doc/rustc/src/platform-support/hexagon-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/hexagon-unknown-linux-musl.md new file mode 100644 index 0000000000000..c1372726a35f4 --- /dev/null +++ b/src/doc/rustc/src/platform-support/hexagon-unknown-linux-musl.md @@ -0,0 +1,102 @@ +# `hexagon-unknown-linux-musl` + +**Tier: 3** + +Target for cross-compiling Linux user-mode applications targeting the Hexagon +DSP architecture. + +| Target | Descriptions | +| ------------------------ | ----------------------------------------- | +| hexagon-unknown-linux-musl | Hexagon 32-bit Linux | + +## Target maintainers + +- [Brian Cain](https://github.com/androm3da), `bcain@quicinc.com` + +## Requirements +The target is cross-compiled. This target supports `std`. By default, code +generated with this target should run on Hexagon DSP hardware. + +- `-Ctarget-cpu=hexagonv73` adds support for instructions defined up to Hexagon V73. + +Binaries can be run using QEMU user emulation. On Debian-based systems, it should be +sufficient to install the package `qemu-user-static` to be able to run simple static +binaries: + +```text +# apt install qemu-user-static +# qemu-hexagon-static ./hello +``` + +In order to build linux programs with Rust, you will require a linker capable +of targeting hexagon. You can use `clang`/`lld` from the [hexagon toolchain +using exclusively public open source repos](https://github.com/quic/toolchain_for_hexagon/releases). + +Also included in that toolchain is the C library that can be used when creating +dynamically linked executables. + +```text +# /opt/clang+llvm-18.1.0-cross-hexagon-unknown-linux-musl/x86_64-linux-gnu/bin/qemu-hexagon -L /opt/clang+llvm-18.1.0-cross-hexagon-unknown-linux-musl/x86_64-linux-gnu/target/hexagon-unknown-linux-musl/usr/ ./hello +``` + +## Building the target +Because it is Tier 3, rust does not yet ship pre-compiled artifacts for this +target. + +Therefore, you can build Rust with support for the target by adding it to the +target list in `config.toml`, a sample configuration is shown below. + +```toml +[build] +target = [ "hexagon-unknown-linux-musl"] + +[target.hexagon-unknown-linux-musl] + +cc = "hexagon-unknown-linux-musl-clang" +cxx = "hexagon-unknown-linux-musl-clang++" +linker = "hexagon-unknown-linux-musl-clang" +ar = "hexagon-unknown-linux-musl-ar" +ranlib = "hexagon-unknown-linux-musl-ranlib" +musl-root = "/opt/clang+llvm-18.1.0-cross-hexagon-unknown-linux-musl/x86_64-linux-gnu/target/hexagon-unknown-linux-musl/usr" +llvm-libunwind = 'in-tree' +qemu-rootfs = "/opt/clang+llvm-18.1.0-cross-hexagon-unknown-linux-musl/x86_64-linux-gnu/target/hexagon-unknown-linux-musl/usr" +``` + + +## Testing + +Currently there is no support to run the rustc test suite for this target. + + +## Building Rust programs + +Download and install the hexagon open source toolchain from https://github.com/quic/toolchain_for_hexagon/releases + +The following `.cargo/config` is needed inside any project directory to build +for the Hexagon Linux target: + +```toml +[build] +target = "hexagon-unknown-linux-musl" + +[target.hexagon-unknown-linux-musl] +linker = "hexagon-unknown-linux-musl-clang" +ar = "hexagon-unknown-linux-musl-ar" +runner = "qemu-hexagon -L /opt/clang+llvm-18.1.0-cross-hexagon-unknown-linux-musl/x86_64-linux-gnu/target/hexagon-unknown-linux-musl/usr" +``` + +Edit the "runner" in `.cargo/config` to point to the path to your toolchain's +C library. + +```text +... +runner = "qemu-hexagon -L /path/to/my/inst/clang+llvm-18.1.0-cross-hexagon-unknown-linux-musl/x86_64-linux-gnu/target/hexagon-unknown-linux-musl/usr" +... +``` + +Build/run your rust program with `qemu-hexagon` in your `PATH`: + +```text +export PATH=/path/to/my/inst/clang+llvm-18.1.0-cross-hexagon-unknown-linux-musl/x86_64-linux-gnu/bin/:$PATH +cargo run -Zbuild-std -Zbuild-std-features=llvm-libunwind +``` diff --git a/src/doc/rustc/src/platform-support/hexagon-unknown-none-elf.md b/src/doc/rustc/src/platform-support/hexagon-unknown-none-elf.md index 3ac1d2c24603c..a0e26b798ac2b 100644 --- a/src/doc/rustc/src/platform-support/hexagon-unknown-none-elf.md +++ b/src/doc/rustc/src/platform-support/hexagon-unknown-none-elf.md @@ -41,6 +41,8 @@ target = ["", "hexagon-unknown-none-elf"] cc = "hexagon-unknown-none-elf-clang" cxx = "hexagon-unknown-none-elf-clang++" linker = "hexagon-unknown-none-elf-clang" +ranlib = "hexagon-unknown-none-elf-ranlib" +ar = "hexagon-unknown-none-elf-ar" llvm-libunwind = 'in-tree' ``` @@ -142,7 +144,7 @@ ${cc} --target=hexagon-unknown-none-elf -o testit \ ${g0_lib_path}/init.o \ -L${sdk_libs}/${q6_arch}/ \ -L${sdk_libs}/ \ - testit.c \ + wrap.c \ target/hexagon-unknown-none-elf/${build_cfg}/libdemo1_hexagon.rlib \ target/hexagon-unknown-none-elf/${build_cfg}/deps/libcore-*.rlib \ target/hexagon-unknown-none-elf/${build_cfg}/deps/libcompiler_builtins-*.rlib \ @@ -217,7 +219,18 @@ fn rust_eh_personality() {} ``` -Next, save the script below as `build.sh` and edit it to suit your +Next, create a C program as an entry point, save the content below as +`wrap.c`: + +```C +int hello(); + +int main() { + hello(); +} +``` + +Then, save the script below as `build.sh` and edit it to suit your environment. The script below will build a shared object against the QuRT RTOS which is suitable for emulation or on-device testing when loaded via the fastrpc-shell. @@ -248,7 +261,7 @@ ${cc} --target=hexagon-unknown-none-elf -o testit.so \ -Wl,--wrap=realloc \ -Wl,--wrap=memalign \ -m${q6_arch} \ - testit.c \ + wrap.c \ target/hexagon-unknown-none-elf/${build_cfg}/libdemo2_hexagon.rlib \ target/hexagon-unknown-none-elf/${build_cfg}/deps/libcore-*.rlib \ target/hexagon-unknown-none-elf/${build_cfg}/deps/libcompiler_builtins-*.rlib \ diff --git a/tests/codegen/sanitizer/cfi-emit-type-metadata-attr-cfi-encoding.rs b/tests/codegen/sanitizer/cfi-emit-type-metadata-attr-cfi-encoding.rs index f15ca30b7e362..be4af9b7962d7 100644 --- a/tests/codegen/sanitizer/cfi-emit-type-metadata-attr-cfi-encoding.rs +++ b/tests/codegen/sanitizer/cfi-emit-type-metadata-attr-cfi-encoding.rs @@ -18,6 +18,13 @@ extern { #[repr(transparent)] pub struct Type3(i32); +#[cfi_encoding = "i"] +pub struct Type4(i32); + +#[cfi_encoding = "j"] +#[repr(transparent)] +pub struct Type5(u32); + pub fn foo0(_: Type1) { } // CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo1(_: Type1, _: Type1) { } @@ -36,6 +43,18 @@ pub fn foo7(_: *mut Type3, _: *mut Type3) { } // CHECK: define{{.*}}foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo8(_: *mut Type3, _: *mut Type3, _: *mut Type3) { } // CHECK: define{{.*}}foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo9(_: Type4) { } +// CHECK: define{{.*}}foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo10(_: Type4, _: Type4) { } +// CHECK: define{{.*}}foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo11(_: Type4, _: Type4, _: Type4) { } +// CHECK: define{{.*}}foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo12(_: Type5) { } +// CHECK: define{{.*}}foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo13(_: Type5, _: Type5) { } +// CHECK: define{{.*}}foo13{{.*}}!type ![[TYPE13:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo14(_: Type5, _: Type5, _: Type5) { } +// CHECK: define{{.*}}foo14{{.*}}!type ![[TYPE14:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} // CHECK: ![[TYPE0]] = !{i64 0, !"_ZTSFv3FooE"} // CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFv3FooS_E"} @@ -46,3 +65,9 @@ pub fn foo8(_: *mut Type3, _: *mut Type3, _: *mut Type3) { } // CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvP3BazE"} // CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvP3BazS0_E"} // CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvP3BazS0_S0_E"} +// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFviE"} +// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFviiE"} +// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFviiiE"} +// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvjE"} +// CHECK: ![[TYPE13]] = !{i64 0, !"_ZTSFvjjE"} +// CHECK: ![[TYPE14]] = !{i64 0, !"_ZTSFvjjjE"} diff --git a/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs b/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs index 9c3b458cd3adf..be4364653159c 100644 --- a/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs +++ b/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs @@ -8,11 +8,15 @@ extern crate block_on; fn main() { block_on::block_on(async { - let x = async || {}; - async fn needs_async_fn_once(x: impl async FnOnce()) { x().await; } - needs_async_fn_once(x).await; + + needs_async_fn_once(async || {}).await; + + needs_async_fn_once(|| async {}).await; + + async fn foo() {} + needs_async_fn_once(foo).await; }); } diff --git a/tests/ui/async-await/async-closures/is-fn.rs b/tests/ui/async-await/async-closures/is-fn.rs new file mode 100644 index 0000000000000..64cc28e425f52 --- /dev/null +++ b/tests/ui/async-await/async-closures/is-fn.rs @@ -0,0 +1,24 @@ +//@ aux-build:block-on.rs +//@ edition:2021 +//@ build-pass +//@ revisions: current next +//@[next] compile-flags: -Znext-solver + +#![feature(async_closure)] + +use std::future::Future; + +extern crate block_on; + +// Check that closures that don't capture any state may implement `Fn`. + +fn main() { + block_on::block_on(async { + async fn call_once(x: impl FnOnce(&'static str) -> F) -> F::Output { + x("hello, world").await + } + call_once(async |x: &'static str| { + println!("hello, {x}"); + }).await + }); +} diff --git a/tests/ui/async-await/async-closures/move-is-async-fn.rs b/tests/ui/async-await/async-closures/move-is-async-fn.rs index 0ccd137266d53..79e2298f6092b 100644 --- a/tests/ui/async-await/async-closures/move-is-async-fn.rs +++ b/tests/ui/async-await/async-closures/move-is-async-fn.rs @@ -2,7 +2,7 @@ //@ edition:2021 //@ build-pass -#![feature(async_closure)] +#![feature(async_closure, async_fn_traits)] extern crate block_on; @@ -15,7 +15,11 @@ fn main() { c().await; c().await; - fn is_static(_: T) {} - is_static(c); + fn is_static(_: &T) {} + is_static(&c); + + // Check that `<{async fn} as AsyncFnOnce>::CallOnceFuture` owns its captures. + fn call_once(f: F) -> F::CallOnceFuture { f() } + is_static(&call_once(c)); }); } diff --git a/tests/ui/async-await/async-closures/once.rs b/tests/ui/async-await/async-closures/once.rs index 55e4cedb267a9..761df3de44429 100644 --- a/tests/ui/async-await/async-closures/once.rs +++ b/tests/ui/async-await/async-closures/once.rs @@ -1,6 +1,8 @@ //@ aux-build:block-on.rs //@ edition:2021 //@ build-pass +//@ revisions: current next +//@[next] compile-flags: -Znext-solver #![feature(async_closure)] @@ -8,11 +10,11 @@ use std::future::Future; extern crate block_on; -struct NoCopy; +// Check that async closures always implement `FnOnce` fn main() { block_on::block_on(async { - async fn call_once(x: impl Fn(&'static str) -> F) -> F::Output { + async fn call_once(x: impl FnOnce(&'static str) -> F) -> F::Output { x("hello, world").await } call_once(async |x: &'static str| { diff --git a/tests/ui/async-await/async-closures/refd.rs b/tests/ui/async-await/async-closures/refd.rs index 1d9bc1a601bdd..0b8d3d7aff554 100644 --- a/tests/ui/async-await/async-closures/refd.rs +++ b/tests/ui/async-await/async-closures/refd.rs @@ -2,8 +2,6 @@ //@ edition:2021 //@ build-pass -// check that `&{async-closure}` implements `AsyncFn`. - #![feature(async_closure)] extern crate block_on; @@ -13,6 +11,15 @@ struct NoCopy; fn main() { block_on::block_on(async { async fn call_once(x: impl async Fn()) { x().await } - call_once(&async || {}).await + + // check that `&{async-closure}` implements `async Fn`. + call_once(&async || {}).await; + + // check that `&{closure}` implements `async Fn`. + call_once(&|| async {}).await; + + // check that `&fndef` implements `async Fn`. + async fn foo() {} + call_once(&foo).await; }); } diff --git a/tests/ui/async-await/async-fn/higher-ranked-async-fn.rs b/tests/ui/async-await/async-fn/higher-ranked-async-fn.rs new file mode 100644 index 0000000000000..5680c05773765 --- /dev/null +++ b/tests/ui/async-await/async-fn/higher-ranked-async-fn.rs @@ -0,0 +1,31 @@ +//@ aux-build:block-on.rs +//@ edition:2018 +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ build-pass (since it ICEs during mono) + +#![feature(async_closure)] + +extern crate block_on; + +use std::future::Future; + +async fn f(arg: &i32) {} + +async fn func(f: F) +where + F: async for<'a> Fn(&'a i32), +{ + let x: i32 = 0; + f(&x).await; +} + +fn main() { + block_on::block_on(async { + // Function + func(f).await; + + // Regular closure (doesn't capture) + func(|x: &i32| async {}); + }); +} diff --git a/tests/ui/async-await/async-fn/project.rs b/tests/ui/async-await/async-fn/project.rs new file mode 100644 index 0000000000000..302564bb9519f --- /dev/null +++ b/tests/ui/async-await/async-fn/project.rs @@ -0,0 +1,12 @@ +//@ edition:2018 +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ check-pass + +#![feature(async_closure, unboxed_closures, async_fn_traits)] + +fn project>(_: F) -> Option { None } + +fn main() { + let x: Option = project(|| async { 1i32 }); +} diff --git a/tests/ui/suggestions/silenced-binding-typo.stderr b/tests/ui/suggestions/silenced-binding-typo.stderr index 8dbd94208d614..c362d00c713a2 100644 --- a/tests/ui/suggestions/silenced-binding-typo.stderr +++ b/tests/ui/suggestions/silenced-binding-typo.stderr @@ -4,7 +4,7 @@ error[E0425]: cannot find value `x` in this scope LL | let _y = x; | ^ | -help: a local variable with a similar name exists, consider changing it +help: a local variable with a similar name exists, consider renaming `_x` into `x` | LL | let x = 42; | ~