Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
ded9c0e
Stop using dlltool for generating import libraries on MinGW
bjorn3 Jun 5, 2026
18018a8
Remove support for dlltool symbol name differences
bjorn3 Sep 9, 2026
47c9070
Parse move exprs as a bottom expr instead of a prefix expr
fmease Oct 7, 2026
604a21c
Document zero sized allocations in `Box` and `Vec`
maxdexh Sep 25, 2026
311c6e3
Revert "Rollup merge of #159562 - Joel-Wwalker:154071-stdio-handle-ca…
lhecker Oct 11, 2026
9a20a07
test(parser): add baseline for missing turbofish with lifetime in str…
raushan728 Sep 12, 2026
508d2f4
test DSL eagerly handle false constraints
born-in-autumn Oct 13, 2026
ebca075
fix(parser): recover missing turbofish for lifetimes in exprs
raushan728 Oct 3, 2026
eb85bf4
[rustdoc] Improve display of `rustc_must_implement_one_of` note and g…
GuillaumeGomez Oct 13, 2026
fe97485
[rustdoc] Generate sidebar link for "required methods" even if there …
GuillaumeGomez Oct 13, 2026
9b08cd0
Windows FileExt trait doesn't need to handle ErrorKind::Interrupted; …
json420 Oct 13, 2026
fca5ba9
Add regression test for higher-ranked param env normalization ICE
Kuksgauzen Oct 13, 2026
cad2ab9
Add regression test for `rustc_must_implement_one_of` changes
GuillaumeGomez Oct 13, 2026
6ffc09a
Add regression test for hang in overlap check with GAT alias
zakrad Oct 13, 2026
c097682
Remove the `span_use_eq_ctxt` lint
nnethercote Oct 6, 2026
9c1eb80
Prefer WriteConsoleW for stdout on Windows
lhecker Oct 14, 2026
6c150fe
fix some nits
born-in-autumn Oct 14, 2026
9aa0839
fix issue number for feature(unsized_const_params)
khyperia Oct 14, 2026
f5e4813
add test
mejrs Oct 11, 2026
f76d613
Use proper mod name for on_unknown attribute
mejrs Oct 14, 2026
6ea7076
Rollup merge of #157712 - bjorn3:remove_dlltool_usage, r=TaKO8Ki
JonathanBrouwer Oct 14, 2026
a00e4cd
Rollup merge of #162749 - raushan728:issues/162656, r=nnethercote
JonathanBrouwer Oct 14, 2026
437b644
Rollup merge of #164170 - lhecker:windows-stdout-perf-is-console, r=C…
JonathanBrouwer Oct 14, 2026
89f3bc5
Rollup merge of #164255 - born-in-autumn:dsl-test-handle, r=khyperia
JonathanBrouwer Oct 14, 2026
e2af6aa
Rollup merge of #163230 - maxdexh:zero-sized-allocations-are-not-real…
JonathanBrouwer Oct 14, 2026
9f994f0
Rollup merge of #163940 - fmease:move-expr-is-bottom-not-prefix, r=Ta…
JonathanBrouwer Oct 14, 2026
9cab1b4
Rollup merge of #164178 - mejrs:on_unknown-mod-names, r=mu001999
JonathanBrouwer Oct 14, 2026
ff51ed4
Rollup merge of #164219 - json420:windows-FileExt-test-cleanup, r=Chr…
JonathanBrouwer Oct 14, 2026
f92f5a7
Rollup merge of #164266 - GuillaumeGomez:rustc_must_implement_one_of,…
JonathanBrouwer Oct 14, 2026
50b4d8c
Rollup merge of #164272 - Kuksgauzen:test-155977, r=adwinwhite
JonathanBrouwer Oct 14, 2026
6bad5c6
Rollup merge of #164287 - zakrad:regr-test-151503, r=adwinwhite
JonathanBrouwer Oct 14, 2026
93ee7ec
Rollup merge of #164292 - nnethercote:rm-span_use_eq_ctxt, r=lqd,Kivooeo
JonathanBrouwer Oct 14, 2026
12c2769
Rollup merge of #164301 - khyperia:unsized-const-params-tracking-issu…
JonathanBrouwer Oct 14, 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
1 change: 1 addition & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4096,6 +4096,7 @@ pub struct TestBinderConstraints {

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct TestBinderBody {
pub span: Span,
pub foralls: ThinVec<TestBinderForall>,
pub exists: ThinVec<TestBinderExists>,
pub constraints: Vec<TestBinderConstraint>,
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2015,7 +2015,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
.iter()
.map(|predicate| self.lower_where_predicate(predicate, &[], &mut dedup_map)),
);
hir::TestBinderBody { foralls, exists, constraints, predicates }
let span = self.lower_span(body.span);
hir::TestBinderBody { foralls, exists, constraints, predicates, span }
}

