Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b4781c8
Use default field values in a few more cases
estebank Jan 15, 2026
996d72b
compiletest: Support `--extern` modifiers with `proc-macro` directive
Enselic Jan 17, 2026
84dad74
link modifier `export-symbols`: export all global symbols from select…
cezarbbb Jan 12, 2026
0271b6b
regression test for alias-relate changes in lub
jdonszelmann Jan 30, 2026
caaee92
more float constants: sqrt(5), 1/sqrt(5)
joshuarayton Sep 23, 2025
cd1c773
Remove `lift_query_info`.
nnethercote Jan 30, 2026
4ff360e
Rename some query-related things.
nnethercote Jan 30, 2026
8e2c9c6
Eliminate some `'a` lifetimes.
nnethercote Jan 30, 2026
c6afd45
Move `depth_limit_error` out of `QueryContext` trait.
nnethercote Feb 1, 2026
f3b7a1a
Update documentation for `Result::ok()`
clundin55 Feb 2, 2026
59868c1
Fix uninitialized UEFI globals in tests
nicholasbishop Jan 23, 2026
09de0fd
Use `#![feature(adt_const_params)]` for static query flags
Zalathar Jan 30, 2026
c725637
explain why we dont skip some of this work when there are field proje…
RalfJung Feb 2, 2026
629ff9b
Update tests/ui/traits/next-solver/generalize/relate-alias-in-lub.rs
jdonszelmann Feb 2, 2026
82a530c
Port
crazazy Feb 2, 2026
1f789ac
Rollup merge of #150992 - cezarbbb:cstyle-export-rules2, r=bjorn3,pet…
JonathanBrouwer Feb 2, 2026
bd58ffb
Rollup merge of #151695 - Enselic:proc-macro-priv-v2, r=Zalathar
JonathanBrouwer Feb 2, 2026
277a665
Rollup merge of #151938 - Zalathar:adt-query-flags, r=nnethercote
JonathanBrouwer Feb 2, 2026
257b0f7
Rollup merge of #151172 - estebank:default-field-values, r=dianne
JonathanBrouwer Feb 2, 2026
9914413
Rollup merge of #151825 - joshuarayton:more-float-constants, r=tgross35
JonathanBrouwer Feb 2, 2026
7ad1cfb
Rollup merge of #151870 - jdonszelmann:regression-test-alias-relate, …
JonathanBrouwer Feb 2, 2026
b05a0f6
Rollup merge of #151902 - RalfJung:place-ty-opt, r=Kobzol
JonathanBrouwer Feb 2, 2026
a13e145
Rollup merge of #151974 - clundin55:doc-fix, r=jhpratt
JonathanBrouwer Feb 2, 2026
1551b63
Rollup merge of #151978 - nnethercote:query-cleanups, r=Zalathar
JonathanBrouwer Feb 2, 2026
c785955
Rollup merge of #151979 - nicholasbishop:push-ssmqyutnpypo, r=jhpratt
JonathanBrouwer Feb 2, 2026
b981e13
Rollup merge of #151992 - crazazy:main, r=JonathanBrouwer
JonathanBrouwer Feb 2, 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
5 changes: 4 additions & 1 deletion compiler/rustc_attr_parsing/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ attr_parsing_expects_feature_list =
attr_parsing_expects_features =
`{$name}` expects feature names
attr_parsing_export_symbols_needs_static =
linking modifier `export-symbols` is only compatible with `static` linking kind
attr_parsing_import_name_type_raw =
import name type can only be used with link kind `raw-dylib`
Expand Down Expand Up @@ -95,7 +98,7 @@ attr_parsing_invalid_issue_string =
.neg_overflow = number too small to fit in target type
attr_parsing_invalid_link_modifier =
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
attr_parsing_invalid_meta_item = expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found {$descr}
.remove_neg_sugg = negative numbers are not literals, try removing the `-` sign
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::util::parse_single_integer;
use crate::attributes::cfg::parse_cfg_entry;
use crate::fluent_generated;
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
8 changes: 8 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,14 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcHasIncoherentInherentImplsParse
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcHasIncoherentInherentImpls;
}

