From 97cc7003ca23289d04e4111b81453e2584856f54 Mon Sep 17 00:00:00 2001 From: Veera Date: Mon, 18 Mar 2024 11:26:30 -0400 Subject: Fix ICE: `global_asm!()` Don't Panic When Unable to Evaluate Constant A bit of an inelegant fix but given that the error is created only after call to `const_eval_poly()` and that the calling function cannot propagate the error anywhere else, the error has to be explicitly handled inside `mono_item.rs`. --- compiler/rustc_codegen_ssa/src/mono_item.rs | 46 ++++++++++++++++++----------- 1 file changed, 29 insertions(+), 17 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs index 7b7cdae0ed6..df564f705bc 100644 --- a/compiler/rustc_codegen_ssa/src/mono_item.rs +++ b/compiler/rustc_codegen_ssa/src/mono_item.rs @@ -2,6 +2,7 @@ use crate::base; use crate::common; use crate::traits::*; use rustc_hir as hir; +use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::mir::mono::MonoItem; use rustc_middle::mir::mono::{Linkage, Visibility}; use rustc_middle::ty; @@ -40,23 +41,34 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { .iter() .map(|(op, op_sp)| match *op { hir::InlineAsmOperand::Const { ref anon_const } => { - let const_value = cx - .tcx() - .const_eval_poly(anon_const.def_id.to_def_id()) - .unwrap_or_else(|_| { - span_bug!(*op_sp, "asm const cannot be resolved") - }); - let ty = cx - .tcx() - .typeck_body(anon_const.body) - .node_type(anon_const.hir_id); - let string = common::asm_const_to_str( - cx.tcx(), - *op_sp, - const_value, - cx.layout_of(ty), - ); - GlobalAsmOperandRef::Const { string } + match cx.tcx().const_eval_poly(anon_const.def_id.to_def_id()) { + Ok(const_value) => { + let ty = cx + .tcx() + .typeck_body(anon_const.body) + .node_type(anon_const.hir_id); + let string = common::asm_const_to_str( + cx.tcx(), + *op_sp, + const_value, + cx.layout_of(ty), + ); + GlobalAsmOperandRef::Const { string } + } + Err(ErrorHandled::Reported { .. }) => { + // An error has already been reported and + // compilation is guaranteed to fail if execution + // hits this path. So an empty string instead of + // a stringified constant value will suffice. + GlobalAsmOperandRef::Const { string: String::new() } + } + Err(ErrorHandled::TooGeneric(_)) => { + span_bug!( + *op_sp, + "asm const cannot be resolved; too generic" + ) + } + } } hir::InlineAsmOperand::SymFn { ref anon_const } => { let ty = cx -- cgit 1.4.1-3-g733a5 From 3e5c468662d0137665a4381ad85912a763c7a3ef Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 5 Mar 2024 17:50:07 +0000 Subject: Make ptr_guaranteed_cmp a rustc_intrinsic and favor its body over backends implementing it --- .../rustc_codegen_cranelift/src/intrinsics/mod.rs | 7 ------ compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 7 ------ compiler/rustc_hir_analysis/src/check/intrinsic.rs | 2 +- library/core/src/intrinsics.rs | 27 ++++++++++++++-------- 4 files changed, 19 insertions(+), 24 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index c802d9bbefb..25694af78f1 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -757,13 +757,6 @@ fn codegen_regular_intrinsic_call<'tcx>( ret.write_cvalue(fx, val); } - sym::ptr_guaranteed_cmp => { - intrinsic_args!(fx, args => (a, b); intrinsic); - - let val = crate::num::codegen_ptr_binop(fx, BinOp::Eq, a, b).load_scalar(fx); - ret.write_cvalue(fx, CValue::by_val(val, fx.layout_of(fx.tcx.types.u8))); - } - sym::caller_location => { intrinsic_args!(fx, args => (); intrinsic); diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index ba023f96107..5532ff6e6a5 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -1,7 +1,6 @@ use super::operand::{OperandRef, OperandValue}; use super::place::PlaceRef; use super::FunctionCx; -use crate::common::IntPredicate; use crate::errors; use crate::errors::InvalidMonomorphization; use crate::meth; @@ -456,12 +455,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return Ok(()); } - sym::ptr_guaranteed_cmp => { - let a = args[0].immediate(); - let b = args[1].immediate(); - bx.icmp(IntPredicate::IntEQ, a, b) - } - sym::ptr_offset_from | sym::ptr_offset_from_unsigned => { let ty = fn_args.type_at(0); let pointee_size = bx.layout_of(ty).size; diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 7a1fe3b1cdc..07054c184f4 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -441,7 +441,7 @@ pub fn check_intrinsic_type( sym::ptr_guaranteed_cmp => ( 1, - 0, + 1, vec![Ty::new_imm_ptr(tcx, param(0)), Ty::new_imm_ptr(tcx, param(0))], tcx.types.u8, ), diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 027a0e8effd..66e55a5e217 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2434,20 +2434,29 @@ extern "rust-intrinsic" { #[rustc_nounwind] pub fn ptr_offset_from_unsigned(ptr: *const T, base: *const T) -> usize; - /// See documentation of `<*const T>::guaranteed_eq` for details. - /// Returns `2` if the result is unknown. - /// Returns `1` if the pointers are guaranteed equal - /// Returns `0` if the pointers are guaranteed inequal - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")] #[rustc_safe_intrinsic] #[rustc_nounwind] + #[cfg(bootstrap)] pub fn ptr_guaranteed_cmp(ptr: *const T, other: *const T) -> u8; +} +/// See documentation of `<*const T>::guaranteed_eq` for details. +/// Returns `2` if the result is unknown. +/// Returns `1` if the pointers are guaranteed equal +/// Returns `0` if the pointers are guaranteed inequal +#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_intrinsic] +#[cfg(not(bootstrap))] +#[rustc_nounwind] +#[rustc_do_not_const_check] +#[inline] +pub const fn ptr_guaranteed_cmp(ptr: *const T, other: *const T) -> u8 { + (ptr == other) as u8 +} + +extern "rust-intrinsic" { /// Determines whether the raw bytes of the two values are equal. /// /// This is particularly handy for arrays, since it allows things like just -- cgit 1.4.1-3-g733a5 From a8f71cf2893e03ec0ef7663f680f5d816e80f801 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 12 Mar 2024 16:04:52 +0000 Subject: Remove all checks of `IntrinsicDef::must_be_overridden` except for the actual overrides in codegen --- compiler/rustc_codegen_ssa/src/back/symbol_export.rs | 4 ---- compiler/rustc_metadata/src/rmeta/encoder.rs | 11 +++-------- compiler/rustc_middle/src/hir/map/mod.rs | 4 +--- compiler/rustc_mir_build/src/build/mod.rs | 9 +++++++-- compiler/rustc_mir_transform/src/cross_crate_inline.rs | 4 ---- compiler/rustc_mir_transform/src/lib.rs | 6 ------ compiler/rustc_monomorphize/src/collector.rs | 5 ----- 7 files changed, 11 insertions(+), 32 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 87b6f0e914c..b19f52182b6 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -81,10 +81,6 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap {} diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 68911f579cd..0a9659745db 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1067,14 +1067,11 @@ fn should_encode_mir( // Full-fledged functions + closures DefKind::AssocFn | DefKind::Fn | DefKind::Closure => { let generics = tcx.generics_of(def_id); - let mut opt = tcx.sess.opts.unstable_opts.always_encode_mir + let opt = tcx.sess.opts.unstable_opts.always_encode_mir || (tcx.sess.opts.output_types.should_codegen() && reachable_set.contains(&def_id) && (generics.requires_monomorphization(tcx) || tcx.cross_crate_inlinable(def_id))); - if let Some(intrinsic) = tcx.intrinsic(def_id) { - opt &= !intrinsic.must_be_overridden; - } // The function has a `const` modifier or is in a `#[const_trait]`. let is_const_fn = tcx.is_const_fn_raw(def_id.to_def_id()) || tcx.is_const_default_method(def_id.to_def_id()); @@ -1704,10 +1701,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { { for &local_def_id in tcx.mir_keys(()) { if let DefKind::AssocFn | DefKind::Fn = tcx.def_kind(local_def_id) { - if tcx.intrinsic(local_def_id).map_or(true, |i| !i.must_be_overridden) { - record_array!(self.tables.deduced_param_attrs[local_def_id.to_def_id()] <- - self.tcx.deduced_param_attrs(local_def_id.to_def_id())); - } + record_array!(self.tables.deduced_param_attrs[local_def_id.to_def_id()] <- + self.tcx.deduced_param_attrs(local_def_id.to_def_id())); } } } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 57a88a03109..5043bd855cc 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1365,9 +1365,7 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> { fn visit_impl_item(&mut self, item: &'hir ImplItem<'hir>) { if associated_body(Node::ImplItem(item)).is_some() { - if !self.tcx.has_attr(item.owner_id.def_id, sym::rustc_intrinsic_must_be_overridden) { - self.body_owners.push(item.owner_id.def_id); - } + self.body_owners.push(item.owner_id.def_id); } self.impl_items.push(item.impl_item_id()); diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 411119b521b..acadfe7b35e 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -1013,8 +1013,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if let Some(source_scope) = scope { self.source_scope = source_scope; } - - self.expr_into_dest(Place::return_place(), block, expr_id) + if self.tcx.intrinsic(self.def_id).is_some_and(|i| i.must_be_overridden) { + let source_info = self.source_info(rustc_span::DUMMY_SP); + self.cfg.terminate(block, source_info, TerminatorKind::Unreachable); + self.cfg.start_new_block().unit() + } else { + self.expr_into_dest(Place::return_place(), block, expr_id) + } } fn set_correct_source_scope_for_arg( diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs index 07e6ecccaa4..483fd753e70 100644 --- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -23,10 +23,6 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { return false; } - if tcx.intrinsic(def_id).is_some_and(|i| i.must_be_overridden) { - return false; - } - // This just reproduces the logic from Instance::requires_inline. match tcx.def_kind(def_id) { DefKind::Ctor(..) | DefKind::Closure => return true, diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index afe228be127..c63bdff9a85 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -633,12 +633,6 @@ fn optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> &Body<'_> { } fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> { - if tcx.intrinsic(did).is_some_and(|i| i.must_be_overridden) { - span_bug!( - tcx.def_span(did), - "this intrinsic must be overridden by the codegen backend, it has no meaningful body", - ) - } if tcx.is_constructor(did.to_def_id()) { // There's no reason to run all of the MIR passes on constructors when // we can just output the MIR we want directly. This also saves const diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index d8bdbd8c442..abe691ba0d8 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1030,11 +1030,6 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> return false; } - if tcx.intrinsic(def_id).is_some_and(|i| i.must_be_overridden) { - // These are implemented by backends directly and have no meaningful body. - return false; - } - if def_id.is_local() { // Local items cannot be referred to locally without monomorphizing them locally. return true; -- cgit 1.4.1-3-g733a5 From 7c98b8293071cf1fce594e7f911410d8f906269f Mon Sep 17 00:00:00 2001 From: Douglas Young Date: Sat, 16 Mar 2024 14:17:10 +0000 Subject: Use MSVC-style escaping when passing a response/@ file to lld on windows LLD parses @ files like the command arguments on the platform it's on, so on windows it needs to follow the MSVC style to work correctly. Otherwise builds can fail if the linker command gets too long and the build path contains spaces. --- compiler/rustc_codegen_ssa/src/back/link.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index f5e8d5fc92a..cdd68331e0f 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -785,7 +785,7 @@ fn link_natively<'a>( let mut i = 0; loop { i += 1; - prog = sess.time("run_linker", || exec_linker(sess, &cmd, out_filename, tmpdir)); + prog = sess.time("run_linker", || exec_linker(sess, &cmd, out_filename, flavor, tmpdir)); let Ok(ref output) = prog else { break; }; @@ -1576,6 +1576,7 @@ fn exec_linker( sess: &Session, cmd: &Command, out_filename: &Path, + flavor: LinkerFlavor, tmpdir: &Path, ) -> io::Result { // When attempting to spawn the linker we run a risk of blowing out the @@ -1584,9 +1585,9 @@ fn exec_linker( // // Here we attempt to handle errors from the OS saying "your list of // arguments is too big" by reinvoking the linker again with an `@`-file - // that contains all the arguments. The theory is that this is then - // accepted on all linkers and the linker will read all its options out of - // there instead of looking at the command line. + // that contains all the arguments (aka 'response' files). + // The theory is that this is then accepted on all linkers and the linker + // will read all its options out of there instead of looking at the command line. if !cmd.very_likely_to_exceed_some_spawn_limit() { match cmd.command().stdout(Stdio::piped()).stderr(Stdio::piped()).spawn() { Ok(child) => { @@ -1606,8 +1607,12 @@ fn exec_linker( let mut args = String::new(); for arg in cmd2.take_args() { args.push_str( - &Escape { arg: arg.to_str().unwrap(), is_like_msvc: sess.target.is_like_msvc } - .to_string(), + &Escape { + arg: arg.to_str().unwrap(), + // LLD also uses MSVC-like parsing for @-files on windows + is_like_msvc: sess.target.is_like_msvc || (cfg!(windows) && flavor.uses_lld()), + } + .to_string(), ); args.push('\n'); } -- cgit 1.4.1-3-g733a5 From 6b0a706cb4ce8114f7e082955cd3e53bdc0bc976 Mon Sep 17 00:00:00 2001 From: Douglas Young Date: Wed, 20 Mar 2024 23:37:46 +0000 Subject: Update comment and remove special-case for Wasm targets which is incompatible with response-file changes --- compiler/rustc_codegen_ssa/src/back/command.rs | 6 ------ compiler/rustc_codegen_ssa/src/back/link.rs | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/command.rs b/compiler/rustc_codegen_ssa/src/back/command.rs index 9b0ba34135c..3a89be89951 100644 --- a/compiler/rustc_codegen_ssa/src/back/command.rs +++ b/compiler/rustc_codegen_ssa/src/back/command.rs @@ -100,12 +100,6 @@ impl Command { Program::Lld(ref p, flavor) => { let mut c = process::Command::new(p); c.arg("-flavor").arg(flavor.as_str()); - if let LldFlavor::Wasm = flavor { - // LLVM expects host-specific formatting for @file - // arguments, but we always generate posix formatted files - // at this time. Indicate as such. - c.arg("--rsp-quoting=posix"); - } c } }; diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index cdd68331e0f..c8b8594c0dd 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1609,7 +1609,7 @@ fn exec_linker( args.push_str( &Escape { arg: arg.to_str().unwrap(), - // LLD also uses MSVC-like parsing for @-files on windows + // LLD also uses MSVC-like parsing for @-files by default when running on windows hosts is_like_msvc: sess.target.is_like_msvc || (cfg!(windows) && flavor.uses_lld()), } .to_string(), -- cgit 1.4.1-3-g733a5 From 23ee523ea61355c332481566bb5a093f29cdce59 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 21 Mar 2024 10:35:19 +1100 Subject: 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. --- compiler/rustc_codegen_ssa/src/traits/backend.rs | 7 --- compiler/rustc_driver_impl/src/lib.rs | 4 +- compiler/rustc_interface/src/interface.rs | 55 ++++++------------------ compiler/rustc_interface/src/tests.rs | 3 +- compiler/rustc_session/src/config.rs | 45 ++++++++----------- compiler/rustc_target/src/spec/mod.rs | 3 ++ 6 files changed, 37 insertions(+), 80 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index e6d42c596d2..e8b9490d401 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -21,7 +21,6 @@ use rustc_session::{ }; use rustc_span::symbol::Symbol; use rustc_target::abi::call::FnAbi; -use rustc_target::spec::Target; use std::fmt; @@ -70,12 +69,6 @@ pub trait CodegenBackend { fn print_passes(&self) {} fn print_version(&self) {} - /// If this plugin provides additional builtin targets, provide the one enabled by the options here. - /// Be careful: this is called *before* init() is called. - fn target_override(&self, _opts: &config::Options) -> Option { - None - } - /// The metadata loader used to load rlib and dylib metadata. /// /// Alternative codegen backends may want to use different rlib or dylib formats than the diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 938f9f0beaa..716e31080dd 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -890,7 +890,7 @@ pub fn version_at_macro_invocation( let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend=")); let opts = config::Options::default(); let sysroot = filesearch::materialize_sysroot(opts.maybe_sysroot.clone()); - let target = config::build_target_config(early_dcx, &opts, None, &sysroot); + let target = config::build_target_config(early_dcx, &opts, &sysroot); get_codegen_backend(early_dcx, &sysroot, backend_name, &target).print_version(); } @@ -1100,7 +1100,7 @@ pub fn describe_flag_categories(early_dcx: &EarlyDiagCtxt, matches: &Matches) -> let opts = config::Options::default(); let sysroot = filesearch::materialize_sysroot(opts.maybe_sysroot.clone()); - let target = config::build_target_config(early_dcx, &opts, None, &sysroot); + let target = config::build_target_config(early_dcx, &opts, &sysroot); get_codegen_backend(early_dcx, &sysroot, backend_name, &target).print_passes(); return true; diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 1a82e6c6910..8ba14d37982 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -341,51 +341,22 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se let sysroot = filesearch::materialize_sysroot(config.opts.maybe_sysroot.clone()); - let (codegen_backend, target_override) = match config.make_codegen_backend { - None => { - // Build a target without override, so that it can override the backend if needed - let target = - config::build_target_config(&early_dcx, &config.opts, None, &sysroot); - - let backend = util::get_codegen_backend( - &early_dcx, - &sysroot, - config.opts.unstable_opts.codegen_backend.as_deref(), - &target, - ); - - // target_override is documented to be called before init(), so this is okay - let target_override = backend.target_override(&config.opts); - - // Assert that we don't use target's override of the backend and - // backend's override of the target at the same time - if config.opts.unstable_opts.codegen_backend.is_none() - && target.default_codegen_backend.is_some() - && target_override.is_some() - { - rustc_middle::bug!( - "Codegen backend requested target override even though the target requested the backend" - ); - } - - (backend, target_override) - } + let target = config::build_target_config(&early_dcx, &config.opts, &sysroot); + + let codegen_backend = match config.make_codegen_backend { + None => util::get_codegen_backend( + &early_dcx, + &sysroot, + config.opts.unstable_opts.codegen_backend.as_deref(), + &target, + ), Some(make_codegen_backend) => { - // N.B. `make_codegen_backend` takes precedence over `target.default_codegen_backend`, - // which is ignored in this case. - let backend = make_codegen_backend(&config.opts); - - // target_override is documented to be called before init(), so this is okay - let target_override = backend.target_override(&config.opts); - - (backend, target_override) + // N.B. `make_codegen_backend` takes precedence over + // `target.default_codegen_backend`, which is ignored in this case. + make_codegen_backend(&config.opts) } }; - // Re-build target with the (potential) override - let target_cfg = - config::build_target_config(&early_dcx, &config.opts, target_override, &sysroot); - let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from); let bundle = match rustc_errors::fluent_bundle( @@ -418,7 +389,7 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se locale_resources, config.lint_caps, config.file_loader, - target_cfg, + target, sysroot, util::rustc_version_str().unwrap_or("unknown"), config.ice_file, diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 4d8e749d1da..c796448e5ee 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -41,8 +41,7 @@ fn mk_session(matches: getopts::Matches) -> (Session, Cfg) { let sysroot = filesearch::materialize_sysroot(sessopts.maybe_sysroot.clone()); - let target_cfg = - rustc_session::config::build_target_config(&early_dcx, &sessopts, None, &sysroot); + let target_cfg = rustc_session::config::build_target_config(&early_dcx, &sessopts, &sysroot); let sess = build_session( early_dcx, diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index e6eb1a3e83c..a88ae268e27 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -22,7 +22,7 @@ use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, SourceFileHa use rustc_target::abi::Align; use rustc_target::spec::LinkSelfContainedComponents; use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, SplitDebuginfo}; -use rustc_target::spec::{Target, TargetTriple, TargetWarnings, TARGETS}; +use rustc_target::spec::{Target, TargetTriple, TARGETS}; use std::collections::btree_map::{ Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter, }; @@ -1549,34 +1549,25 @@ pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg { user_cfg } -pub fn build_target_config( - early_dcx: &EarlyDiagCtxt, - opts: &Options, - target_override: Option, - sysroot: &Path, -) -> Target { - let target_result = target_override.map_or_else( - || Target::search(&opts.target_triple, sysroot), - |t| Ok((t, TargetWarnings::empty())), - ); - let (target, target_warnings) = target_result.unwrap_or_else(|e| { - early_dcx.early_fatal(format!( +pub fn build_target_config(early_dcx: &EarlyDiagCtxt, opts: &Options, sysroot: &Path) -> Target { + match Target::search(&opts.target_triple, sysroot) { + Ok((target, warnings)) => { + for warning in warnings.warning_messages() { + early_dcx.early_warn(warning) + } + if !matches!(target.pointer_width, 16 | 32 | 64) { + early_dcx.early_fatal(format!( + "target specification was invalid: unrecognized target-pointer-width {}", + target.pointer_width + )) + } + target + } + Err(e) => early_dcx.early_fatal(format!( "Error loading target specification: {e}. \ - Run `rustc --print target-list` for a list of built-in targets" - )) - }); - for warning in target_warnings.warning_messages() { - early_dcx.early_warn(warning) - } - - if !matches!(target.pointer_width, 16 | 32 | 64) { - early_dcx.early_fatal(format!( - "target specification was invalid: unrecognized target-pointer-width {}", - target.pointer_width - )) + Run `rustc --print target-list` for a list of built-in targets" + )), } - - target } #[derive(Copy, Clone, PartialEq, Eq, Debug)] diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 941d767b850..e10282ae8a9 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2091,6 +2091,9 @@ pub struct TargetOptions { /// compiling `rustc` will be used instead (or llvm if it is not set). /// /// N.B. when *using* the compiler, backend can always be overridden with `-Zcodegen-backend`. + /// + /// This was added by WaffleLapkin in #116793. The motivation is a rustc fork that requires a + /// custom codegen backend for a particular target. pub default_codegen_backend: Option>, /// Whether to generate trap instructions in places where optimization would -- cgit 1.4.1-3-g733a5