Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Rollup of 6 pull requests #129728

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 15 additions & 46 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::BTreeSet;
use std::ffi::OsString;
use std::fs::{read, File, OpenOptions};
use std::io::{BufWriter, Write};
use std::ops::Deref;
use std::ops::{ControlFlow, Deref};
use std::path::{Path, PathBuf};
use std::process::{ExitStatus, Output, Stdio};
use std::{env, fmt, fs, io, mem, str};
Expand All @@ -18,8 +18,8 @@ use rustc_data_structures::temp_dir::MaybeTempDir;
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, FatalError};
use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_metadata::find_native_static_library;
use rustc_metadata::fs::{copy_to_stdout, emit_wrapper_file, METADATA_FILENAME};
use rustc_metadata::{find_native_static_library, walk_native_lib_search_dirs};
use rustc_middle::bug;
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
use rustc_middle::middle::dependency_format::Linkage;
Expand Down Expand Up @@ -2110,50 +2110,19 @@ fn add_library_search_dirs(
return;
}

// Library search paths explicitly supplied by user (`-L` on the command line).
for search_path in sess.target_filesearch(PathKind::Native).cli_search_paths() {
cmd.include_path(&fix_windows_verbatim_for_gcc(&search_path.dir));
}
for search_path in sess.target_filesearch(PathKind::Framework).cli_search_paths() {
// Contrary to the `-L` docs only framework-specific paths are considered here.
if search_path.kind != PathKind::All {
cmd.framework_path(&search_path.dir);
}
}

// The toolchain ships some native library components and self-contained linking was enabled.
// Add the self-contained library directory to search paths.
if self_contained_components.intersects(
LinkSelfContainedComponents::LIBC
| LinkSelfContainedComponents::UNWIND
| LinkSelfContainedComponents::MINGW,
) {
let lib_path = sess.target_tlib_path.dir.join("self-contained");
cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
}

// Toolchains for some targets may ship `libunwind.a`, but place it into the main sysroot
// library directory instead of the self-contained directories.
// Sanitizer libraries have the same issue and are also linked by name on Apple targets.
// The targets here should be in sync with `copy_third_party_objects` in bootstrap.
// FIXME: implement `-Clink-self-contained=+/-unwind,+/-sanitizers`, move the shipped libunwind
// and sanitizers to self-contained directory, and stop adding this search path.
if sess.target.vendor == "fortanix"
|| sess.target.os == "linux"
|| sess.target.os == "fuchsia"
|| sess.target.is_like_osx && !sess.opts.unstable_opts.sanitizer.is_empty()
{
cmd.include_path(&fix_windows_verbatim_for_gcc(&sess.target_tlib_path.dir));
}

// Mac Catalyst uses the macOS SDK, but to link to iOS-specific frameworks
// we must have the support library stubs in the library search path (#121430).
if let Some(sdk_root) = apple_sdk_root
&& sess.target.llvm_target.contains("macabi")
{
cmd.include_path(&sdk_root.join("System/iOSSupport/usr/lib"));
cmd.framework_path(&sdk_root.join("System/iOSSupport/System/Library/Frameworks"));
}
walk_native_lib_search_dirs(
sess,
self_contained_components,
apple_sdk_root,
|dir, is_framework| {
if is_framework {
cmd.framework_path(dir);
} else {
cmd.include_path(&fix_windows_verbatim_for_gcc(dir));
}
ControlFlow::<()>::Continue(())
},
);
}

/// Add options making relocation sections in the produced ELF files read-only
Expand Down
14 changes: 10 additions & 4 deletions compiler/rustc_codegen_ssa/src/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::{env, iter, mem, str};

use cc::windows_registry;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_metadata::find_native_static_library;
use rustc_metadata::{find_native_static_library, try_find_native_static_library};
use rustc_middle::bug;
use rustc_middle::middle::dependency_format::Linkage;
use rustc_middle::middle::exported_symbols;
Expand Down Expand Up @@ -891,9 +891,15 @@ impl<'a> Linker for MsvcLinker<'a> {
}

