mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-13 12:36:47 +00:00
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:
commit
28fc2ba714
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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
|
||||
//!
|
||||
//!
|
||||
|
@ -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!(),
|
||||
|
@ -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() };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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!(),
|
||||
|
@ -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!(),
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
20
tests/rustdoc-ui/intra-doc/auxiliary/in-proc-item-comment.rs
Normal file
20
tests/rustdoc-ui/intra-doc/auxiliary/in-proc-item-comment.rs
Normal 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!()
|
||||
}
|
8
tests/rustdoc-ui/intra-doc/pub-proc-item.rs
Normal file
8
tests/rustdoc-ui/intra-doc/pub-proc-item.rs
Normal 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};
|
@ -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;
|
||||
|
||||
|
@ -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`.
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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`.
|
||||
|
@ -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!()
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user