From 01b68b74ba7d41be7703dc574c14939ba2b97bec Mon Sep 17 00:00:00 2001 From: Ibraheem Ahmed Date: Mon, 11 Jul 2022 21:39:07 -0400 Subject: [PATCH 01/12] add `Thread::{into_raw, from_raw}` --- library/std/src/thread/mod.rs | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index c70ac8c9806d6..a62f0a6ea5434 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -1230,6 +1230,52 @@ impl Thread { self.cname().map(|s| unsafe { str::from_utf8_unchecked(s.to_bytes()) }) } + /// Consumes the `Thread`, returning a raw pointer. + /// + /// To avoid a memory leak the pointer must be converted + /// back into a `Thread` using [`Thread::from_raw`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(thread_raw)] + /// + /// use std::thread::{self, Thread}; + /// + /// let thread = thread::current(); + /// let id = thread.id(); + /// let ptr = Thread::into_raw(thread); + /// unsafe { + /// assert_eq!(Thread::from_raw(ptr).id(), id); + /// } + /// ``` + #[unstable(feature = "thread_raw", issue = "97523")] + pub fn into_raw(self) -> *const () { + Arc::into_raw(Pin::into_inner(self.inner)) as *const () + } + + /// Constructs a `Thread` from a raw pointer. + /// + /// The raw pointer must have been previously returned + /// by a call to [`Thread::into_raw`]. + /// + /// # Safety + /// + /// This function is unsafe because improper use may lead + /// to memory unsafety, even if the returned `Thread` is never + /// accessed. + /// + /// Creating a `Thread` from a pointer other than one returned + /// from [`Thread::into_raw`] is **undefined behavior**. + /// + /// Calling this function twice on the same raw pointer can lead + /// to a double-free if both `Thread` instances are dropped. + #[unstable(feature = "thread_raw", issue = "97523")] + pub unsafe fn from_raw(ptr: *const ()) -> Thread { + // SAFETY: upheld by caller + unsafe { Thread { inner: Pin::new_unchecked(Arc::from_raw(ptr as *const Inner)) } } + } + fn cname(&self) -> Option<&CStr> { self.inner.name.as_deref() } From 78caecf8f30dbdbfcb6e0fda25edc72b3e4d04a5 Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Sat, 3 Aug 2024 21:04:19 -0700 Subject: [PATCH 02/12] Special case DUMMY_SP to emit line 0/column 0 locations on DWARF platforms. Line 0 has a special meaning in DWARF. From the version 5 spec: The compiler may emit the value 0 in cases where an instruction cannot be attributed to any source line. DUMMY_SP spans cannot be attributed to any line. However, because rustc internally stores line numbers starting at zero, lookup_debug_loc() adjusts every line number by one. Special casing DUMMY_SP to actually emit line 0 ensures rustc communicates to the debugger that there's no meaningful source code for this instruction, rather than telling the debugger to jump to line 1 randomly. --- compiler/rustc_codegen_llvm/src/debuginfo/mod.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index b23e05182ca1b..3706d31e66e17 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -20,7 +20,7 @@ use rustc_session::config::{self, DebugInfo}; use rustc_session::Session; use rustc_span::symbol::Symbol; use rustc_span::{ - BytePos, Pos, SourceFile, SourceFileAndLine, SourceFileHash, Span, StableSourceFileId, + BytePos, Pos, SourceFile, SourceFileAndLine, SourceFileHash, Span, StableSourceFileId, DUMMY_SP, }; use rustc_target::abi::Size; use smallvec::SmallVec; @@ -570,7 +570,12 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { inlined_at: Option<&'ll DILocation>, span: Span, ) -> &'ll DILocation { - let DebugLoc { line, col, .. } = self.lookup_debug_loc(span.lo()); + let (line, col) = if span == DUMMY_SP && !self.sess().target.is_like_msvc { + (0, 0) + } else { + let DebugLoc { line, col, .. } = self.lookup_debug_loc(span.lo()); + (line, col) + }; unsafe { llvm::LLVMRustDIBuilderCreateDebugLocation(line, col, scope, inlined_at) } } From e5878555387e4ced52b3dd6c5f6a04a5f47eeed7 Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Sun, 4 Aug 2024 05:26:50 -0700 Subject: [PATCH 03/12] Use Span::is_dummy(). --- compiler/rustc_codegen_llvm/src/debuginfo/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 3706d31e66e17..57b8fb2fe71b8 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -570,7 +570,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { inlined_at: Option<&'ll DILocation>, span: Span, ) -> &'ll DILocation { - let (line, col) = if span == DUMMY_SP && !self.sess().target.is_like_msvc { + let (line, col) = if span.is_dummy() && !self.sess().target.is_like_msvc { (0, 0) } else { let DebugLoc { line, col, .. } = self.lookup_debug_loc(span.lo()); From 5dc4a1969c6ea5ba0b1d11f9d43045ed5a2be5cc Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Sun, 4 Aug 2024 06:09:55 -0700 Subject: [PATCH 04/12] Fix warning. --- compiler/rustc_codegen_llvm/src/debuginfo/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 57b8fb2fe71b8..66dd653bb2166 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -20,7 +20,7 @@ use rustc_session::config::{self, DebugInfo}; use rustc_session::Session; use rustc_span::symbol::Symbol; use rustc_span::{ - BytePos, Pos, SourceFile, SourceFileAndLine, SourceFileHash, Span, StableSourceFileId, DUMMY_SP, + BytePos, Pos, SourceFile, SourceFileAndLine, SourceFileHash, Span, StableSourceFileId, }; use rustc_target::abi::Size; use smallvec::SmallVec; From 1687c55168f3837506afcd2240a8a0b6eadcc1eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sat, 17 Aug 2024 17:06:26 +0800 Subject: [PATCH 05/12] bootstrap: fix clean's `remove_dir_all` implementation ... by using `std::fs::remove_dir_all`, which handles a bunch of edge cases including read-only files and symlinks which are extremely tricky on Windows. --- src/bootstrap/src/core/build_steps/clean.rs | 93 ++++----------------- 1 file changed, 15 insertions(+), 78 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/clean.rs b/src/bootstrap/src/core/build_steps/clean.rs index f608e5d715e49..bcbe490c36a0f 100644 --- a/src/bootstrap/src/core/build_steps/clean.rs +++ b/src/bootstrap/src/core/build_steps/clean.rs @@ -6,7 +6,6 @@ //! directory unless the `--all` flag is present. use std::fs; -use std::io::{self, ErrorKind}; use std::path::Path; use crate::core::builder::{crate_description, Builder, RunConfig, ShouldRun, Step}; @@ -101,11 +100,11 @@ fn clean(build: &Build, all: bool, stage: Option) { return; } - rm_rf("tmp".as_ref()); + remove_dir_recursive("tmp"); // Clean the entire build directory if all { - rm_rf(&build.out); + remove_dir_recursive(&build.out); return; } @@ -136,17 +135,17 @@ fn clean_specific_stage(build: &Build, stage: u32) { } let path = t!(entry.path().canonicalize()); - rm_rf(&path); + remove_dir_recursive(&path); } } } fn clean_default(build: &Build) { - rm_rf(&build.out.join("tmp")); - rm_rf(&build.out.join("dist")); - rm_rf(&build.out.join("bootstrap").join(".last-warned-change-id")); - rm_rf(&build.out.join("bootstrap-shims-dump")); - rm_rf(&build.out.join("rustfmt.stamp")); + remove_dir_recursive(build.out.join("tmp")); + remove_dir_recursive(build.out.join("dist")); + remove_dir_recursive(build.out.join("bootstrap").join(".last-warned-change-id")); + remove_dir_recursive(build.out.join("bootstrap-shims-dump")); + remove_dir_recursive(build.out.join("rustfmt.stamp")); let mut hosts: Vec<_> = build.hosts.iter().map(|t| build.out.join(t)).collect(); // After cross-compilation, artifacts of the host architecture (which may differ from build.host) @@ -166,78 +165,16 @@ fn clean_default(build: &Build) { continue; } let path = t!(entry.path().canonicalize()); - rm_rf(&path); + remove_dir_recursive(&path); } } } -fn rm_rf(path: &Path) { - match path.symlink_metadata() { - Err(e) => { - if e.kind() == ErrorKind::NotFound { - return; - } - panic!("failed to get metadata for file {}: {}", path.display(), e); - } - Ok(metadata) => { - if metadata.file_type().is_file() || metadata.file_type().is_symlink() { - do_op(path, "remove file", |p| match fs::remove_file(p) { - #[cfg(windows)] - Err(e) - if e.kind() == std::io::ErrorKind::PermissionDenied - && p.file_name().and_then(std::ffi::OsStr::to_str) - == Some("bootstrap.exe") => - { - eprintln!("WARNING: failed to delete '{}'.", p.display()); - Ok(()) - } - r => r, - }); - - return; - } - - for file in t!(fs::read_dir(path)) { - rm_rf(&t!(file).path()); - } - - do_op(path, "remove dir", |p| match fs::remove_dir(p) { - // Check for dir not empty on Windows - // FIXME: Once `ErrorKind::DirectoryNotEmpty` is stabilized, - // match on `e.kind()` instead. - #[cfg(windows)] - Err(e) if e.raw_os_error() == Some(145) => Ok(()), - r => r, - }); - } - }; -} - -fn do_op(path: &Path, desc: &str, mut f: F) -where - F: FnMut(&Path) -> io::Result<()>, -{ - match f(path) { - Ok(()) => {} - // On windows we can't remove a readonly file, and git will often clone files as readonly. - // As a result, we have some special logic to remove readonly files on windows. - // This is also the reason that we can't use things like fs::remove_dir_all(). - #[cfg(windows)] - Err(ref e) if e.kind() == ErrorKind::PermissionDenied => { - let m = t!(path.symlink_metadata()); - let mut p = m.permissions(); - p.set_readonly(false); - t!(fs::set_permissions(path, p)); - f(path).unwrap_or_else(|e| { - // Delete symlinked directories on Windows - if m.file_type().is_symlink() && path.is_dir() && fs::remove_dir(path).is_ok() { - return; - } - panic!("failed to {} {}: {}", desc, path.display(), e); - }); - } - Err(e) => { - panic!("failed to {} {}: {}", desc, path.display(), e); - } +/// Wrapper for [`std::fs::remove_dir_all`] that panics on failure and prints the `path` we failed +/// on. +fn remove_dir_recursive>(path: P) { + let path = path.as_ref(); + if let Err(e) = fs::remove_dir_all(path) { + panic!("failed to `remove_dir_all` at `{}`: {e}", path.display()); } } From 35752cf058047262a9b6e970426db43ffa9ce206 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 19 Aug 2024 07:30:11 -0500 Subject: [PATCH 06/12] Update `library/Cargo.toml` in weekly job Before the workspace split, the library was covered by the weekly `cargo update` cron job. Now that the library has its own workspace, it doesn't get these updates. Add `library/Cargo.toml` to the job so updates happen again. --- .github/workflows/dependencies.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml index 5e54ceea3d7f8..83b92b7fa092f 100644 --- a/.github/workflows/dependencies.yml +++ b/.github/workflows/dependencies.yml @@ -64,6 +64,10 @@ jobs: - name: cargo update # Remove first line that always just says "Updating crates.io index" run: cargo update 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log + - name: cargo update library + run: | + echo -e "\nlibrary dependencies:" >> cargo_update.log + cargo update --manifest-path library/Cargo.toml 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log - name: cargo update rustbook run: | echo -e "\nrustbook dependencies:" >> cargo_update.log @@ -74,6 +78,7 @@ jobs: name: Cargo-lock path: | Cargo.lock + library/Cargo.lock src/tools/rustbook/Cargo.lock retention-days: 1 - name: upload cargo-update log artifact for use in PR @@ -119,7 +124,7 @@ jobs: git config user.name github-actions git config user.email github-actions@github.com git switch --force-create cargo_update - git add ./Cargo.lock ./src/tools/rustbook/Cargo.lock + git add ./Cargo.lock ./library/Cargo.lock ./src/tools/rustbook/Cargo.lock git commit --no-verify --file=commit.txt - name: push From 76fbf0af77d98d60bbc7c2598cb6563e9e1ef7e3 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sun, 18 Aug 2024 22:45:34 +0000 Subject: [PATCH 07/12] Test wholearchive on rust staticlib --- tests/run-make/msvc-wholearchive/c.c | 1 + tests/run-make/msvc-wholearchive/dll.def | 4 ++ tests/run-make/msvc-wholearchive/rmake.rs | 52 ++++++++++++++++++++++ tests/run-make/msvc-wholearchive/static.rs | 9 ++++ 4 files changed, 66 insertions(+) create mode 100644 tests/run-make/msvc-wholearchive/c.c create mode 100644 tests/run-make/msvc-wholearchive/dll.def create mode 100644 tests/run-make/msvc-wholearchive/rmake.rs create mode 100644 tests/run-make/msvc-wholearchive/static.rs diff --git a/tests/run-make/msvc-wholearchive/c.c b/tests/run-make/msvc-wholearchive/c.c new file mode 100644 index 0000000000000..d6847845c6846 --- /dev/null +++ b/tests/run-make/msvc-wholearchive/c.c @@ -0,0 +1 @@ +// This page is intentionally left blank diff --git a/tests/run-make/msvc-wholearchive/dll.def b/tests/run-make/msvc-wholearchive/dll.def new file mode 100644 index 0000000000000..d55819e0d5e9f --- /dev/null +++ b/tests/run-make/msvc-wholearchive/dll.def @@ -0,0 +1,4 @@ +LIBRARY dll +EXPORTS + hello + number diff --git a/tests/run-make/msvc-wholearchive/rmake.rs b/tests/run-make/msvc-wholearchive/rmake.rs new file mode 100644 index 0000000000000..98586fd8cc8bd --- /dev/null +++ b/tests/run-make/msvc-wholearchive/rmake.rs @@ -0,0 +1,52 @@ +//! This is a regression test for #129020 +//! It ensures we can use `/WHOLEARCHIVE` to link a rust staticlib into DLL +//! using the MSVC linker + +//@ only-msvc +// Reason: this is testing the MSVC linker + +use std::path::PathBuf; + +use run_make_support::{cc, cmd, env_var, extra_c_flags, rustc}; + +fn main() { + // Build the staticlib + rustc().crate_type("staticlib").input("static.rs").output("static.lib").run(); + // Build an empty object to pass to the linker. + cc().input("c.c").output("c.obj").args(["-c"]).run(); + + // Find the C toolchain's linker. + let mut linker = PathBuf::from(env_var("CC")); + let linker_flavour = if linker.file_stem().is_some_and(|s| s == "cl") { + linker.set_file_name("link.exe"); + "msvc" + } else if linker.file_stem().is_some_and(|s| s == "clang-cl") { + linker.set_file_name("lld-link.exe"); + "llvm" + } else { + panic!("unknown C toolchain"); + }; + + // As a sanity check, make sure this works without /WHOLEARCHIVE. + // Otherwise the actual test failure may be caused by something else. + cmd(&linker) + .args(["c.obj", "./static.lib", "-dll", "-def:dll.def", "-out:dll.dll"]) + .args(extra_c_flags()) + .run(); + + // FIXME(@ChrisDenton): this doesn't currently work with llvm's lld-link for other reasons. + // May need LLVM patches. + if linker_flavour == "msvc" { + // Link in the staticlib using `/WHOLEARCHIVE` and produce a DLL. + cmd(&linker) + .args([ + "c.obj", + "-WHOLEARCHIVE:./static.lib", + "-dll", + "-def:dll.def", + "-out:dll_whole_archive.dll", + ]) + .args(extra_c_flags()) + .run(); + } +} diff --git a/tests/run-make/msvc-wholearchive/static.rs b/tests/run-make/msvc-wholearchive/static.rs new file mode 100644 index 0000000000000..881c88565737a --- /dev/null +++ b/tests/run-make/msvc-wholearchive/static.rs @@ -0,0 +1,9 @@ +#[no_mangle] +pub extern "C" fn hello() { + println!("Hello world!"); +} + +#[no_mangle] +pub extern "C" fn number() -> u32 { + 42 +} From 3c735a00f70c8c3df737eb18494e9eb9c6196971 Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Mon, 19 Aug 2024 17:10:37 -0700 Subject: [PATCH 08/12] Add a test. --- tests/debuginfo/dummy_span.rs | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 tests/debuginfo/dummy_span.rs diff --git a/tests/debuginfo/dummy_span.rs b/tests/debuginfo/dummy_span.rs new file mode 100644 index 0000000000000..d02eead470fa1 --- /dev/null +++ b/tests/debuginfo/dummy_span.rs @@ -0,0 +1,45 @@ +//@ min-lldb-version: 310 + +//@ compile-flags:-g + +// === GDB TESTS =================================================================================== + +// gdb-command:run 7 + +// gdb-command:next +// gdb-command:next +// gdb-check:[...]#loc1[...] +// gdb-command:next +// gdb-check:[...]#loc2[...] + +// === LLDB TESTS ================================================================================== + +// lldb-command:run 7 + +// lldb-command:next +// lldb-command:next +// lldb-command:frame select +// lldb-check:[...]#loc1[...] +// lldb-command:next +// lldb-command:frame select +// lldb-check:[...]#loc2[...] + +use std::env; +use std::num::ParseIntError; + +fn main() -> Result<(), ParseIntError> { + let args = env::args(); + let number_str = args.skip(1).next().unwrap(); + let number = number_str.parse::()?; + zzz(); // #break + if number % 7 == 0 { + // This generates code with a dummy span for + // some reason. If that ever changes this + // test will not test what it wants to test. + return Ok(()); // #loc1 + } + println!("{}", number); + Ok(()) +} // #loc2 + +fn zzz() { () } From 4e9725cd2f5327f65f881c59d6bcbae46308318e Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Mon, 19 Aug 2024 17:13:30 -0700 Subject: [PATCH 09/12] Add a comment. --- compiler/rustc_codegen_llvm/src/debuginfo/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 66dd653bb2166..3fbaebe28aaec 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -570,6 +570,11 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { inlined_at: Option<&'ll DILocation>, span: Span, ) -> &'ll DILocation { + // When emitting debugging information, DWARF (i.e. everything but MSVC) + // treats line 0 as a magic value meaning that the code could not be + // attributed to any line in the source. That's also exactly what dummy + // spans are. Make that equivalence here, rather than passing dummy spans + // to lookup_debug_loc, which will return line 1 for them. let (line, col) = if span.is_dummy() && !self.sess().target.is_like_msvc { (0, 0) } else { From 9d7574f9b0925a5b681e19e81f96ad8d5f2a5be2 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 19 Aug 2024 16:16:34 -0700 Subject: [PATCH 10/12] rustdoc: animate the `:target` highlight This approach is, roughly, based on how Discourse does it. It came up while discussing some other possible sidebar changes, as a design that made rapid scanning easier while avoiding the inherent trade-offs in summarizing. --- src/librustdoc/html/static/css/rustdoc.css | 13 +++++++++++++ tests/rustdoc-gui/target.goml | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index eb5a5d935e202..28df8d3f011fe 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1547,10 +1547,23 @@ instead, we check that it's not a "finger" cursor. margin-left: 24px; } +@keyframes targetfadein { + from { + background-color: var(--main-background-color); + } + 10% { + background-color: var(--target-border-color); + } + to { + background-color: var(--target-background-color); + } +} + :target { padding-right: 3px; background-color: var(--target-background-color); border-right: 3px solid var(--target-border-color); + animation: 0.65s cubic-bezier(0, 0, 0.1, 1.0) 0.1s targetfadein; } .code-header a.tooltip { diff --git a/tests/rustdoc-gui/target.goml b/tests/rustdoc-gui/target.goml index 82bd34ed2746e..92846f8e01d27 100644 --- a/tests/rustdoc-gui/target.goml +++ b/tests/rustdoc-gui/target.goml @@ -11,7 +11,7 @@ define-function: ( [theme, background, border], block { call-function: ("switch-theme", {"theme": |theme|}) - assert-css: ("#method\.a_method:target", { + wait-for-css: ("#method\.a_method:target", { "background-color": |background|, "border-right": "3px solid " + |border|, }) From 40af2143f19c3f8fcd32513b0761198b64465242 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Mon, 19 Aug 2024 17:33:24 +0000 Subject: [PATCH 11/12] Make import libraries compatible with wholearchive --- Cargo.lock | 4 ++-- compiler/rustc_codegen_ssa/Cargo.toml | 2 +- compiler/rustc_codegen_ssa/src/back/archive.rs | 6 +++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3ad21b0abf920..084723ec3a6a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -205,9 +205,9 @@ dependencies = [ [[package]] name = "ar_archive_writer" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de11a9d32db3327f981143bdf699ade4d637c6887b13b97e6e91a9154666963c" +checksum = "01667f6f40216b9a0b2945e05fed5f1ad0ab6470e69cb9378001e37b1c0668e4" dependencies = [ "object 0.36.2", ] diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 0af34a1b9fa62..779aeb721843e 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start -ar_archive_writer = "0.4.0" +ar_archive_writer = "0.4.2" arrayvec = { version = "0.7", default-features = false } bitflags = "2.4.1" cc = "1.0.90" diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index 38a440a707a23..c8c1bd3e8f9c3 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -108,7 +108,11 @@ pub trait ArchiveBuilderBuilder { &exports, machine, !sess.target.is_like_msvc, - /*comdat=*/ false, + // Enable compatibility with MSVC's `/WHOLEARCHIVE` flag. + // Without this flag a duplicate symbol error would be emitted + // when linking a rust staticlib using `/WHOLEARCHIVE`. + // See #129020 + true, ) { sess.dcx() .emit_fatal(ErrorCreatingImportLibrary { lib_name, error: error.to_string() }); From 0f5c6eaccc3259c3ce182544077077f1248a7c2e Mon Sep 17 00:00:00 2001 From: beetrees Date: Wed, 21 Aug 2024 02:43:12 +0100 Subject: [PATCH 12/12] Make `ArgAbi::make_indirect_force` more specific --- compiler/rustc_target/src/abi/call/mod.rs | 18 ++++++++++++++---- compiler/rustc_target/src/abi/call/powerpc.rs | 2 +- compiler/rustc_target/src/abi/call/s390x.rs | 2 +- compiler/rustc_target/src/abi/call/sparc64.rs | 2 +- .../rustc_target/src/abi/call/x86_win64.rs | 2 +- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 25e4d70945b2c..c1ddfcb2f9090 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -642,7 +642,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> { pub fn make_indirect(&mut self) { match self.mode { PassMode::Direct(_) | PassMode::Pair(_, _) => { - self.make_indirect_force(); + self.mode = Self::indirect_pass_mode(&self.layout); } PassMode::Indirect { attrs: _, meta_attrs: _, on_stack: false } => { // already indirect @@ -652,9 +652,19 @@ impl<'a, Ty> ArgAbi<'a, Ty> { } } - /// Same as make_indirect, but doesn't check the current `PassMode`. - pub fn make_indirect_force(&mut self) { - self.mode = Self::indirect_pass_mode(&self.layout); + /// Same as `make_indirect`, but for arguments that are ignored. Only needed for ABIs that pass + /// ZSTs indirectly. + pub fn make_indirect_from_ignore(&mut self) { + match self.mode { + PassMode::Ignore => { + self.mode = Self::indirect_pass_mode(&self.layout); + } + PassMode::Indirect { attrs: _, meta_attrs: _, on_stack: false } => { + // already indirect + return; + } + _ => panic!("Tried to make {:?} indirect (expected `PassMode::Ignore`)", self.mode), + } } /// Pass this argument indirectly, by placing it at a fixed stack offset. diff --git a/compiler/rustc_target/src/abi/call/powerpc.rs b/compiler/rustc_target/src/abi/call/powerpc.rs index cb80d64c94304..8f67f57cd2b3e 100644 --- a/compiler/rustc_target/src/abi/call/powerpc.rs +++ b/compiler/rustc_target/src/abi/call/powerpc.rs @@ -16,7 +16,7 @@ fn classify_arg(cx: &impl HasTargetSpec, arg: &mut ArgAbi<'_, Ty>) { && matches!(&*cx.target_spec().env, "gnu" | "musl" | "uclibc") && arg.layout.is_zst() { - arg.make_indirect_force(); + arg.make_indirect_from_ignore(); } return; } diff --git a/compiler/rustc_target/src/abi/call/s390x.rs b/compiler/rustc_target/src/abi/call/s390x.rs index 7dcbb3e4a9e9b..901ce139c7be1 100644 --- a/compiler/rustc_target/src/abi/call/s390x.rs +++ b/compiler/rustc_target/src/abi/call/s390x.rs @@ -28,7 +28,7 @@ where && matches!(&*cx.target_spec().env, "gnu" | "musl" | "uclibc") && arg.layout.is_zst() { - arg.make_indirect_force(); + arg.make_indirect_from_ignore(); } return; } diff --git a/compiler/rustc_target/src/abi/call/sparc64.rs b/compiler/rustc_target/src/abi/call/sparc64.rs index 3b2bf9b3187f1..311691d8efb9b 100644 --- a/compiler/rustc_target/src/abi/call/sparc64.rs +++ b/compiler/rustc_target/src/abi/call/sparc64.rs @@ -225,7 +225,7 @@ where && matches!(&*cx.target_spec().env, "gnu" | "musl" | "uclibc") && arg.layout.is_zst() { - arg.make_indirect_force(); + arg.make_indirect_from_ignore(); } return; } diff --git a/compiler/rustc_target/src/abi/call/x86_win64.rs b/compiler/rustc_target/src/abi/call/x86_win64.rs index 6ca01cf84eaa4..720707ef53f95 100644 --- a/compiler/rustc_target/src/abi/call/x86_win64.rs +++ b/compiler/rustc_target/src/abi/call/x86_win64.rs @@ -43,7 +43,7 @@ pub fn compute_abi_info(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) && cx.target_spec().env == "gnu" && arg.layout.is_zst() { - arg.make_indirect_force(); + arg.make_indirect_from_ignore(); } continue; }