Skip to content

Commit b0ce416

Browse files
committed
linker: Report linker flavors incompatible with the current target
Previously they would be reported as link time errors about unknown linker options
1 parent 2013ccc commit b0ce416

File tree

7 files changed

+51
-2
lines changed

7 files changed

+51
-2
lines changed

compiler/rustc_session/messages.ftl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ session_feature_gate_error = {$explain}
2727
session_file_is_not_writeable = output file {$file} is not writeable -- check its permissions
2828
2929
session_hexadecimal_float_literal_not_supported = hexadecimal float literal is not supported
30+
31+
session_incompatible_linker_flavor = linker flavor `{$flavor}` is incompatible with the current target
32+
.note = compatible flavors are: {$compatible_list}
33+
3034
session_incorrect_cgu_reuse_type =
3135
CGU-reuse for `{$cgu_user_name}` is `{$actual_reuse}` but should be {$at_least ->
3236
[one] {"at least "}

compiler/rustc_session/src/errors.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,3 +422,11 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
422422
pub struct OptimisationFuelExhausted {
423423
pub msg: String,
424424
}
425+
426+
#[derive(Diagnostic)]
427+
#[diag(session_incompatible_linker_flavor)]
428+
#[note]
429+
pub struct IncompatibleLinkerFlavor {
430+
pub flavor: &'static str,
431+
pub compatible_list: String,
432+
}

compiler/rustc_session/src/session.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,6 +1675,13 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
16751675
if sess.opts.unstable_opts.instrument_xray.is_some() && !sess.target.options.supports_xray {
16761676
sess.emit_err(errors::InstrumentationNotSupported { us: "XRay".to_string() });
16771677
}
1678+
1679+
if let Some(flavor) = sess.opts.cg.linker_flavor {
1680+
if let Some(compatible_list) = sess.target.linker_flavor.check_compatibility(flavor) {
1681+
let flavor = flavor.desc();
1682+
sess.emit_err(errors::IncompatibleLinkerFlavor { flavor, compatible_list });
1683+
}
1684+
}
16781685
}
16791686

16801687
/// Holds data on the current incremental compilation session, if there is one.

compiler/rustc_target/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#![feature(assert_matches)]
1212
#![feature(associated_type_bounds)]
1313
#![feature(exhaustive_patterns)]
14+
#![feature(iter_intersperse)]
1415
#![feature(min_specialization)]
1516
#![feature(never_type)]
1617
#![feature(rustc_attrs)]

compiler/rustc_target/src/spec/mod.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,19 @@ impl LinkerFlavor {
319319
self.with_hints(LinkerFlavor::infer_linker_hints(linker_stem))
320320
}
321321

322+
pub fn check_compatibility(self, cli: LinkerFlavorCli) -> Option<String> {
323+
// The CLI flavor should be compatible with the target if it survives this roundtrip.
324+
let compatible = |cli| cli == self.with_cli_hints(cli).to_cli();
325+
(!compatible(cli)).then(|| {
326+
LinkerFlavorCli::all()
327+
.iter()
328+
.filter(|cli| compatible(**cli))
329+
.map(|cli| cli.desc())
330+
.intersperse(", ")
331+
.collect()
332+
})
333+
}
334+
322335
pub fn lld_flavor(self) -> LldFlavor {
323336
match self {
324337
LinkerFlavor::Gnu(..)
@@ -340,6 +353,10 @@ impl LinkerFlavor {
340353
macro_rules! linker_flavor_cli_impls {
341354
($(($($flavor:tt)*) $string:literal)*) => (
342355
impl LinkerFlavorCli {
356+
const fn all() -> &'static [LinkerFlavorCli] {
357+
&[$($($flavor)*,)*]
358+
}
359+
343360
pub const fn one_of() -> &'static str {
344361
concat!("one of: ", $($string, " ",)*)
345362
}
@@ -351,8 +368,8 @@ macro_rules! linker_flavor_cli_impls {
351368
})
352369
}
353370

354-
pub fn desc(&self) -> &str {
355-
match *self {
371+
pub fn desc(self) -> &'static str {
372+
match self {
356373
$($($flavor)* => $string,)*
357374
}
358375
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// compile-flags: --target=x86_64-unknown-linux-gnu -C linker-flavor=msvc --crate-type=rlib
2+
// error-pattern: linker flavor `msvc` is incompatible with the current target
3+
// needs-llvm-components:
4+
5+
#![feature(no_core)]
6+
#![no_core]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
error: linker flavor `msvc` is incompatible with the current target
2+
|
3+
= note: compatible flavors are: gcc, ld, ld.lld
4+
5+
error: aborting due to previous error
6+

0 commit comments

Comments
 (0)