Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 6 pull requests #133423

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 1 addition & 18 deletions compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_ssa/src/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
32 changes: 17 additions & 15 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
5 changes: 0 additions & 5 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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>);
Expand Down Expand Up @@ -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);
Expand Down
47 changes: 47 additions & 0 deletions library/core/src/ops/deref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -258,23 +282,46 @@ 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")]
#[rustc_diagnostic_item = "deref_mut_method"]
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 {
*self
}
}

#[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.
Expand Down
3 changes: 2 additions & 1 deletion library/std/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down
3 changes: 0 additions & 3 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
//!
//!
Expand Down
6 changes: 4 additions & 2 deletions library/std/src/sync/mpmc/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(),
Expand Down Expand Up @@ -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!(),
Expand Down
13 changes: 9 additions & 4 deletions library/std/src/sync/mpmc/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
}),
}
Expand Down Expand Up @@ -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));
Expand All @@ -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) {
Expand All @@ -135,7 +139,8 @@ impl Context {
};
}
} else {
thread::park();
// SAFETY: guaranteed by caller.
unsafe { self.inner.thread.park() };
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion library/std/src/sync/mpmc/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(),
Expand Down
6 changes: 4 additions & 2 deletions library/std/src/sync/mpmc/zero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(),
Expand Down Expand Up @@ -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!(),
Expand Down
9 changes: 5 additions & 4 deletions library/std/src/sys/sync/once/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
}
Expand Down Expand Up @@ -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()),
};
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
Loading
Loading