Skip to content
Open
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
d501f96
rustc_target: callconv: powerpc64: Use llvm_abiname rather than targe…
Gelbpunkt Feb 24, 2026
acbfd79
Fix: On wasm targets, call `panic_in_cleanup` if panic occurs in cleanup
hoodmane Jan 27, 2026
4450740
Split `is_msvc_link_exe` into a function
jyn514 Dec 12, 2025
1679dfb
Split `report_linker_output` into its own function
jyn514 Dec 12, 2025
1e3bf5e
Split out linker-info from linker-messages
jyn514 Dec 12, 2025
f7e1936
Set linker-messages to warn-by-default
jyn514 Dec 13, 2025
8e3cb10
Ignore linker messages for `raw_dylib_elf`
jyn514 Feb 18, 2026
5847b63
Revert "Set linker-messages to warn-by-default"
jyn514 Feb 24, 2026
783afe9
`is_ty_must_use`: do not require a `span` argument
samueltardieu Feb 24, 2026
f4407f2
Update books
rustbot Feb 25, 2026
d13924c
mGCA: Reject negated non-integer literals in const args
reddevilmidzy Feb 25, 2026
5127108
mGCA: drop literal anon-const special case in parser
reddevilmidzy Feb 25, 2026
8eed8bd
Rename `pass_by_value` lint as `disallowed_pass_by_ref`.
nnethercote Feb 23, 2026
d2619b5
Remove mgca_direct_lit_hack indirection
reddevilmidzy Feb 25, 2026
b76b26d
Remove `QuerySystemFns`.
nnethercote Feb 25, 2026
608d85f
Move two functions into `hooks`.
nnethercote Feb 25, 2026
f1ec10e
deprecate `Eq::assert_receiver_is_total_eq` and emit a FCW on manual …
cyrgani Jan 8, 2026
1bc5c6c
Rollup merge of #149937 - jyn514:linker-info, r=mati865
JonathanBrouwer Feb 25, 2026
1e13159
Rollup merge of #151771 - hoodmane:wasm-double-panic, r=bjorn3
JonathanBrouwer Feb 25, 2026
6143c77
Rollup merge of #153035 - Gelbpunkt:ppc64-callconv-llvm-abiname, r=Ra…
JonathanBrouwer Feb 25, 2026
63fd1cd
Rollup merge of #153075 - reddevilmidzy:mgca-neg, r=BoxyUwU
JonathanBrouwer Feb 25, 2026
f01d162
Rollup merge of #153078 - nnethercote:rm-QuerySystemFns, r=petrochenkov
JonathanBrouwer Feb 25, 2026
dfec97b
Rollup merge of #149978 - cyrgani:no-eq-assert-receiver-method, r=mad…
JonathanBrouwer Feb 25, 2026
72d0068
Rollup merge of #153029 - nnethercote:disallowed-pass-by-ref, r=Urgau
JonathanBrouwer Feb 25, 2026
f6aacfe
Rollup merge of #153063 - samueltardieu:features/remove-span-paramete…
JonathanBrouwer Feb 25, 2026
5e35d4a
Rollup merge of #153071 - rustbot:docs-update, r=ehuss
JonathanBrouwer Feb 25, 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
6 changes: 4 additions & 2 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -757,9 +757,11 @@ macro_rules! common_visitor_and_walkers {
) -> V::Result;
}

