Auto merge of #133423 - jieyouxu:rollup-m3gyoz6, r=jieyouxu

Rollup of 6 pull requests

Successful merges:

 - #132730 (std: allow after-main use of synchronization primitives)
 - #133105 (only store valid proc macro item for doc link)
 - #133260 (Constify the `Deref`/`DerefMut` traits, too)
 - #133297 (Remove legacy bitcode for iOS)
 - #133298 (Mention that std::fs::remove_dir_all fails on files)
 - #133384 (add a test for target-feature-ABI warnings in closures and when calling extern fn)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-11-24 23:17:56 +00:00
commit 28fc2ba714
26 changed files with 269 additions and 120 deletions

View File

@ -955,24 +955,7 @@ pub(crate) fn bitcode_section_name(cgcx: &CodegenContext<LlvmCodegenBackend>) ->
}
}
/// Embed the bitcode of an LLVM module in the LLVM module itself.
///
/// This is done primarily for iOS where it appears to be standard to compile C
/// code at least with `-fembed-bitcode` which creates two sections in the
/// executable:
///
/// * __LLVM,__bitcode
/// * __LLVM,__cmdline
///
/// It appears *both* of these sections are necessary to get the linker to
/// recognize what's going on. A suitable cmdline value is taken from the
/// target spec.
///
/// Furthermore debug/O1 builds don't actually embed bitcode but rather just
/// embed an empty section.
///
/// Basically all of this is us attempting to follow in the footsteps of clang
/// on iOS. See #35968 for lots more info.
/// Embed the bitcode of an LLVM module for LTO in the LLVM module itself.
unsafe fn embed_bitcode(
cgcx: &CodegenContext<LlvmCodegenBackend>,
llcx: &llvm::Context,

View File

@ -432,11 +432,9 @@ struct CompiledModules {
fn need_bitcode_in_object(tcx: TyCtxt<'_>) -> bool {
let sess = tcx.sess;
let requested_for_rlib = sess.opts.cg.embed_bitcode
sess.opts.cg.embed_bitcode
&& tcx.crate_types().contains(&CrateType::Rlib)
&& sess.opts.output_types.contains_key(&OutputType::Exe);
let forced_by_target = sess.target.forces_embed_bitcode;
requested_for_rlib || forced_by_target
&& sess.opts.output_types.contains_key(&OutputType::Exe)
}
fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool {

View File

@ -576,9 +576,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
// If this closure is marked `#[inline(always)]`, simply skip adding `#[target_feature]`.
//
// At this point, `unsafe` has already been checked and `#[target_feature]` only affects codegen.
// Emitting both `#[inline(always)]` and `#[target_feature]` can potentially result in an
// ICE, because LLVM errors when the function fails to be inlined due to a target feature
// mismatch.
// Due to LLVM limitations, emitting both `#[inline(always)]` and `#[target_feature]` is *unsound*:
// the function may be inlined into a caller with fewer target features. Also see
// <https://github.com/rust-lang/rust/issues/116573>.
//
// Using `#[inline(always)]` implies that this closure will most likely be inlined into
// its parent function, which effectively inherits the features anyway. Boxing this closure

View File

@ -4794,14 +4794,10 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
let res = self.r.resolve_rustdoc_path(path.as_str(), *ns, self.parent_scope);
if let Some(res) = res
&& let Some(def_id) = res.opt_def_id()
&& !def_id.is_local()
&& self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
&& matches!(
self.r.tcx.sess.opts.resolve_doc_links,
ResolveDocLinks::ExportedMetadata
)
&& self.is_invalid_proc_macro_item_for_doc(def_id)
{
// Encoding foreign def ids in proc macro crate metadata will ICE.
// Encoding def ids in proc macro crate metadata will ICE,
// because it will only store proc macros for it.
return None;
}
res
@ -4810,6 +4806,17 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
res
}
fn is_invalid_proc_macro_item_for_doc(&self, did: DefId) -> bool {
if !matches!(self.r.tcx.sess.opts.resolve_doc_links, ResolveDocLinks::ExportedMetadata)
|| !self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
{
return false;
}
let Some(local_did) = did.as_local() else { return true };
let Some(node_id) = self.r.def_id_to_node_id.get(local_did) else { return true };
!self.r.proc_macros.contains(node_id)
}
fn resolve_doc_links(&mut self, attrs: &[Attribute], maybe_exported: MaybeExported<'_>) {
match self.r.tcx.sess.opts.resolve_doc_links {
ResolveDocLinks::None => return,
@ -4872,14 +4879,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
.traits_in_scope(None, &self.parent_scope, SyntaxContext::root(), None)
.into_iter()
.filter_map(|tr| {
if !tr.def_id.is_local()
&& self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
&& matches!(
self.r.tcx.sess.opts.resolve_doc_links,
ResolveDocLinks::ExportedMetadata
)
{
// Encoding foreign def ids in proc macro crate metadata will ICE.
if self.is_invalid_proc_macro_item_for_doc(tr.def_id) {
// Encoding def ids in proc macro crate metadata will ICE.
// because it will only store proc macros for it.
return None;
}
Some(tr.def_id)

View File

@ -2327,8 +2327,6 @@ pub struct TargetOptions {
/// If we give emcc .o files that are actually .bc files it
/// will 'just work'.
pub obj_is_bitcode: bool,
/// Whether the target requires that emitted object code includes bitcode.
pub forces_embed_bitcode: bool,
/// Content of the LLVM cmdline section associated with embedded bitcode.
pub bitcode_llvm_cmdline: StaticCow<str>,
@ -2671,7 +2669,6 @@ impl Default for TargetOptions {
allow_asm: true,
has_thread_local: false,
obj_is_bitcode: false,
forces_embed_bitcode: false,
bitcode_llvm_cmdline: "".into(),
min_atomic_width: None,
max_atomic_width: None,
@ -3412,7 +3409,6 @@ impl Target {
key!(main_needs_argc_argv, bool);
key!(has_thread_local, bool);
key!(obj_is_bitcode, bool);
key!(forces_embed_bitcode, bool);
key!(bitcode_llvm_cmdline);
key!(max_atomic_width, Option<u64>);
key!(min_atomic_width, Option<u64>);
@ -3687,7 +3683,6 @@ impl ToJson for Target {
target_option_val!(main_needs_argc_argv);
target_option_val!(has_thread_local);
target_option_val!(obj_is_bitcode);
target_option_val!(forces_embed_bitcode);
target_option_val!(bitcode_llvm_cmdline);
target_option_val!(min_atomic_width);
target_option_val!(max_atomic_width);

View File

@ -133,6 +133,7 @@
#[doc(alias = "&*")]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "Deref"]
#[cfg_attr(not(bootstrap), const_trait)]
pub trait Deref {
/// The resulting type after dereferencing.
#[stable(feature = "rust1", since = "1.0.0")]
@ -147,6 +148,7 @@ pub trait Deref {
fn deref(&self) -> &Self::Target;
}
#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Deref for &T {
type Target = T;
@ -157,9 +159,21 @@ impl<T: ?Sized> Deref for &T {
}
}
#[cfg(not(bootstrap))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> const Deref for &T {
type Target = T;
#[rustc_diagnostic_item = "noop_method_deref"]
fn deref(&self) -> &T {
*self
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> !DerefMut for &T {}
#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Deref for &mut T {
type Target = T;
@ -169,6 +183,16 @@ impl<T: ?Sized> Deref for &mut T {
}
}
#[cfg(not(bootstrap))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> const Deref for &mut T {
type Target = T;
fn deref(&self) -> &T {
*self
}
}
/// Used for mutable dereferencing operations, like in `*v = 1;`.
///
/// In addition to being used for explicit dereferencing operations with the
@ -258,9 +282,23 @@ impl<T: ?Sized> Deref for &mut T {
/// *x = 'b';
/// assert_eq!('b', x.value);
/// ```
#[cfg(not(bootstrap))]
#[lang = "deref_mut"]
#[doc(alias = "*")]
#[stable(feature = "rust1", since = "1.0.0")]
#[const_trait]
pub trait DerefMut: ~const Deref {
/// Mutably dereferences the value.
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "deref_mut_method"]
fn deref_mut(&mut self) -> &mut Self::Target;
}
/// Bootstrap
#[lang = "deref_mut"]
#[doc(alias = "*")]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(bootstrap)]
pub trait DerefMut: Deref {
/// Mutably dereferences the value.
#[stable(feature = "rust1", since = "1.0.0")]
@ -268,6 +306,7 @@ pub trait DerefMut: Deref {
fn deref_mut(&mut self) -> &mut Self::Target;
}
#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> DerefMut for &mut T {
fn deref_mut(&mut self) -> &mut T {
@ -275,6 +314,14 @@ impl<T: ?Sized> DerefMut for &mut T {
}
}
#[cfg(not(bootstrap))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> const DerefMut for &mut T {
fn deref_mut(&mut self) -> &mut T {
*self
}
}
/// Perma-unstable marker trait. Indicates that the type has a well-behaved [`Deref`]
/// (and, if applicable, [`DerefMut`]) implementation. This is relied on for soundness
/// of deref patterns.

View File

@ -2804,8 +2804,9 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
///
/// See [`fs::remove_file`] and [`fs::remove_dir`].
///
/// `remove_dir_all` will fail if `remove_dir` or `remove_file` fail on any constituent paths, including the root path.
/// `remove_dir_all` will fail if `remove_dir` or `remove_file` fail on any constituent paths, including the root `path`.
/// As a result, the directory you are deleting must exist, meaning that this function is not idempotent.
/// Additionally, `remove_dir_all` will also fail if the `path` is not a directory.
///
/// Consider ignoring the error if validating the removal is not required for your use case.
///

View File

@ -174,9 +174,6 @@
//!
//! - after-main use of thread-locals, which also affects additional features:
//! - [`thread::current()`]
//! - [`thread::scope()`]
//! - [`sync::mpmc`]
//! - [`sync::mpsc`]
//! - before-main stdio file descriptors are not guaranteed to be open on unix platforms
//!
//!

View File

@ -346,7 +346,8 @@ impl<T> Channel<T> {
}
// Block the current thread.
let sel = cx.wait_until(deadline);
// SAFETY: the context belongs to the current thread.
let sel = unsafe { cx.wait_until(deadline) };
match sel {
Selected::Waiting => unreachable!(),
@ -397,7 +398,8 @@ impl<T> Channel<T> {
}
// Block the current thread.
let sel = cx.wait_until(deadline);
// SAFETY: the context belongs to the current thread.
let sel = unsafe { cx.wait_until(deadline) };
match sel {
Selected::Waiting => unreachable!(),

View File

@ -69,7 +69,7 @@ impl Context {
inner: Arc::new(Inner {
select: AtomicUsize::new(Selected::Waiting.into()),
packet: AtomicPtr::new(ptr::null_mut()),
thread: thread::current(),
thread: thread::current_or_unnamed(),
thread_id: current_thread_id(),
}),
}
@ -112,8 +112,11 @@ impl Context {
/// Waits until an operation is selected and returns it.
///
/// If the deadline is reached, `Selected::Aborted` will be selected.
///
/// # Safety
/// This may only be called from the thread this `Context` belongs to.
#[inline]
pub fn wait_until(&self, deadline: Option<Instant>) -> Selected {
pub unsafe fn wait_until(&self, deadline: Option<Instant>) -> Selected {
loop {
// Check whether an operation has been selected.
let sel = Selected::from(self.inner.select.load(Ordering::Acquire));
@ -126,7 +129,8 @@ impl Context {
let now = Instant::now();
if now < end {
thread::park_timeout(end - now);
// SAFETY: guaranteed by caller.
unsafe { self.inner.thread.park_timeout(end - now) };
} else {
// The deadline has been reached. Try aborting select.
return match self.try_select(Selected::Aborted) {
@ -135,7 +139,8 @@ impl Context {
};
}
} else {
thread::park();
// SAFETY: guaranteed by caller.
unsafe { self.inner.thread.park() };
}
}
}

View File

@ -444,7 +444,8 @@ impl<T> Channel<T> {
}
// Block the current thread.
let sel = cx.wait_until(deadline);
// SAFETY: the context belongs to the current thread.
let sel = unsafe { cx.wait_until(deadline) };
match sel {
Selected::Waiting => unreachable!(),

View File

@ -190,7 +190,8 @@ impl<T> Channel<T> {
drop(inner);
// Block the current thread.
let sel = cx.wait_until(deadline);
// SAFETY: the context belongs to the current thread.
let sel = unsafe { cx.wait_until(deadline) };
match sel {
Selected::Waiting => unreachable!(),
@ -257,7 +258,8 @@ impl<T> Channel<T> {
drop(inner);
// Block the current thread.
let sel = cx.wait_until(deadline);
// SAFETY: the context belongs to the current thread.
let sel = unsafe { cx.wait_until(deadline) };
match sel {
Selected::Waiting => unreachable!(),

View File

@ -93,7 +93,7 @@ const QUEUE_MASK: usize = !STATE_MASK;
// use interior mutability.
#[repr(align(4))] // Ensure the two lower bits are free to use as state bits.
struct Waiter {
thread: Cell<Option<Thread>>,
thread: Thread,
signaled: AtomicBool,
next: Cell<*const Waiter>,
}
@ -238,7 +238,7 @@ fn wait(
return_on_poisoned: bool,
) -> StateAndQueue {
let node = &Waiter {
thread: Cell::new(Some(thread::current())),
thread: thread::current_or_unnamed(),
signaled: AtomicBool::new(false),
next: Cell::new(ptr::null()),
};
@ -277,7 +277,8 @@ fn wait(
// can park ourselves, the result could be this thread never gets
// unparked. Luckily `park` comes with the guarantee that if it got
// an `unpark` just before on an unparked thread it does not park.
thread::park();
// SAFETY: we retrieved this handle on the current thread above.
unsafe { node.thread.park() }
}
return state_and_queue.load(Acquire);
@ -309,7 +310,7 @@ impl Drop for WaiterQueue<'_> {
let mut queue = to_queue(current);
while !queue.is_null() {
let next = (*queue).next.get();
let thread = (*queue).thread.take().unwrap();
let thread = (*queue).thread.clone();
(*queue).signaled.store(true, Release);
thread.unpark();
queue = next;

View File

@ -118,7 +118,7 @@ use crate::mem;
use crate::ptr::{self, NonNull, null_mut, without_provenance_mut};
use crate::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release};
use crate::sync::atomic::{AtomicBool, AtomicPtr};
use crate::thread::{self, Thread, ThreadId};
use crate::thread::{self, Thread};
/// The atomic lock state.
type AtomicState = AtomicPtr<()>;
@ -217,9 +217,7 @@ impl Node {
/// Prepare this node for waiting.
fn prepare(&mut self) {
// Fall back to creating an unnamed `Thread` handle to allow locking in TLS destructors.
self.thread.get_or_init(|| {
thread::try_current().unwrap_or_else(|| Thread::new_unnamed(ThreadId::new()))
});
self.thread.get_or_init(thread::current_or_unnamed);
self.completed = AtomicBool::new(false);
}

View File

@ -165,6 +165,23 @@ pub(crate) fn try_current() -> Option<Thread> {
}
}
/// Gets a handle to the thread that invokes it. If the handle stored in thread-
/// local storage was already destroyed, this creates a new unnamed temporary
/// handle to allow thread parking in nearly all situations.
pub(crate) fn current_or_unnamed() -> Thread {
let current = CURRENT.get();
if current > DESTROYED {
unsafe {
let current = ManuallyDrop::new(Thread::from_raw(current));
(*current).clone()
}
} else if current == DESTROYED {
Thread::new_unnamed(id::get_or_init())
} else {
init_current(current)
}
}
/// Gets a handle to the thread that invokes it.
///
/// # Examples

View File

@ -186,7 +186,7 @@ mod current;
#[stable(feature = "rust1", since = "1.0.0")]
pub use current::current;
pub(crate) use current::{current_id, drop_current, set_current, try_current};
pub(crate) use current::{current_id, current_or_unnamed, drop_current, set_current, try_current};
mod spawnhook;
@ -1146,9 +1146,9 @@ pub fn park_timeout_ms(ms: u32) {
#[stable(feature = "park_timeout", since = "1.4.0")]
pub fn park_timeout(dur: Duration) {
let guard = PanicGuard;
// SAFETY: park_timeout is called on the parker owned by this thread.
// SAFETY: park_timeout is called on a handle owned by this thread.
unsafe {
current().0.parker().park_timeout(dur);
current().park_timeout(dur);
}
// No panic occurred, do not abort.
forget(guard);
@ -1446,6 +1446,15 @@ impl Thread {
unsafe { self.0.parker().park() }
}
/// Like the public [`park_timeout`], but callable on any handle. This is
/// used to allow parking in TLS destructors.
///
/// # Safety
/// May only be called from the thread to which this handle belongs.
pub(crate) unsafe fn park_timeout(&self, dur: Duration) {
unsafe { self.0.parker().park_timeout(dur) }
}
/// Atomically makes the handle's token available if it is not already.
///
/// Every thread is equipped with some basic low-level blocking support, via

View File

@ -1,4 +1,4 @@
use super::{Builder, JoinInner, Result, Thread, current, park};
use super::{Builder, JoinInner, Result, Thread, current_or_unnamed};
use crate::marker::PhantomData;
use crate::panic::{AssertUnwindSafe, catch_unwind, resume_unwind};
use crate::sync::Arc;
@ -140,7 +140,7 @@ where
let scope = Scope {
data: Arc::new(ScopeData {
num_running_threads: AtomicUsize::new(0),
main_thread: current(),
main_thread: current_or_unnamed(),
a_thread_panicked: AtomicBool::new(false),
}),
env: PhantomData,
@ -152,7 +152,8 @@ where
// Wait until all the threads are finished.
while scope.data.num_running_threads.load(Ordering::Acquire) != 0 {
park();
// SAFETY: this is the main thread, the handle belongs to us.
unsafe { scope.data.main_thread.park() };
}
// Throw any panic from `f`, or the return value of `f` if no thread panicked.

View File

@ -119,17 +119,14 @@ files. It takes one of the following values:
* `n`, `no`, `off` or `false`: omit bitcode from rlibs.
LLVM bitcode is required when rustc is performing link-time optimization (LTO).
It is also required on some targets like iOS ones where vendors look for LLVM
bitcode. Embedded bitcode will appear in rustc-generated object files inside of
a section whose name is defined by the target platform. Most of the time this is
`.llvmbc`.
Embedded bitcode will appear in rustc-generated object files inside of a section
whose name is defined by the target platform. Most of the time this is `.llvmbc`.
The use of `-C embed-bitcode=no` can significantly improve compile times and
reduce generated file sizes if your compilation does not actually need bitcode
(e.g. if you're not compiling for iOS or you're not performing LTO). For these
reasons, Cargo uses `-C embed-bitcode=no` whenever possible. Likewise, if you
are building directly with `rustc` we recommend using `-C embed-bitcode=no`
whenever you are not using LTO.
(e.g. if you're not performing LTO). For these reasons, Cargo uses `-C embed-bitcode=no`
whenever possible. Likewise, if you are building directly with `rustc` we recommend
using `-C embed-bitcode=no` whenever you are not using LTO.
If combined with `-C lto`, `-C embed-bitcode=no` will cause `rustc` to abort
at start-up, because the combination is invalid.

View File

@ -0,0 +1,20 @@
//@ force-host
//@ no-prefer-dynamic
#![crate_type = "proc-macro"]
extern crate proc_macro;
use proc_macro::TokenStream;
mod view {}
/// [`view`]
#[proc_macro]
pub fn f(_: TokenStream) -> TokenStream {
todo!()
}
/// [`f()`]
#[proc_macro]
pub fn g(_: TokenStream) -> TokenStream {
todo!()
}

View File

@ -0,0 +1,8 @@
//@ aux-build:in-proc-item-comment.rs
//@ check-pass
// issue#132743
extern crate in_proc_item_comment;
pub use in_proc_item_comment::{f, g};

View File

@ -2,7 +2,7 @@ struct A;
struct B;
static S: &'static B = &A;
//~^ ERROR cannot perform deref coercion
//~^ ERROR cannot call conditionally-const method
use std::ops::Deref;

View File

@ -1,23 +1,13 @@
error[E0015]: cannot perform deref coercion on `A` in statics
error[E0658]: cannot call conditionally-const method `<A as Deref>::deref` in statics
--> $DIR/issue-25901.rs:4:24
|
LL | static S: &'static B = &A;
| ^^
|
= note: attempting to deref into `B`
note: deref defined here
--> $DIR/issue-25901.rs:10:5
|
LL | type Target = B;
| ^^^^^^^^^^^
note: impl defined here, but it is not `const`
--> $DIR/issue-25901.rs:9:1
|
LL | impl Deref for A {
| ^^^^^^^^^^^^^^^^
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0015`.
For more information about this error, try `rustc --explain E0658`.

View File

@ -11,7 +11,7 @@ impl Foo {
//~^ ERROR invalid generic `self` parameter type
//~| ERROR destructor of `R` cannot be evaluated at compile-time
self.0
//~^ ERROR cannot call non-const fn `<R as Deref>::deref` in constant function
//~^ ERROR cannot call conditionally-const method `<R as Deref>::deref` in constant function
}
}

View File

@ -1,10 +1,12 @@
error[E0015]: cannot call non-const fn `<R as Deref>::deref` in constant functions
error[E0658]: cannot call conditionally-const method `<R as Deref>::deref` in constant functions
--> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9
|
LL | self.0
| ^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0493]: destructor of `R` cannot be evaluated at compile-time
--> $DIR/arbitrary-self-from-method-substs-ice.rs:10:43
@ -26,5 +28,5 @@ LL | const fn get<R: Deref<Target = Self>>(self: R) -> u32 {
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0015, E0493, E0801.
For more information about an error, try `rustc --explain E0015`.
Some errors have detailed explanations: E0493, E0658, E0801.
For more information about an error, try `rustc --explain E0493`.

View File

@ -4,6 +4,7 @@
#![feature(avx512_target_feature)]
#![feature(portable_simd)]
#![feature(target_feature_11, simd_ffi)]
#![allow(improper_ctypes_definitions)]
use std::arch::x86_64::*;
@ -50,6 +51,14 @@ unsafe fn test() {
as_f64x8(arg);
}
#[target_feature(enable = "avx")]
unsafe fn in_closure() -> impl FnOnce() -> __m256 {
#[inline(always)] // this disables target-feature inheritance
|| g()
//~^ WARNING this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
//~| WARNING this was previously accepted by the compiler
}
fn main() {
unsafe {
f(g());
@ -78,4 +87,24 @@ fn main() {
//~| WARNING this was previously accepted by the compiler
//~| WARNING this was previously accepted by the compiler
}
unsafe {
in_closure()();
}
unsafe {
#[expect(improper_ctypes)]
extern "C" {
fn some_extern() -> __m256;
}
some_extern();
//~^ WARNING this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
//~| WARNING this was previously accepted by the compiler
}
}
#[no_mangle]
#[target_feature(enable = "avx")]
fn some_extern() -> __m256 {
todo!()
}

View File

@ -1,5 +1,5 @@
warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
--> $DIR/simd-abi-checks.rs:55:11
--> $DIR/simd-abi-checks.rs:64:11
|
LL | f(g());
| ^^^ function called here
@ -10,7 +10,7 @@ LL | f(g());
= note: `#[warn(abi_unsupported_vector_types)]` on by default
warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
--> $DIR/simd-abi-checks.rs:55:9
--> $DIR/simd-abi-checks.rs:64:9
|
LL | f(g());
| ^^^^^^ function called here
@ -20,7 +20,7 @@ LL | f(g());
= help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
--> $DIR/simd-abi-checks.rs:63:14
--> $DIR/simd-abi-checks.rs:72:14
|
LL | gavx(favx());
| ^^^^^^ function called here
@ -30,7 +30,7 @@ LL | gavx(favx());
= help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
--> $DIR/simd-abi-checks.rs:63:9
--> $DIR/simd-abi-checks.rs:72:9
|
LL | gavx(favx());
| ^^^^^^^^^^^^ function called here
@ -40,7 +40,7 @@ LL | gavx(favx());
= help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
--> $DIR/simd-abi-checks.rs:75:19
--> $DIR/simd-abi-checks.rs:84:19
|
LL | w(Wrapper(g()));
| ^^^ function called here
@ -50,7 +50,7 @@ LL | w(Wrapper(g()));
= help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
--> $DIR/simd-abi-checks.rs:75:9
--> $DIR/simd-abi-checks.rs:84:9
|
LL | w(Wrapper(g()));
| ^^^^^^^^^^^^^^^ function called here
@ -59,8 +59,18 @@ LL | w(Wrapper(g()));
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
= help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
--> $DIR/simd-abi-checks.rs:100:9
|
LL | some_extern();
| ^^^^^^^^^^^^^ function called here
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
= help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled
--> $DIR/simd-abi-checks.rs:26:1
--> $DIR/simd-abi-checks.rs:27:1
|
LL | unsafe extern "C" fn g() -> __m256 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -70,7 +80,7 @@ LL | unsafe extern "C" fn g() -> __m256 {
= help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled
--> $DIR/simd-abi-checks.rs:20:1
--> $DIR/simd-abi-checks.rs:21:1
|
LL | unsafe extern "C" fn f(_: __m256) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -80,7 +90,7 @@ LL | unsafe extern "C" fn f(_: __m256) {
= help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled
--> $DIR/simd-abi-checks.rs:14:1
--> $DIR/simd-abi-checks.rs:15:1
|
LL | unsafe extern "C" fn w(_: Wrapper) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -89,11 +99,21 @@ LL | unsafe extern "C" fn w(_: Wrapper) {
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
= help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
warning: 9 warnings emitted
warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
--> $DIR/simd-abi-checks.rs:57:8
|
LL | || g()
| ^^^ function called here
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
= help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
warning: 11 warnings emitted
Future incompatibility report: Future breakage diagnostic:
warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
--> $DIR/simd-abi-checks.rs:55:11
--> $DIR/simd-abi-checks.rs:64:11
|
LL | f(g());
| ^^^ function called here
@ -105,7 +125,7 @@ LL | f(g());
Future breakage diagnostic:
warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
--> $DIR/simd-abi-checks.rs:55:9
--> $DIR/simd-abi-checks.rs:64:9
|
LL | f(g());
| ^^^^^^ function called here
@ -117,7 +137,7 @@ LL | f(g());
Future breakage diagnostic:
warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
--> $DIR/simd-abi-checks.rs:63:14
--> $DIR/simd-abi-checks.rs:72:14
|
LL | gavx(favx());
| ^^^^^^ function called here
@ -129,7 +149,7 @@ LL | gavx(favx());
Future breakage diagnostic:
warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
--> $DIR/simd-abi-checks.rs:63:9
--> $DIR/simd-abi-checks.rs:72:9
|
LL | gavx(favx());
| ^^^^^^^^^^^^ function called here
@ -141,7 +161,7 @@ LL | gavx(favx());
Future breakage diagnostic:
warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
--> $DIR/simd-abi-checks.rs:75:19
--> $DIR/simd-abi-checks.rs:84:19
|
LL | w(Wrapper(g()));
| ^^^ function called here
@ -153,7 +173,7 @@ LL | w(Wrapper(g()));
Future breakage diagnostic:
warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
--> $DIR/simd-abi-checks.rs:75:9
--> $DIR/simd-abi-checks.rs:84:9
|
LL | w(Wrapper(g()));
| ^^^^^^^^^^^^^^^ function called here
@ -163,9 +183,21 @@ LL | w(Wrapper(g()));
= help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
= note: `#[warn(abi_unsupported_vector_types)]` on by default
Future breakage diagnostic:
warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
--> $DIR/simd-abi-checks.rs:100:9
|
LL | some_extern();
| ^^^^^^^^^^^^^ function called here
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
= help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
= note: `#[warn(abi_unsupported_vector_types)]` on by default
Future breakage diagnostic:
warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled
--> $DIR/simd-abi-checks.rs:26:1
--> $DIR/simd-abi-checks.rs:27:1
|
LL | unsafe extern "C" fn g() -> __m256 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -177,7 +209,7 @@ LL | unsafe extern "C" fn g() -> __m256 {
Future breakage diagnostic:
warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled
--> $DIR/simd-abi-checks.rs:20:1
--> $DIR/simd-abi-checks.rs:21:1
|
LL | unsafe extern "C" fn f(_: __m256) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -189,7 +221,7 @@ LL | unsafe extern "C" fn f(_: __m256) {
Future breakage diagnostic:
warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled
--> $DIR/simd-abi-checks.rs:14:1
--> $DIR/simd-abi-checks.rs:15:1
|
LL | unsafe extern "C" fn w(_: Wrapper) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -199,3 +231,15 @@ LL | unsafe extern "C" fn w(_: Wrapper) {
= help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
= note: `#[warn(abi_unsupported_vector_types)]` on by default
Future breakage diagnostic:
warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
--> $DIR/simd-abi-checks.rs:57:8
|
LL | || g()
| ^^^ function called here
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
= help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
= note: `#[warn(abi_unsupported_vector_types)]` on by default