Skip to content

Commit 9859fda

Browse files
committed
Auto merge of rust-lang#136045 - matthiaskrgr:rollup-70c22eb, r=<try>
Rollup of 7 pull requests Successful merges: - rust-lang#130808 (Fix linking for symbols starting with ? on i686-pc-windows-msvc) - rust-lang#133138 (Target modifiers (special marked options) are recorded in metainfo) - rust-lang#133154 (Reword resolve errors caused by likely missing crate in dep tree) - rust-lang#135707 (Shorten linker output even more when `--verbose` is not present) - rust-lang#135764 (Fix tests on LLVM 20) - rust-lang#135785 (use `PassMode::Direct` for vector types on `s390x`) - rust-lang#135818 (tests: Port `translation` to rmake.rs) Failed merges: - rust-lang#133951 (Make the wasm_c_abi future compat warning a hard error) r? `@ghost` `@rustbot` modify labels: rollup try-job: aarch64-apple try-job: i686-mingw try-job: x86_64-gnu-llvm-19-3
2 parents 6365178 + 3cc4dd1 commit 9859fda

File tree

162 files changed

+1665
-445
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

162 files changed

+1665
-445
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3537,6 +3537,7 @@ dependencies = [
35373537
"ar_archive_writer",
35383538
"arrayvec",
35393539
"bitflags",
3540+
"bstr",
35403541
"cc",
35413542
"either",
35423543
"itertools",

compiler/rustc_codegen_ssa/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ edition = "2021"
88
ar_archive_writer = "0.4.2"
99
arrayvec = { version = "0.7", default-features = false }
1010
bitflags = "2.4.1"
11+
bstr = "1.11.3"
1112
# Pinned so `cargo update` bumps don't cause breakage. Please also update the
1213
# `cc` in `rustc_llvm` if you update the `cc` here.
1314
cc = "=1.2.7"

compiler/rustc_codegen_ssa/src/back/command.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub(crate) struct Command {
1313
args: Vec<OsString>,
1414
env: Vec<(OsString, OsString)>,
1515
env_remove: Vec<OsString>,
16+
env_clear: bool,
1617
}
1718

1819
#[derive(Clone)]
@@ -36,7 +37,13 @@ impl Command {
3637
}
3738

3839
fn _new(program: Program) -> Command {
39-
Command { program, args: Vec::new(), env: Vec::new(), env_remove: Vec::new() }
40+
Command {
41+
program,
42+
args: Vec::new(),
43+
env: Vec::new(),
44+
env_remove: Vec::new(),
45+
env_clear: false,
46+
}
4047
}
4148

4249
pub(crate) fn arg<P: AsRef<OsStr>>(&mut self, arg: P) -> &mut Command {
@@ -79,6 +86,11 @@ impl Command {
7986
self
8087
}
8188

89+
pub(crate) fn env_clear(&mut self) -> &mut Command {
90+
self.env_clear = true;
91+
self
92+
}
93+
8294
fn _env_remove(&mut self, key: &OsStr) {
8395
self.env_remove.push(key.to_owned());
8496
}
@@ -106,6 +118,9 @@ impl Command {
106118
for k in &self.env_remove {
107119
ret.env_remove(k);
108120
}
121+
if self.env_clear {
122+
ret.env_clear();
123+
}
109124
ret
110125
}
111126

compiler/rustc_codegen_ssa/src/back/link.rs

+1
Original file line numberDiff line numberDiff line change
@@ -991,6 +991,7 @@ fn link_natively(
991991
command: cmd,
992992
escaped_output,
993993
verbose: sess.opts.verbose,
994+
sysroot_dir: sess.sysroot.clone(),
994995
};
995996
sess.dcx().emit_err(err);
996997
// If MSVC's `link.exe` was expected but the return code

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

+3
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,9 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
577577
}
578578

579579
let prefix = match &target.arch[..] {
580+
"x86" | "x86_64" if target.is_like_msvc && undecorated.starts_with("?") => {
581+
return undecorated;
582+
}
580583
"x86" => Some('_'),
581584
"x86_64" => None,
582585
"arm64ec" => Some('#'),

compiler/rustc_codegen_ssa/src/errors.rs

+47-15
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ pub(crate) struct LinkingFailed<'a> {
351351
pub command: Command,
352352
pub escaped_output: String,
353353
pub verbose: bool,
354+
pub sysroot_dir: PathBuf,
354355
}
355356

356357
impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> {
@@ -364,6 +365,8 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> {
364365
if self.verbose {
365366
diag.note(format!("{:?}", self.command));
366367
} else {
368+
self.command.env_clear();
369+
367370
enum ArgGroup {
368371
Regular(OsString),
369372
Objects(usize),
@@ -398,26 +401,55 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> {
398401
args.push(ArgGroup::Regular(arg));
399402
}
400403
}
401-
self.command.args(args.into_iter().map(|arg_group| match arg_group {
402-
ArgGroup::Regular(arg) => arg,
403-
ArgGroup::Objects(n) => OsString::from(format!("<{n} object files omitted>")),
404-
ArgGroup::Rlibs(dir, rlibs) => {
405-
let mut arg = dir.into_os_string();
406-
arg.push("/{");
407-
let mut first = true;
408-
for rlib in rlibs {
409-
if !first {
410-
arg.push(",");
404+
let crate_hash = regex::bytes::Regex::new(r"-[0-9a-f]+\.rlib$").unwrap();
405+
self.command.args(args.into_iter().map(|arg_group| {
406+
match arg_group {
407+
// SAFETY: we are only matching on ASCII, not any surrogate pairs, so any replacements we do will still be valid.
408+
ArgGroup::Regular(arg) => unsafe {
409+
use bstr::ByteSlice;
410+
OsString::from_encoded_bytes_unchecked(
411+
arg.as_encoded_bytes().replace(
412+
self.sysroot_dir.as_os_str().as_encoded_bytes(),
413+
b"<sysroot>",
414+
),
415+
)
416+
},
417+
ArgGroup::Objects(n) => OsString::from(format!("<{n} object files omitted>")),
418+
ArgGroup::Rlibs(mut dir, rlibs) => {
419+
let is_sysroot_dir = match dir.strip_prefix(&self.sysroot_dir) {
420+
Ok(short) => {
421+
dir = Path::new("<sysroot>").join(short);
422+
true
423+
}
424+
Err(_) => false,
425+
};
426+
let mut arg = dir.into_os_string();
427+
arg.push("/{");
428+
let mut first = true;
429+
for mut rlib in rlibs {
430+
if !first {
431+
arg.push(",");
432+
}
433+
first = false;
434+
if is_sysroot_dir {
435+
// SAFETY: Regex works one byte at a type, and our regex will not match surrogate pairs (because it only matches ascii).
436+
rlib = unsafe {
437+
OsString::from_encoded_bytes_unchecked(
438+
crate_hash
439+
.replace(rlib.as_encoded_bytes(), b"-*")
440+
.into_owned(),
441+
)
442+
};
443+
}
444+
arg.push(rlib);
411445
}
412-
first = false;
413-
arg.push(rlib);
446+
arg.push("}.rlib");
447+
arg
414448
}
415-
arg.push("}");
416-
arg
417449
}
418450
}));
419451

420-
diag.note(format!("{:?}", self.command));
452+
diag.note(format!("{:?}", self.command).trim_start_matches("env -i").to_owned());
421453
diag.note("some arguments are omitted. use `--verbose` to show all linker arguments");
422454
}
423455

compiler/rustc_error_codes/src/error_codes/E0433.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ If you've expected to use a crate name:
1919

2020
```compile_fail
2121
use ferris_wheel::BigO;
22-
// error: failed to resolve: use of undeclared crate or module `ferris_wheel`
22+
// error: failed to resolve: use of undeclared module or unlinked crate
2323
```
2424

2525
Make sure the crate has been added as a dependency in `Cargo.toml`.

compiler/rustc_interface/src/passes.rs

+1
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ fn configure_and_expand(
269269

270270
resolver.resolve_crate(&krate);
271271

272+
CStore::from_tcx(tcx).report_incompatible_target_modifiers(tcx, &krate);
272273
krate
273274
}
274275

compiler/rustc_metadata/messages.ftl

+10
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,14 @@ metadata_incompatible_rustc =
113113
found crate `{$crate_name}` compiled by an incompatible version of rustc{$add_info}
114114
.help = please recompile that crate using this compiler ({$rustc_version}) (consider running `cargo clean` first)
115115
116+
metadata_incompatible_target_modifiers =
117+
mixing `{$flag_name_prefixed}` will cause an ABI mismatch in crate `{$local_crate}`
118+
.note = `{$flag_name_prefixed}={$flag_local_value}` in this crate is incompatible with `{$flag_name_prefixed}={$flag_extern_value}` in dependency `{$extern_crate}`
119+
.help = the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
120+
121+
metadata_incompatible_target_modifiers_help_allow = if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch={$flag_name}` to silence this error
122+
metadata_incompatible_target_modifiers_help_fix = set `{$flag_name_prefixed}={$flag_extern_value}` in this crate or `{$flag_name_prefixed}={$flag_local_value}` in `{$extern_crate}`
123+
116124
metadata_incompatible_wasm_link =
117125
`wasm_import_module` is incompatible with other arguments in `#[link]` attributes
118126
@@ -284,6 +292,8 @@ metadata_unknown_link_kind =
284292
metadata_unknown_link_modifier =
285293
unknown linking modifier `{$modifier}`, expected one of: bundle, verbatim, whole-archive, as-needed
286294
295+
metadata_unknown_target_modifier_unsafe_allowed = unknown target modifier `{$flag_name}`, requested by `-Cunsafe-allow-abi-mismatch={$flag_name}`
296+
287297
metadata_unsupported_abi =
288298
ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture
289299

compiler/rustc_metadata/src/creader.rs

+118-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ use rustc_hir::definitions::Definitions;
2323
use rustc_index::IndexVec;
2424
use rustc_middle::bug;
2525
use rustc_middle::ty::{TyCtxt, TyCtxtFeed};
26-
use rustc_session::config::{self, CrateType, ExternLocation};
26+
use rustc_session::config::{
27+
self, CrateType, ExtendedTargetModifierInfo, ExternLocation, OptionsTargetModifiers,
28+
TargetModifier,
29+
};
2730
use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate, ExternCrateSource};
2831
use rustc_session::lint::{self, BuiltinLintDiag};
2932
use rustc_session::output::validate_crate_name;
@@ -35,7 +38,9 @@ use tracing::{debug, info, trace};
3538

3639
use crate::errors;
3740
use crate::locator::{CrateError, CrateLocator, CratePaths};
38-
use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob};
41+
use crate::rmeta::{
42+
CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob, TargetModifiers,
43+
};
3944

4045
/// The backend's way to give the crate store access to the metadata in a library.
4146
/// Note that it returns the raw metadata bytes stored in the library file, whether
@@ -296,6 +301,96 @@ impl CStore {
296301
}
297302
}
298303

304+
fn report_target_modifiers_extended(
305+
tcx: TyCtxt<'_>,
306+
krate: &Crate,
307+
mods: &Vec<TargetModifier>,
308+
data: &CrateMetadata,
309+
) {
310+
let span = krate.spans.inner_span.shrink_to_lo();
311+
let allowed_flag_mismatches = &tcx.sess.opts.cg.unsafe_allow_abi_mismatch;
312+
let name = tcx.crate_name(LOCAL_CRATE);
313+
let tmod_extender = |tmod: &TargetModifier| (tmod.extend(), tmod.clone());
314+
let report_diff = |prefix: &String,
315+
opt_name: &String,
316+
flag_local_value: &String,
317+
flag_extern_value: &String| {
318+
if allowed_flag_mismatches.contains(&opt_name) {
319+
return;
320+
}
321+
tcx.dcx().emit_err(errors::IncompatibleTargetModifiers {
322+
span,
323+
extern_crate: data.name(),
324+
local_crate: name,
325+
flag_name: opt_name.clone(),
326+
flag_name_prefixed: format!("-{}{}", prefix, opt_name),
327+
flag_local_value: flag_local_value.to_string(),
328+
flag_extern_value: flag_extern_value.to_string(),
329+
});
330+
};
331+
let mut it1 = mods.iter().map(tmod_extender);
332+
let mut it2 = data.target_modifiers().iter().map(tmod_extender);
333+
let mut left_name_val: Option<(ExtendedTargetModifierInfo, TargetModifier)> = None;
334+
let mut right_name_val: Option<(ExtendedTargetModifierInfo, TargetModifier)> = None;
335+
let no_val = "*".to_string();
336+
loop {
337+
left_name_val = left_name_val.or_else(|| it1.next());
338+
right_name_val = right_name_val.or_else(|| it2.next());
339+
match (&left_name_val, &right_name_val) {
340+
(Some(l), Some(r)) => match l.1.opt.cmp(&r.1.opt) {
341+
cmp::Ordering::Equal => {
342+
if l.0.tech_value != r.0.tech_value {
343+
report_diff(&l.0.prefix, &l.0.name, &l.1.value_name, &r.1.value_name);
344+
}
345+
left_name_val = None;
346+
right_name_val = None;
347+
}
348+
cmp::Ordering::Greater => {
349+
report_diff(&r.0.prefix, &r.0.name, &no_val, &r.1.value_name);
350+
right_name_val = None;
351+
}
352+
cmp::Ordering::Less => {
353+
report_diff(&l.0.prefix, &l.0.name, &l.1.value_name, &no_val);
354+
left_name_val = None;
355+
}
356+
},
357+
(Some(l), None) => {
358+
report_diff(&l.0.prefix, &l.0.name, &l.1.value_name, &no_val);
359+
left_name_val = None;
360+
}
361+
(None, Some(r)) => {
362+
report_diff(&r.0.prefix, &r.0.name, &no_val, &r.1.value_name);
363+
right_name_val = None;
364+
}
365+
(None, None) => break,
366+
}
367+
}
368+
}
369+
370+
pub fn report_incompatible_target_modifiers(&self, tcx: TyCtxt<'_>, krate: &Crate) {
371+
for flag_name in &tcx.sess.opts.cg.unsafe_allow_abi_mismatch {
372+
if !OptionsTargetModifiers::is_target_modifier(flag_name) {
373+
tcx.dcx().emit_err(errors::UnknownTargetModifierUnsafeAllowed {
374+
span: krate.spans.inner_span.shrink_to_lo(),
375+
flag_name: flag_name.clone(),
376+
});
377+
}
378+
}
379+
380+
if tcx.crate_types().contains(&CrateType::ProcMacro) {
381+
return;
382+
}
383+
let mods = tcx.sess.opts.gather_target_modifiers();
384+
for (_cnum, data) in self.iter_crate_data() {
385+
if data.is_proc_macro_crate() {
386+
continue;
387+
}
388+
if mods != *data.target_modifiers() {
389+
Self::report_target_modifiers_extended(tcx, krate, &mods, data);
390+
}
391+
}
392+
}
393+
299394
pub fn new(metadata_loader: Box<MetadataLoaderDyn>) -> CStore {
300395
CStore {
301396
metadata_loader,
@@ -471,6 +566,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
471566
};
472567

473568
let cnum_map = self.resolve_crate_deps(dep_root, &crate_root, &metadata, cnum, dep_kind)?;
569+
let target_modifiers = self.resolve_target_modifiers(&crate_root, &metadata, cnum)?;
474570

475571
let raw_proc_macros = if crate_root.is_proc_macro_crate() {
476572
let temp_root;
@@ -495,6 +591,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
495591
raw_proc_macros,
496592
cnum,
497593
cnum_map,
594+
target_modifiers,
498595
dep_kind,
499596
source,
500597
private_dep,
@@ -738,6 +835,25 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
738835
Ok(crate_num_map)
739836
}
740837

838+
fn resolve_target_modifiers(
839+
&mut self,
840+
crate_root: &CrateRoot,
841+
metadata: &MetadataBlob,
842+
krate: CrateNum,
843+
) -> Result<TargetModifiers, CrateError> {
844+
debug!("resolving target modifiers of external crate");
845+
if crate_root.is_proc_macro_crate() {
846+
return Ok(TargetModifiers::new());
847+
}
848+
let mods = crate_root.decode_target_modifiers(metadata);
849+
let mut target_modifiers = TargetModifiers::with_capacity(mods.len());
850+
for modifier in mods {
851+
target_modifiers.push(modifier);
852+
}
853+
debug!("resolve_target_modifiers: target mods for {:?} is {:?}", krate, target_modifiers);
854+
Ok(target_modifiers)
855+
}
856+
741857
fn dlsym_proc_macros(
742858
&self,
743859
path: &Path,

compiler/rustc_metadata/src/errors.rs

+25
Original file line numberDiff line numberDiff line change
@@ -732,3 +732,28 @@ pub struct ImportNameTypeRaw {
732732
#[primary_span]
733733
pub span: Span,
734734
}
735+
736+
#[derive(Diagnostic)]
737+
#[diag(metadata_incompatible_target_modifiers)]
738+
#[help]
739+
#[note]
740+
#[help(metadata_incompatible_target_modifiers_help_fix)]
741+
#[help(metadata_incompatible_target_modifiers_help_allow)]
742+
pub struct IncompatibleTargetModifiers {
743+
#[primary_span]
744+
pub span: Span,
745+
pub extern_crate: Symbol,
746+
pub local_crate: Symbol,
747+
pub flag_name: String,
748+
pub flag_name_prefixed: String,
749+
pub flag_local_value: String,
750+
pub flag_extern_value: String,
751+
}
752+
753+
#[derive(Diagnostic)]
754+
#[diag(metadata_unknown_target_modifier_unsafe_allowed)]
755+
pub struct UnknownTargetModifierUnsafeAllowed {
756+
#[primary_span]
757+
pub span: Span,
758+
pub flag_name: String,
759+
}

0 commit comments

Comments
 (0)