// this is only used by the MutVisitor. We include this symmetry here to make writing other functions easier
// This is only used by the MutVisitor. We include this symmetry here to make writing other
// functions easier.
$(${ignore($lt)}
#[expect(unused, rustc::pass_by_value)]
#[cfg_attr(not(bootstrap), expect(unused, rustc::disallowed_pass_by_ref))]
#[cfg_attr(bootstrap, expect(unused, rustc::pass_by_value))]
#[inline]
)?
fn visit_span<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, span: &$($lt)? $($mut)? Span) -> V::Result {
Expand Down
21 changes: 11 additions & 10 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2521,16 +2521,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ExprKind::Block(block, _) => {
if let [stmt] = block.stmts.as_slice()
&& let StmtKind::Expr(expr) = &stmt.kind
&& matches!(
expr.kind,
ExprKind::Block(..)
| ExprKind::Path(..)
| ExprKind::Struct(..)
| ExprKind::Call(..)
| ExprKind::Tup(..)
| ExprKind::Array(..)
| ExprKind::ConstBlock(..)
)
{
return self.lower_expr_to_const_arg_direct(expr);
}
Expand All @@ -2553,6 +2543,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let span = expr.span;
let literal = self.lower_lit(literal, span);

if !matches!(literal.node, LitKind::Int(..)) {
let err =
self.dcx().struct_span_err(expr.span, "negated literal must be an integer");

return ConstArg {
hir_id: self.next_id(),
kind: hir::ConstArgKind::Error(err.emit()),
span,
};
}

ConstArg {
hir_id: self.lower_node_id(expr.id),
kind: hir::ConstArgKind::Literal { lit: literal.node, negated: true },
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,14 @@ pub(crate) fn expand_deriving_eq(
additional_bounds: Vec::new(),
supports_unions: true,
methods: vec![MethodDef {
name: sym::assert_receiver_is_total_eq,
name: sym::assert_fields_are_eq,
generics: Bounds::empty(),
explicit_self: true,
nonself_args: vec![],
ret_ty: Unit,
attributes: thin_vec![
cx.attr_word(sym::inline, span),
cx.attr_nested_word(sym::doc, sym::hidden, span),
cx.attr_nested_word(sym::coverage, sym::off, span)
cx.attr_nested_word(sym::coverage, sym::off, span),
],
fieldless_variants_strategy: FieldlessVariantsStrategy::Unify,
combine_substructure: combine_substructure(Box::new(|a, b, c| {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_gcc/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1655,6 +1655,10 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
unimplemented!();
}

fn get_funclet_cleanuppad(&self, _funclet: &Funclet) -> RValue<'gcc> {
unimplemented!();
}

// Atomic Operations
fn atomic_cmpxchg(
&mut self,
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1296,6 +1296,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
ret
}

fn get_funclet_cleanuppad(&self, funclet: &Funclet<'ll>) -> &'ll Value {
funclet.cleanuppad()
}

// Atomic Operations
fn atomic_cmpxchg(
&mut self,
Expand Down
199 changes: 152 additions & 47 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use rustc_errors::DiagCtxtHandle;
use rustc_fs_util::{TempDirBuilder, fix_windows_verbatim_for_gcc, try_canonicalize};
use rustc_hir::attrs::NativeLibKind;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_lint_defs::builtin::LINKER_INFO;
use rustc_macros::Diagnostic;
use rustc_metadata::fs::{METADATA_FILENAME, copy_to_stdout, emit_wrapper_file};
use rustc_metadata::{
Expand Down Expand Up @@ -60,7 +61,8 @@ use super::rpath::{self, RPathConfig};
use super::{apple, versioned_llvm_target};
use crate::base::needs_allocator_shim_for_linking;
use crate::{
CodegenResults, CompiledModule, CrateInfo, NativeLib, errors, looks_like_rust_object_file,
CodegenLintLevels, CodegenResults, CompiledModule, CrateInfo, NativeLib, errors,
looks_like_rust_object_file,
};

pub fn ensure_removed(dcx: DiagCtxtHandle<'_>, path: &Path) {
Expand Down Expand Up @@ -670,6 +672,147 @@ struct LinkerOutput {
inner: String,
}

fn is_msvc_link_exe(sess: &Session) -> bool {
let (linker_path, flavor) = linker_and_flavor(sess);
sess.target.is_like_msvc
&& flavor == LinkerFlavor::Msvc(Lld::No)
// Match exactly "link.exe"
&& linker_path.to_str() == Some("link.exe")
}

fn is_macos_ld(sess: &Session) -> bool {
let (_, flavor) = linker_and_flavor(sess);
sess.target.is_like_darwin && matches!(flavor, LinkerFlavor::Darwin(_, Lld::No))
}

fn is_windows_gnu_ld(sess: &Session) -> bool {
let (_, flavor) = linker_and_flavor(sess);
sess.target.is_like_windows
&& !sess.target.is_like_msvc
&& matches!(flavor, LinkerFlavor::Gnu(_, Lld::No))
}

fn report_linker_output(sess: &Session, levels: CodegenLintLevels, stdout: &[u8], stderr: &[u8]) {
let mut escaped_stderr = escape_string(&stderr);
let mut escaped_stdout = escape_string(&stdout);
let mut linker_info = String::new();

info!("linker stderr:\n{}", &escaped_stderr);
info!("linker stdout:\n{}", &escaped_stdout);

fn for_each(bytes: &[u8], mut f: impl FnMut(&str, &mut String)) -> String {
let mut output = String::new();
if let Ok(str) = str::from_utf8(bytes) {
info!("line: {str}");
output = String::with_capacity(str.len());
for line in str.lines() {
f(line.trim(), &mut output);
}
}
escape_string(output.trim().as_bytes())
}

if is_msvc_link_exe(sess) {
info!("inferred MSVC link.exe");

escaped_stdout = for_each(&stdout, |line, output| {
// Hide some progress messages from link.exe that we don't care about.
// See https://github.com/chromium/chromium/blob/bfa41e41145ffc85f041384280caf2949bb7bd72/build/toolchain/win/tool_wrapper.py#L144-L146
if line.starts_with(" Creating library")
|| line.starts_with("Generating code")
|| line.starts_with("Finished generating code")
{
linker_info += line;
linker_info += "\r\n";
} else {
*output += line;
*output += "\r\n"
}
});
} else if is_macos_ld(sess) {
info!("inferred macOS LD");

// FIXME: Tracked by https://github.com/rust-lang/rust/issues/136113
let deployment_mismatch = |line: &str| {
line.starts_with("ld: warning: object file (")
&& line.contains("was built for newer 'macOS' version")
&& line.contains("than being linked")
};
// FIXME: This is a real warning we would like to show, but it hits too many crates
// to want to turn it on immediately.
let search_path = |line: &str| {
line.starts_with("ld: warning: search path '") && line.ends_with("' not found")
};
escaped_stderr = for_each(&stderr, |line, output| {
// This duplicate library warning is just not helpful at all.
if line.starts_with("ld: warning: ignoring duplicate libraries: ")
|| deployment_mismatch(line)
|| search_path(line)
{
linker_info += line;
linker_info += "\n";
} else {
*output += line;
*output += "\n"
}
});
} else if is_windows_gnu_ld(sess) {
info!("inferred Windows GNU LD");

let mut saw_exclude_symbol = false;
// See https://github.com/rust-lang/rust/issues/112368.
// FIXME: maybe check that binutils is older than 2.40 before downgrading this warning?
let exclude_symbols = |line: &str| {
line.starts_with("Warning: .drectve `-exclude-symbols:")
&& line.ends_with("' unrecognized")
};
escaped_stderr = for_each(&stderr, |line, output| {
if exclude_symbols(line) {
saw_exclude_symbol = true;
linker_info += line;
linker_info += "\n";
} else if saw_exclude_symbol && line == "Warning: corrupt .drectve at end of def file" {
linker_info += line;
linker_info += "\n";
} else {
*output += line;
*output += "\n"
}
});
}

let lint_msg = |msg| {
diag_lint_level(
sess,
LINKER_MESSAGES,
levels.linker_messages,
None,
LinkerOutput { inner: msg },
);
};
let lint_info = |msg| {
diag_lint_level(sess, LINKER_INFO, levels.linker_info, None, LinkerOutput { inner: msg });
};

if !escaped_stderr.is_empty() {
// We already print `warning:` at the start of the diagnostic. Remove it from the linker output if present.
escaped_stderr =
escaped_stderr.strip_prefix("warning: ").unwrap_or(&escaped_stderr).to_owned();
// Windows GNU LD prints uppercase Warning
escaped_stderr = escaped_stderr
.strip_prefix("Warning: ")
.unwrap_or(&escaped_stderr)
.replace(": warning: ", ": ");
lint_msg(format!("linker stderr: {escaped_stderr}"));
}
if !escaped_stdout.is_empty() {
lint_msg(format!("linker stdout: {}", escaped_stdout))
}
if !linker_info.is_empty() {
lint_info(linker_info);
}
}

/// Create a dynamic library or executable.
///
/// This will invoke the system linker/cc to create the resulting file. This links to all upstream
Expand Down Expand Up @@ -856,11 +999,6 @@ fn link_natively(

match prog {
Ok(prog) => {
let is_msvc_link_exe = sess.target.is_like_msvc
&& flavor == LinkerFlavor::Msvc(Lld::No)
// Match exactly "link.exe"
&& linker_path.to_str() == Some("link.exe");

if !prog.status.success() {
let mut output = prog.stderr.clone();
output.extend_from_slice(&prog.stdout);
Expand All @@ -880,7 +1018,7 @@ fn link_natively(
if let Some(code) = prog.status.code() {
// All Microsoft `link.exe` linking ror codes are
// four digit numbers in the range 1000 to 9999 inclusive
if is_msvc_link_exe && (code < 1000 || code > 9999) {
if is_msvc_link_exe(sess) && (code < 1000 || code > 9999) {
let is_vs_installed = find_msvc_tools::find_vs_version().is_ok();
let has_linker =
find_msvc_tools::find_tool(sess.target.arch.desc(), "link.exe")
Expand Down Expand Up @@ -912,46 +1050,13 @@ fn link_natively(
sess.dcx().abort_if_errors();
}

let stderr = escape_string(&prog.stderr);
let mut stdout = escape_string(&prog.stdout);
info!("linker stderr:\n{}", &stderr);
info!("linker stdout:\n{}", &stdout);

// Hide some progress messages from link.exe that we don't care about.
// See https://github.com/chromium/chromium/blob/bfa41e41145ffc85f041384280caf2949bb7bd72/build/toolchain/win/tool_wrapper.py#L144-L146
if is_msvc_link_exe {
if let Ok(str) = str::from_utf8(&prog.stdout) {
let mut output = String::with_capacity(str.len());
for line in stdout.lines() {
if line.starts_with(" Creating library")
|| line.starts_with("Generating code")
|| line.starts_with("Finished generating code")
{
continue;
}
output += line;
output += "\r\n"
}
stdout = escape_string(output.trim().as_bytes())
}
}

let level = codegen_results.crate_info.lint_levels.linker_messages;
let lint = |msg| {
diag_lint_level(sess, LINKER_MESSAGES, level, None, LinkerOutput { inner: msg });
};

if !prog.stderr.is_empty() {
// We already print `warning:` at the start of the diagnostic. Remove it from the linker output if present.
let stderr = stderr
.strip_prefix("warning: ")
.unwrap_or(&stderr)
.replace(": warning: ", ": ");
lint(format!("linker stderr: {stderr}"));
}
if !stdout.is_empty() {
lint(format!("linker stdout: {}", stdout))
}
info!("reporting linker output: flavor={flavor:?}");
report_linker_output(
sess,
codegen_results.crate_info.lint_levels,
&prog.stdout,
&prog.stderr,
);
}
Err(e) => {
let linker_not_found = e.kind() == io::ErrorKind::NotFound;
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_codegen_ssa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use rustc_data_structures::unord::UnordMap;
use rustc_hir::CRATE_HIR_ID;
use rustc_hir::attrs::{CfgEntry, NativeLibKind, WindowsSubsystemKind};
use rustc_hir::def_id::CrateNum;
use rustc_lint_defs::builtin::LINKER_INFO;
use rustc_macros::{Decodable, Encodable};
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::WorkProduct;
Expand Down Expand Up @@ -361,10 +362,14 @@ impl CodegenResults {
#[derive(Copy, Clone, Debug, Encodable, Decodable)]
pub struct CodegenLintLevels {
linker_messages: LevelAndSource,
linker_info: LevelAndSource,
}

impl CodegenLintLevels {
pub fn from_tcx(tcx: TyCtxt<'_>) -> Self {
Self { linker_messages: tcx.lint_level_at_node(LINKER_MESSAGES, CRATE_HIR_ID) }
Self {
linker_messages: tcx.lint_level_at_node(LINKER_MESSAGES, CRATE_HIR_ID),
linker_info: tcx.lint_level_at_node(LINKER_INFO, CRATE_HIR_ID),
}
}
}
Loading
Loading