diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index d8c89f5947fb5..bcbb75d959976 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2880,6 +2880,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { } let sdk_name = match (arch.as_ref(), os.as_ref()) { + ("aarch64", "tvos") if llvm_target.ends_with("-simulator") => "appletvsimulator", ("aarch64", "tvos") => "appletvos", ("x86_64", "tvos") => "appletvsimulator", ("arm", "ios") => "iphoneos", diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 277060573bcb9..793dcf0d994c3 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -439,6 +439,11 @@ impl<'tcx> Inliner<'tcx> { } if callee_attrs.target_features != self.codegen_fn_attrs.target_features { + // In general it is not correct to inline a callee with target features that are a + // subset of the caller. This is because the callee might contain calls, and the ABI of + // those calls depends on the target features of the surrounding function. By moving a + // `Call` terminator from one MIR body to another with more target features, we might + // change the ABI of that call! return Err("incompatible target features"); } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index df92d8262e3c9..30c8b9d67002c 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1899,6 +1899,7 @@ written to standard error output)"), `hir` (the HIR), `hir,identified`, `hir,typed` (HIR with types for each node), `hir-tree` (dump the raw HIR), + `thir-tree`, `thir-flat`, `mir` (the MIR), or `mir-cfg` (graphviz formatted MIR)"), unsound_mir_opts: bool = (false, parse_bool, [TRACKED], "enable unsound and buggy MIR optimizations (default: no)"), diff --git a/compiler/rustc_target/src/spec/aarch64_apple_tvos_sim.rs b/compiler/rustc_target/src/spec/aarch64_apple_tvos_sim.rs new file mode 100644 index 0000000000000..909a52a5097eb --- /dev/null +++ b/compiler/rustc_target/src/spec/aarch64_apple_tvos_sim.rs @@ -0,0 +1,31 @@ +use super::apple_base::{opts, tvos_sim_llvm_target, Arch}; +use crate::spec::{FramePointer, Target, TargetOptions}; + +pub fn target() -> Target { + let arch = Arch::Arm64_sim; + Target { + llvm_target: tvos_sim_llvm_target(arch).into(), + pointer_width: 64, + data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(), + arch: arch.target_arch(), + options: TargetOptions { + features: "+neon,+fp-armv8,+apple-a7".into(), + max_atomic_width: Some(128), + forces_embed_bitcode: true, + frame_pointer: FramePointer::NonLeaf, + // Taken from (and slightly modified) the aarch64-apple-ios-sim spec which says: + // Taken from a clang build on Xcode 11.4.1. + // These arguments are not actually invoked - they just have + // to look right to pass App Store validation. + bitcode_llvm_cmdline: "-triple\0\ + arm64-apple-tvos15.0-simulator\0\ + -emit-obj\0\ + -disable-llvm-passes\0\ + -target-abi\0\ + darwinpcs\0\ + -Os\0" + .into(), + ..opts("tvos", arch) + }, + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 3541810d437ba..31f538d8b612c 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1603,6 +1603,7 @@ supported_targets! { ("aarch64-apple-ios-macabi", aarch64_apple_ios_macabi), ("aarch64-apple-ios-sim", aarch64_apple_ios_sim), ("aarch64-apple-tvos", aarch64_apple_tvos), + ("aarch64-apple-tvos-sim", aarch64_apple_tvos_sim), ("x86_64-apple-tvos", x86_64_apple_tvos), ("armv7k-apple-watchos", armv7k_apple_watchos), diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index 66573b90db963..61c5950b02731 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -434,8 +434,9 @@ impl BinaryHeap { /// heap.push(4); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_binary_heap_constructor", issue = "112353")] #[must_use] - pub fn new() -> BinaryHeap { + pub const fn new() -> BinaryHeap { BinaryHeap { data: vec![] } } @@ -477,8 +478,9 @@ impl BinaryHeap { /// heap.push(4); /// ``` #[unstable(feature = "allocator_api", issue = "32838")] + #[rustc_const_unstable(feature = "const_binary_heap_constructor", issue = "112353")] #[must_use] - pub fn new_in(alloc: A) -> BinaryHeap { + pub const fn new_in(alloc: A) -> BinaryHeap { BinaryHeap { data: Vec::new_in(alloc) } } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index fbb30e483fae6..b277b571829d6 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -290,6 +290,9 @@ pub mod assert_matches { pub use crate::macros::{assert_matches, debug_assert_matches}; } +#[unstable(feature = "cfg_match", issue = "115585")] +pub use crate::macros::cfg_match; + #[macro_use] mod internal_macros; diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index c367b53b72027..125a6f57bfbaa 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -168,6 +168,94 @@ pub macro assert_matches { }, } +/// A macro for defining `#[cfg]` match-like statements. +/// +/// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of +/// `#[cfg]` cases, emitting the implementation which matches first. +/// +/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code +/// without having to rewrite each clause multiple times. +/// +/// Trailing `_` wildcard match arms are **optional** and they indicate a fallback branch when +/// all previous declarations do not evaluate to true. +/// +/// # Example +/// +/// ``` +/// #![feature(cfg_match)] +/// +/// cfg_match! { +/// cfg(unix) => { +/// fn foo() { /* unix specific functionality */ } +/// } +/// cfg(target_pointer_width = "32") => { +/// fn foo() { /* non-unix, 32-bit functionality */ } +/// } +/// _ => { +/// fn foo() { /* fallback implementation */ } +/// } +/// } +/// ``` +#[unstable(feature = "cfg_match", issue = "115585")] +#[rustc_diagnostic_item = "cfg_match"] +pub macro cfg_match { + // with a final wildcard + ( + $(cfg($initial_meta:meta) => { $($initial_tokens:item)* })+ + _ => { $($extra_tokens:item)* } + ) => { + cfg_match! { + @__items (); + $((($initial_meta) ($($initial_tokens)*)),)+ + (() ($($extra_tokens)*)), + } + }, + + // without a final wildcard + ( + $(cfg($extra_meta:meta) => { $($extra_tokens:item)* })* + ) => { + cfg_match! { + @__items (); + $((($extra_meta) ($($extra_tokens)*)),)* + } + }, + + // Internal and recursive macro to emit all the items + // + // Collects all the previous cfgs in a list at the beginning, so they can be + // negated. After the semicolon is all the remaining items. + (@__items ($($_:meta,)*);) => {}, + ( + @__items ($($no:meta,)*); + (($($yes:meta)?) ($($tokens:item)*)), + $($rest:tt,)* + ) => { + // Emit all items within one block, applying an appropriate #[cfg]. The + // #[cfg] will require all `$yes` matchers specified and must also negate + // all previous matchers. + #[cfg(all( + $($yes,)? + not(any($($no),*)) + ))] + cfg_match! { @__identity $($tokens)* } + + // Recurse to emit all other items in `$rest`, and when we do so add all + // our `$yes` matchers to the list of `$no` matchers as future emissions + // will have to negate everything we just matched as well. + cfg_match! { + @__items ($($no,)* $($yes,)?); + $($rest,)* + } + }, + + // Internal macro to make __apply work out right for different match types, + // because of how macros match/expand stuff. + (@__identity $($tokens:item)*) => { + $($tokens)* + } +} + /// Asserts that a boolean expression is `true` at runtime. /// /// This will invoke the [`panic!`] macro if the provided expression cannot be @@ -321,95 +409,6 @@ pub macro debug_assert_matches($($arg:tt)*) { } } -/// A macro for defining `#[cfg]` match-like statements. -/// -/// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of -/// `#[cfg]` cases, emitting the implementation which matches first. -/// -/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code -/// without having to rewrite each clause multiple times. -/// -/// Trailing `_` wildcard match arms are **optional** and they indicate a fallback branch when -/// all previous declarations do not evaluate to true. -/// -/// # Example -/// -/// ``` -/// #![feature(cfg_match)] -/// -/// cfg_match! { -/// cfg(unix) => { -/// fn foo() { /* unix specific functionality */ } -/// } -/// cfg(target_pointer_width = "32") => { -/// fn foo() { /* non-unix, 32-bit functionality */ } -/// } -/// _ => { -/// fn foo() { /* fallback implementation */ } -/// } -/// } -/// ``` -#[macro_export] -#[unstable(feature = "cfg_match", issue = "115585")] -#[rustc_diagnostic_item = "cfg_match"] -macro_rules! cfg_match { - // with a final wildcard - ( - $(cfg($initial_meta:meta) => { $($initial_tokens:item)* })+ - _ => { $($extra_tokens:item)* } - ) => { - cfg_match! { - @__items (); - $((($initial_meta) ($($initial_tokens)*)),)+ - (() ($($extra_tokens)*)), - } - }; - - // without a final wildcard - ( - $(cfg($extra_meta:meta) => { $($extra_tokens:item)* })* - ) => { - cfg_match! { - @__items (); - $((($extra_meta) ($($extra_tokens)*)),)* - } - }; - - // Internal and recursive macro to emit all the items - // - // Collects all the previous cfgs in a list at the beginning, so they can be - // negated. After the semicolon is all the remaining items. - (@__items ($($_:meta,)*);) => {}; - ( - @__items ($($no:meta,)*); - (($($yes:meta)?) ($($tokens:item)*)), - $($rest:tt,)* - ) => { - // Emit all items within one block, applying an appropriate #[cfg]. The - // #[cfg] will require all `$yes` matchers specified and must also negate - // all previous matchers. - #[cfg(all( - $($yes,)? - not(any($($no),*)) - ))] - cfg_match! { @__identity $($tokens)* } - - // Recurse to emit all other items in `$rest`, and when we do so add all - // our `$yes` matchers to the list of `$no` matchers as future emissions - // will have to negate everything we just matched as well. - cfg_match! { - @__items ($($no,)* $($yes,)?); - $($rest,)* - } - }; - - // Internal macro to make __apply work out right for different match types, - // because of how macros match/expand stuff. - (@__identity $($tokens:item)*) => { - $($tokens)* - }; -} - /// Returns whether the given expression matches any of the given patterns. /// /// Like in a `match` expression, the pattern can be optionally followed by `if` diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 4e55d36043027..ae514ff38fa0a 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -217,6 +217,7 @@ target | std | host | notes -------|:---:|:----:|------- `aarch64-apple-ios-macabi` | ? | | Apple Catalyst on ARM64 [`aarch64-apple-tvos`](platform-support/apple-tvos.md) | ? | | ARM64 tvOS +[`aarch64-apple-tvos-sim`](platform-support/apple-tvos.md) | ? | | ARM64 tvOS Simulator [`aarch64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | ARM64 Apple WatchOS Simulator [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon diff --git a/src/doc/rustc/src/platform-support/apple-tvos.md b/src/doc/rustc/src/platform-support/apple-tvos.md index d87fd1959b49c..e7ea109df1ba1 100644 --- a/src/doc/rustc/src/platform-support/apple-tvos.md +++ b/src/doc/rustc/src/platform-support/apple-tvos.md @@ -52,7 +52,7 @@ The targets can be built by enabling them for a `rustc` build in `config.toml`, ```toml [build] build-stage = 1 -target = ["aarch64-apple-tvos", "x86_64-apple-tvos"] +target = ["aarch64-apple-tvos", "x86_64-apple-tvos", "aarch64-apple-tvos-sim"] ``` It's possible that cargo under `-Zbuild-std` may also be used to target them. @@ -67,6 +67,8 @@ Rust programs can be built for these targets $ rustc --target aarch64-apple-tvos your-code.rs ... $ rustc --target x86_64-apple-tvos your-code.rs +... +$ rustc --target aarch64-apple-tvos-sim your-code.rs ``` ## Testing