fn link_staticlib_by_name(&mut self, name: &str, verbatim: bool, whole_archive: bool) {
let prefix = if whole_archive { "/WHOLEARCHIVE:" } else { "" };
let suffix = if verbatim { "" } else { ".lib" };
self.link_arg(format!("{prefix}{name}{suffix}"));
// On MSVC-like targets rustc supports static libraries using alternative naming
// scheme (`libfoo.a`) unsupported by linker, search for such libraries manually.
if let Some(path) = try_find_native_static_library(self.sess, name, verbatim) {
self.link_staticlib_by_path(&path, whole_archive);
} else {
let prefix = if whole_archive { "/WHOLEARCHIVE:" } else { "" };
let suffix = if verbatim { "" } else { ".lib" };
self.link_arg(format!("{prefix}{name}{suffix}"));
}
}

fn link_staticlib_by_path(&mut self, path: &Path, whole_archive: bool) {
Expand Down
25 changes: 13 additions & 12 deletions compiler/rustc_lint/src/foreign_modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,6 @@ fn structurally_same_type_impl<'tcx>(
} else {
// Do a full, depth-first comparison between the two.
use rustc_type_ir::TyKind::*;
let a_kind = a.kind();
let b_kind = b.kind();

let compare_layouts = |a, b| -> Result<bool, &'tcx LayoutError<'tcx>> {
debug!("compare_layouts({:?}, {:?})", a, b);
Expand All @@ -281,12 +279,11 @@ fn structurally_same_type_impl<'tcx>(
Ok(a_layout == b_layout)
};

#[allow(rustc::usage_of_ty_tykind)]
let is_primitive_or_pointer =
|kind: &ty::TyKind<'_>| kind.is_primitive() || matches!(kind, RawPtr(..) | Ref(..));
|ty: Ty<'tcx>| ty.is_primitive() || matches!(ty.kind(), RawPtr(..) | Ref(..));

ensure_sufficient_stack(|| {
match (a_kind, b_kind) {
match (a.kind(), b.kind()) {
(Adt(a_def, _), Adt(b_def, _)) => {
// We can immediately rule out these types as structurally same if
// their layouts differ.
Expand Down Expand Up @@ -382,17 +379,21 @@ fn structurally_same_type_impl<'tcx>(

// An Adt and a primitive or pointer type. This can be FFI-safe if non-null
// enum layout optimisation is being applied.
(Adt(..), other_kind) | (other_kind, Adt(..))
if is_primitive_or_pointer(other_kind) =>
{
let (primitive, adt) =
if is_primitive_or_pointer(a.kind()) { (a, b) } else { (b, a) };
if let Some(ty) = types::repr_nullable_ptr(tcx, param_env, adt, ckind) {
ty == primitive
(Adt(..), _) if is_primitive_or_pointer(b) => {
if let Some(ty) = types::repr_nullable_ptr(tcx, param_env, a, ckind) {
ty == b
} else {
compare_layouts(a, b).unwrap_or(false)
}
}
(_, Adt(..)) if is_primitive_or_pointer(a) => {
if let Some(ty) = types::repr_nullable_ptr(tcx, param_env, b, ckind) {
ty == a
} else {
compare_layouts(a, b).unwrap_or(false)
}
}

// Otherwise, just compare the layouts. This may fail to lint for some
// incompatible types, but at the very least, will stop reads into
// uninitialised memory.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4771,7 +4771,7 @@ declare_lint! {
/// version of Rust this will be fixed and therefore dependencies relying
/// on the non-spec-compliant C ABI will stop functioning.
pub WASM_C_ABI,
Warn,
Deny,
"detects dependencies that are incompatible with the Wasm C ABI",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_metadata/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#![allow(rustc::potential_query_instability)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(control_flow_enum)]
#![feature(coroutines)]
#![feature(decl_macro)]
#![feature(error_iter)]
Expand Down Expand Up @@ -34,7 +35,9 @@ pub mod locator;

pub use creader::{load_symbol_from_dylib, DylibError};
pub use fs::{emit_wrapper_file, METADATA_FILENAME};
pub use native_libs::find_native_static_library;
pub use native_libs::{
find_native_static_library, try_find_native_static_library, walk_native_lib_search_dirs,
};
pub use rmeta::{encode_metadata, rendered_const, EncodedMetadata, METADATA_HEADER};

rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
92 changes: 82 additions & 10 deletions compiler/rustc_metadata/src/native_libs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::path::PathBuf;
use std::ops::ControlFlow;
use std::path::{Path, PathBuf};

use rustc_ast::{NestedMetaItem, CRATE_NODE_ID};
use rustc_attr as attr;
Expand All @@ -16,10 +17,68 @@ use rustc_session::Session;
use rustc_span::def_id::{DefId, LOCAL_CRATE};
use rustc_span::symbol::{sym, Symbol};
use rustc_target::spec::abi::Abi;
use rustc_target::spec::LinkSelfContainedComponents;

use crate::{errors, fluent_generated};

pub fn find_native_static_library(name: &str, verbatim: bool, sess: &Session) -> PathBuf {
pub fn walk_native_lib_search_dirs<R>(
sess: &Session,
self_contained_components: LinkSelfContainedComponents,
apple_sdk_root: Option<&Path>,
mut f: impl FnMut(&Path, bool /*is_framework*/) -> ControlFlow<R>,
) -> ControlFlow<R> {
// Library search paths explicitly supplied by user (`-L` on the command line).
for search_path in sess.target_filesearch(PathKind::Native).cli_search_paths() {
f(&search_path.dir, false)?;
}
for search_path in sess.target_filesearch(PathKind::Framework).cli_search_paths() {
// Frameworks are looked up strictly in framework-specific paths.
if search_path.kind != PathKind::All {
f(&search_path.dir, true)?;
}
}

// The toolchain ships some native library components and self-contained linking was enabled.
// Add the self-contained library directory to search paths.
if self_contained_components.intersects(
LinkSelfContainedComponents::LIBC
| LinkSelfContainedComponents::UNWIND
| LinkSelfContainedComponents::MINGW,
) {
f(&sess.target_tlib_path.dir.join("self-contained"), false)?;
}

// Toolchains for some targets may ship `libunwind.a`, but place it into the main sysroot
// library directory instead of the self-contained directories.
// Sanitizer libraries have the same issue and are also linked by name on Apple targets.
// The targets here should be in sync with `copy_third_party_objects` in bootstrap.
// FIXME: implement `-Clink-self-contained=+/-unwind,+/-sanitizers`, move the shipped libunwind
// and sanitizers to self-contained directory, and stop adding this search path.
if sess.target.vendor == "fortanix"
|| sess.target.os == "linux"
|| sess.target.os == "fuchsia"
|| sess.target.is_like_osx && !sess.opts.unstable_opts.sanitizer.is_empty()
{
f(&sess.target_tlib_path.dir, false)?;
}

// Mac Catalyst uses the macOS SDK, but to link to iOS-specific frameworks
// we must have the support library stubs in the library search path (#121430).
if let Some(sdk_root) = apple_sdk_root
&& sess.target.llvm_target.contains("macabi")
{
f(&sdk_root.join("System/iOSSupport/usr/lib"), false)?;
f(&sdk_root.join("System/iOSSupport/System/Library/Frameworks"), true)?;
}

ControlFlow::Continue(())
}

pub fn try_find_native_static_library(
sess: &Session,
name: &str,
verbatim: bool,
) -> Option<PathBuf> {
let formats = if verbatim {
vec![("".into(), "".into())]
} else {
Expand All @@ -30,16 +89,29 @@ pub fn find_native_static_library(name: &str, verbatim: bool, sess: &Session) ->
if os == unix { vec![os] } else { vec![os, unix] }
};

for path in sess.target_filesearch(PathKind::Native).search_paths() {
for (prefix, suffix) in &formats {
let test = path.dir.join(format!("{prefix}{name}{suffix}"));
if test.exists() {
return test;
// FIXME: Account for self-contained linking settings and Apple SDK.
walk_native_lib_search_dirs(
sess,
LinkSelfContainedComponents::empty(),
None,
|dir, is_framework| {
if !is_framework {
for (prefix, suffix) in &formats {
let test = dir.join(format!("{prefix}{name}{suffix}"));
if test.exists() {
return ControlFlow::Break(test);
}
}
}
}
}
ControlFlow::Continue(())
},
)
.break_value()
}

sess.dcx().emit_fatal(errors::MissingNativeLibrary::new(name, verbatim));
pub fn find_native_static_library(name: &str, verbatim: bool, sess: &Session) -> PathBuf {
try_find_native_static_library(sess, name, verbatim)
.unwrap_or_else(|| sess.dcx().emit_fatal(errors::MissingNativeLibrary::new(name, verbatim)))
}

fn find_bundled_library(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1000,7 +1000,7 @@ impl<'tcx> Ty<'tcx> {

#[inline]
pub fn is_primitive(self) -> bool {
self.kind().is_primitive()
matches!(self.kind(), Bool | Char | Int(_) | Uint(_) | Float(_))
}

#[inline]
Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_type_ir/src/ty_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,13 +254,6 @@ pub enum TyKind<I: Interner> {
Error(I::ErrorGuaranteed),
}

impl<I: Interner> TyKind<I> {
#[inline]
pub fn is_primitive(&self) -> bool {
matches!(self, Bool | Char | Int(_) | Uint(_) | Float(_))
}
}

// This is manually implemented because a derive would require `I: Debug`
impl<I: Interner> fmt::Debug for TyKind<I> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down
3 changes: 0 additions & 3 deletions library/alloc/benches/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// Disabling on android for the time being
// See https://github.com/rust-lang/rust/issues/73535#event-3477699747
#![cfg(not(target_os = "android"))]
// Disabling in Miri as these would take too long.
#![cfg(not(miri))]
#![feature(btree_extract_if)]
Expand Down
3 changes: 0 additions & 3 deletions library/alloc/tests/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,6 @@ fn test_reserve_exact() {

#[test]
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
#[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
fn test_try_with_capacity() {
let string = String::try_with_capacity(1000).unwrap();
assert_eq!(0, string.len());
Expand All @@ -734,7 +733,6 @@ fn test_try_with_capacity() {

#[test]
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
#[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
fn test_try_reserve() {
// These are the interesting cases:
// * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM)
Expand Down Expand Up @@ -803,7 +801,6 @@ fn test_try_reserve() {

#[test]
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
#[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
fn test_try_reserve_exact() {
// This is exactly the same as test_try_reserve with the method changed.
// See that test for comments.
Expand Down
3 changes: 0 additions & 3 deletions library/alloc/tests/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1695,7 +1695,6 @@ fn test_reserve_exact() {

#[test]
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
#[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
fn test_try_with_capacity() {
let mut vec: Vec<u32> = Vec::try_with_capacity(5).unwrap();
assert_eq!(0, vec.len());
Expand All @@ -1707,7 +1706,6 @@ fn test_try_with_capacity() {

#[test]
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
#[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
fn test_try_reserve() {
// These are the interesting cases:
// * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM)
Expand Down Expand Up @@ -1803,7 +1801,6 @@ fn test_try_reserve() {

#[test]
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
#[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
fn test_try_reserve_exact() {
// This is exactly the same as test_try_reserve with the method changed.
// See that test for comments.
Expand Down
Loading
Loading