Skip to content

Commit 23ee523

Browse files
committed
Remove CodegenBackend::target_override.
Backend and target selection is a mess: the target can override the backend (via `Target::default_codegen_backend`), *and* the backend can override the target (via `CodegenBackend::target_override`). The code that handles this is ugly. It calls `build_target_config` twice, once before getting the backend and once again afterward. It also must check that both overrides aren't triggering at the same time. This commit removes the latter override. It's used in rust-gpu but @eddyb said via Zulip that removing it would be ok. This simplifies the code greatly, and will allow some nice follow-up refactorings.
1 parent e3df96c commit 23ee523

File tree

6 files changed

+37
-80
lines changed

6 files changed

+37
-80
lines changed

compiler/rustc_codegen_ssa/src/traits/backend.rs

-7
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use rustc_session::{
2121
};
2222
use rustc_span::symbol::Symbol;
2323
use rustc_target::abi::call::FnAbi;
24-
use rustc_target::spec::Target;
2524

2625
use std::fmt;
2726

@@ -70,12 +69,6 @@ pub trait CodegenBackend {
7069
fn print_passes(&self) {}
7170
fn print_version(&self) {}
7271

73-
/// If this plugin provides additional builtin targets, provide the one enabled by the options here.
74-
/// Be careful: this is called *before* init() is called.
75-
fn target_override(&self, _opts: &config::Options) -> Option<Target> {
76-
None
77-
}
78-
7972
/// The metadata loader used to load rlib and dylib metadata.
8073
///
8174
/// Alternative codegen backends may want to use different rlib or dylib formats than the

compiler/rustc_driver_impl/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,7 @@ pub fn version_at_macro_invocation(
890890
let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend="));
891891
let opts = config::Options::default();
892892
let sysroot = filesearch::materialize_sysroot(opts.maybe_sysroot.clone());
893-
let target = config::build_target_config(early_dcx, &opts, None, &sysroot);
893+
let target = config::build_target_config(early_dcx, &opts, &sysroot);
894894

895895
get_codegen_backend(early_dcx, &sysroot, backend_name, &target).print_version();
896896
}
@@ -1100,7 +1100,7 @@ pub fn describe_flag_categories(early_dcx: &EarlyDiagCtxt, matches: &Matches) ->
11001100

11011101
let opts = config::Options::default();
11021102
let sysroot = filesearch::materialize_sysroot(opts.maybe_sysroot.clone());
1103-
let target = config::build_target_config(early_dcx, &opts, None, &sysroot);
1103+
let target = config::build_target_config(early_dcx, &opts, &sysroot);
11041104

11051105
get_codegen_backend(early_dcx, &sysroot, backend_name, &target).print_passes();
11061106
return true;

compiler/rustc_interface/src/interface.rs

+13-42
Original file line numberDiff line numberDiff line change
@@ -341,51 +341,22 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
341341

342342
let sysroot = filesearch::materialize_sysroot(config.opts.maybe_sysroot.clone());
343343

344-
let (codegen_backend, target_override) = match config.make_codegen_backend {
345-
None => {
346-
// Build a target without override, so that it can override the backend if needed
347-
let target =
348-
config::build_target_config(&early_dcx, &config.opts, None, &sysroot);
349-
350-
let backend = util::get_codegen_backend(
351-
&early_dcx,
352-
&sysroot,
353-
config.opts.unstable_opts.codegen_backend.as_deref(),
354-
&target,
355-
);
356-
357-
// target_override is documented to be called before init(), so this is okay
358-
let target_override = backend.target_override(&config.opts);
359-
360-
// Assert that we don't use target's override of the backend and
361-
// backend's override of the target at the same time
362-
if config.opts.unstable_opts.codegen_backend.is_none()
363-
&& target.default_codegen_backend.is_some()
364-
&& target_override.is_some()
365-
{
366-
rustc_middle::bug!(
367-
"Codegen backend requested target override even though the target requested the backend"
368-
);
369-
}
370-
371-
(backend, target_override)
372-
}
344+
let target = config::build_target_config(&early_dcx, &config.opts, &sysroot);
345+
346+
let codegen_backend = match config.make_codegen_backend {
347+
None => util::get_codegen_backend(
348+
&early_dcx,
349+
&sysroot,
350+
config.opts.unstable_opts.codegen_backend.as_deref(),
351+
&target,
352+
),
373353
Some(make_codegen_backend) => {
374-
// N.B. `make_codegen_backend` takes precedence over `target.default_codegen_backend`,
375-
// which is ignored in this case.
376-
let backend = make_codegen_backend(&config.opts);
377-
378-
// target_override is documented to be called before init(), so this is okay
379-
let target_override = backend.target_override(&config.opts);
380-
381-
(backend, target_override)
354+
// N.B. `make_codegen_backend` takes precedence over
355+
// `target.default_codegen_backend`, which is ignored in this case.
356+
make_codegen_backend(&config.opts)
382357
}
383358
};
384359

385-
// Re-build target with the (potential) override
386-
let target_cfg =
387-
config::build_target_config(&early_dcx, &config.opts, target_override, &sysroot);
388-
389360
let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
390361

391362
let bundle = match rustc_errors::fluent_bundle(
@@ -418,7 +389,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
418389
locale_resources,
419390
config.lint_caps,
420391
config.file_loader,
421-
target_cfg,
392+
target,
422393
sysroot,
423394
util::rustc_version_str().unwrap_or("unknown"),
424395
config.ice_file,

compiler/rustc_interface/src/tests.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ fn mk_session(matches: getopts::Matches) -> (Session, Cfg) {
4141

4242
let sysroot = filesearch::materialize_sysroot(sessopts.maybe_sysroot.clone());
4343

44-
let target_cfg =
45-
rustc_session::config::build_target_config(&early_dcx, &sessopts, None, &sysroot);
44+
let target_cfg = rustc_session::config::build_target_config(&early_dcx, &sessopts, &sysroot);
4645

4746
let sess = build_session(
4847
early_dcx,

compiler/rustc_session/src/config.rs

+18-27
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, SourceFileHa
2222
use rustc_target::abi::Align;
2323
use rustc_target::spec::LinkSelfContainedComponents;
2424
use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, SplitDebuginfo};
25-
use rustc_target::spec::{Target, TargetTriple, TargetWarnings, TARGETS};
25+
use rustc_target::spec::{Target, TargetTriple, TARGETS};
2626
use std::collections::btree_map::{
2727
Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter,
2828
};
@@ -1549,34 +1549,25 @@ pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg {
15491549
user_cfg
15501550
}
15511551

1552-
pub fn build_target_config(
1553-
early_dcx: &EarlyDiagCtxt,
1554-
opts: &Options,
1555-
target_override: Option<Target>,
1556-
sysroot: &Path,
1557-
) -> Target {
1558-
let target_result = target_override.map_or_else(
1559-
|| Target::search(&opts.target_triple, sysroot),
1560-
|t| Ok((t, TargetWarnings::empty())),
1561-
);
1562-
let (target, target_warnings) = target_result.unwrap_or_else(|e| {
1563-
early_dcx.early_fatal(format!(
1552+
pub fn build_target_config(early_dcx: &EarlyDiagCtxt, opts: &Options, sysroot: &Path) -> Target {
1553+
match Target::search(&opts.target_triple, sysroot) {
1554+
Ok((target, warnings)) => {
1555+
for warning in warnings.warning_messages() {
1556+
early_dcx.early_warn(warning)
1557+
}
1558+
if !matches!(target.pointer_width, 16 | 32 | 64) {
1559+
early_dcx.early_fatal(format!(
1560+
"target specification was invalid: unrecognized target-pointer-width {}",
1561+
target.pointer_width
1562+
))
1563+
}
1564+
target
1565+
}
1566+
Err(e) => early_dcx.early_fatal(format!(
15641567
"Error loading target specification: {e}. \
1565-
Run `rustc --print target-list` for a list of built-in targets"
1566-
))
1567-
});
1568-
for warning in target_warnings.warning_messages() {
1569-
early_dcx.early_warn(warning)
1570-
}
1571-
1572-
if !matches!(target.pointer_width, 16 | 32 | 64) {
1573-
early_dcx.early_fatal(format!(
1574-
"target specification was invalid: unrecognized target-pointer-width {}",
1575-
target.pointer_width
1576-
))
1568+
Run `rustc --print target-list` for a list of built-in targets"
1569+
)),
15771570
}
1578-
1579-
target
15801571
}
15811572

15821573
#[derive(Copy, Clone, PartialEq, Eq, Debug)]

compiler/rustc_target/src/spec/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -2091,6 +2091,9 @@ pub struct TargetOptions {
20912091
/// compiling `rustc` will be used instead (or llvm if it is not set).
20922092
///
20932093
/// N.B. when *using* the compiler, backend can always be overridden with `-Zcodegen-backend`.
2094+
///
2095+
/// This was added by WaffleLapkin in #116793. The motivation is a rustc fork that requires a
2096+
/// custom codegen backend for a particular target.
20942097
pub default_codegen_backend: Option<StaticCow<str>>,
20952098

20962099
/// Whether to generate trap instructions in places where optimization would

0 commit comments

Comments
 (0)