Auto merge of #146812 - matthiaskrgr:rollup-aiap18m, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - rust-lang/rust#144592 (generate list of all variants with `target_spec_enum`) - rust-lang/rust#146762 (Fix and provide instructions for running test suite on Apple simulators) - rust-lang/rust#146770 (fixes for numerous clippy warnings) - rust-lang/rust#146774 (Allow running `x <cmd> <path>` from a different directory) - rust-lang/rust#146800 (Fix unsupported `std::sys::thread` after move) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
dd7fda5700
52 changed files with 316 additions and 168 deletions
|
|
@ -45,6 +45,7 @@ use rustc_middle::util::Providers;
|
|||
use rustc_session::Session;
|
||||
use rustc_session::config::{OptLevel, OutputFilenames, PrintKind, PrintRequest};
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::spec::{RelocModel, TlsModel};
|
||||
|
||||
mod abi;
|
||||
mod allocator;
|
||||
|
|
@ -244,16 +245,7 @@ impl CodegenBackend for LlvmCodegenBackend {
|
|||
match req.kind {
|
||||
PrintKind::RelocationModels => {
|
||||
writeln!(out, "Available relocation models:").unwrap();
|
||||
for name in &[
|
||||
"static",
|
||||
"pic",
|
||||
"pie",
|
||||
"dynamic-no-pic",
|
||||
"ropi",
|
||||
"rwpi",
|
||||
"ropi-rwpi",
|
||||
"default",
|
||||
] {
|
||||
for name in RelocModel::ALL.iter().map(RelocModel::desc).chain(["default"]) {
|
||||
writeln!(out, " {name}").unwrap();
|
||||
}
|
||||
writeln!(out).unwrap();
|
||||
|
|
@ -267,9 +259,7 @@ impl CodegenBackend for LlvmCodegenBackend {
|
|||
}
|
||||
PrintKind::TlsModels => {
|
||||
writeln!(out, "Available TLS models:").unwrap();
|
||||
for name in
|
||||
&["global-dynamic", "local-dynamic", "initial-exec", "local-exec", "emulated"]
|
||||
{
|
||||
for name in TlsModel::ALL.iter().map(TlsModel::desc) {
|
||||
writeln!(out, " {name}").unwrap();
|
||||
}
|
||||
writeln!(out).unwrap();
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ impl Callbacks for TimePassesCallbacks {
|
|||
// time because it will mess up the --print output. See #64339.
|
||||
//
|
||||
self.time_passes = (config.opts.prints.is_empty() && config.opts.unstable_opts.time_passes)
|
||||
.then(|| config.opts.unstable_opts.time_passes_format);
|
||||
.then_some(config.opts.unstable_opts.time_passes_format);
|
||||
config.opts.trimmed_def_paths = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -439,8 +439,9 @@ fn make_input(early_dcx: &EarlyDiagCtxt, free_matches: &[String]) -> Option<Inpu
|
|||
"when UNSTABLE_RUSTDOC_TEST_PATH is set \
|
||||
UNSTABLE_RUSTDOC_TEST_LINE also needs to be set",
|
||||
);
|
||||
let line = isize::from_str_radix(&line, 10)
|
||||
.expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be an number");
|
||||
let line = line
|
||||
.parse::<isize>()
|
||||
.expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be a number");
|
||||
FileName::doc_test_source_code(PathBuf::from(path), line)
|
||||
}
|
||||
Err(_) => FileName::anon_source_code(&input),
|
||||
|
|
@ -474,8 +475,7 @@ fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, col
|
|||
let mut text = String::new();
|
||||
// Slice off the leading newline and print.
|
||||
for line in description.lines() {
|
||||
let indent_level =
|
||||
line.find(|c: char| !c.is_whitespace()).unwrap_or_else(|| line.len());
|
||||
let indent_level = line.find(|c: char| !c.is_whitespace()).unwrap_or(line.len());
|
||||
let dedented_line = &line[indent_level..];
|
||||
if dedented_line.starts_with("```") {
|
||||
is_in_code_block = !is_in_code_block;
|
||||
|
|
@ -547,7 +547,7 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) {
|
|||
|
||||
// The pager failed. Try to print pretty output to stdout.
|
||||
if let Some((bufwtr, mdbuf)) = &pretty_data
|
||||
&& bufwtr.print(&mdbuf).is_ok()
|
||||
&& bufwtr.print(mdbuf).is_ok()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -598,8 +598,7 @@ fn process_rlink(sess: &Session, compiler: &interface::Compiler) {
|
|||
|
||||
fn list_metadata(sess: &Session, metadata_loader: &dyn MetadataLoader) {
|
||||
match sess.io.input {
|
||||
Input::File(ref ifile) => {
|
||||
let path = &(*ifile);
|
||||
Input::File(ref path) => {
|
||||
let mut v = Vec::new();
|
||||
locator::list_file_metadata(
|
||||
&sess.target,
|
||||
|
|
@ -833,7 +832,7 @@ fn print_crate_info(
|
|||
SupportedCrateTypes => {
|
||||
let supported_crate_types = CRATE_TYPES
|
||||
.iter()
|
||||
.filter(|(_, crate_type)| !invalid_output_for_target(&sess, *crate_type))
|
||||
.filter(|(_, crate_type)| !invalid_output_for_target(sess, *crate_type))
|
||||
.filter(|(_, crate_type)| *crate_type != CrateType::Sdylib)
|
||||
.map(|(crate_type_sym, _)| *crate_type_sym)
|
||||
.collect::<BTreeSet<_>>();
|
||||
|
|
@ -1434,7 +1433,7 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&DiagCtxt))
|
|||
eprintln!();
|
||||
|
||||
if let Some(ice_path) = ice_path()
|
||||
&& let Ok(mut out) = File::options().create(true).append(true).open(&ice_path)
|
||||
&& let Ok(mut out) = File::options().create(true).append(true).open(ice_path)
|
||||
{
|
||||
// The current implementation always returns `Some`.
|
||||
let location = info.location().unwrap();
|
||||
|
|
@ -1510,7 +1509,7 @@ fn report_ice(
|
|||
|
||||
let file = if let Some(path) = ice_path() {
|
||||
// Create the ICE dump target file.
|
||||
match crate::fs::File::options().create(true).append(true).open(&path) {
|
||||
match crate::fs::File::options().create(true).append(true).open(path) {
|
||||
Ok(mut file) => {
|
||||
dcx.emit_note(session_diagnostics::IcePath { path: path.clone() });
|
||||
if FIRST_PANIC.swap(false, Ordering::SeqCst) {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ macro_rules! safe_println {
|
|||
}
|
||||
|
||||
pub(crate) fn print(args: fmt::Arguments<'_>) {
|
||||
if let Err(_) = io::stdout().write_fmt(args) {
|
||||
if io::stdout().write_fmt(args).is_err() {
|
||||
rustc_errors::FatalError.raise();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ fn typeck_with_inspect<'tcx>(
|
|||
}
|
||||
|
||||
fcx.select_obligations_where_possible(|_| {});
|
||||
if let None = fcx.infcx.tainted_by_errors() {
|
||||
if fcx.infcx.tainted_by_errors().is_none() {
|
||||
fcx.report_ambiguity_errors();
|
||||
}
|
||||
|
||||
|
|
@ -295,7 +295,7 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti
|
|||
} else if let Node::AnonConst(_) = node {
|
||||
let id = tcx.local_def_id_to_hir_id(def_id);
|
||||
match tcx.parent_hir_node(id) {
|
||||
Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), span, .. })
|
||||
Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(anon_const), span, .. })
|
||||
if anon_const.hir_id == id =>
|
||||
{
|
||||
Some(fcx.next_ty_var(span))
|
||||
|
|
|
|||
|
|
@ -421,7 +421,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// Not all upvars are captured by ref, so use
|
||||
// `apply_capture_kind_on_capture_ty` to ensure that we
|
||||
// compute the right captured type.
|
||||
return apply_capture_kind_on_capture_ty(
|
||||
apply_capture_kind_on_capture_ty(
|
||||
self.tcx,
|
||||
upvar_ty,
|
||||
capture,
|
||||
|
|
@ -430,7 +430,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
} else {
|
||||
self.tcx.lifetimes.re_erased
|
||||
},
|
||||
);
|
||||
)
|
||||
},
|
||||
),
|
||||
);
|
||||
|
|
@ -529,11 +529,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// process any deferred resolutions.
|
||||
let deferred_call_resolutions = self.remove_deferred_call_resolutions(closure_def_id);
|
||||
for deferred_call_resolution in deferred_call_resolutions {
|
||||
deferred_call_resolution.resolve(&mut FnCtxt::new(
|
||||
self,
|
||||
self.param_env,
|
||||
closure_def_id,
|
||||
));
|
||||
deferred_call_resolution.resolve(&FnCtxt::new(self, self.param_env, closure_def_id));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1493,7 +1489,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
/// Notation:
|
||||
/// - Ty(place): Type of place
|
||||
/// - `(a, b)`: Represents the function parameters `base_path_ty` and `captured_by_move_projs`
|
||||
/// respectively.
|
||||
/// respectively.
|
||||
/// ```ignore (illustrative)
|
||||
/// (Ty(w), [ &[p, x], &[c] ])
|
||||
/// // |
|
||||
|
|
@ -2179,9 +2175,10 @@ fn restrict_precision_for_unsafe(
|
|||
(place, curr_mode)
|
||||
}
|
||||
|
||||
/// Truncate projections so that following rules are obeyed by the captured `place`:
|
||||
/// Truncate projections so that the following rules are obeyed by the captured `place`:
|
||||
/// - No Index projections are captured, since arrays are captured completely.
|
||||
/// - No unsafe block is required to capture `place`
|
||||
/// - No unsafe block is required to capture `place`.
|
||||
///
|
||||
/// Returns the truncated place and updated capture mode.
|
||||
fn restrict_capture_precision(
|
||||
place: Place<'_>,
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
// to use builtin indexing because the index type is known to be
|
||||
// usize-ish
|
||||
fn fix_index_builtin_expr(&mut self, e: &hir::Expr<'_>) {
|
||||
if let hir::ExprKind::Index(ref base, ref index, _) = e.kind {
|
||||
if let hir::ExprKind::Index(base, index, _) = e.kind {
|
||||
// All valid indexing looks like this; might encounter non-valid indexes at this point.
|
||||
let base_ty = self.typeck_results.expr_ty_adjusted(base);
|
||||
if let ty::Ref(_, base_ty_inner, _) = *base_ty.kind() {
|
||||
|
|
@ -583,7 +583,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
if let Err(err) = opaque_type_has_defining_use_args(
|
||||
&self.fcx,
|
||||
self.fcx,
|
||||
opaque_type_key,
|
||||
hidden_type.span,
|
||||
DefiningScopeKind::HirTypeck,
|
||||
|
|
@ -792,7 +792,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
|
||||
fn visit_potentially_region_dependent_goals(&mut self) {
|
||||
let obligations = self.fcx.take_hir_typeck_potentially_region_dependent_goals();
|
||||
if let None = self.fcx.tainted_by_errors() {
|
||||
if self.fcx.tainted_by_errors().is_none() {
|
||||
for obligation in obligations {
|
||||
let (predicate, mut cause) =
|
||||
self.fcx.resolve_vars_if_possible((obligation.predicate, obligation.cause));
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ fn configure_and_expand(
|
|||
unsafe {
|
||||
env::set_var(
|
||||
"PATH",
|
||||
&env::join_paths(
|
||||
env::join_paths(
|
||||
new_path.iter().filter(|p| env::join_paths(iter::once(p)).is_ok()),
|
||||
)
|
||||
.unwrap(),
|
||||
|
|
@ -446,7 +446,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
|
|||
let prev_source = sess.psess.source_map().span_to_prev_source(first_span);
|
||||
let ferris_fix = prev_source
|
||||
.map_or(FerrisFix::SnakeCase, |source| {
|
||||
let mut source_before_ferris = source.trim_end().split_whitespace().rev();
|
||||
let mut source_before_ferris = source.split_whitespace().rev();
|
||||
match source_before_ferris.next() {
|
||||
Some("struct" | "trait" | "mod" | "union" | "type" | "enum") => {
|
||||
FerrisFix::PascalCase
|
||||
|
|
@ -500,7 +500,7 @@ fn env_var_os<'tcx>(tcx: TyCtxt<'tcx>, key: &'tcx OsStr) -> Option<&'tcx OsStr>
|
|||
// properly change-tracked.
|
||||
tcx.sess.psess.env_depinfo.borrow_mut().insert((
|
||||
Symbol::intern(&key.to_string_lossy()),
|
||||
value.as_ref().and_then(|value| value.to_str()).map(|value| Symbol::intern(&value)),
|
||||
value.as_ref().and_then(|value| value.to_str()).map(|value| Symbol::intern(value)),
|
||||
));
|
||||
|
||||
value_tcx
|
||||
|
|
@ -824,7 +824,7 @@ pub fn write_dep_info(tcx: TyCtxt<'_>) {
|
|||
|
||||
let outputs = tcx.output_filenames(());
|
||||
let output_paths =
|
||||
generated_output_paths(tcx, &outputs, sess.io.output_file.is_some(), crate_name);
|
||||
generated_output_paths(tcx, outputs, sess.io.output_file.is_some(), crate_name);
|
||||
|
||||
// Ensure the source file isn't accidentally overwritten during compilation.
|
||||
if let Some(input_path) = sess.io.input.opt_path() {
|
||||
|
|
@ -847,7 +847,7 @@ pub fn write_dep_info(tcx: TyCtxt<'_>) {
|
|||
}
|
||||
}
|
||||
|
||||
write_out_deps(tcx, &outputs, &output_paths);
|
||||
write_out_deps(tcx, outputs, &output_paths);
|
||||
|
||||
let only_dep_info = sess.opts.output_types.contains_key(&OutputType::DepInfo)
|
||||
&& sess.opts.output_types.len() == 1;
|
||||
|
|
@ -1303,7 +1303,7 @@ pub(crate) fn parse_crate_name(
|
|||
let rustc_hir::Attribute::Parsed(AttributeKind::CrateName { name, name_span, .. }) =
|
||||
AttributeParser::parse_limited_should_emit(
|
||||
sess,
|
||||
&attrs,
|
||||
attrs,
|
||||
sym::crate_name,
|
||||
DUMMY_SP,
|
||||
rustc_ast::node_id::CRATE_NODE_ID,
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ impl Linker {
|
|||
&rlink_file,
|
||||
&codegen_results,
|
||||
&self.metadata,
|
||||
&*self.output_filenames,
|
||||
&self.output_filenames,
|
||||
)
|
||||
.unwrap_or_else(|error| {
|
||||
sess.dcx().emit_fatal(FailedWritingFile { path: &rlink_file, error })
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ pub(crate) fn run_in_thread_pool_with_globals<
|
|||
let query_map = rustc_span::set_session_globals_then(unsafe { &*(session_globals as *const SessionGlobals) }, || {
|
||||
// Ensure there was no errors collecting all active jobs.
|
||||
// We need the complete map to ensure we find a cycle to break.
|
||||
QueryCtxt::new(tcx).collect_active_jobs().ok().expect("failed to collect active queries in deadlock handler")
|
||||
QueryCtxt::new(tcx).collect_active_jobs().expect("failed to collect active queries in deadlock handler")
|
||||
});
|
||||
break_query_cycles(query_map, ®istry);
|
||||
})
|
||||
|
|
@ -561,7 +561,7 @@ pub fn build_output_filenames(attrs: &[ast::Attribute], sess: &Session) -> Outpu
|
|||
}
|
||||
Some(out_file.clone())
|
||||
};
|
||||
if sess.io.output_dir != None {
|
||||
if sess.io.output_dir.is_some() {
|
||||
sess.dcx().emit_warn(errors::IgnoringOutDir);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -374,11 +374,13 @@ impl CheckCfg {
|
|||
|
||||
ins!(sym::overflow_checks, no_values);
|
||||
|
||||
ins!(sym::panic, empty_values).extend(&PanicStrategy::all());
|
||||
ins!(sym::panic, empty_values)
|
||||
.extend(PanicStrategy::ALL.iter().map(PanicStrategy::desc_symbol));
|
||||
|
||||
ins!(sym::proc_macro, no_values);
|
||||
|
||||
ins!(sym::relocation_model, empty_values).extend(RelocModel::all());
|
||||
ins!(sym::relocation_model, empty_values)
|
||||
.extend(RelocModel::ALL.iter().map(RelocModel::desc_symbol));
|
||||
|
||||
let sanitize_values = SanitizerSet::all()
|
||||
.into_iter()
|
||||
|
|
|
|||
|
|
@ -76,10 +76,10 @@ fn find_relative_libdir(sysroot: &Path) -> std::borrow::Cow<'static, str> {
|
|||
macro_rules! target_spec_enum {
|
||||
(
|
||||
$( #[$attr:meta] )*
|
||||
pub enum $name:ident {
|
||||
pub enum $Name:ident {
|
||||
$(
|
||||
$( #[$variant_attr:meta] )*
|
||||
$variant:ident = $string:literal,
|
||||
$Variant:ident = $string:literal,
|
||||
)*
|
||||
}
|
||||
parse_error_type = $parse_error_type:literal;
|
||||
|
|
@ -87,20 +87,20 @@ macro_rules! target_spec_enum {
|
|||
$( #[$attr] )*
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
|
||||
#[derive(schemars::JsonSchema)]
|
||||
pub enum $name {
|
||||
pub enum $Name {
|
||||
$(
|
||||
$( #[$variant_attr] )*
|
||||
#[serde(rename = $string)] // for JSON schema generation only
|
||||
$variant,
|
||||
$Variant,
|
||||
)*
|
||||
}
|
||||
|
||||
impl FromStr for $name {
|
||||
impl FromStr for $Name {
|
||||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(match s {
|
||||
$( $string => Self::$variant, )*
|
||||
$( $string => Self::$Variant, )*
|
||||
_ => {
|
||||
let all = [$( concat!("'", $string, "'") ),*].join(", ");
|
||||
return Err(format!("invalid {}: '{s}'. allowed values: {all}", $parse_error_type));
|
||||
|
|
@ -109,24 +109,25 @@ macro_rules! target_spec_enum {
|
|||
}
|
||||
}
|
||||
|
||||
impl $name {
|
||||
impl $Name {
|
||||
pub const ALL: &'static [$Name] = &[ $( $Name::$Variant, )* ];
|
||||
pub fn desc(&self) -> &'static str {
|
||||
match self {
|
||||
$( Self::$variant => $string, )*
|
||||
$( Self::$Variant => $string, )*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::json::ToJson for $name {
|
||||
impl crate::json::ToJson for $Name {
|
||||
fn to_json(&self) -> crate::json::Json {
|
||||
self.desc().to_json()
|
||||
}
|
||||
}
|
||||
|
||||
crate::json::serde_deserialize_from_str!($name);
|
||||
crate::json::serde_deserialize_from_str!($Name);
|
||||
|
||||
|
||||
impl std::fmt::Display for $name {
|
||||
impl std::fmt::Display for $Name {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(self.desc())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -854,10 +854,6 @@ impl PanicStrategy {
|
|||
PanicStrategy::Abort => sym::abort,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn all() -> [Symbol; 2] {
|
||||
[Self::Abort.desc_symbol(), Self::Unwind.desc_symbol()]
|
||||
}
|
||||
}
|
||||
|
||||
crate::target_spec_enum! {
|
||||
|
|
@ -974,18 +970,6 @@ impl RelocModel {
|
|||
RelocModel::RopiRwpi => sym::ropi_rwpi,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn all() -> [Symbol; 7] {
|
||||
[
|
||||
RelocModel::Static.desc_symbol(),
|
||||
RelocModel::Pic.desc_symbol(),
|
||||
RelocModel::Pie.desc_symbol(),
|
||||
RelocModel::DynamicNoPic.desc_symbol(),
|
||||
RelocModel::Ropi.desc_symbol(),
|
||||
RelocModel::Rwpi.desc_symbol(),
|
||||
RelocModel::RopiRwpi.desc_symbol(),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
crate::target_spec_enum! {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
//!
|
||||
//! Better known as "varargs".
|
||||
|
||||
#[cfg(not(target_arch = "xtensa"))]
|
||||
use crate::ffi::c_void;
|
||||
#[allow(unused_imports)]
|
||||
use crate::fmt;
|
||||
|
|
|
|||
|
|
@ -406,8 +406,10 @@ pub trait ChildExt: Sealed {
|
|||
/// use libc::SIGTERM;
|
||||
///
|
||||
/// fn main() -> io::Result<()> {
|
||||
/// # if cfg!(not(all(target_vendor = "apple", not(target_os = "macos")))) {
|
||||
/// let child = Command::new("cat").stdin(Stdio::piped()).spawn()?;
|
||||
/// child.send_signal(SIGTERM)?;
|
||||
/// # }
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
|
|
|
|||
|
|
@ -532,6 +532,7 @@ impl fmt::Debug for ChildStderr {
|
|||
/// to be changed (for example, by adding arguments) prior to spawning:
|
||||
///
|
||||
/// ```
|
||||
/// # if cfg!(not(all(target_vendor = "apple", not(target_os = "macos")))) {
|
||||
/// use std::process::Command;
|
||||
///
|
||||
/// let output = if cfg!(target_os = "windows") {
|
||||
|
|
@ -548,6 +549,7 @@ impl fmt::Debug for ChildStderr {
|
|||
/// };
|
||||
///
|
||||
/// let hello = output.stdout;
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// `Command` can be reused to spawn multiple processes. The builder methods
|
||||
|
|
@ -1348,7 +1350,7 @@ impl Output {
|
|||
///
|
||||
/// ```
|
||||
/// #![feature(exit_status_error)]
|
||||
/// # #[cfg(all(unix, not(target_os = "android")))] {
|
||||
/// # #[cfg(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos")))))] {
|
||||
/// use std::process::Command;
|
||||
/// assert!(Command::new("false").output().unwrap().exit_ok().is_err());
|
||||
/// # }
|
||||
|
|
@ -1695,7 +1697,7 @@ impl From<io::Stdout> for Stdio {
|
|||
/// # Ok(())
|
||||
/// # }
|
||||
/// #
|
||||
/// # if cfg!(all(unix, not(target_os = "android"))) {
|
||||
/// # if cfg!(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos"))))) {
|
||||
/// # test().unwrap();
|
||||
/// # }
|
||||
/// ```
|
||||
|
|
@ -1724,7 +1726,7 @@ impl From<io::Stderr> for Stdio {
|
|||
/// # Ok(())
|
||||
/// # }
|
||||
/// #
|
||||
/// # if cfg!(all(unix, not(target_os = "android"))) {
|
||||
/// # if cfg!(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos"))))) {
|
||||
/// # test().unwrap();
|
||||
/// # }
|
||||
/// ```
|
||||
|
|
@ -1800,7 +1802,7 @@ impl ExitStatus {
|
|||
///
|
||||
/// ```
|
||||
/// #![feature(exit_status_error)]
|
||||
/// # if cfg!(unix) {
|
||||
/// # if cfg!(all(unix, not(all(target_vendor = "apple", not(target_os = "macos"))))) {
|
||||
/// use std::process::Command;
|
||||
///
|
||||
/// let status = Command::new("ls")
|
||||
|
|
@ -1907,7 +1909,7 @@ impl crate::sealed::Sealed for ExitStatusError {}
|
|||
///
|
||||
/// ```
|
||||
/// #![feature(exit_status_error)]
|
||||
/// # if cfg!(all(unix, not(target_os = "android"))) {
|
||||
/// # if cfg!(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos"))))) {
|
||||
/// use std::process::{Command, ExitStatusError};
|
||||
///
|
||||
/// fn run(cmd: &str) -> Result<(), ExitStatusError> {
|
||||
|
|
@ -1950,7 +1952,7 @@ impl ExitStatusError {
|
|||
///
|
||||
/// ```
|
||||
/// #![feature(exit_status_error)]
|
||||
/// # #[cfg(all(unix, not(target_os = "android")))] {
|
||||
/// # #[cfg(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos")))))] {
|
||||
/// use std::process::Command;
|
||||
///
|
||||
/// let bad = Command::new("false").status().unwrap().exit_ok().unwrap_err();
|
||||
|
|
@ -1975,7 +1977,7 @@ impl ExitStatusError {
|
|||
/// ```
|
||||
/// #![feature(exit_status_error)]
|
||||
///
|
||||
/// # if cfg!(all(unix, not(target_os = "android"))) {
|
||||
/// # if cfg!(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos"))))) {
|
||||
/// use std::num::NonZero;
|
||||
/// use std::process::Command;
|
||||
///
|
||||
|
|
|
|||
|
|
@ -5,7 +5,15 @@ use crate::mem::MaybeUninit;
|
|||
use crate::str;
|
||||
|
||||
fn known_command() -> Command {
|
||||
if cfg!(windows) { Command::new("help") } else { Command::new("echo") }
|
||||
if cfg!(windows) {
|
||||
Command::new("help")
|
||||
} else if cfg!(all(target_vendor = "apple", not(target_os = "macos"))) {
|
||||
// iOS/tvOS/watchOS/visionOS have a very limited set of commandline
|
||||
// binaries available.
|
||||
Command::new("log")
|
||||
} else {
|
||||
Command::new("echo")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
|
|
@ -19,7 +27,10 @@ fn shell_cmd() -> Command {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(any(target_os = "vxworks"), ignore)]
|
||||
#[cfg_attr(
|
||||
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
|
||||
ignore = "no shell available"
|
||||
)]
|
||||
fn smoke() {
|
||||
let p = if cfg!(target_os = "windows") {
|
||||
Command::new("cmd").args(&["/C", "exit 0"]).spawn()
|
||||
|
|
@ -41,7 +52,10 @@ fn smoke_failure() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(any(target_os = "vxworks"), ignore)]
|
||||
#[cfg_attr(
|
||||
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
|
||||
ignore = "no shell available"
|
||||
)]
|
||||
fn exit_reported_right() {
|
||||
let p = if cfg!(target_os = "windows") {
|
||||
Command::new("cmd").args(&["/C", "exit 1"]).spawn()
|
||||
|
|
@ -56,7 +70,10 @@ fn exit_reported_right() {
|
|||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
#[cfg_attr(any(target_os = "vxworks"), ignore)]
|
||||
#[cfg_attr(
|
||||
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
|
||||
ignore = "no shell available"
|
||||
)]
|
||||
fn signal_reported_right() {
|
||||
use crate::os::unix::process::ExitStatusExt;
|
||||
|
||||
|
|
@ -80,7 +97,10 @@ pub fn run_output(mut cmd: Command) -> String {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(any(target_os = "vxworks"), ignore)]
|
||||
#[cfg_attr(
|
||||
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
|
||||
ignore = "no shell available"
|
||||
)]
|
||||
fn stdout_works() {
|
||||
if cfg!(target_os = "windows") {
|
||||
let mut cmd = Command::new("cmd");
|
||||
|
|
@ -94,7 +114,11 @@ fn stdout_works() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(any(windows, target_os = "vxworks"), ignore)]
|
||||
#[cfg_attr(windows, ignore)]
|
||||
#[cfg_attr(
|
||||
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
|
||||
ignore = "no shell available"
|
||||
)]
|
||||
fn set_current_dir_works() {
|
||||
// On many Unix platforms this will use the posix_spawn path.
|
||||
let mut cmd = shell_cmd();
|
||||
|
|
@ -116,7 +140,11 @@ fn set_current_dir_works() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(any(windows, target_os = "vxworks"), ignore)]
|
||||
#[cfg_attr(windows, ignore)]
|
||||
#[cfg_attr(
|
||||
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
|
||||
ignore = "no shell available"
|
||||
)]
|
||||
fn stdin_works() {
|
||||
let mut p = shell_cmd()
|
||||
.arg("-c")
|
||||
|
|
@ -134,7 +162,10 @@ fn stdin_works() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(any(target_os = "vxworks"), ignore)]
|
||||
#[cfg_attr(
|
||||
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
|
||||
ignore = "no shell available"
|
||||
)]
|
||||
fn child_stdout_read_buf() {
|
||||
let mut cmd = if cfg!(target_os = "windows") {
|
||||
let mut cmd = Command::new("cmd");
|
||||
|
|
@ -165,7 +196,10 @@ fn child_stdout_read_buf() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(any(target_os = "vxworks"), ignore)]
|
||||
#[cfg_attr(
|
||||
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
|
||||
ignore = "no shell available"
|
||||
)]
|
||||
fn test_process_status() {
|
||||
let mut status = if cfg!(target_os = "windows") {
|
||||
Command::new("cmd").args(&["/C", "exit 1"]).status().unwrap()
|
||||
|
|
@ -191,7 +225,10 @@ fn test_process_output_fail_to_start() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(any(target_os = "vxworks"), ignore)]
|
||||
#[cfg_attr(
|
||||
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
|
||||
ignore = "no shell available"
|
||||
)]
|
||||
fn test_process_output_output() {
|
||||
let Output { status, stdout, stderr } = if cfg!(target_os = "windows") {
|
||||
Command::new("cmd").args(&["/C", "echo hello"]).output().unwrap()
|
||||
|
|
@ -206,7 +243,10 @@ fn test_process_output_output() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(any(target_os = "vxworks"), ignore)]
|
||||
#[cfg_attr(
|
||||
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
|
||||
ignore = "no shell available"
|
||||
)]
|
||||
fn test_process_output_error() {
|
||||
let Output { status, stdout, stderr } = if cfg!(target_os = "windows") {
|
||||
Command::new("cmd").args(&["/C", "mkdir ."]).output().unwrap()
|
||||
|
|
@ -221,7 +261,10 @@ fn test_process_output_error() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(any(target_os = "vxworks"), ignore)]
|
||||
#[cfg_attr(
|
||||
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
|
||||
ignore = "no shell available"
|
||||
)]
|
||||
fn test_finish_once() {
|
||||
let mut prog = if cfg!(target_os = "windows") {
|
||||
Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
|
||||
|
|
@ -232,7 +275,10 @@ fn test_finish_once() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(any(target_os = "vxworks"), ignore)]
|
||||
#[cfg_attr(
|
||||
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
|
||||
ignore = "no shell available"
|
||||
)]
|
||||
fn test_finish_twice() {
|
||||
let mut prog = if cfg!(target_os = "windows") {
|
||||
Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
|
||||
|
|
@ -244,7 +290,10 @@ fn test_finish_twice() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(any(target_os = "vxworks"), ignore)]
|
||||
#[cfg_attr(
|
||||
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
|
||||
ignore = "no shell available"
|
||||
)]
|
||||
fn test_wait_with_output_once() {
|
||||
let prog = if cfg!(target_os = "windows") {
|
||||
Command::new("cmd").args(&["/C", "echo hello"]).stdout(Stdio::piped()).spawn().unwrap()
|
||||
|
|
@ -279,7 +328,10 @@ pub fn env_cmd() -> Command {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_os = "vxworks", ignore)]
|
||||
#[cfg_attr(
|
||||
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
|
||||
ignore = "no shell available"
|
||||
)]
|
||||
fn test_override_env() {
|
||||
use crate::env;
|
||||
|
||||
|
|
@ -302,7 +354,10 @@ fn test_override_env() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_os = "vxworks", ignore)]
|
||||
#[cfg_attr(
|
||||
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
|
||||
ignore = "no shell available"
|
||||
)]
|
||||
fn test_add_to_env() {
|
||||
let result = env_cmd().env("RUN_TEST_NEW_ENV", "123").output().unwrap();
|
||||
let output = String::from_utf8_lossy(&result.stdout).to_string();
|
||||
|
|
@ -314,7 +369,10 @@ fn test_add_to_env() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_os = "vxworks", ignore)]
|
||||
#[cfg_attr(
|
||||
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
|
||||
ignore = "no shell available"
|
||||
)]
|
||||
fn test_capture_env_at_spawn() {
|
||||
use crate::env;
|
||||
|
||||
|
|
@ -378,7 +436,10 @@ fn test_interior_nul_in_current_dir_is_error() {
|
|||
|
||||
// Regression tests for #30862.
|
||||
#[test]
|
||||
#[cfg_attr(target_os = "vxworks", ignore)]
|
||||
#[cfg_attr(
|
||||
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
|
||||
ignore = "no `env` cmd available"
|
||||
)]
|
||||
fn test_interior_nul_in_env_key_is_error() {
|
||||
match env_cmd().env("has-some-\0\0s-inside", "value").spawn() {
|
||||
Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
|
||||
|
|
@ -387,7 +448,10 @@ fn test_interior_nul_in_env_key_is_error() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_os = "vxworks", ignore)]
|
||||
#[cfg_attr(
|
||||
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
|
||||
ignore = "no `env` cmd available"
|
||||
)]
|
||||
fn test_interior_nul_in_env_value_is_error() {
|
||||
match env_cmd().env("key", "has-some-\0\0s-inside").spawn() {
|
||||
Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
// Replaces the #[else] gate with #[cfg(not(any(…)))] of all the other gates.
|
||||
// This ensures that they must be mutually exclusive and do not have precedence
|
||||
// like cfg_if!.
|
||||
// like cfg_select!.
|
||||
macro cfg_unordered(
|
||||
$(#[cfg($cfg:meta)] $os:item)*
|
||||
#[else] $fallback:item
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ mod common;
|
|||
pub mod os;
|
||||
#[path = "../unsupported/pipe.rs"]
|
||||
pub mod pipe;
|
||||
#[path = "../unsupported/thread.rs"]
|
||||
pub mod thread;
|
||||
#[path = "../unsupported/time.rs"]
|
||||
pub mod time;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
pub mod os;
|
||||
pub mod pipe;
|
||||
pub mod thread;
|
||||
pub mod time;
|
||||
|
||||
mod common;
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@ pub mod abi;
|
|||
pub mod os;
|
||||
#[path = "../unsupported/pipe.rs"]
|
||||
pub mod pipe;
|
||||
#[path = "../unsupported/thread.rs"]
|
||||
pub mod thread;
|
||||
#[path = "../unsupported/time.rs"]
|
||||
pub mod time;
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ fn exitstatus_display_tests() {
|
|||
|
||||
#[test]
|
||||
#[cfg_attr(target_os = "emscripten", ignore)]
|
||||
#[cfg_attr(any(target_os = "tvos", target_os = "watchos"), ignore = "fork is prohibited")]
|
||||
fn test_command_fork_no_unwind() {
|
||||
let got = catch_unwind(|| {
|
||||
let mut c = Command::new("echo");
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@ use libc::{self, RTP_ID, c_char, c_int};
|
|||
use super::common::*;
|
||||
use crate::io::{self, ErrorKind};
|
||||
use crate::num::NonZero;
|
||||
use crate::sys::cvt;
|
||||
use crate::sys::pal::thread;
|
||||
use crate::sys::{cvt, thread};
|
||||
use crate::{fmt, sys};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ mod common;
|
|||
#[test]
|
||||
// Process spawning not supported by Miri, Emscripten and wasi
|
||||
#[cfg_attr(any(miri, target_os = "emscripten", target_os = "wasi"), ignore)]
|
||||
#[cfg_attr(any(target_os = "tvos", target_os = "watchos"), ignore = "fork is prohibited")]
|
||||
fn issue_15149() {
|
||||
// If we're the parent, copy our own binary to a new directory.
|
||||
let my_path = env::current_exe().unwrap();
|
||||
|
|
|
|||
|
|
@ -590,18 +590,30 @@ impl StepDescription {
|
|||
// Attempt to resolve paths to be relative to the builder source directory.
|
||||
let mut paths: Vec<PathBuf> = paths
|
||||
.iter()
|
||||
.map(|p| {
|
||||
.map(|original_path| {
|
||||
let mut path = original_path.clone();
|
||||
|
||||
// Someone could run `x <cmd> <path>` from a different repository than the source
|
||||
// directory.
|
||||
// In that case, we should not try to resolve the paths relative to the working
|
||||
// directory, but rather relative to the source directory.
|
||||
// So we forcefully "relocate" the path to the source directory here.
|
||||
if !path.is_absolute() {
|
||||
path = builder.src.join(path);
|
||||
}
|
||||
|
||||
// If the path does not exist, it may represent the name of a Step, such as `tidy` in `x test tidy`
|
||||
if !p.exists() {
|
||||
return p.clone();
|
||||
if !path.exists() {
|
||||
// Use the original path here
|
||||
return original_path.clone();
|
||||
}
|
||||
|
||||
// Make the path absolute, strip the prefix, and convert to a PathBuf.
|
||||
match std::path::absolute(p) {
|
||||
match std::path::absolute(&path) {
|
||||
Ok(p) => p.strip_prefix(&builder.src).unwrap_or(&p).to_path_buf(),
|
||||
Err(e) => {
|
||||
eprintln!("ERROR: {e:?}");
|
||||
panic!("Due to the above error, failed to resolve path: {p:?}");
|
||||
panic!("Due to the above error, failed to resolve path: {path:?}");
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -339,9 +339,34 @@ results. The Docker image is set up to launch `remote-test-server` and the
|
|||
build tools use `remote-test-client` to communicate with the server to
|
||||
coordinate running tests (see [src/bootstrap/src/core/build_steps/test.rs]).
|
||||
|
||||
> **TODO**
|
||||
>
|
||||
> - Is there any support for using an iOS emulator?
|
||||
To run on the iOS/tvOS/watchOS/visionOS simulator, we can similarly treat it as
|
||||
a "remote" machine. A curious detail here is that the network is shared between
|
||||
the simulator instance and the host macOS, so we can use the local loopback
|
||||
address `127.0.0.1`. Something like the following should work:
|
||||
|
||||
```sh
|
||||
# Build the test server for the iOS simulator:
|
||||
./x build src/tools/remote-test-server --target aarch64-apple-ios-sim
|
||||
|
||||
# If you already have a simulator instance open, copy the device UUID from:
|
||||
xcrun simctl list devices booted
|
||||
UDID=01234567-89AB-CDEF-0123-456789ABCDEF
|
||||
|
||||
# Alternatively, create and boot a new simulator instance:
|
||||
xcrun simctl list runtimes
|
||||
xcrun simctl list devicetypes
|
||||
UDID=$(xcrun simctl create $CHOSEN_DEVICE_TYPE $CHOSEN_RUNTIME)
|
||||
xcrun simctl boot $UDID
|
||||
# See https://nshipster.com/simctl/ for details.
|
||||
|
||||
# Spawn the runner on port 12345:
|
||||
xcrun simctl spawn $UDID ./build/host/stage2-tools/aarch64-apple-ios-sim/release/remote-test-server -v --bind 127.0.0.1:12345
|
||||
|
||||
# In a new terminal, run tests via the runner:
|
||||
export TEST_DEVICE_ADDR="127.0.0.1:12345"
|
||||
./x test --host='' --target aarch64-apple-ios-sim --skip tests/debuginfo
|
||||
# FIXME(madsmtm): Allow debuginfo tests to work (maybe needs `.dSYM` folder to be copied to the target?).
|
||||
```
|
||||
|
||||
[armhf-gnu]: https://github.com/rust-lang/rust/tree/master/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile
|
||||
[QEMU]: https://www.qemu.org/
|
||||
|
|
|
|||
|
|
@ -66,6 +66,11 @@ Rust programs can be built for these targets by specifying `--target`, if
|
|||
$ rustc --target aarch64-apple-ios your-code.rs
|
||||
```
|
||||
|
||||
Or if using Cargo and `-Zbuild-std`:
|
||||
```console
|
||||
$ cargo +nightly build -Zbuild-std --target armv7s-apple-ios
|
||||
```
|
||||
|
||||
The simulator variants can be differentiated from the variants running
|
||||
on-device with the `target_env = "sim"` cfg (or `target_abi = "sim"` before
|
||||
Rust CURRENT_RUSTC_VERSION).
|
||||
|
|
@ -73,7 +78,7 @@ Rust CURRENT_RUSTC_VERSION).
|
|||
```rust
|
||||
if cfg!(all(target_vendor = "apple", target_env = "sim")) {
|
||||
// Do something on the iOS/tvOS/visionOS/watchOS Simulator.
|
||||
} {
|
||||
} else {
|
||||
// Everything else, like Windows and non-Simulator iOS.
|
||||
}
|
||||
```
|
||||
|
|
@ -82,8 +87,15 @@ This is similar to the `TARGET_OS_SIMULATOR` define in C code.
|
|||
|
||||
## Testing
|
||||
|
||||
There is no support for running the Rust or standard library testsuite at the
|
||||
moment. Testing has mostly been done manually with builds of static libraries
|
||||
embedded into applications called from Xcode or a simulator.
|
||||
Running and testing your code naturally requires either an actual device
|
||||
running iOS, or the equivalent Xcode simulator environment. There exists
|
||||
several tools in the ecosystem for running a Cargo project on one of these.
|
||||
One of these tools is [`cargo-dinghy`]. [madsmtm/objc2#459] contains a more
|
||||
exhaustive list.
|
||||
|
||||
It hopefully will be possible to improve this in the future.
|
||||
See also [testing on emulators in the `rustc-dev-guide`][test-sim] for
|
||||
instructions on running the standard library's test suite.
|
||||
|
||||
[`cargo-dinghy`]: https://github.com/sonos/dinghy
|
||||
[madsmtm/objc2#459]: https://github.com/madsmtm/objc2/issues/459
|
||||
[test-sim]: https://rustc-dev-guide.rust-lang.org/tests/running.html#testing-on-emulators
|
||||
|
|
|
|||
|
|
@ -65,17 +65,8 @@ Using the unstable `-Zbuild-std` with a nightly Cargo may also work.
|
|||
|
||||
## Building Rust programs
|
||||
|
||||
Rust programs can be built for these targets by specifying `--target`, if
|
||||
`rustc` has been built with support for them. For example:
|
||||
|
||||
```console
|
||||
$ rustc --target aarch64-apple-tvos your-code.rs
|
||||
```
|
||||
See [the instructions for iOS](./apple-ios.md#building-rust-programs).
|
||||
|
||||
## Testing
|
||||
|
||||
There is no support for running the Rust or standard library testsuite at the
|
||||
moment. Testing has mostly been done manually with builds of static libraries
|
||||
embedded into applications called from Xcode or a simulator.
|
||||
|
||||
It hopefully will be possible to improve this in the future.
|
||||
See [the instructions for iOS](./apple-ios.md#testing).
|
||||
|
|
|
|||
|
|
@ -46,20 +46,11 @@ be fixed in [#124560](https://github.com/rust-lang/rust/pull/124560).
|
|||
|
||||
## Building Rust programs
|
||||
|
||||
Rust programs can be built for these targets by specifying `--target`, if
|
||||
`rustc` has been built with support for them. For example:
|
||||
|
||||
```console
|
||||
$ rustc --target aarch64-apple-visionos-sim your-code.rs
|
||||
```
|
||||
See [the instructions for iOS](./apple-ios.md#building-rust-programs).
|
||||
|
||||
## Testing
|
||||
|
||||
There is no support for running the Rust or standard library testsuite at the
|
||||
moment. Testing has mostly been done manually with builds of static libraries
|
||||
embedded into applications called from Xcode or a simulator.
|
||||
|
||||
It hopefully will be possible to improve this in the future.
|
||||
See [the instructions for iOS](./apple-ios.md#testing).
|
||||
|
||||
## Cross-compilation toolchains and C code
|
||||
|
||||
|
|
|
|||
|
|
@ -50,17 +50,8 @@ Using the unstable `-Zbuild-std` with a nightly Cargo may also work.
|
|||
|
||||
## Building Rust programs
|
||||
|
||||
Rust programs can be built for these targets by specifying `--target`, if
|
||||
`rustc` has been built with support for them. For example:
|
||||
|
||||
```console
|
||||
$ rustc --target aarch64-apple-watchos-sim your-code.rs
|
||||
```
|
||||
See [the instructions for iOS](./apple-ios.md#building-rust-programs).
|
||||
|
||||
## Testing
|
||||
|
||||
There is no support for running the Rust or standard library testsuite at the
|
||||
moment. Testing has mostly been done manually with builds of static libraries
|
||||
embedded into applications called from Xcode or a simulator.
|
||||
|
||||
It hopefully will be possible to improve this in the future.
|
||||
See [the instructions for iOS](./apple-ios.md#testing).
|
||||
|
|
|
|||
|
|
@ -53,6 +53,10 @@ impl Config {
|
|||
batch: false,
|
||||
bind: if cfg!(target_os = "android") || cfg!(windows) {
|
||||
([0, 0, 0, 0], 12345).into()
|
||||
} else if cfg!(target_env = "sim") {
|
||||
// iOS/tvOS/watchOS/visionOS simulators share network device
|
||||
// with the host machine.
|
||||
([127, 0, 0, 1], 12345).into()
|
||||
} else {
|
||||
([10, 0, 2, 15], 12345).into()
|
||||
},
|
||||
|
|
@ -262,10 +266,17 @@ fn handle_run(socket: TcpStream, work: &Path, tmp: &Path, lock: &Mutex<()>, conf
|
|||
cmd.args(args);
|
||||
cmd.envs(env);
|
||||
|
||||
// On windows, libraries are just searched in the executable directory,
|
||||
// system directories, PWD, and PATH, in that order. PATH is the only one
|
||||
// we can change for this.
|
||||
let library_path = if cfg!(windows) { "PATH" } else { "LD_LIBRARY_PATH" };
|
||||
let library_path = if cfg!(windows) {
|
||||
// On windows, libraries are just searched in the executable directory,
|
||||
// system directories, PWD, and PATH, in that order. PATH is the only
|
||||
// one we can change for this.
|
||||
"PATH"
|
||||
} else if cfg!(target_vendor = "apple") {
|
||||
// On Apple platforms, the environment variable is named differently.
|
||||
"DYLD_LIBRARY_PATH"
|
||||
} else {
|
||||
"LD_LIBRARY_PATH"
|
||||
};
|
||||
|
||||
// Support libraries were uploaded to `work` earlier, so make sure that's
|
||||
// in `LD_LIBRARY_PATH`. Also include our own current dir which may have
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
//@ compile-flags:-Cstrip=none
|
||||
//@ compile-flags:-g -Csplit-debuginfo=unpacked
|
||||
//@ only-apple
|
||||
//@ ignore-remote needs the compiler-produced `.o` file to be copied to the device
|
||||
|
||||
use std::process::Command;
|
||||
use std::str;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,10 @@
|
|||
//@ ignore-android FIXME #17520
|
||||
//@ ignore-fuchsia Backtraces not symbolized
|
||||
//@ ignore-musl musl doesn't support dynamic libraries (at least when the original test was written).
|
||||
//@ ignore-ios needs the `.dSYM` files to be moved to the device
|
||||
//@ ignore-tvos needs the `.dSYM` files to be moved to the device
|
||||
//@ ignore-watchos needs the `.dSYM` files to be moved to the device
|
||||
//@ ignore-visionos needs the `.dSYM` files to be moved to the device
|
||||
//@ needs-unwind
|
||||
//@ ignore-backends: gcc
|
||||
//@ compile-flags: -g -Copt-level=0 -Cstrip=none -Cforce-frame-pointers=yes
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@
|
|||
//@ ignore-android FIXME #17520
|
||||
//@ ignore-fuchsia Backtraces not symbolized
|
||||
//@ ignore-emscripten Requires custom symbolization code
|
||||
//@ ignore-ios needs the `.dSYM` files to be moved to the device
|
||||
//@ ignore-tvos needs the `.dSYM` files to be moved to the device
|
||||
//@ ignore-watchos needs the `.dSYM` files to be moved to the device
|
||||
//@ ignore-visionos needs the `.dSYM` files to be moved to the device
|
||||
//@ needs-unwind
|
||||
//@ aux-build: line-tables-only-helper.rs
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
//@ no-prefer-dynamic We move the binary around, so do not depend dynamically on libstd
|
||||
//@ needs-subprocess
|
||||
//@ ignore-fuchsia Needs directory creation privilege
|
||||
//@ ignore-tvos `Command::current_dir` requires fork, which is prohibited
|
||||
//@ ignore-watchos `Command::current_dir` requires fork, which is prohibited
|
||||
|
||||
use std::env;
|
||||
use std::fs;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
//@ only-unix (this is a unix-specific test)
|
||||
//@ needs-subprocess
|
||||
//@ ignore-fuchsia no execvp syscall provided
|
||||
//@ ignore-tvos execvp is prohibited
|
||||
//@ ignore-watchos execvp is prohibited
|
||||
|
||||
use std::env;
|
||||
use std::os::unix::process::CommandExt;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
//@ only-unix (this is a unix-specific test)
|
||||
//@ needs-subprocess
|
||||
//@ ignore-fuchsia no execvp syscall
|
||||
//@ ignore-tvos execvp is prohibited
|
||||
//@ ignore-watchos execvp is prohibited
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
//@ run-pass
|
||||
//@ ignore-android
|
||||
//@ ignore-fuchsia no '/bin/sh', '/bin/ls'
|
||||
//@ ignore-tvos `Command::uid/gid` requires fork, which is prohibited
|
||||
//@ ignore-watchos `Command::uid/gid` requires fork, which is prohibited
|
||||
//@ needs-subprocess
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
//@ ignore-cross-compile because aux-bin does not yet support it
|
||||
//@ ignore-remote because aux-bin does not yet support it
|
||||
//@ aux-bin: print-it-works.rs
|
||||
//@ run-pass
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
//@ run-pass
|
||||
//@ aux-build:exporting-impl-from-root-causes-ice-2472-b.rs
|
||||
|
||||
//@ ignore-ios FIXME(madsmtm): For some reason the necessary dylib isn't copied to the remote?
|
||||
//@ ignore-tvos FIXME(madsmtm): For some reason the necessary dylib isn't copied to the remote?
|
||||
//@ ignore-watchos FIXME(madsmtm): For some reason the necessary dylib isn't copied to the remote?
|
||||
//@ ignore-visionos FIXME(madsmtm): For some reason the necessary dylib isn't copied to the remote?
|
||||
|
||||
extern crate exporting_impl_from_root_causes_ice_2472_b as lib;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
//@ run-pass
|
||||
#![allow(unused_variables)]
|
||||
//@ compile-flags:--test -g
|
||||
//@ ignore-ios needs the `.dSYM` files to be moved to the device
|
||||
//@ ignore-tvos needs the `.dSYM` files to be moved to the device
|
||||
//@ ignore-watchos needs the `.dSYM` files to be moved to the device
|
||||
//@ ignore-visionos needs the `.dSYM` files to be moved to the device
|
||||
|
||||
#[cfg(target_vendor = "apple")]
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@
|
|||
//@ needs-subprocess
|
||||
//@ ignore-vxworks no 'cat' and 'sleep'
|
||||
//@ ignore-fuchsia no 'cat'
|
||||
//@ ignore-ios no 'cat' and 'sleep'
|
||||
//@ ignore-tvos no 'cat' and 'sleep'
|
||||
//@ ignore-watchos no 'cat' and 'sleep'
|
||||
//@ ignore-visionos no 'cat' and 'sleep'
|
||||
|
||||
// N.B., these tests kill child processes. Valgrind sees these children as leaking
|
||||
// memory, which makes for some *confusing* logs. That's why these are here
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
//@ run-pass
|
||||
//@ edition: 2021
|
||||
// Ignore this test on Android, because it segfaults there.
|
||||
|
||||
//@ ignore-android
|
||||
//@ ignore-android segfaults
|
||||
//@ ignore-windows
|
||||
//@ ignore-wasm32 no execve
|
||||
//@ ignore-sgx no execve
|
||||
|
|
@ -24,6 +23,9 @@ use std::ptr;
|
|||
fn main() {
|
||||
if env::args_os().count() == 2 {
|
||||
for (key, value) in env::vars_os() {
|
||||
if key == "DYLD_ROOT_PATH" {
|
||||
continue;
|
||||
}
|
||||
panic!("found env value {:?} {:?}", key, value);
|
||||
}
|
||||
return;
|
||||
|
|
@ -35,7 +37,18 @@ fn main() {
|
|||
.as_bytes()).unwrap();
|
||||
let filename: *const c_char = current_exe.as_ptr();
|
||||
let argv: &[*const c_char] = &[filename, filename, ptr::null()];
|
||||
let envp: &[*const c_char] = &[c"FOOBAR".as_ptr(), ptr::null()];
|
||||
|
||||
let root;
|
||||
let envp: &[*const c_char] = if cfg!(all(target_vendor = "apple", target_env = "sim")) {
|
||||
// Workaround: iOS/tvOS/watchOS/visionOS simulators need the root path
|
||||
// from the current process.
|
||||
root = format!("DYLD_ROOT_PATH={}\0", std::env::var("DYLD_ROOT_PATH").unwrap());
|
||||
&[c"FOOBAR".as_ptr(), root.as_ptr().cast(), ptr::null()]
|
||||
} else {
|
||||
// Try to set an environment variable without a value.
|
||||
&[c"FOOBAR".as_ptr(), ptr::null()]
|
||||
};
|
||||
|
||||
unsafe {
|
||||
execve(filename, &argv[0], &envp[0]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,8 +74,15 @@ fn child(args: &[String]) {
|
|||
let fd: libc::c_int = arg.parse().unwrap();
|
||||
unsafe {
|
||||
assert_eq!(libc::read(fd, b.as_mut_ptr() as *mut _, 2), -1);
|
||||
assert_eq!(io::Error::last_os_error().raw_os_error(),
|
||||
Some(libc::EBADF));
|
||||
let raw = io::Error::last_os_error().raw_os_error();
|
||||
if cfg!(all(target_vendor = "apple", not(target_os = "macos"))) {
|
||||
// Workaround: iOS/tvOS/watchOS/visionOS seems to treat `tcp6`
|
||||
// as a directory?
|
||||
if raw == Some(libc::EISDIR) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
assert_eq!(raw, Some(libc::EBADF));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@
|
|||
//@ ignore-fuchsia
|
||||
//@ ignore-horizon
|
||||
//@ ignore-android
|
||||
//@ ignore-ios no 'head'
|
||||
//@ ignore-tvos no 'head'
|
||||
//@ ignore-watchos no 'head'
|
||||
//@ ignore-visionos no 'head'
|
||||
//@ ignore-backends: gcc
|
||||
//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC"
|
||||
//@ compile-flags: -Zon-broken-pipe=error
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
//@ needs-subprocess
|
||||
//@ ignore-vxworks no 'env'
|
||||
//@ ignore-fuchsia no 'env'
|
||||
//@ ignore-ios no 'env'
|
||||
//@ ignore-tvos no 'env'
|
||||
//@ ignore-watchos no 'env'
|
||||
//@ ignore-visionos no 'env'
|
||||
|
||||
use std::process::Command;
|
||||
use std::env;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
//@ only-unix
|
||||
//@ needs-subprocess
|
||||
//@ ignore-fuchsia no fork
|
||||
//@ ignore-tvos fork is prohibited
|
||||
//@ ignore-watchos fork is prohibited
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(never_type)]
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
//@ needs-subprocess
|
||||
//@ ignore-vxworks no 'env'
|
||||
//@ ignore-fuchsia no 'env'
|
||||
//@ ignore-ios no 'env'
|
||||
//@ ignore-tvos no 'env'
|
||||
//@ ignore-watchos no 'env'
|
||||
//@ ignore-visionos no 'env'
|
||||
|
||||
use std::process::Command;
|
||||
use std::env;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@
|
|||
|
||||
//@ ignore-vxworks no 'sh'
|
||||
//@ ignore-fuchsia no 'sh'
|
||||
//@ ignore-ios no 'sh'
|
||||
//@ ignore-tvos no 'sh'
|
||||
//@ ignore-watchos no 'sh'
|
||||
//@ ignore-visionos no 'sh'
|
||||
//@ needs-threads
|
||||
//@ only-unix SIGPIPE is a unix feature
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@
|
|||
//@ ignore-vxworks no 'ps'
|
||||
//@ ignore-fuchsia no 'ps'
|
||||
//@ ignore-nto no 'ps'
|
||||
//@ ignore-ios no 'ps'
|
||||
//@ ignore-tvos no 'ps'
|
||||
//@ ignore-watchos no 'ps'
|
||||
//@ ignore-visionos no 'ps'
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@
|
|||
//@ compile-flags:-Cstrip=none
|
||||
//@ needs-subprocess
|
||||
//@ ignore-fuchsia Backtrace not symbolized, trace different line alignment
|
||||
//@ ignore-ios needs the `.dSYM` files to be moved to the device
|
||||
//@ ignore-tvos needs the `.dSYM` files to be moved to the device
|
||||
//@ ignore-watchos needs the `.dSYM` files to be moved to the device
|
||||
//@ ignore-visionos needs the `.dSYM` files to be moved to the device
|
||||
|
||||
// FIXME(#117097): backtrace (possibly unwinding mechanism) seems to be different on at least
|
||||
// `i686-mingw` (32-bit windows-gnu)? cc #128911.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
//@ revisions: default error kill inherit
|
||||
//@ ignore-cross-compile because aux-bin does not yet support it
|
||||
//@ ignore-remote because aux-bin does not yet support it
|
||||
//@ only-unix because SIGPIPE is a unix thing
|
||||
//@ ignore-backends: gcc
|
||||
//@ run-pass
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
//@ ignore-cross-compile because aux-bin does not yet support it
|
||||
//@ ignore-remote because aux-bin does not yet support it
|
||||
//@ only-unix because SIGPIPE is a unix thing
|
||||
//@ aux-bin: assert-inherit-sig_dfl.rs
|
||||
//@ aux-bin: assert-inherit-sig_ign.rs
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue