Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c0c6e21
make generic test invariant of function order
ZuseZ4 Jan 23, 2026
d787761
Update test after new mangling scheme, make test more robust
ZuseZ4 Jan 24, 2026
7bcc8a7
update abi handling test
ZuseZ4 Jan 24, 2026
b6d567c
Shorten the autodiff batching test, to make it more reliable
ZuseZ4 Jan 24, 2026
76b6623
target: fix destabilising target-spec-json
davidtwco Jan 23, 2026
2a9de6b
CI: rfl: move to temporary commit to pass `-Zunstable-options` for cu…
ojeda Jan 27, 2026
590fa1e
Convert to inline diagnostics in `rustc_ty_utils`
JonathanBrouwer Feb 3, 2026
815f466
Convert to inline diagnostics in `rustc_pattern_analysis`
JonathanBrouwer Feb 3, 2026
d457ffd
Convert to inline diagnostics in `rustc_monomorphize`
JonathanBrouwer Feb 3, 2026
07e4a99
citool: report debuginfo test statistics
Unique-Usman Jan 29, 2026
dcdffe8
link modifier `export-symbols`: export all global symbols from select…
cezarbbb Jan 12, 2026
8e62b1d
Fix set_times_nofollow for directory on windows
chenyukang Feb 4, 2026
c77779e
rustbook/README.md: add missing `)`
DanielEScherzer Feb 4, 2026
024c9b7
Convert to inline diagnostics in `rustc_resolve`
JonathanBrouwer Feb 3, 2026
5002994
Rollup merge of #150992 - cezarbbb:cstyle-export-rules2, r=bjorn3,pet…
JonathanBrouwer Feb 4, 2026
587ba1c
Rollup merge of #151534 - davidtwco:destabilise-target-spec-json-agai…
JonathanBrouwer Feb 4, 2026
2dad086
Rollup merge of #152088 - DanielEScherzer:patch-1, r=chenyukang
JonathanBrouwer Feb 4, 2026
8ecb092
Rollup merge of #151526 - ZuseZ4:fix-autodiff-codegen-tests, r=oli-obk
JonathanBrouwer Feb 4, 2026
03c96ae
Rollup merge of #151810 - Unique-Usman:ua/debuginfostat, r=Kobzol
JonathanBrouwer Feb 4, 2026
19edc5e
Rollup merge of #152065 - JonathanBrouwer:convert_ty_utils, r=lqd
JonathanBrouwer Feb 4, 2026
13d79ed
Rollup merge of #152068 - JonathanBrouwer:convert_resolve, r=lqd
JonathanBrouwer Feb 4, 2026
d774555
Rollup merge of #152070 - JonathanBrouwer:convert_pattern_analysis, r…
JonathanBrouwer Feb 4, 2026
f501633
Rollup merge of #152072 - JonathanBrouwer:convert_monomorphize, r=jdo…
JonathanBrouwer Feb 4, 2026
4939825
Rollup merge of #152083 - chenyukang:yukang-fix-set-times-nofollow-on…
JonathanBrouwer Feb 4, 2026
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
7 changes: 0 additions & 7 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3799,18 +3799,15 @@ dependencies = [
"rustc_middle",
"rustc_mir_build",
"rustc_mir_transform",
"rustc_monomorphize",
"rustc_parse",
"rustc_passes",
"rustc_pattern_analysis",
"rustc_privacy",
"rustc_public",
"rustc_resolve",
"rustc_session",
"rustc_span",
"rustc_target",
"rustc_trait_selection",
"rustc_ty_utils",
"serde_json",
"shlex",
"tracing",
Expand Down Expand Up @@ -4373,7 +4370,6 @@ dependencies = [
"rustc_abi",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_macros",
Expand Down Expand Up @@ -4466,7 +4462,6 @@ dependencies = [
"rustc_arena",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_macros",
Expand Down Expand Up @@ -4587,7 +4582,6 @@ dependencies = [
"rustc_errors",
"rustc_expand",
"rustc_feature",
"rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_macros",
Expand Down Expand Up @@ -4797,7 +4791,6 @@ dependencies = [
"rustc_abi",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
"rustc_hashes",
"rustc_hir",
"rustc_index",
Expand Down
21 changes: 16 additions & 5 deletions compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ use super::prelude::*;
use super::util::parse_single_integer;
use crate::attributes::cfg::parse_cfg_entry;
use crate::session_diagnostics::{
AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, ImportNameTypeRaw, ImportNameTypeX86,
IncompatibleWasmLink, InvalidLinkModifier, LinkFrameworkApple, LinkOrdinalOutOfRange,
LinkRequiresName, MultipleModifiers, NullOnLinkSection, RawDylibNoNul, RawDylibOnlyWindows,
WholeArchiveNeedsStatic,
AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, ExportSymbolsNeedsStatic,
ImportNameTypeRaw, ImportNameTypeX86, IncompatibleWasmLink, InvalidLinkModifier,
LinkFrameworkApple, LinkOrdinalOutOfRange, LinkRequiresName, MultipleModifiers,
NullOnLinkSection, RawDylibNoNul, RawDylibOnlyWindows, WholeArchiveNeedsStatic,
};

pub(crate) struct LinkNameParser;
Expand Down Expand Up @@ -165,6 +165,14 @@ impl<S: Stage> CombineAttributeParser<S> for LinkParser {
cx.emit_err(BundleNeedsStatic { span });
}

(sym::export_symbols, Some(NativeLibKind::Static { export_symbols, .. })) => {
assign_modifier(export_symbols)
}

(sym::export_symbols, _) => {
cx.emit_err(ExportSymbolsNeedsStatic { span });
}

(sym::verbatim, _) => assign_modifier(&mut verbatim),

(
Expand All @@ -190,6 +198,7 @@ impl<S: Stage> CombineAttributeParser<S> for LinkParser {
span,
&[
sym::bundle,
sym::export_symbols,
sym::verbatim,
sym::whole_dash_archive,
sym::as_dash_needed,
Expand Down Expand Up @@ -285,7 +294,9 @@ impl LinkParser {
};

let link_kind = match link_kind {
kw::Static => NativeLibKind::Static { bundle: None, whole_archive: None },
kw::Static => {
NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }
}
sym::dylib => NativeLibKind::Dylib { as_needed: None },
sym::framework => {
if !sess.target.is_like_darwin {
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,7 @@ pub(crate) struct RawDylibOnlyWindows {

#[derive(Diagnostic)]
#[diag(
"invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed"
"invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols"
)]
pub(crate) struct InvalidLinkModifier {
#[primary_span]
Expand Down Expand Up @@ -938,6 +938,13 @@ pub(crate) struct BundleNeedsStatic {
pub span: Span,
}

#[derive(Diagnostic)]
#[diag("linking modifier `export-symbols` is only compatible with `static` linking kind")]
pub(crate) struct ExportSymbolsNeedsStatic {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag("linking modifier `whole-archive` is only compatible with `static` linking kind")]
pub(crate) struct WholeArchiveNeedsStatic {
Expand Down
95 changes: 88 additions & 7 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ use std::{env, fmt, fs, io, mem, str};

use find_msvc_tools;
use itertools::Itertools;
use object::{Object, ObjectSection, ObjectSymbol};
use regex::Regex;
use rustc_arena::TypedArena;
use rustc_attr_parsing::eval_config_entry;
use rustc_data_structures::fx::FxIndexSet;
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_data_structures::memmap::Mmap;
use rustc_data_structures::temp_dir::MaybeTempDir;
use rustc_errors::{DiagCtxtHandle, LintDiagnostic};
Expand Down Expand Up @@ -2185,6 +2186,71 @@ fn add_rpath_args(
}
}

fn add_c_staticlib_symbols(
sess: &Session,
lib: &NativeLib,
out: &mut Vec<(String, SymbolExportKind)>,
) -> io::Result<()> {
let file_path = find_native_static_library(lib.name.as_str(), lib.verbatim, sess);

let archive_map = unsafe { Mmap::map(File::open(&file_path)?)? };

let archive = object::read::archive::ArchiveFile::parse(&*archive_map)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;

for member in archive.members() {
let member = member.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;

let data = member
.data(&*archive_map)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;

// clang LTO: raw LLVM bitcode
if data.starts_with(b"BC\xc0\xde") {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"LLVM bitcode object in C static library (LTO not supported)",
));
}

let object = object::File::parse(&*data)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;

// gcc / clang ELF / Mach-O LTO
if object.sections().any(|s| {
s.name().map(|n| n.starts_with(".gnu.lto_") || n == ".llvm.lto").unwrap_or(false)
}) {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"LTO object in C static library is not supported",
));
}

for symbol in object.symbols() {
if symbol.scope() != object::SymbolScope::Dynamic {
continue;
}

let name = match symbol.name() {
Ok(n) => n,
Err(_) => continue,
};

let export_kind = match symbol.kind() {
object::SymbolKind::Text => SymbolExportKind::Text,
object::SymbolKind::Data => SymbolExportKind::Data,
_ => continue,
};

// FIXME:The symbol mangle rules are slightly different in Windows(32-bit) and Apple.
// Need to be resolved.
out.push((name.to_string(), export_kind));
}
}

Ok(())
}

/// Produce the linker command line containing linker path and arguments.
///
/// When comments in the function say "order-(in)dependent" they mean order-dependence between
Expand Down Expand Up @@ -2217,18 +2283,33 @@ fn linker_with_args(
);
let link_output_kind = link_output_kind(sess, crate_type);

let mut export_symbols = codegen_results.crate_info.exported_symbols[&crate_type].clone();

if crate_type == CrateType::Cdylib {
let mut seen = FxHashSet::default();

for lib in &codegen_results.crate_info.used_libraries {
if let NativeLibKind::Static { export_symbols: Some(true), .. } = lib.kind
&& seen.insert((lib.name, lib.verbatim))
{
if let Err(err) = add_c_staticlib_symbols(&sess, lib, &mut export_symbols) {
sess.dcx().fatal(format!(
"failed to process C static library `{}`: {}",
lib.name, err
));
}
}
}
}

// ------------ Early order-dependent options ------------

// If we're building something like a dynamic library then some platforms
// need to make sure that all symbols are exported correctly from the
// dynamic library.
// Must be passed before any libraries to prevent the symbols to export from being thrown away,
// at least on some platforms (e.g. windows-gnu).
cmd.export_symbols(
tmpdir,
crate_type,
&codegen_results.crate_info.exported_symbols[&crate_type],
);
cmd.export_symbols(tmpdir, crate_type, &export_symbols);

// Can be used for adding custom CRT objects or overriding order-dependent options above.
// FIXME: In practice built-in target specs use this for arbitrary order-independent options,
Expand Down Expand Up @@ -2678,7 +2759,7 @@ fn add_native_libs_from_crate(
let name = lib.name.as_str();
let verbatim = lib.verbatim;
match lib.kind {
NativeLibKind::Static { bundle, whole_archive } => {
NativeLibKind::Static { bundle, whole_archive, .. } => {
if link_static {
let bundle = bundle.unwrap_or(true);
let whole_archive = whole_archive == Some(true);
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_driver_impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,15 @@ rustc_metadata = { path = "../rustc_metadata" }
rustc_middle = { path = "../rustc_middle" }
rustc_mir_build = { path = "../rustc_mir_build" }
rustc_mir_transform = { path = "../rustc_mir_transform" }
rustc_monomorphize = { path = "../rustc_monomorphize" }
rustc_parse = { path = "../rustc_parse" }
rustc_passes = { path = "../rustc_passes" }
rustc_pattern_analysis = { path = "../rustc_pattern_analysis" }
rustc_privacy = { path = "../rustc_privacy" }
rustc_public = { path = "../rustc_public", features = ["rustc_internal"] }
rustc_resolve = { path = "../rustc_resolve" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
rustc_trait_selection = { path = "../rustc_trait_selection" }
rustc_ty_utils = { path = "../rustc_ty_utils" }
serde_json = "1.0.59"
shlex = "1.0"
tracing = { version = "0.1.35" }
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,11 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[
rustc_middle::DEFAULT_LOCALE_RESOURCE,
rustc_mir_build::DEFAULT_LOCALE_RESOURCE,
rustc_mir_transform::DEFAULT_LOCALE_RESOURCE,
rustc_monomorphize::DEFAULT_LOCALE_RESOURCE,
rustc_parse::DEFAULT_LOCALE_RESOURCE,
rustc_passes::DEFAULT_LOCALE_RESOURCE,
rustc_pattern_analysis::DEFAULT_LOCALE_RESOURCE,
rustc_privacy::DEFAULT_LOCALE_RESOURCE,
rustc_resolve::DEFAULT_LOCALE_RESOURCE,
rustc_session::DEFAULT_LOCALE_RESOURCE,
rustc_trait_selection::DEFAULT_LOCALE_RESOURCE,
rustc_ty_utils::DEFAULT_LOCALE_RESOURCE,
// tidy-alphabetical-end
];

Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,8 @@ pub enum NativeLibKind {
bundle: Option<bool>,
/// Whether to link static library without throwing any object files away
whole_archive: Option<bool>,
/// Whether to export c static library symbols
export_symbols: Option<bool>,
},
/// Dynamic library (e.g. `libfoo.so` on Linux)
/// or an import library corresponding to a dynamic library (e.g. `foo.lib` on Windows/MSVC).
Expand Down Expand Up @@ -363,8 +365,8 @@ pub enum NativeLibKind {
impl NativeLibKind {
pub fn has_modifiers(&self) -> bool {
match self {
NativeLibKind::Static { bundle, whole_archive } => {
bundle.is_some() || whole_archive.is_some()
NativeLibKind::Static { bundle, whole_archive, export_symbols } => {
bundle.is_some() || whole_archive.is_some() || export_symbols.is_some()
}
NativeLibKind::Dylib { as_needed }
| NativeLibKind::Framework { as_needed }
Expand Down
18 changes: 9 additions & 9 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ fn test_native_libs_tracking_hash_different_values() {
NativeLib {
name: String::from("a"),
new_name: None,
kind: NativeLibKind::Static { bundle: None, whole_archive: None },
kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None },
verbatim: None,
},
NativeLib {
Expand All @@ -401,7 +401,7 @@ fn test_native_libs_tracking_hash_different_values() {
NativeLib {
name: String::from("a"),
new_name: None,
kind: NativeLibKind::Static { bundle: None, whole_archive: None },
kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None },
verbatim: None,
},
NativeLib {
Expand All @@ -423,13 +423,13 @@ fn test_native_libs_tracking_hash_different_values() {
NativeLib {
name: String::from("a"),
new_name: None,
kind: NativeLibKind::Static { bundle: None, whole_archive: None },
kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None },
verbatim: None,
},
NativeLib {
name: String::from("b"),
new_name: None,
kind: NativeLibKind::Static { bundle: None, whole_archive: None },
kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None },
verbatim: None,
},
NativeLib {
Expand All @@ -445,7 +445,7 @@ fn test_native_libs_tracking_hash_different_values() {
NativeLib {
name: String::from("a"),
new_name: None,
kind: NativeLibKind::Static { bundle: None, whole_archive: None },
kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None },
verbatim: None,
},
NativeLib {
Expand All @@ -467,7 +467,7 @@ fn test_native_libs_tracking_hash_different_values() {
NativeLib {
name: String::from("a"),
new_name: None,
kind: NativeLibKind::Static { bundle: None, whole_archive: None },
kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None },
verbatim: None,
},
NativeLib {
Expand Down Expand Up @@ -501,7 +501,7 @@ fn test_native_libs_tracking_hash_different_order() {
NativeLib {
name: String::from("a"),
new_name: None,
kind: NativeLibKind::Static { bundle: None, whole_archive: None },
kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None },
verbatim: None,
},
NativeLib {
Expand All @@ -528,7 +528,7 @@ fn test_native_libs_tracking_hash_different_order() {
NativeLib {
name: String::from("a"),
new_name: None,
kind: NativeLibKind::Static { bundle: None, whole_archive: None },
kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None },
verbatim: None,
},
NativeLib {
Expand All @@ -549,7 +549,7 @@ fn test_native_libs_tracking_hash_different_order() {
NativeLib {
name: String::from("a"),
new_name: None,
kind: NativeLibKind::Static { bundle: None, whole_archive: None },
kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None },
verbatim: None,
},
NativeLib {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/native_libs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ fn find_bundled_library(
tcx: TyCtxt<'_>,
) -> Option<Symbol> {
let sess = tcx.sess;
if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive } = kind
if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive, .. } = kind
&& tcx.crate_types().iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::StaticLib))
&& (sess.opts.unstable_opts.packed_bundled_libs || has_cfg || whole_archive == Some(true))
{
Expand Down
Loading
Loading