Skip to content

Commit 28fc2ba

Browse files
committed
Auto merge of rust-lang#133423 - jieyouxu:rollup-m3gyoz6, r=jieyouxu
Rollup of 6 pull requests Successful merges: - rust-lang#132730 (std: allow after-main use of synchronization primitives) - rust-lang#133105 (only store valid proc macro item for doc link) - rust-lang#133260 (Constify the `Deref`/`DerefMut` traits, too) - rust-lang#133297 (Remove legacy bitcode for iOS) - rust-lang#133298 (Mention that std::fs::remove_dir_all fails on files) - rust-lang#133384 (add a test for target-feature-ABI warnings in closures and when calling extern fn) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 481b5fa + c50e19b commit 28fc2ba

File tree

26 files changed

+269
-120
lines changed

26 files changed

+269
-120
lines changed

compiler/rustc_codegen_llvm/src/back/write.rs

+1-18
Original file line numberDiff line numberDiff line change
@@ -955,24 +955,7 @@ pub(crate) fn bitcode_section_name(cgcx: &CodegenContext<LlvmCodegenBackend>) ->
955955
}
956956
}
957957

958-
/// Embed the bitcode of an LLVM module in the LLVM module itself.
959-
///
960-
/// This is done primarily for iOS where it appears to be standard to compile C
961-
/// code at least with `-fembed-bitcode` which creates two sections in the
962-
/// executable:
963-
///
964-
/// * __LLVM,__bitcode
965-
/// * __LLVM,__cmdline
966-
///
967-
/// It appears *both* of these sections are necessary to get the linker to
968-
/// recognize what's going on. A suitable cmdline value is taken from the
969-
/// target spec.
970-
///
971-
/// Furthermore debug/O1 builds don't actually embed bitcode but rather just
972-
/// embed an empty section.
973-
///
974-
/// Basically all of this is us attempting to follow in the footsteps of clang
975-
/// on iOS. See #35968 for lots more info.
958+
/// Embed the bitcode of an LLVM module for LTO in the LLVM module itself.
976959
unsafe fn embed_bitcode(
977960
cgcx: &CodegenContext<LlvmCodegenBackend>,
978961
llcx: &llvm::Context,

compiler/rustc_codegen_ssa/src/back/write.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -432,11 +432,9 @@ struct CompiledModules {
432432

433433
fn need_bitcode_in_object(tcx: TyCtxt<'_>) -> bool {
434434
let sess = tcx.sess;
435-
let requested_for_rlib = sess.opts.cg.embed_bitcode
435+
sess.opts.cg.embed_bitcode
436436
&& tcx.crate_types().contains(&CrateType::Rlib)
437-
&& sess.opts.output_types.contains_key(&OutputType::Exe);
438-
let forced_by_target = sess.target.forces_embed_bitcode;
439-
requested_for_rlib || forced_by_target
437+
&& sess.opts.output_types.contains_key(&OutputType::Exe)
440438
}
441439

442440
fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool {

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

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

compiler/rustc_resolve/src/late.rs

+17-15
Original file line numberDiff line numberDiff line change
@@ -4794,14 +4794,10 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
47944794
let res = self.r.resolve_rustdoc_path(path.as_str(), *ns, self.parent_scope);
47954795
if let Some(res) = res
47964796
&& let Some(def_id) = res.opt_def_id()
4797-
&& !def_id.is_local()
4798-
&& self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
4799-
&& matches!(
4800-
self.r.tcx.sess.opts.resolve_doc_links,
4801-
ResolveDocLinks::ExportedMetadata
4802-
)
4797+
&& self.is_invalid_proc_macro_item_for_doc(def_id)
48034798
{
4804-
// Encoding foreign def ids in proc macro crate metadata will ICE.
4799+
// Encoding def ids in proc macro crate metadata will ICE,
4800+
// because it will only store proc macros for it.
48054801
return None;
48064802
}
48074803
res
@@ -4810,6 +4806,17 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
48104806
res
48114807
}
48124808

4809+
fn is_invalid_proc_macro_item_for_doc(&self, did: DefId) -> bool {
4810+
if !matches!(self.r.tcx.sess.opts.resolve_doc_links, ResolveDocLinks::ExportedMetadata)
4811+
|| !self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
4812+
{
4813+
return false;
4814+
}
4815+
let Some(local_did) = did.as_local() else { return true };
4816+
let Some(node_id) = self.r.def_id_to_node_id.get(local_did) else { return true };
4817+
!self.r.proc_macros.contains(node_id)
4818+
}
4819+
48134820
fn resolve_doc_links(&mut self, attrs: &[Attribute], maybe_exported: MaybeExported<'_>) {
48144821
match self.r.tcx.sess.opts.resolve_doc_links {
48154822
ResolveDocLinks::None => return,
@@ -4872,14 +4879,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
48724879
.traits_in_scope(None, &self.parent_scope, SyntaxContext::root(), None)
48734880
.into_iter()
48744881
.filter_map(|tr| {
4875-
if !tr.def_id.is_local()
4876-
&& self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
4877-
&& matches!(
4878-
self.r.tcx.sess.opts.resolve_doc_links,
4879-
ResolveDocLinks::ExportedMetadata
4880-
)
4881-
{
4882-
// Encoding foreign def ids in proc macro crate metadata will ICE.
4882+
if self.is_invalid_proc_macro_item_for_doc(tr.def_id) {
4883+
// Encoding def ids in proc macro crate metadata will ICE.
4884+
// because it will only store proc macros for it.
48834885
return None;
48844886
}
48854887
Some(tr.def_id)

compiler/rustc_target/src/spec/mod.rs

-5
Original file line numberDiff line numberDiff line change
@@ -2327,8 +2327,6 @@ pub struct TargetOptions {
23272327
/// If we give emcc .o files that are actually .bc files it
23282328
/// will 'just work'.
23292329
pub obj_is_bitcode: bool,
2330-
/// Whether the target requires that emitted object code includes bitcode.
2331-
pub forces_embed_bitcode: bool,
23322330
/// Content of the LLVM cmdline section associated with embedded bitcode.
23332331
pub bitcode_llvm_cmdline: StaticCow<str>,
23342332

@@ -2671,7 +2669,6 @@ impl Default for TargetOptions {
26712669
allow_asm: true,
26722670
has_thread_local: false,
26732671
obj_is_bitcode: false,
2674-
forces_embed_bitcode: false,
26752672
bitcode_llvm_cmdline: "".into(),
26762673
min_atomic_width: None,
26772674
max_atomic_width: None,
@@ -3412,7 +3409,6 @@ impl Target {
34123409
key!(main_needs_argc_argv, bool);
34133410
key!(has_thread_local, bool);
34143411
key!(obj_is_bitcode, bool);
3415-
key!(forces_embed_bitcode, bool);
34163412
key!(bitcode_llvm_cmdline);
34173413
key!(max_atomic_width, Option<u64>);
34183414
key!(min_atomic_width, Option<u64>);
@@ -3687,7 +3683,6 @@ impl ToJson for Target {
36873683
target_option_val!(main_needs_argc_argv);
36883684
target_option_val!(has_thread_local);
36893685
target_option_val!(obj_is_bitcode);
3690-
target_option_val!(forces_embed_bitcode);
36913686
target_option_val!(bitcode_llvm_cmdline);
36923687
target_option_val!(min_atomic_width);
36933688
target_option_val!(max_atomic_width);

library/core/src/ops/deref.rs

+47
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@
133133
#[doc(alias = "&*")]
134134
#[stable(feature = "rust1", since = "1.0.0")]
135135
#[rustc_diagnostic_item = "Deref"]
136+
#[cfg_attr(not(bootstrap), const_trait)]
136137
pub trait Deref {
137138
/// The resulting type after dereferencing.
138139
#[stable(feature = "rust1", since = "1.0.0")]
@@ -147,6 +148,7 @@ pub trait Deref {
147148
fn deref(&self) -> &Self::Target;
148149
}
149150

151+
#[cfg(bootstrap)]
150152
#[stable(feature = "rust1", since = "1.0.0")]
151153
impl<T: ?Sized> Deref for &T {
152154
type Target = T;
@@ -157,9 +159,21 @@ impl<T: ?Sized> Deref for &T {
157159
}
158160
}
159161

162+
#[cfg(not(bootstrap))]
163+
#[stable(feature = "rust1", since = "1.0.0")]
164+
impl<T: ?Sized> const Deref for &T {
165+
type Target = T;
166+
167+
#[rustc_diagnostic_item = "noop_method_deref"]
168+
fn deref(&self) -> &T {
169+
*self
170+
}
171+
}
172+
160173
#[stable(feature = "rust1", since = "1.0.0")]
161174
impl<T: ?Sized> !DerefMut for &T {}
162175

176+
#[cfg(bootstrap)]
163177
#[stable(feature = "rust1", since = "1.0.0")]
164178
impl<T: ?Sized> Deref for &mut T {
165179
type Target = T;
@@ -169,6 +183,16 @@ impl<T: ?Sized> Deref for &mut T {
169183
}
170184
}
171185

186+
#[cfg(not(bootstrap))]
187+
#[stable(feature = "rust1", since = "1.0.0")]
188+
impl<T: ?Sized> const Deref for &mut T {
189+
type Target = T;
190+
191+
fn deref(&self) -> &T {
192+
*self
193+
}
194+
}
195+
172196
/// Used for mutable dereferencing operations, like in `*v = 1;`.
173197
///
174198
/// In addition to being used for explicit dereferencing operations with the
@@ -258,23 +282,46 @@ impl<T: ?Sized> Deref for &mut T {
258282
/// *x = 'b';
259283
/// assert_eq!('b', x.value);
260284
/// ```
285+
#[cfg(not(bootstrap))]
286+
#[lang = "deref_mut"]
287+
#[doc(alias = "*")]
288+
#[stable(feature = "rust1", since = "1.0.0")]
289+
#[const_trait]
290+
pub trait DerefMut: ~const Deref {
291+
/// Mutably dereferences the value.
292+
#[stable(feature = "rust1", since = "1.0.0")]
293+
#[rustc_diagnostic_item = "deref_mut_method"]
294+
fn deref_mut(&mut self) -> &mut Self::Target;
295+
}
296+
297+
/// Bootstrap
261298
#[lang = "deref_mut"]
262299
#[doc(alias = "*")]
263300
#[stable(feature = "rust1", since = "1.0.0")]
301+
#[cfg(bootstrap)]
264302
pub trait DerefMut: Deref {
265303
/// Mutably dereferences the value.
266304
#[stable(feature = "rust1", since = "1.0.0")]
267305
#[rustc_diagnostic_item = "deref_mut_method"]
268306
fn deref_mut(&mut self) -> &mut Self::Target;
269307
}
270308

309+
#[cfg(bootstrap)]
271310
#[stable(feature = "rust1", since = "1.0.0")]
272311
impl<T: ?Sized> DerefMut for &mut T {
273312
fn deref_mut(&mut self) -> &mut T {
274313
*self
275314
}
276315
}
277316

317+
#[cfg(not(bootstrap))]
318+
#[stable(feature = "rust1", since = "1.0.0")]
319+
impl<T: ?Sized> const DerefMut for &mut T {
320+
fn deref_mut(&mut self) -> &mut T {
321+
*self
322+
}
323+
}
324+
278325
/// Perma-unstable marker trait. Indicates that the type has a well-behaved [`Deref`]
279326
/// (and, if applicable, [`DerefMut`]) implementation. This is relied on for soundness
280327
/// of deref patterns.

library/std/src/fs.rs

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

library/std/src/lib.rs

-3
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,6 @@
174174
//!
175175
//! - after-main use of thread-locals, which also affects additional features:
176176
//! - [`thread::current()`]
177-
//! - [`thread::scope()`]
178-
//! - [`sync::mpmc`]
179-
//! - [`sync::mpsc`]
180177
//! - before-main stdio file descriptors are not guaranteed to be open on unix platforms
181178
//!
182179
//!

library/std/src/sync/mpmc/array.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,8 @@ impl<T> Channel<T> {
346346
}
347347

348348
// Block the current thread.
349-
let sel = cx.wait_until(deadline);
349+
// SAFETY: the context belongs to the current thread.
350+
let sel = unsafe { cx.wait_until(deadline) };
350351

351352
match sel {
352353
Selected::Waiting => unreachable!(),
@@ -397,7 +398,8 @@ impl<T> Channel<T> {
397398
}
398399

399400
// Block the current thread.
400-
let sel = cx.wait_until(deadline);
401+
// SAFETY: the context belongs to the current thread.
402+
let sel = unsafe { cx.wait_until(deadline) };
401403

402404
match sel {
403405
Selected::Waiting => unreachable!(),

library/std/src/sync/mpmc/context.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ impl Context {
6969
inner: Arc::new(Inner {
7070
select: AtomicUsize::new(Selected::Waiting.into()),
7171
packet: AtomicPtr::new(ptr::null_mut()),
72-
thread: thread::current(),
72+
thread: thread::current_or_unnamed(),
7373
thread_id: current_thread_id(),
7474
}),
7575
}
@@ -112,8 +112,11 @@ impl Context {
112112
/// Waits until an operation is selected and returns it.
113113
///
114114
/// If the deadline is reached, `Selected::Aborted` will be selected.
115+
///
116+
/// # Safety
117+
/// This may only be called from the thread this `Context` belongs to.
115118
#[inline]
116-
pub fn wait_until(&self, deadline: Option<Instant>) -> Selected {
119+
pub unsafe fn wait_until(&self, deadline: Option<Instant>) -> Selected {
117120
loop {
118121
// Check whether an operation has been selected.
119122
let sel = Selected::from(self.inner.select.load(Ordering::Acquire));
@@ -126,7 +129,8 @@ impl Context {
126129
let now = Instant::now();
127130

128131
if now < end {
129-
thread::park_timeout(end - now);
132+
// SAFETY: guaranteed by caller.
133+
unsafe { self.inner.thread.park_timeout(end - now) };
130134
} else {
131135
// The deadline has been reached. Try aborting select.
132136
return match self.try_select(Selected::Aborted) {
@@ -135,7 +139,8 @@ impl Context {
135139
};
136140
}
137141
} else {
138-
thread::park();
142+
// SAFETY: guaranteed by caller.
143+
unsafe { self.inner.thread.park() };
139144
}
140145
}
141146
}

library/std/src/sync/mpmc/list.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,8 @@ impl<T> Channel<T> {
444444
}
445445

446446
// Block the current thread.
447-
let sel = cx.wait_until(deadline);
447+
// SAFETY: the context belongs to the current thread.
448+
let sel = unsafe { cx.wait_until(deadline) };
448449

449450
match sel {
450451
Selected::Waiting => unreachable!(),

library/std/src/sync/mpmc/zero.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,8 @@ impl<T> Channel<T> {
190190
drop(inner);
191191

192192
// Block the current thread.
193-
let sel = cx.wait_until(deadline);
193+
// SAFETY: the context belongs to the current thread.
194+
let sel = unsafe { cx.wait_until(deadline) };
194195

195196
match sel {
196197
Selected::Waiting => unreachable!(),
@@ -257,7 +258,8 @@ impl<T> Channel<T> {
257258
drop(inner);
258259

259260
// Block the current thread.
260-
let sel = cx.wait_until(deadline);
261+
// SAFETY: the context belongs to the current thread.
262+
let sel = unsafe { cx.wait_until(deadline) };
261263

262264
match sel {
263265
Selected::Waiting => unreachable!(),

library/std/src/sys/sync/once/queue.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ const QUEUE_MASK: usize = !STATE_MASK;
9393
// use interior mutability.
9494
#[repr(align(4))] // Ensure the two lower bits are free to use as state bits.
9595
struct Waiter {
96-
thread: Cell<Option<Thread>>,
96+
thread: Thread,
9797
signaled: AtomicBool,
9898
next: Cell<*const Waiter>,
9999
}
@@ -238,7 +238,7 @@ fn wait(
238238
return_on_poisoned: bool,
239239
) -> StateAndQueue {
240240
let node = &Waiter {
241-
thread: Cell::new(Some(thread::current())),
241+
thread: thread::current_or_unnamed(),
242242
signaled: AtomicBool::new(false),
243243
next: Cell::new(ptr::null()),
244244
};
@@ -277,7 +277,8 @@ fn wait(
277277
// can park ourselves, the result could be this thread never gets
278278
// unparked. Luckily `park` comes with the guarantee that if it got
279279
// an `unpark` just before on an unparked thread it does not park.
280-
thread::park();
280+
// SAFETY: we retrieved this handle on the current thread above.
281+
unsafe { node.thread.park() }
281282
}
282283

283284
return state_and_queue.load(Acquire);
@@ -309,7 +310,7 @@ impl Drop for WaiterQueue<'_> {
309310
let mut queue = to_queue(current);
310311
while !queue.is_null() {
311312
let next = (*queue).next.get();
312-
let thread = (*queue).thread.take().unwrap();
313+
let thread = (*queue).thread.clone();
313314
(*queue).signaled.store(true, Release);
314315
thread.unpark();
315316
queue = next;

0 commit comments

Comments
 (0)