Auto merge of #121800 - GuillaumeGomez:rollup-wob2qcz, r=GuillaumeGomez

Rollup of 10 pull requests

Successful merges:

 - #118217 (Document which methods on `f64` are precise)
 - #119748 (Increase visibility of `join_path` and `split_paths`)
 - #121412 (platform docs: clarify hexagon-unknown-none-elf example, add hexagon-unknown-linux-musl)
 - #121654 (Fix `async Fn` confirmation for `FnDef`/`FnPtr`/`Closure` types)
 - #121700 (CFI: Don't compress user-defined builtin types)
 - #121765 (add platform-specific function to get the error number for HermitOS)
 - #121781 (bootstrap/format: send larger batches to rustfmt)
 - #121788 (bootstrap: fix clap deprecated warnings)
 - #121792 (Improve renaming suggestion when item starts with underscore)
 - #121793 (Document which methods on `f32` are precise)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-02-29 13:35:16 +00:00
commit 384d26fc7e
28 changed files with 891 additions and 144 deletions

View File

@ -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",

View File

@ -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 },

View File

@ -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!(

View File

@ -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:

View File

@ -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<ty::Predicate<'tcx>>), NoSolution>
{
) -> Result<
(ty::Binder<'tcx, AsyncCallableRelevantTypes<'tcx>>, Vec<ty::Predicate<'tcx>>),
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

View File

@ -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,21 +393,27 @@ 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)| {
.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(), inputs],
[goal.predicate.self_ty(), tupled_inputs_ty],
),
coroutine.into(),
output_coroutine_ty.into(),
),
sym::CallMutFuture | sym::CallFuture => (
ty::AliasTy::new(
@ -414,24 +421,28 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
goal.predicate.def_id(),
[
ty::GenericArg::from(goal.predicate.self_ty()),
inputs.into(),
tupled_inputs_ty.into(),
env_region.into(),
],
),
coroutine.into(),
output_coroutine_ty.into(),
),
sym::Output => (
ty::AliasTy::new(
tcx,
goal.predicate.def_id(),
[ty::GenericArg::from(goal.predicate.self_ty()), inputs.into()],
[
ty::GenericArg::from(goal.predicate.self_ty()),
tupled_inputs_ty.into(),
],
),
output.into(),
coroutine_return_ty.into(),
),
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.

View File

@ -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.

View File

@ -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"),

View File

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

View File

@ -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
///
/// ```

View File

@ -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
///
/// ```

View File

@ -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<PathBuf> {
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<PathBuf> {

View File

@ -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);

View File

@ -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,

View File

@ -31,7 +31,7 @@ pub enum Warnings {
/// Deserialized version of all flags for this compile.
#[derive(Debug, Parser)]
#[clap(
#[command(
override_usage = "x.py <subcommand> [options] [<paths>...]",
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 `<cmd> -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<String>,
},
/// 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<String>,
},
/// 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<PathBuf>,
},
/// 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)]

View File

@ -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)

View File

@ -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

View File

@ -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
```

View File

@ -41,6 +41,8 @@ target = ["<target for your host>", "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 \

View File

@ -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"}

View File

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

View File

@ -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<F: Future>(x: impl FnOnce(&'static str) -> F) -> F::Output {
x("hello, world").await
}
call_once(async |x: &'static str| {
println!("hello, {x}");
}).await
});
}

View File

@ -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: 'static>(_: T) {}
is_static(c);
fn is_static<T: 'static>(_: &T) {}
is_static(&c);
// Check that `<{async fn} as AsyncFnOnce>::CallOnceFuture` owns its captures.
fn call_once<F: async FnOnce()>(f: F) -> F::CallOnceFuture { f() }
is_static(&call_once(c));
});
}

View File

@ -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<F: Future>(x: impl Fn(&'static str) -> F) -> F::Output {
async fn call_once<F: Future>(x: impl FnOnce(&'static str) -> F) -> F::Output {
x("hello, world").await
}
call_once(async |x: &'static str| {

View File

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

View File

@ -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: 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 {});
});
}

View File

@ -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: async Fn<()>>(_: F) -> Option<F::Output> { None }
fn main() {
let x: Option<i32> = project(|| async { 1i32 });
}

View File

@ -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;
| ~