linker: Report linker flavors incompatible with the current target

Previously they would be reported as link time errors about unknown linker options
This commit is contained in:
Vadim Petrochenkov 2023-04-25 15:48:53 +03:00
parent 2013ccc218
commit b0ce4164f0
7 changed files with 51 additions and 2 deletions

View file

@ -27,6 +27,10 @@ session_feature_gate_error = {$explain}
session_file_is_not_writeable = output file {$file} is not writeable -- check its permissions
session_hexadecimal_float_literal_not_supported = hexadecimal float literal is not supported
session_incompatible_linker_flavor = linker flavor `{$flavor}` is incompatible with the current target
.note = compatible flavors are: {$compatible_list}
session_incorrect_cgu_reuse_type =
CGU-reuse for `{$cgu_user_name}` is `{$actual_reuse}` but should be {$at_least ->
[one] {"at least "}

View file

@ -422,3 +422,11 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
pub struct OptimisationFuelExhausted {
pub msg: String,
}
#[derive(Diagnostic)]
#[diag(session_incompatible_linker_flavor)]
#[note]
pub struct IncompatibleLinkerFlavor {
pub flavor: &'static str,
pub compatible_list: String,
}

View file

@ -1675,6 +1675,13 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
if sess.opts.unstable_opts.instrument_xray.is_some() && !sess.target.options.supports_xray {
sess.emit_err(errors::InstrumentationNotSupported { us: "XRay".to_string() });
}
if let Some(flavor) = sess.opts.cg.linker_flavor {
if let Some(compatible_list) = sess.target.linker_flavor.check_compatibility(flavor) {
let flavor = flavor.desc();
sess.emit_err(errors::IncompatibleLinkerFlavor { flavor, compatible_list });
}
}
}
/// Holds data on the current incremental compilation session, if there is one.

View file

@ -11,6 +11,7 @@
#![feature(assert_matches)]
#![feature(associated_type_bounds)]
#![feature(exhaustive_patterns)]
#![feature(iter_intersperse)]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(rustc_attrs)]

View file

@ -319,6 +319,19 @@ impl LinkerFlavor {
self.with_hints(LinkerFlavor::infer_linker_hints(linker_stem))
}
pub fn check_compatibility(self, cli: LinkerFlavorCli) -> Option<String> {
// The CLI flavor should be compatible with the target if it survives this roundtrip.
let compatible = |cli| cli == self.with_cli_hints(cli).to_cli();
(!compatible(cli)).then(|| {
LinkerFlavorCli::all()
.iter()
.filter(|cli| compatible(**cli))
.map(|cli| cli.desc())
.intersperse(", ")
.collect()
})
}
pub fn lld_flavor(self) -> LldFlavor {
match self {
LinkerFlavor::Gnu(..)
@ -340,6 +353,10 @@ impl LinkerFlavor {
macro_rules! linker_flavor_cli_impls {
($(($($flavor:tt)*) $string:literal)*) => (
impl LinkerFlavorCli {
const fn all() -> &'static [LinkerFlavorCli] {
&[$($($flavor)*,)*]
}
pub const fn one_of() -> &'static str {
concat!("one of: ", $($string, " ",)*)
}
@ -351,8 +368,8 @@ macro_rules! linker_flavor_cli_impls {
})
}
pub fn desc(&self) -> &str {
match *self {
pub fn desc(self) -> &'static str {
match self {
$($($flavor)* => $string,)*
}
}

View file

@ -0,0 +1,6 @@
// compile-flags: --target=x86_64-unknown-linux-gnu -C linker-flavor=msvc --crate-type=rlib
// error-pattern: linker flavor `msvc` is incompatible with the current target
// needs-llvm-components:
#![feature(no_core)]
#![no_core]

View file

@ -0,0 +1,6 @@
error: linker flavor `msvc` is incompatible with the current target
|
= note: compatible flavors are: gcc, ld, ld.lld
error: aborting due to previous error