fn lower_test_binder_forall(
Expand Down
8 changes: 1 addition & 7 deletions compiler/rustc_codegen_llvm/src/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,8 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t
let llfn = if tcx.sess.target.arch == Arch::X86
&& let Some(dllimport) = crate::common::get_dllimport(tcx, instance_def_id, sym)
{
// When calling functions in generated import libraries,
// LLVM/ar_archive_writer needs the fully decorated name
// (as would have been in the declaring object file), but dlltool
// wants the name as exported (as would be in the def file)
// which may be missing decorations.
let using_dlltool = common::is_using_dlltool(&tcx.sess.target);
let llfn = cx.declare_fn(
&common::i686_decorated_name(dllimport, using_dlltool, true, !using_dlltool),
&common::i686_decorated_name(dllimport, true, true),
fn_abi,
Some(instance),
);
Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_codegen_llvm/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use std::ops::Range;
use rustc_abi::{Align, ExternAbi, HasDataLayout, Primitive, Scalar, Size, WrappingRange};
use rustc_attr_ir::Linkage;
use rustc_attr_ir::lang_items::LangItem;
use rustc_codegen_ssa::common;
use rustc_codegen_ssa::traits::*;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
Expand All @@ -16,7 +15,6 @@ use rustc_middle::mono::MonoItem;
use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf};
use rustc_middle::ty::{self, Instance};
use rustc_span::{Symbol, bug, span_bug};
use rustc_target::spec::Arch;
use tracing::{debug, instrument, trace};

use crate::common::CodegenCx;
Expand Down Expand Up @@ -268,11 +266,6 @@ fn check_and_apply_linkage<'ll, 'tcx>(
llvm::set_initializer(g2, initializer);

g2
} else if cx.tcx.sess.target.arch == Arch::X86
&& common::is_using_dlltool(&cx.tcx.sess.target)
&& let Some(dllimport) = crate::common::get_dllimport(cx.tcx, def_id, sym)
{
cx.declare_global(&common::i686_decorated_name(dllimport, true, true, false), llty)
} else {
// Generate an external declaration.
// FIXME(nagisa): investigate whether it can be changed into define_global
Expand Down
238 changes: 50 additions & 188 deletions compiler/rustc_codegen_ssa/src/back/archive.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use std::borrow::Cow;
use std::env;
use std::error::Error;
use std::ffi::OsString;
use std::fs::{self, File};
use std::io::{self, BufWriter, Write};
use std::path::{Path, PathBuf};
Expand All @@ -24,13 +22,9 @@ use tracing::trace;
use super::metadata::{create_compressed_metadata_file, search_for_section};
use super::rmeta_link::{self, RmetaLinkCache};
use super::symbol_edit::{apply_edits, collect_internal_names};
use crate::common;
// Public for ArchiveBuilderBuilder::extract_bundled_libs
pub use crate::diagnostics::ExtractBundledLibsError;
use crate::diagnostics::{
ArchiveBuildFailure, DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorCreatingImportLibrary,
ErrorWritingDEFFile, UnknownArchiveKind,
};
use crate::diagnostics::{ArchiveBuildFailure, ErrorCreatingImportLibrary, UnknownArchiveKind};

/// An item to be included in an import library.
/// This is a slimmed down version of `COFFShortExport` from `ar-archive-writer`.
Expand Down Expand Up @@ -87,66 +81,57 @@ pub trait ArchiveBuilderBuilder {
items: Vec<ImportLibraryItem>,
output_path: &Path,
) {
if common::is_using_dlltool(&sess.target) {
// The binutils linker used on -windows-gnu targets cannot read the import
// libraries generated by LLVM: in our attempts, the linker produced an .EXE
// that loaded but crashed with an AV upon calling one of the imported
// functions. Therefore, use binutils to create the import library instead,
// by writing a .DEF file to the temp dir and calling binutils's dlltool.
create_mingw_dll_import_lib(sess, lib_name, items, output_path);
} else {
trace!("creating import library");
trace!(" dll_name {:#?}", lib_name);
trace!(" output_path {}", output_path.display());
trace!(
" import names: {}",
items
.iter()
.map(|ImportLibraryItem { name, .. }| name.clone())
.collect::<Vec<_>>()
.join(", "),
);

// All import names are Rust identifiers and therefore cannot contain \0 characters.
// FIXME: when support for #[link_name] is implemented, ensure that the import names
// still don't contain any \0 characters. Also need to check that the names don't
// contain substrings like " @" or "NONAME" that are keywords or otherwise reserved
// in definition files.

let mut file = match fs::File::create_new(&output_path) {
Ok(file) => file,
Err(error) => sess
.dcx()
.emit_fatal(ErrorCreatingImportLibrary { lib_name, error: error.to_string() }),
};
trace!("creating import library");
trace!(" dll_name {:#?}", lib_name);
trace!(" output_path {}", output_path.display());
trace!(
" import names: {}",
items
.iter()
.map(|ImportLibraryItem { name, .. }| name.clone())
.collect::<Vec<_>>()
.join(", "),
);

// All import names are Rust identifiers and therefore cannot contain \0 characters.
// FIXME: when support for #[link_name] is implemented, ensure that the import names
// still don't contain any \0 characters. Also need to check that the names don't
// contain substrings like " @" or "NONAME" that are keywords or otherwise reserved
// in definition files.

let mut file = match fs::File::create_new(&output_path) {
Ok(file) => file,
Err(error) => sess
.dcx()
.emit_fatal(ErrorCreatingImportLibrary { lib_name, error: error.to_string() }),
};

let exports =
items.into_iter().map(|item| item.into_coff_short_export(sess)).collect::<Vec<_>>();
let machine = match &sess.target.arch {
Arch::X86_64 => MachineTypes::AMD64,
Arch::X86 => MachineTypes::I386,
Arch::AArch64 => MachineTypes::ARM64,
Arch::Arm64EC => MachineTypes::ARM64EC,
Arch::Arm => MachineTypes::ARMNT,
cpu => panic!("unsupported cpu type {cpu}"),
};
let exports =
items.into_iter().map(|item| item.into_coff_short_export(sess)).collect::<Vec<_>>();
let machine = match &sess.target.arch {
Arch::X86_64 => MachineTypes::AMD64,
Arch::X86 => MachineTypes::I386,
Arch::AArch64 => MachineTypes::ARM64,
Arch::Arm64EC => MachineTypes::ARM64EC,
Arch::Arm => MachineTypes::ARMNT,
cpu => panic!("unsupported cpu type {cpu}"),
};

if let Err(error) = ar_archive_writer::write_import_library(
&mut file,
lib_name,
&exports,
machine,
!sess.target.is_like_msvc,
// 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() });
}
if let Err(error) = ar_archive_writer::write_import_library(
&mut file,
lib_name,
&exports,
machine,
!sess.target.is_like_msvc,
// 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() });
}
}

Expand Down Expand Up @@ -187,129 +172,6 @@ pub trait ArchiveBuilderBuilder {
}
}

fn create_mingw_dll_import_lib(
sess: &Session,
lib_name: &str,
items: Vec<ImportLibraryItem>,
output_path: &Path,
) {
let def_file_path = output_path.with_extension("def");

let def_file_content = format!(
"EXPORTS\n{}",
items
.into_iter()
.map(|ImportLibraryItem { name, ordinal, .. }| {
match ordinal {
Some(n) => format!("{name} @{n} NONAME"),
None => name,
}
})
.collect::<Vec<String>>()
.join("\n")
);

match std::fs::write(&def_file_path, def_file_content) {
Ok(_) => {}
Err(e) => {
sess.dcx().emit_fatal(ErrorWritingDEFFile { error: e });
}
};

// --no-leading-underscore: For the `import_name_type` feature to work, we need to be
// able to control the *exact* spelling of each of the symbols that are being imported:
// hence we don't want `dlltool` adding leading underscores automatically.
let dlltool = find_binutils_dlltool(sess);
// temp_prefix doesn't handle paths with spaces so
// use a relative path and set the current working directory
let cwd = output_path.parent().unwrap_or(output_path);
let temp_prefix = lib_name;
// dlltool target architecture args from:
// https://github.com/llvm/llvm-project-release-prs/blob/llvmorg-15.0.6/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp#L69
let (dlltool_target_arch, dlltool_target_bitness) = match &sess.target.arch {
Arch::X86_64 => ("i386:x86-64", "--64"),
Arch::X86 => ("i386", "--32"),
Arch::AArch64 => ("arm64", "--64"),
Arch::Arm => ("arm", "--32"),
arch => panic!("unsupported arch {arch}"),
};
let mut dlltool_cmd = std::process::Command::new(&dlltool);
dlltool_cmd
.arg("-d")
.arg(def_file_path)
.arg("-D")
.arg(lib_name)
.arg("-l")
.arg(&output_path)
.arg("-m")
.arg(dlltool_target_arch)
.arg("-f")
.arg(dlltool_target_bitness)
.arg("--no-leading-underscore")
.arg("--temp-prefix")
.arg(temp_prefix)
.current_dir(cwd);

match dlltool_cmd.output() {
Err(e) => {
sess.dcx().emit_fatal(ErrorCallingDllTool {
dlltool_path: dlltool.to_string_lossy(),
error: e,
});
}
// dlltool returns '0' on failure, so check for error output instead.
Ok(output) if !output.stderr.is_empty() => {
sess.dcx().emit_fatal(DlltoolFailImportLibrary {
dlltool_path: dlltool.to_string_lossy(),
dlltool_args: dlltool_cmd
.get_args()
.map(|arg| arg.to_string_lossy())
.collect::<Vec<_>>()
.join(" "),
stdout: String::from_utf8_lossy(&output.stdout),
stderr: String::from_utf8_lossy(&output.stderr),
})
}
_ => {}
}
}

fn find_binutils_dlltool(sess: &Session) -> OsString {
assert!(sess.target.options.is_like_windows && !sess.target.options.is_like_msvc);
if let Some(dlltool_path) = &sess.opts.cg.dlltool {
return dlltool_path.clone().into_os_string();
}

let tool_name: OsString = if sess.host.options.is_like_windows {
// If we're compiling on Windows, always use "dlltool.exe".
"dlltool.exe"
} else {
// On other platforms, use the architecture-specific name.
match sess.target.arch {
Arch::X86_64 => "x86_64-w64-mingw32-dlltool",
Arch::X86 => "i686-w64-mingw32-dlltool",
Arch::AArch64 => "aarch64-w64-mingw32-dlltool",

// For non-standard architectures (e.g., aarch32) fallback to "dlltool".
_ => "dlltool",
}
}
.into();

// NOTE: it's not clear how useful it is to explicitly search PATH.
for dir in env::split_paths(&env::var_os("PATH").unwrap_or_default()) {
let full_path = dir.join(&tool_name);
if full_path.is_file() {
return full_path.into_os_string();
}
}

// The user didn't specify the location of the dlltool binary, and we weren't able
// to find the appropriate one on the PATH. Just return the name of the tool
// and let the invocation fail with a hopefully useful error message.
tool_name
}

pub enum AddArchiveKind<'a> {
Rlib(&'a mut RmetaLinkCache, /*skip*/ &'a dyn Fn(&str, ArchiveEntryKind) -> bool),
Other,
Expand Down
10 changes: 4 additions & 6 deletions compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,16 @@ pub(super) fn create_raw_dylib_dll_import_libs<'a>(
let name_suffix = if is_direct_dependency { "_imports" } else { "_imports_indirect" };
let output_path = tmpdir.join(format!("{raw_dylib_name}{name_suffix}.lib"));

let using_dlltool = common::is_using_dlltool(&sess.target);

let items: Vec<ImportLibraryItem> = raw_dylib_imports
.iter()
.map(|import: &DllImport| {
if sess.target.arch == Arch::X86 {
ImportLibraryItem {
name: common::i686_decorated_name(import, using_dlltool, false, false),
name: common::i686_decorated_name(import, false, false),
ordinal: import.ordinal(),
symbol_name: import.is_missing_decorations().then(|| {
common::i686_decorated_name(import, using_dlltool, false, true)
}),
symbol_name: import
.is_missing_decorations()
.then(|| common::i686_decorated_name(import, false, true)),
is_data: import.symbol_type != DllImportSymbolType::Function,
}
} else {
Expand Down
12 changes: 2 additions & 10 deletions compiler/rustc_codegen_ssa/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use rustc_middle::mir::interpret::{GlobalAlloc, PointerArithmetic, Scalar};
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::{self, Instance, ScalarInt, TyCtxt};
use rustc_span::{Span, bug, span_bug};
use rustc_target::spec::{CfgAbi, Env, Os, Target};

use crate::traits::*;

Expand Down Expand Up @@ -199,13 +198,8 @@ pub fn asm_const_ptr_clean<'tcx>(tcx: TyCtxt<'tcx>, scalar: Scalar) -> Scalar {
}
}

pub fn is_using_dlltool(target: &Target) -> bool {
target.os == Os::Windows && target.env == Env::Gnu && target.cfg_abi == CfgAbi::Unspecified
}

pub fn i686_decorated_name(
dll_import: &DllImport,
mingw: bool,
disable_name_mangling: bool,
force_fully_decorated: bool,
) -> String {
Expand All @@ -231,12 +225,10 @@ pub fn i686_decorated_name(
let prefix = if add_prefix && dll_import.symbol_type == DllImportSymbolType::Function {
match dll_import.calling_convention {
DllCallingConvention::C | DllCallingConvention::Vectorcall(_) => None,
DllCallingConvention::Stdcall(_) => (!mingw
|| dll_import.import_name_type == Some(PeImportNameType::Decorated))
.then_some('_'),
DllCallingConvention::Stdcall(_) => Some('_'),
DllCallingConvention::Fastcall(_) => Some('@'),
}
} else if dll_import.symbol_type != DllImportSymbolType::Function && !mingw {
} else if dll_import.symbol_type != DllImportSymbolType::Function {
// For static variables, prefix with '_' on MSVC.
Some('_')
} else {
Expand Down
Loading
Loading