Skip to content

Commit 6c96bb1

Browse files
committed
Auto merge of rust-lang#138637 - jhpratt:rollup-4bw5bn8, r=jhpratt
Rollup of 7 pull requests Successful merges: - rust-lang#136320 (exit: document interaction with C) - rust-lang#138301 (Implement `read_buf` for Hermit) - rust-lang#138508 (Clarify "owned data" in E0515.md) - rust-lang#138556 (Fix ICE: attempted to remap an already remapped filename) - rust-lang#138569 (rustdoc-json: Add tests for `#[repr(...)]`) - rust-lang#138608 (rustc_target: Add target feature constraints for LoongArch) - rust-lang#138619 (Flatten `if`s in `rustc_codegen_ssa`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 493c38b + 83f4bc4 commit 6c96bb1

File tree

22 files changed

+333
-114
lines changed

22 files changed

+333
-114
lines changed

compiler/rustc_codegen_ssa/src/back/archive.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -389,11 +389,10 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> {
389389
mut skip: Box<dyn FnMut(&str) -> bool + 'static>,
390390
) -> io::Result<()> {
391391
let mut archive_path = archive_path.to_path_buf();
392-
if self.sess.target.llvm_target.contains("-apple-macosx") {
393-
if let Some(new_archive_path) = try_extract_macho_fat_archive(self.sess, &archive_path)?
394-
{
395-
archive_path = new_archive_path
396-
}
392+
if self.sess.target.llvm_target.contains("-apple-macosx")
393+
&& let Some(new_archive_path) = try_extract_macho_fat_archive(self.sess, &archive_path)?
394+
{
395+
archive_path = new_archive_path
397396
}
398397

399398
if self.src_archives.iter().any(|archive| archive.0 == archive_path) {

compiler/rustc_codegen_ssa/src/back/link.rs

+25-28
Original file line numberDiff line numberDiff line change
@@ -151,17 +151,17 @@ pub fn link_binary(
151151
sess.dcx().emit_artifact_notification(&out_filename, "link");
152152
}
153153

154-
if sess.prof.enabled() {
155-
if let Some(artifact_name) = out_filename.file_name() {
156-
// Record size for self-profiling
157-
let file_size = std::fs::metadata(&out_filename).map(|m| m.len()).unwrap_or(0);
158-
159-
sess.prof.artifact_size(
160-
"linked_artifact",
161-
artifact_name.to_string_lossy(),
162-
file_size,
163-
);
164-
}
154+
if sess.prof.enabled()
155+
&& let Some(artifact_name) = out_filename.file_name()
156+
{
157+
// Record size for self-profiling
158+
let file_size = std::fs::metadata(&out_filename).map(|m| m.len()).unwrap_or(0);
159+
160+
sess.prof.artifact_size(
161+
"linked_artifact",
162+
artifact_name.to_string_lossy(),
163+
file_size,
164+
);
165165
}
166166

167167
if output.is_stdout() {
@@ -186,16 +186,12 @@ pub fn link_binary(
186186

187187
let maybe_remove_temps_from_module =
188188
|preserve_objects: bool, preserve_dwarf_objects: bool, module: &CompiledModule| {
189-
if !preserve_objects {
190-
if let Some(ref obj) = module.object {
191-
ensure_removed(sess.dcx(), obj);
192-
}
189+
if !preserve_objects && let Some(ref obj) = module.object {
190+
ensure_removed(sess.dcx(), obj);
193191
}
194192

195-
if !preserve_dwarf_objects {
196-
if let Some(ref dwo_obj) = module.dwarf_object {
197-
ensure_removed(sess.dcx(), dwo_obj);
198-
}
193+
if !preserve_dwarf_objects && let Some(ref dwo_obj) = module.dwarf_object {
194+
ensure_removed(sess.dcx(), dwo_obj);
199195
}
200196
};
201197

@@ -2116,11 +2112,11 @@ fn add_local_crate_metadata_objects(
21162112
// When linking a dynamic library, we put the metadata into a section of the
21172113
// executable. This metadata is in a separate object file from the main
21182114
// object file, so we link that in here.
2119-
if crate_type == CrateType::Dylib || crate_type == CrateType::ProcMacro {
2120-
if let Some(obj) = codegen_results.metadata_module.as_ref().and_then(|m| m.object.as_ref())
2121-
{
2122-
cmd.add_object(obj);
2123-
}
2115+
if matches!(crate_type, CrateType::Dylib | CrateType::ProcMacro)
2116+
&& let Some(m) = &codegen_results.metadata_module
2117+
&& let Some(obj) = &m.object
2118+
{
2119+
cmd.add_object(obj);
21242120
}
21252121
}
21262122

@@ -2540,10 +2536,11 @@ fn add_order_independent_options(
25402536

25412537
cmd.output_filename(out_filename);
25422538

2543-
if crate_type == CrateType::Executable && sess.target.is_like_windows {
2544-
if let Some(ref s) = codegen_results.crate_info.windows_subsystem {
2545-
cmd.subsystem(s);
2546-
}
2539+
if crate_type == CrateType::Executable
2540+
&& sess.target.is_like_windows
2541+
&& let Some(s) = &codegen_results.crate_info.windows_subsystem
2542+
{
2543+
cmd.subsystem(s);
25472544
}
25482545

25492546
// Try to strip as much out of the generated object by removing unused

compiler/rustc_codegen_ssa/src/back/linker.rs

+12-14
Original file line numberDiff line numberDiff line change
@@ -111,24 +111,22 @@ pub(crate) fn get_linker<'a>(
111111
// PATH for the child.
112112
let mut new_path = sess.get_tools_search_paths(self_contained);
113113
let mut msvc_changed_path = false;
114-
if sess.target.is_like_msvc {
115-
if let Some(ref tool) = msvc_tool {
116-
cmd.args(tool.args());
117-
for (k, v) in tool.env() {
118-
if k == "PATH" {
119-
new_path.extend(env::split_paths(v));
120-
msvc_changed_path = true;
121-
} else {
122-
cmd.env(k, v);
123-
}
114+
if sess.target.is_like_msvc
115+
&& let Some(ref tool) = msvc_tool
116+
{
117+
cmd.args(tool.args());
118+
for (k, v) in tool.env() {
119+
if k == "PATH" {
120+
new_path.extend(env::split_paths(v));
121+
msvc_changed_path = true;
122+
} else {
123+
cmd.env(k, v);
124124
}
125125
}
126126
}
127127

128-
if !msvc_changed_path {
129-
if let Some(path) = env::var_os("PATH") {
130-
new_path.extend(env::split_paths(&path));
131-
}
128+
if !msvc_changed_path && let Some(path) = env::var_os("PATH") {
129+
new_path.extend(env::split_paths(&path));
132130
}
133131
cmd.env("PATH", env::join_paths(new_path).unwrap());
134132

compiler/rustc_codegen_ssa/src/back/write.rs

+13-19
Original file line numberDiff line numberDiff line change
@@ -566,16 +566,13 @@ fn produce_final_output_artifacts(
566566

567567
// Produce final compile outputs.
568568
let copy_gracefully = |from: &Path, to: &OutFileName| match to {
569-
OutFileName::Stdout => {
570-
if let Err(e) = copy_to_stdout(from) {
571-
sess.dcx().emit_err(errors::CopyPath::new(from, to.as_path(), e));
572-
}
569+
OutFileName::Stdout if let Err(e) = copy_to_stdout(from) => {
570+
sess.dcx().emit_err(errors::CopyPath::new(from, to.as_path(), e));
573571
}
574-
OutFileName::Real(path) => {
575-
if let Err(e) = fs::copy(from, path) {
576-
sess.dcx().emit_err(errors::CopyPath::new(from, path, e));
577-
}
572+
OutFileName::Real(path) if let Err(e) = fs::copy(from, path) => {
573+
sess.dcx().emit_err(errors::CopyPath::new(from, path, e));
578574
}
575+
_ => {}
579576
};
580577

581578
let copy_if_one_unit = |output_type: OutputType, keep_numbered: bool| {
@@ -685,14 +682,12 @@ fn produce_final_output_artifacts(
685682
needs_crate_object || (user_wants_objects && sess.codegen_units().as_usize() > 1);
686683

687684
for module in compiled_modules.modules.iter() {
688-
if let Some(ref path) = module.object {
689-
if !keep_numbered_objects {
685+
if !keep_numbered_objects {
686+
if let Some(ref path) = module.object {
690687
ensure_removed(sess.dcx(), path);
691688
}
692-
}
693689

694-
if let Some(ref path) = module.dwarf_object {
695-
if !keep_numbered_objects {
690+
if let Some(ref path) = module.dwarf_object {
696691
ensure_removed(sess.dcx(), path);
697692
}
698693
}
@@ -704,12 +699,11 @@ fn produce_final_output_artifacts(
704699
}
705700
}
706701

707-
if !user_wants_bitcode {
708-
if let Some(ref allocator_module) = compiled_modules.allocator_module {
709-
if let Some(ref path) = allocator_module.bytecode {
710-
ensure_removed(sess.dcx(), path);
711-
}
712-
}
702+
if !user_wants_bitcode
703+
&& let Some(ref allocator_module) = compiled_modules.allocator_module
704+
&& let Some(ref path) = allocator_module.bytecode
705+
{
706+
ensure_removed(sess.dcx(), path);
713707
}
714708
}
715709

compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -555,11 +555,9 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
555555

556556
pub fn push_item_name(tcx: TyCtxt<'_>, def_id: DefId, qualified: bool, output: &mut String) {
557557
let def_key = tcx.def_key(def_id);
558-
if qualified {
559-
if let Some(parent) = def_key.parent {
560-
push_item_name(tcx, DefId { krate: def_id.krate, index: parent }, true, output);
561-
output.push_str("::");
562-
}
558+
if qualified && let Some(parent) = def_key.parent {
559+
push_item_name(tcx, DefId { krate: def_id.krate, index: parent }, true, output);
560+
output.push_str("::");
563561
}
564562

565563
push_unqualified_item_name(tcx, def_id, def_key.disambiguated_data, output);

compiler/rustc_codegen_ssa/src/mir/block.rs

+19-19
Original file line numberDiff line numberDiff line change
@@ -163,25 +163,25 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
163163
mergeable_succ: bool,
164164
) -> MergingSucc {
165165
let tcx = bx.tcx();
166-
if let Some(instance) = instance {
167-
if is_call_from_compiler_builtins_to_upstream_monomorphization(tcx, instance) {
168-
if destination.is_some() {
169-
let caller_def = fx.instance.def_id();
170-
let e = CompilerBuiltinsCannotCall {
171-
span: tcx.def_span(caller_def),
172-
caller: with_no_trimmed_paths!(tcx.def_path_str(caller_def)),
173-
callee: with_no_trimmed_paths!(tcx.def_path_str(instance.def_id())),
174-
};
175-
tcx.dcx().emit_err(e);
176-
} else {
177-
info!(
178-
"compiler_builtins call to diverging function {:?} replaced with abort",
179-
instance.def_id()
180-
);
181-
bx.abort();
182-
bx.unreachable();
183-
return MergingSucc::False;
184-
}
166+
if let Some(instance) = instance
167+
&& is_call_from_compiler_builtins_to_upstream_monomorphization(tcx, instance)
168+
{
169+
if destination.is_some() {
170+
let caller_def = fx.instance.def_id();
171+
let e = CompilerBuiltinsCannotCall {
172+
span: tcx.def_span(caller_def),
173+
caller: with_no_trimmed_paths!(tcx.def_path_str(caller_def)),
174+
callee: with_no_trimmed_paths!(tcx.def_path_str(instance.def_id())),
175+
};
176+
tcx.dcx().emit_err(e);
177+
} else {
178+
info!(
179+
"compiler_builtins call to diverging function {:?} replaced with abort",
180+
instance.def_id()
181+
);
182+
bx.abort();
183+
bx.unreachable();
184+
return MergingSucc::False;
185185
}
186186
}
187187

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -837,15 +837,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
837837
fn evaluate_array_len(&mut self, bx: &mut Bx, place: mir::Place<'tcx>) -> Bx::Value {
838838
// ZST are passed as operands and require special handling
839839
// because codegen_place() panics if Local is operand.
840-
if let Some(index) = place.as_local() {
841-
if let LocalRef::Operand(op) = self.locals[index] {
842-
if let ty::Array(_, n) = op.layout.ty.kind() {
843-
let n = n
844-
.try_to_target_usize(bx.tcx())
845-
.expect("expected monomorphic const in codegen");
846-
return bx.cx().const_usize(n);
847-
}
848-
}
840+
if let Some(index) = place.as_local()
841+
&& let LocalRef::Operand(op) = self.locals[index]
842+
&& let ty::Array(_, n) = op.layout.ty.kind()
843+
{
844+
let n = n.try_to_target_usize(bx.tcx()).expect("expected monomorphic const in codegen");
845+
return bx.cx().const_usize(n);
849846
}
850847
// use common size calculation for non zero-sized types
851848
let cg_value = self.codegen_place(bx, place.as_ref());

compiler/rustc_error_codes/src/error_codes/E0515.md

+6-3
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@ fn get_dangling_iterator<'a>() -> Iter<'a, i32> {
1717
}
1818
```
1919

20-
Local variables, function parameters and temporaries are all dropped before the
21-
end of the function body. So a reference to them cannot be returned.
20+
Local variables, function parameters and temporaries are all dropped before
21+
the end of the function body. A returned reference (or struct containing a
22+
reference) to such a dropped value would immediately be invalid. Therefore
23+
it is not allowed to return such a reference.
2224

23-
Consider returning an owned value instead:
25+
Consider returning a value that takes ownership of local data instead of
26+
referencing it:
2427

2528
```
2629
use std::vec::IntoIter;

compiler/rustc_target/src/target_features.rs

+22
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,28 @@ impl Target {
923923
_ => unreachable!(),
924924
}
925925
}
926+
"loongarch64" => {
927+
// LoongArch handles ABI in a very sane way, being fully explicit via `llvm_abiname`
928+
// about what the intended ABI is.
929+
match &*self.llvm_abiname {
930+
"ilp32d" | "lp64d" => {
931+
// Requires d (which implies f), incompatible with nothing.
932+
FeatureConstraints { required: &["d"], incompatible: &[] }
933+
}
934+
"ilp32f" | "lp64f" => {
935+
// Requires f, incompatible with nothing.
936+
FeatureConstraints { required: &["f"], incompatible: &[] }
937+
}
938+
"ilp32s" | "lp64s" => {
939+
// The soft-float ABI does not require any features and is also not
940+
// incompatible with any features. Rust targets explicitly specify the
941+
// LLVM ABI names, which allows for enabling hard-float support even on
942+
// soft-float targets, and ensures that the ABI behavior is as expected.
943+
NOTHING
944+
}
945+
_ => unreachable!(),
946+
}
947+
}
926948
_ => NOTHING,
927949
}
928950
}

library/std/src/env.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ impl Error for VarError {
333333
///
334334
/// Discussion of this unsafety on Unix may be found in:
335335
///
336-
/// - [Austin Group Bugzilla](https://austingroupbugs.net/view.php?id=188)
336+
/// - [Austin Group Bugzilla (for POSIX)](https://austingroupbugs.net/view.php?id=188)
337337
/// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15607#c2)
338338
///
339339
/// To pass an environment variable to a child process, you can instead use [`Command::env`].

library/std/src/process.rs

+30-3
Original file line numberDiff line numberDiff line change
@@ -2018,9 +2018,9 @@ impl ExitCode {
20182018
///
20192019
/// Note that this has the same caveats as [`process::exit()`][exit], namely that this function
20202020
/// terminates the process immediately, so no destructors on the current stack or any other
2021-
/// thread's stack will be run. If a clean shutdown is needed, it is recommended to simply
2022-
/// return this ExitCode from the `main` function, as demonstrated in the [type
2023-
/// documentation](#examples).
2021+
/// thread's stack will be run. Also see those docs for some important notes on interop with C
2022+
/// code. If a clean shutdown is needed, it is recommended to simply return this ExitCode from
2023+
/// the `main` function, as demonstrated in the [type documentation](#examples).
20242024
///
20252025
/// # Differences from `process::exit()`
20262026
///
@@ -2326,6 +2326,33 @@ impl Child {
23262326
///
23272327
/// process::exit(0x0100);
23282328
/// ```
2329+
///
2330+
/// ### Safe interop with C code
2331+
///
2332+
/// On Unix, this function is currently implemented using the `exit` C function [`exit`][C-exit]. As
2333+
/// of C23, the C standard does not permit multiple threads to call `exit` concurrently. Rust
2334+
/// mitigates this with a lock, but if C code calls `exit`, that can still cause undefined behavior.
2335+
/// Note that returning from `main` is equivalent to calling `exit`.
2336+
///
2337+
/// Therefore, it is undefined behavior to have two concurrent threads perform the following
2338+
/// without synchronization:
2339+
/// - One thread calls Rust's `exit` function or returns from Rust's `main` function
2340+
/// - Another thread calls the C function `exit` or `quick_exit`, or returns from C's `main` function
2341+
///
2342+
/// Note that if a binary contains multiple copies of the Rust runtime (e.g., when combining
2343+
/// multiple `cdylib` or `staticlib`), they each have their own separate lock, so from the
2344+
/// perspective of code running in one of the Rust runtimes, the "outside" Rust code is basically C
2345+
/// code, and concurrent `exit` again causes undefined behavior.
2346+
///
2347+
/// Individual C implementations might provide more guarantees than the standard and permit concurrent
2348+
/// calls to `exit`; consult the documentation of your C implementation for details.
2349+
///
2350+
/// For some of the on-going discussion to make `exit` thread-safe in C, see:
2351+
/// - [Rust issue #126600](https://github.com/rust-lang/rust/issues/126600)
2352+
/// - [Austin Group Bugzilla (for POSIX)](https://austingroupbugs.net/view.php?id=1845)
2353+
/// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=31997)
2354+
///
2355+
/// [C-exit]: https://en.cppreference.com/w/c/program/exit
23292356
#[stable(feature = "rust1", since = "1.0.0")]
23302357
#[cfg_attr(not(test), rustc_diagnostic_item = "process_exit")]
23312358
pub fn exit(code: i32) -> ! {

library/std/src/sys/fs/hermit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ impl File {
396396
}
397397

398398
pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
399-
crate::io::default_read_buf(|buf| self.read(buf), cursor)
399+
self.0.read_buf(cursor)
400400
}
401401

402402
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {

0 commit comments

Comments
 (0)