From 78caecf8f30dbdbfcb6e0fda25edc72b3e4d04a5 Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Sat, 3 Aug 2024 21:04:19 -0700 Subject: [PATCH 01/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 02/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 03/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 8a61674559c58b9cfcc7d297425b33520fcf39fa Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Mon, 5 Aug 2024 09:48:26 +0100 Subject: [PATCH 04/12] WASI fixing unsafe_op_in_unsafe_fn for std::{os, sys} --- library/std/src/os/wasi/fs.rs | 1 - library/std/src/os/wasi/mod.rs | 2 +- library/std/src/os/wasip2/mod.rs | 1 + library/std/src/sys/pal/wasi/args.rs | 2 +- library/std/src/sys/pal/wasi/env.rs | 2 ++ library/std/src/sys/pal/wasi/fd.rs | 2 +- library/std/src/sys/pal/wasi/fs.rs | 2 +- library/std/src/sys/pal/wasi/helpers.rs | 2 ++ library/std/src/sys/pal/wasi/io.rs | 2 +- library/std/src/sys/pal/wasi/net.rs | 2 +- library/std/src/sys/pal/wasi/os.rs | 2 +- library/std/src/sys/pal/wasi/stdio.rs | 2 +- library/std/src/sys/pal/wasi/thread.rs | 18 ++++++++++-------- library/std/src/sys/pal/wasi/time.rs | 2 +- 14 files changed, 24 insertions(+), 18 deletions(-) diff --git a/library/std/src/os/wasi/fs.rs b/library/std/src/os/wasi/fs.rs index a58ca543d6777..9ec3e387e2ba9 100644 --- a/library/std/src/os/wasi/fs.rs +++ b/library/std/src/os/wasi/fs.rs @@ -2,7 +2,6 @@ //! //! [`std::fs`]: crate::fs -#![deny(unsafe_op_in_unsafe_fn)] #![unstable(feature = "wasi_ext", issue = "71213")] // Used for `File::read` on intra-doc links diff --git a/library/std/src/os/wasi/mod.rs b/library/std/src/os/wasi/mod.rs index e36b93e60ea1c..33b50c9e53b8f 100644 --- a/library/std/src/os/wasi/mod.rs +++ b/library/std/src/os/wasi/mod.rs @@ -30,7 +30,7 @@ #![cfg_attr(not(target_env = "p2"), stable(feature = "rust1", since = "1.0.0"))] #![cfg_attr(target_env = "p2", unstable(feature = "wasip2", issue = "none"))] -#![deny(unsafe_op_in_unsafe_fn)] +#![forbid(unsafe_op_in_unsafe_fn)] #![doc(cfg(target_os = "wasi"))] pub mod ffi; diff --git a/library/std/src/os/wasip2/mod.rs b/library/std/src/os/wasip2/mod.rs index 1d44dd72814b8..809a288f20d04 100644 --- a/library/std/src/os/wasip2/mod.rs +++ b/library/std/src/os/wasip2/mod.rs @@ -2,4 +2,5 @@ //! //! This module is currently empty, but will be filled over time as wasi-libc support for WASI Preview 2 is stabilized. +#![forbid(unsafe_op_in_unsafe_fn)] #![stable(feature = "raw_ext", since = "1.1.0")] diff --git a/library/std/src/sys/pal/wasi/args.rs b/library/std/src/sys/pal/wasi/args.rs index 6b6d1b8ff4e2e..52cfa202af825 100644 --- a/library/std/src/sys/pal/wasi/args.rs +++ b/library/std/src/sys/pal/wasi/args.rs @@ -1,4 +1,4 @@ -#![deny(unsafe_op_in_unsafe_fn)] +#![forbid(unsafe_op_in_unsafe_fn)] use crate::ffi::{CStr, OsStr, OsString}; use crate::os::wasi::ffi::OsStrExt; diff --git a/library/std/src/sys/pal/wasi/env.rs b/library/std/src/sys/pal/wasi/env.rs index 730e356d7fe95..8d44498267360 100644 --- a/library/std/src/sys/pal/wasi/env.rs +++ b/library/std/src/sys/pal/wasi/env.rs @@ -1,3 +1,5 @@ +#![forbid(unsafe_op_in_unsafe_fn)] + pub mod os { pub const FAMILY: &str = ""; pub const OS: &str = ""; diff --git a/library/std/src/sys/pal/wasi/fd.rs b/library/std/src/sys/pal/wasi/fd.rs index 8966e4b80ad37..19b60157e2e00 100644 --- a/library/std/src/sys/pal/wasi/fd.rs +++ b/library/std/src/sys/pal/wasi/fd.rs @@ -1,4 +1,4 @@ -#![deny(unsafe_op_in_unsafe_fn)] +#![forbid(unsafe_op_in_unsafe_fn)] #![allow(dead_code)] use super::err2io; diff --git a/library/std/src/sys/pal/wasi/fs.rs b/library/std/src/sys/pal/wasi/fs.rs index 11900886f0b5c..6a97621ad50a5 100644 --- a/library/std/src/sys/pal/wasi/fs.rs +++ b/library/std/src/sys/pal/wasi/fs.rs @@ -1,4 +1,4 @@ -#![deny(unsafe_op_in_unsafe_fn)] +#![forbid(unsafe_op_in_unsafe_fn)] use super::fd::WasiFd; use crate::ffi::{CStr, OsStr, OsString}; diff --git a/library/std/src/sys/pal/wasi/helpers.rs b/library/std/src/sys/pal/wasi/helpers.rs index 4b770ee23bc5d..d047bf2fce857 100644 --- a/library/std/src/sys/pal/wasi/helpers.rs +++ b/library/std/src/sys/pal/wasi/helpers.rs @@ -1,3 +1,5 @@ +#![forbid(unsafe_op_in_unsafe_fn)] + use crate::{io as std_io, mem}; #[inline] diff --git a/library/std/src/sys/pal/wasi/io.rs b/library/std/src/sys/pal/wasi/io.rs index 2cd45df88fad1..b7c2f03daa048 100644 --- a/library/std/src/sys/pal/wasi/io.rs +++ b/library/std/src/sys/pal/wasi/io.rs @@ -1,4 +1,4 @@ -#![deny(unsafe_op_in_unsafe_fn)] +#![forbid(unsafe_op_in_unsafe_fn)] use crate::marker::PhantomData; use crate::os::fd::{AsFd, AsRawFd}; diff --git a/library/std/src/sys/pal/wasi/net.rs b/library/std/src/sys/pal/wasi/net.rs index b4cf94c8781ec..a648679982812 100644 --- a/library/std/src/sys/pal/wasi/net.rs +++ b/library/std/src/sys/pal/wasi/net.rs @@ -1,4 +1,4 @@ -#![deny(unsafe_op_in_unsafe_fn)] +#![forbid(unsafe_op_in_unsafe_fn)] use super::err2io; use super::fd::WasiFd; diff --git a/library/std/src/sys/pal/wasi/os.rs b/library/std/src/sys/pal/wasi/os.rs index f5b17d9df94b4..f7701360f5a9c 100644 --- a/library/std/src/sys/pal/wasi/os.rs +++ b/library/std/src/sys/pal/wasi/os.rs @@ -1,4 +1,4 @@ -#![deny(unsafe_op_in_unsafe_fn)] +#![forbid(unsafe_op_in_unsafe_fn)] use core::slice::memchr; diff --git a/library/std/src/sys/pal/wasi/stdio.rs b/library/std/src/sys/pal/wasi/stdio.rs index 4cc0e4ed5a45a..ca49f871e1957 100644 --- a/library/std/src/sys/pal/wasi/stdio.rs +++ b/library/std/src/sys/pal/wasi/stdio.rs @@ -1,4 +1,4 @@ -#![deny(unsafe_op_in_unsafe_fn)] +#![forbid(unsafe_op_in_unsafe_fn)] use super::fd::WasiFd; use crate::io::{self, IoSlice, IoSliceMut}; diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs index c37acd8dfeeb7..31c9cbd4699bd 100644 --- a/library/std/src/sys/pal/wasi/thread.rs +++ b/library/std/src/sys/pal/wasi/thread.rs @@ -1,3 +1,5 @@ +#![forbid(unsafe_op_in_unsafe_fn)] + use crate::ffi::CStr; use crate::num::NonZero; use crate::sys::unsupported; @@ -73,13 +75,13 @@ impl Thread { if #[cfg(target_feature = "atomics")] { pub unsafe fn new(stack: usize, p: Box) -> io::Result { let p = Box::into_raw(Box::new(p)); - let mut native: libc::pthread_t = mem::zeroed(); - let mut attr: libc::pthread_attr_t = mem::zeroed(); - assert_eq!(libc::pthread_attr_init(&mut attr), 0); + let mut native: libc::pthread_t = unsafe { mem::zeroed() }; + let mut attr: libc::pthread_attr_t = unsafe { mem::zeroed() }; + assert_eq!(unsafe { libc::pthread_attr_init(&mut attr) }, 0); let stack_size = cmp::max(stack, DEFAULT_MIN_STACK_SIZE); - match libc::pthread_attr_setstacksize(&mut attr, stack_size) { + match unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) } { 0 => {} n => { assert_eq!(n, libc::EINVAL); @@ -90,20 +92,20 @@ impl Thread { let page_size = os::page_size(); let stack_size = (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1); - assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0); + assert_eq!(unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) }, 0); } }; - let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _); + let ret = unsafe { libc::pthread_create(&mut native, &attr, thread_start, p as *mut _) }; // Note: if the thread creation fails and this assert fails, then p will // be leaked. However, an alternative design could cause double-free // which is clearly worse. - assert_eq!(libc::pthread_attr_destroy(&mut attr), 0); + assert_eq!(unsafe {libc::pthread_attr_destroy(&mut attr) }, 0); return if ret != 0 { // The thread failed to start and as a result p was not consumed. Therefore, it is // safe to reconstruct the box so that it gets deallocated. - drop(Box::from_raw(p)); + unsafe { drop(Box::from_raw(p)); } Err(io::Error::from_raw_os_error(ret)) } else { Ok(Thread { id: native }) diff --git a/library/std/src/sys/pal/wasi/time.rs b/library/std/src/sys/pal/wasi/time.rs index 016b06efbdc63..0d8d0b59ac14a 100644 --- a/library/std/src/sys/pal/wasi/time.rs +++ b/library/std/src/sys/pal/wasi/time.rs @@ -1,4 +1,4 @@ -#![deny(unsafe_op_in_unsafe_fn)] +#![forbid(unsafe_op_in_unsafe_fn)] use crate::time::Duration; 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 e424e7fcaacf1bd26584a2ecf50299c0058fbba5 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 20 Aug 2024 14:04:48 -0700 Subject: [PATCH 12/12] Avoid extra `cast()`s after `CStr::as_ptr()` These used to be `&str` literals that did need a pointer cast, but that became a no-op after switching to `c""` literals in #118566. --- compiler/rustc_codegen_llvm/src/allocator.rs | 2 +- compiler/rustc_codegen_llvm/src/back/lto.rs | 2 +- compiler/rustc_codegen_llvm/src/back/write.rs | 8 +++---- compiler/rustc_codegen_llvm/src/consts.rs | 2 +- compiler/rustc_codegen_llvm/src/context.rs | 22 +++++++++---------- .../rustc_codegen_llvm/src/debuginfo/gdb.rs | 5 ++--- .../src/debuginfo/metadata.rs | 2 +- .../rustc_codegen_llvm/src/debuginfo/mod.rs | 6 ++--- library/std/src/sys/pal/unix/mod.rs | 4 ++-- 9 files changed, 26 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index 8fb3108279391..b4f3784a31abd 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -149,7 +149,7 @@ fn create_wrapper_function( } llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden); - let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, c"entry".as_ptr().cast()); + let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, c"entry".as_ptr()); let llbuilder = llvm::LLVMCreateBuilderInContext(llcx); llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb); diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index f68155f523a6e..aac446f3149c4 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -616,7 +616,7 @@ pub(crate) fn run_pass_manager( llvm::LLVMRustAddModuleFlagU32( module.module_llvm.llmod(), llvm::LLVMModFlagBehavior::Error, - c"LTOPostLink".as_ptr().cast(), + c"LTOPostLink".as_ptr(), 1, ); } diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index a1f2433ab6f3b..51b02891d026b 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -1031,7 +1031,7 @@ unsafe fn embed_bitcode( let llglobal = llvm::LLVMAddGlobal( llmod, common::val_ty(llconst), - c"rustc.embedded.module".as_ptr().cast(), + c"rustc.embedded.module".as_ptr(), ); llvm::LLVMSetInitializer(llglobal, llconst); @@ -1044,7 +1044,7 @@ unsafe fn embed_bitcode( let llglobal = llvm::LLVMAddGlobal( llmod, common::val_ty(llconst), - c"rustc.embedded.cmdline".as_ptr().cast(), + c"rustc.embedded.cmdline".as_ptr(), ); llvm::LLVMSetInitializer(llglobal, llconst); let section = if is_apple { @@ -1054,7 +1054,7 @@ unsafe fn embed_bitcode( } else { c".llvmcmd" }; - llvm::LLVMSetSection(llglobal, section.as_ptr().cast()); + llvm::LLVMSetSection(llglobal, section.as_ptr()); llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage); } else { // We need custom section flags, so emit module-level inline assembly. @@ -1107,7 +1107,7 @@ fn create_msvc_imps( .collect::>(); for (imp_name, val) in globals { - let imp = llvm::LLVMAddGlobal(llmod, ptr_ty, imp_name.as_ptr().cast()); + let imp = llvm::LLVMAddGlobal(llmod, ptr_ty, imp_name.as_ptr()); llvm::LLVMSetInitializer(imp, val); llvm::LLVMRustSetLinkage(imp, llvm::Linkage::ExternalLinkage); } diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 75b298f14ca1e..a764b263ec7fd 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -525,7 +525,7 @@ impl<'ll> CodegenCx<'ll, '_> { let val = llvm::LLVMMetadataAsValue(self.llcx, meta); llvm::LLVMAddNamedMetadataOperand( self.llmod, - c"wasm.custom_sections".as_ptr().cast(), + c"wasm.custom_sections".as_ptr(), val, ); } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 1fd9f9e811671..8862f139affb8 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -207,7 +207,7 @@ pub unsafe fn create_module<'ll>( // If skipping the PLT is enabled, we need to add some module metadata // to ensure intrinsic calls don't use it. if !sess.needs_plt() { - let avoid_plt = c"RtLibUseGOT".as_ptr().cast(); + let avoid_plt = c"RtLibUseGOT".as_ptr(); unsafe { llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Warning, avoid_plt, 1); } @@ -215,7 +215,7 @@ pub unsafe fn create_module<'ll>( // Enable canonical jump tables if CFI is enabled. (See https://reviews.llvm.org/D65629.) if sess.is_sanitizer_cfi_canonical_jump_tables_enabled() && sess.is_sanitizer_cfi_enabled() { - let canonical_jump_tables = c"CFI Canonical Jump Tables".as_ptr().cast(); + let canonical_jump_tables = c"CFI Canonical Jump Tables".as_ptr(); unsafe { llvm::LLVMRustAddModuleFlagU32( llmod, @@ -228,7 +228,7 @@ pub unsafe fn create_module<'ll>( // Enable LTO unit splitting if specified or if CFI is enabled. (See https://reviews.llvm.org/D53891.) if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() { - let enable_split_lto_unit = c"EnableSplitLTOUnit".as_ptr().cast(); + let enable_split_lto_unit = c"EnableSplitLTOUnit".as_ptr(); unsafe { llvm::LLVMRustAddModuleFlagU32( llmod, @@ -241,7 +241,7 @@ pub unsafe fn create_module<'ll>( // Add "kcfi" module flag if KCFI is enabled. (See https://reviews.llvm.org/D119296.) if sess.is_sanitizer_kcfi_enabled() { - let kcfi = c"kcfi".as_ptr().cast(); + let kcfi = c"kcfi".as_ptr(); unsafe { llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1); } @@ -280,26 +280,26 @@ pub unsafe fn create_module<'ll>( llvm::LLVMRustAddModuleFlagU32( llmod, llvm::LLVMModFlagBehavior::Min, - c"branch-target-enforcement".as_ptr().cast(), + c"branch-target-enforcement".as_ptr(), bti.into(), ); llvm::LLVMRustAddModuleFlagU32( llmod, llvm::LLVMModFlagBehavior::Min, - c"sign-return-address".as_ptr().cast(), + c"sign-return-address".as_ptr(), pac_ret.is_some().into(), ); let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A }); llvm::LLVMRustAddModuleFlagU32( llmod, llvm::LLVMModFlagBehavior::Min, - c"sign-return-address-all".as_ptr().cast(), + c"sign-return-address-all".as_ptr(), pac_opts.leaf.into(), ); llvm::LLVMRustAddModuleFlagU32( llmod, llvm::LLVMModFlagBehavior::Min, - c"sign-return-address-with-bkey".as_ptr().cast(), + c"sign-return-address-with-bkey".as_ptr(), u32::from(pac_opts.key == PAuthKey::B), ); } @@ -317,7 +317,7 @@ pub unsafe fn create_module<'ll>( llvm::LLVMRustAddModuleFlagU32( llmod, llvm::LLVMModFlagBehavior::Override, - c"cf-protection-branch".as_ptr().cast(), + c"cf-protection-branch".as_ptr(), 1, ); } @@ -327,7 +327,7 @@ pub unsafe fn create_module<'ll>( llvm::LLVMRustAddModuleFlagU32( llmod, llvm::LLVMModFlagBehavior::Override, - c"cf-protection-return".as_ptr().cast(), + c"cf-protection-return".as_ptr(), 1, ); } @@ -338,7 +338,7 @@ pub unsafe fn create_module<'ll>( llvm::LLVMRustAddModuleFlagU32( llmod, llvm::LLVMModFlagBehavior::Error, - c"Virtual Function Elim".as_ptr().cast(), + c"Virtual Function Elim".as_ptr(), 1, ); } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs index 5a08f2f00e5be..e91bcea16a26c 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs @@ -34,8 +34,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global<'ll>(cx: &CodegenCx<'ll, ' let c_section_var_name = c"__rustc_debug_gdb_scripts_section__"; let section_var_name = c_section_var_name.to_str().unwrap(); - let section_var = - unsafe { llvm::LLVMGetNamedGlobal(cx.llmod, c_section_var_name.as_ptr().cast()) }; + let section_var = unsafe { llvm::LLVMGetNamedGlobal(cx.llmod, c_section_var_name.as_ptr()) }; section_var.unwrap_or_else(|| { let mut section_contents = Vec::new(); @@ -70,7 +69,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global<'ll>(cx: &CodegenCx<'ll, ' let section_var = cx .define_global(section_var_name, llvm_type) .unwrap_or_else(|| bug!("symbol `{}` is already defined", section_var_name)); - llvm::LLVMSetSection(section_var, c".debug_gdb_scripts".as_ptr().cast()); + llvm::LLVMSetSection(section_var, c".debug_gdb_scripts".as_ptr()); llvm::LLVMSetInitializer(section_var, cx.const_bytes(section_contents)); llvm::LLVMSetGlobalConstant(section_var, llvm::True); llvm::LLVMSetUnnamedAddress(section_var, llvm::UnnamedAddr::Global); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 87bea22d8ddaf..30f90bada9adc 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -952,7 +952,7 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>( producer.as_ptr().cast(), producer.len(), tcx.sess.opts.optimize != config::OptLevel::No, - c"".as_ptr().cast(), + c"".as_ptr(), 0, // NB: this doesn't actually have any perceptible effect, it seems. LLVM will instead // put the path supplied to `MCSplitDwarfFile` into the debug info of the final diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index b23e05182ca1b..a179254c9c08f 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -109,7 +109,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> { llvm::LLVMRustAddModuleFlagU32( self.llmod, llvm::LLVMModFlagBehavior::Warning, - c"Dwarf Version".as_ptr().cast(), + c"Dwarf Version".as_ptr(), dwarf_version, ); } else { @@ -117,7 +117,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> { llvm::LLVMRustAddModuleFlagU32( self.llmod, llvm::LLVMModFlagBehavior::Warning, - c"CodeView".as_ptr().cast(), + c"CodeView".as_ptr(), 1, ) } @@ -126,7 +126,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> { llvm::LLVMRustAddModuleFlagU32( self.llmod, llvm::LLVMModFlagBehavior::Warning, - c"Debug Info Version".as_ptr().cast(), + c"Debug Info Version".as_ptr(), llvm::LLVMRustDebugMetadataVersion(), ); } diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index b62129f4cdd26..10df3306f9251 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -116,7 +116,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { if pfd.revents & libc::POLLNVAL == 0 { continue; } - if open64(c"/dev/null".as_ptr().cast(), libc::O_RDWR, 0) == -1 { + if open64(c"/dev/null".as_ptr(), libc::O_RDWR, 0) == -1 { // If the stream is closed but we failed to reopen it, abort the // process. Otherwise we wouldn't preserve the safety of // operations on the corresponding Rust object Stdin, Stdout, or @@ -147,7 +147,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { use crate::sys::os::errno; for fd in 0..3 { if libc::fcntl(fd, libc::F_GETFD) == -1 && errno() == libc::EBADF { - if open64(c"/dev/null".as_ptr().cast(), libc::O_RDWR, 0) == -1 { + if open64(c"/dev/null".as_ptr(), libc::O_RDWR, 0) == -1 { // If the stream is closed but we failed to reopen it, abort the // process. Otherwise we wouldn't preserve the safety of // operations on the corresponding Rust object Stdin, Stdout, or