pub(crate) struct RustcHiddenTypeOfOpaquesParser;

impl<S: Stage> NoArgsAttributeParser<S> for RustcHiddenTypeOfOpaquesParser {
const PATH: &[Symbol] = &[sym::rustc_hidden_type_of_opaques];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcHiddenTypeOfOpaques;
}
pub(crate) struct RustcNounwindParser;

impl<S: Stage> NoArgsAttributeParser<S> for RustcNounwindParser {
Expand Down
16 changes: 9 additions & 7 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,14 @@ use crate::attributes::rustc_dump::{
RustcDumpVtable,
};
use crate::attributes::rustc_internal::{
RustcHasIncoherentInherentImplsParser, RustcLayoutParser, RustcLayoutScalarValidRangeEndParser,
RustcLayoutScalarValidRangeStartParser, RustcLegacyConstGenericsParser,
RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser, RustcLintQueryInstabilityParser,
RustcLintUntrackedQueryInformationParser, RustcMainParser, RustcMustImplementOneOfParser,
RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser,
RustcNonConstTraitMethodParser, RustcNounwindParser, RustcObjectLifetimeDefaultParser,
RustcOffloadKernelParser, RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser,
RustcHasIncoherentInherentImplsParser, RustcHiddenTypeOfOpaquesParser, RustcLayoutParser,
RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser,
RustcLegacyConstGenericsParser, RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser,
RustcLintQueryInstabilityParser, RustcLintUntrackedQueryInformationParser, RustcMainParser,
RustcMustImplementOneOfParser, RustcNeverReturnsNullPointerParser,
RustcNoImplicitAutorefsParser, RustcNonConstTraitMethodParser, RustcNounwindParser,
RustcObjectLifetimeDefaultParser, RustcOffloadKernelParser, RustcScalableVectorParser,
RustcSimdMonomorphizeLaneLimitParser,
};
use crate::attributes::semantics::MayDangleParser;
use crate::attributes::stability::{
Expand Down Expand Up @@ -299,6 +300,7 @@ attribute_parsers!(
Single<WithoutArgs<RustcDumpUserArgs>>,
Single<WithoutArgs<RustcDumpVtable>>,
Single<WithoutArgs<RustcHasIncoherentInherentImplsParser>>,
Single<WithoutArgs<RustcHiddenTypeOfOpaquesParser>>,
Single<WithoutArgs<RustcLintOptTyParser>>,
Single<WithoutArgs<RustcLintQueryInstabilityParser>>,
Single<WithoutArgs<RustcLintUntrackedQueryInformationParser>>,
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,13 @@ pub(crate) struct BundleNeedsStatic {
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(attr_parsing_export_symbols_needs_static)]
pub(crate) struct ExportSymbolsNeedsStatic {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(attr_parsing_whole_archive_needs_static)]
pub(crate) struct WholeArchiveNeedsStatic {
Expand Down
48 changes: 15 additions & 33 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2309,12 +2309,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
tcx: TyCtxt<'hir>,
issue_span: Span,
expr_span: Span,
body_expr: Option<&'hir hir::Expr<'hir>>,
loop_bind: Option<&'hir Ident>,
loop_span: Option<Span>,
head_span: Option<Span>,
pat_span: Option<Span>,
head: Option<&'hir hir::Expr<'hir>>,
body_expr: Option<&'hir hir::Expr<'hir>> = None,
loop_bind: Option<&'hir Ident> = None,
loop_span: Option<Span> = None,
head_span: Option<Span> = None,
pat_span: Option<Span> = None,
head: Option<&'hir hir::Expr<'hir>> = None,
}
impl<'hir> Visitor<'hir> for ExprFinder<'hir> {
fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) {
Expand Down Expand Up @@ -2380,17 +2380,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
hir::intravisit::walk_expr(self, ex);
}
}
let mut finder = ExprFinder {
tcx,
expr_span: span,
issue_span,
loop_bind: None,
body_expr: None,
head_span: None,
loop_span: None,
pat_span: None,
head: None,
};
let mut finder = ExprFinder { tcx, expr_span: span, issue_span, .. };
finder.visit_expr(tcx.hir_body(body_id).value);

if let Some(body_expr) = finder.body_expr
Expand Down Expand Up @@ -2625,13 +2615,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {

struct ExpressionFinder<'tcx> {
capture_span: Span,
closure_change_spans: Vec<Span>,
closure_arg_span: Option<Span>,
in_closure: bool,
suggest_arg: String,
closure_change_spans: Vec<Span> = vec![],
closure_arg_span: Option<Span> = None,
in_closure: bool = false,
suggest_arg: String = String::new(),
tcx: TyCtxt<'tcx>,
closure_local_id: Option<hir::HirId>,
closure_call_changes: Vec<(Span, String)>,
closure_local_id: Option<hir::HirId> = None,
closure_call_changes: Vec<(Span, String)> = vec![],
}
impl<'hir> Visitor<'hir> for ExpressionFinder<'hir> {
fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) {
Expand Down Expand Up @@ -2712,16 +2702,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
}) = self.infcx.tcx.hir_node(self.mir_hir_id())
&& let hir::Node::Expr(expr) = self.infcx.tcx.hir_node(body_id.hir_id)
{
let mut finder = ExpressionFinder {
capture_span: *capture_kind_span,
closure_change_spans: vec![],
closure_arg_span: None,
in_closure: false,
suggest_arg: String::new(),
closure_local_id: None,
closure_call_changes: vec![],
tcx: self.infcx.tcx,
};
let mut finder =
ExpressionFinder { capture_span: *capture_kind_span, tcx: self.infcx.tcx, .. };
finder.visit_expr(expr);

if finder.closure_change_spans.is_empty() || finder.closure_call_changes.is_empty() {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#![allow(internal_features)]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(default_field_values)]
#![feature(file_buffered)]
#![feature(if_let_guard)]
#![feature(negative_impls)]
Expand Down
100 changes: 93 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,76 @@ 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 mut name = match symbol.name() {
Ok(n) => n,
Err(_) => continue,
};

if sess.target.is_like_darwin {
if let Some(stripped) = name.strip_prefix('_') {
name = stripped;
}
}

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 32-bit Windows. 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 +2288,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 +2764,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
9 changes: 7 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 Expand Up @@ -1057,6 +1059,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_has_incoherent_inherent_impls]`
RustcHasIncoherentInherentImpls,

/// Represents `#[rustc_hidden_type_of_opaques]`
RustcHiddenTypeOfOpaques,

/// Represents `#[rustc_layout]`
RustcLayout(ThinVec<RustcLayoutType>),

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/attrs/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ impl AttributeKind {
RustcDumpVtable(..) => No,
RustcDynIncompatibleTrait(..) => No,
RustcHasIncoherentInherentImpls => Yes,
RustcHiddenTypeOfOpaques => No,
RustcLayout(..) => No,
RustcLayoutScalarValidRangeEnd(..) => Yes,
RustcLayoutScalarValidRangeStart(..) => Yes,
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir_analysis/src/collect/dump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_span::sym;

pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) {
if !tcx.has_attr(CRATE_DEF_ID, sym::rustc_hidden_type_of_opaques) {
if !find_attr!(tcx.get_all_attrs(CRATE_DEF_ID), AttributeKind::RustcHiddenTypeOfOpaques) {
return;
}

for id in tcx.hir_crate_items(()).opaques() {
if let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. }
| hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, .. } =
Expand Down
Loading
Loading