From 3ce89e257d20c34795d0577ea4ba0e0be194c0db Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 27 Oct 2025 15:54:49 +0000 Subject: [PATCH 1/6] Use the actual StableCrateId for the incr comp session dir Previously only --crate-type would be taken into account, not #![crate_type]. --- compiler/rustc_incremental/src/persist/fs.rs | 20 +++++++------------ .../rustc_incremental/src/persist/load.rs | 11 +++++++--- compiler/rustc_interface/src/passes.rs | 2 +- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index 975bf1d18622a..f73cc4d43e8c5 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -116,8 +116,6 @@ use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_data_structures::{base_n, flock}; use rustc_fs_util::{LinkOrCopy, link_or_copy, try_canonicalize}; use rustc_middle::bug; -use rustc_session::config::CrateType; -use rustc_session::output::collect_crate_types; use rustc_session::{Session, StableCrateId}; use rustc_span::Symbol; use tracing::debug; @@ -212,7 +210,11 @@ pub fn in_incr_comp_dir(incr_comp_session_dir: &Path, file_name: &str) -> PathBu /// The garbage collection will take care of it. /// /// [`rustc_interface::queries::dep_graph`]: ../../rustc_interface/struct.Queries.html#structfield.dep_graph -pub(crate) fn prepare_session_directory(sess: &Session, crate_name: Symbol) { +pub(crate) fn prepare_session_directory( + sess: &Session, + crate_name: Symbol, + stable_crate_id: StableCrateId, +) { if sess.opts.incremental.is_none() { return; } @@ -222,7 +224,7 @@ pub(crate) fn prepare_session_directory(sess: &Session, crate_name: Symbol) { debug!("prepare_session_directory"); // {incr-comp-dir}/{crate-name-and-disambiguator} - let crate_dir = crate_path(sess, crate_name); + let crate_dir = crate_path(sess, crate_name, stable_crate_id); debug!("crate-dir: {}", crate_dir.display()); create_dir(sess, &crate_dir, "crate"); @@ -595,17 +597,9 @@ fn string_to_timestamp(s: &str) -> Result { Ok(UNIX_EPOCH + duration) } -fn crate_path(sess: &Session, crate_name: Symbol) -> PathBuf { +fn crate_path(sess: &Session, crate_name: Symbol, stable_crate_id: StableCrateId) -> PathBuf { let incr_dir = sess.opts.incremental.as_ref().unwrap().clone(); - let crate_types = collect_crate_types(sess, &[]); - let stable_crate_id = StableCrateId::new( - crate_name, - crate_types.contains(&CrateType::Executable), - sess.opts.cg.metadata.clone(), - sess.cfg_version, - ); - let crate_name = format!("{crate_name}-{}", stable_crate_id.as_u64().to_base_fixed_len(CASE_INSENSITIVE)); incr_dir.join(crate_name) diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index 0e646b136c452..1b2a283a1a0d1 100644 --- a/compiler/rustc_incremental/src/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs @@ -10,8 +10,8 @@ use rustc_middle::dep_graph::{DepGraph, DepsType, SerializedDepGraph, WorkProduc use rustc_middle::query::on_disk_cache::OnDiskCache; use rustc_serialize::Decodable; use rustc_serialize::opaque::MemDecoder; -use rustc_session::Session; use rustc_session::config::IncrementalStateAssertion; +use rustc_session::{Session, StableCrateId}; use rustc_span::Symbol; use tracing::{debug, warn}; @@ -208,9 +208,14 @@ pub fn load_query_result_cache(sess: &Session) -> Option { /// Setups the dependency graph by loading an existing graph from disk and set up streaming of a /// new graph to an incremental session directory. -pub fn setup_dep_graph(sess: &Session, crate_name: Symbol, deps: &DepsType) -> DepGraph { +pub fn setup_dep_graph( + sess: &Session, + crate_name: Symbol, + stable_crate_id: StableCrateId, + deps: &DepsType, +) -> DepGraph { // `load_dep_graph` can only be called after `prepare_session_directory`. - prepare_session_directory(sess, crate_name); + prepare_session_directory(sess, crate_name, stable_crate_id); let res = sess.opts.build_dep_graph().then(|| load_dep_graph(sess, deps)); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 03b8b61bbc0a8..08659f8511d5f 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -936,7 +936,7 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( let outputs = util::build_output_filenames(&pre_configured_attrs, sess); let dep_type = DepsType { dep_names: rustc_query_impl::dep_kind_names() }; - let dep_graph = setup_dep_graph(sess, crate_name, &dep_type); + let dep_graph = setup_dep_graph(sess, crate_name, stable_crate_id, &dep_type); let cstore = FreezeLock::new(Box::new(CStore::new(compiler.codegen_backend.metadata_loader())) as _); From b443a59ba80b92ba6ddd6c1cc5fedf07c53531a3 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 27 Oct 2025 16:14:03 +0000 Subject: [PATCH 2/6] Allow codegen backends to indicate which crate types they support This way cargo will drop the unsupported crate types for crates that specify multiple crate types. --- .../rustc_codegen_ssa/src/traits/backend.rs | 14 +++++++++++++- compiler/rustc_driver_impl/src/lib.rs | 3 ++- compiler/rustc_interface/src/passes.rs | 6 +++++- compiler/rustc_interface/src/util.rs | 17 +++++++++++++++-- compiler/rustc_session/src/output.rs | 13 +++++++++++-- 5 files changed, 46 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index ec53d9f53eb83..85bff45408140 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -10,7 +10,7 @@ use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session; -use rustc_session::config::{self, OutputFilenames, PrintRequest}; +use rustc_session::config::{self, CrateType, OutputFilenames, PrintRequest}; use rustc_span::Symbol; use super::CodegenObject; @@ -62,6 +62,18 @@ pub trait CodegenBackend { } } + fn supported_crate_types(&self, _sess: &Session) -> Vec { + vec![ + CrateType::Executable, + CrateType::Dylib, + CrateType::Rlib, + CrateType::Staticlib, + CrateType::Cdylib, + CrateType::ProcMacro, + CrateType::Sdylib, + ] + } + fn print_passes(&self) {} fn print_version(&self) {} diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 9529ef2b99ad3..c926a7c742a0a 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -686,7 +686,8 @@ fn print_crate_info( }; let t_outputs = rustc_interface::util::build_output_filenames(attrs, sess); let crate_name = passes::get_crate_name(sess, attrs); - let crate_types = collect_crate_types(sess, attrs); + let crate_types = + collect_crate_types(sess, &codegen_backend.supported_crate_types(sess), attrs); for &style in &crate_types { let fname = rustc_session::output::filename_for_input( sess, style, crate_name, &t_outputs, diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 08659f8511d5f..6842b61f629e5 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -925,7 +925,11 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( let pre_configured_attrs = rustc_expand::config::pre_configure_attrs(sess, &krate.attrs); let crate_name = get_crate_name(sess, &pre_configured_attrs); - let crate_types = collect_crate_types(sess, &pre_configured_attrs); + let crate_types = collect_crate_types( + sess, + &compiler.codegen_backend.supported_crate_types(sess), + &pre_configured_attrs, + ); let stable_crate_id = StableCrateId::new( crate_name, crate_types.contains(&CrateType::Executable), diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index be2fd0787b98a..801c144c811a7 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -354,6 +354,14 @@ impl CodegenBackend for DummyCodegenBackend { "dummy" } + fn supported_crate_types(&self, _sess: &Session) -> Vec { + // This includes bin despite failing on the link step to ensure that you + // can still get the frontend handling for binaries. For all library + // like crate types cargo will fallback to rlib unless you specifically + // say that only a different crate type must be used. + vec![CrateType::Rlib, CrateType::Executable] + } + fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box { Box::new(CodegenResults { modules: vec![], @@ -380,12 +388,17 @@ impl CodegenBackend for DummyCodegenBackend { ) { // JUSTIFICATION: TyCtxt no longer available here #[allow(rustc::bad_opt_access)] - if sess.opts.crate_types.iter().any(|&crate_type| crate_type != CrateType::Rlib) { + if codegen_results + .crate_info + .crate_types + .iter() + .any(|&crate_type| crate_type != CrateType::Rlib) + { #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] sess.dcx().fatal(format!( "crate type {} not supported by the dummy codegen backend", - sess.opts.crate_types[0], + codegen_results.crate_info.crate_types[0], )); } diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs index cba70b5bd5d17..a48a4f649da1d 100644 --- a/compiler/rustc_session/src/output.rs +++ b/compiler/rustc_session/src/output.rs @@ -174,7 +174,11 @@ pub fn categorize_crate_type(s: Symbol) -> Option { Some(CRATE_TYPES.iter().find(|(key, _)| *key == s)?.1) } -pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec { +pub fn collect_crate_types( + session: &Session, + backend_crate_types: &[CrateType], + attrs: &[ast::Attribute], +) -> Vec { // If we're generating a test executable, then ignore all other output // styles at all other locations if session.opts.test { @@ -219,7 +223,12 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec Date: Mon, 27 Oct 2025 10:04:27 -0700 Subject: [PATCH 3/6] rustdoc: remove `--emit=unversioned-shared-resources` This option hasn't done anything for a long time, and can be removed. I've kept a shim in place to avoid breaking docs.rs, but the option no longer does anything. Using git-blame, I tracked this option down to f77ebd4ffaea7fc5af49425cafefe141e7458cc3, the commit that introduced EmitType in the first place. It was used with SharedResource::Unversioned, which no longer exists since f9e1f6ffdf03ec33cb29e20c88fc7bcc938c7f42 removed them. CC https://github.com/rust-lang/rust/pull/146220 Part of https://github.com/rust-lang/rust/issues/83784 --- src/librustdoc/config.rs | 2 -- src/librustdoc/lib.rs | 2 +- tests/run-make/emit-shared-files/rmake.rs | 2 +- tests/run-make/rustdoc-default-output/output-default.stdout | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index cf0858810f55f..630b2a6e5c18b 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -311,7 +311,6 @@ pub(crate) enum ModuleSorting { #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) enum EmitType { - Unversioned, Toolchain, InvocationSpecific, DepInfo(Option), @@ -322,7 +321,6 @@ impl FromStr for EmitType { fn from_str(s: &str) -> Result { match s { - "unversioned-shared-resources" => Ok(Self::Unversioned), "toolchain-shared-resources" => Ok(Self::Toolchain), "invocation-specific" => Ok(Self::InvocationSpecific), "dep-info" => Ok(Self::DepInfo(None)), diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 820b2392e07ce..dd6378b25def7 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -567,7 +567,7 @@ fn opts() -> Vec { "", "emit", "Comma separated list of types of output for rustdoc to emit", - "[unversioned-shared-resources,toolchain-shared-resources,invocation-specific,dep-info]", + "[toolchain-shared-resources,invocation-specific,dep-info]", ), opt(Unstable, FlagMulti, "", "no-run", "Compile doctests without running them", ""), opt( diff --git a/tests/run-make/emit-shared-files/rmake.rs b/tests/run-make/emit-shared-files/rmake.rs index 911ceb3adca4b..bd868d4fd19e2 100644 --- a/tests/run-make/emit-shared-files/rmake.rs +++ b/tests/run-make/emit-shared-files/rmake.rs @@ -68,7 +68,7 @@ fn main() { rustdoc() .arg("-Zunstable-options") - .arg("--emit=toolchain-shared-resources,unversioned-shared-resources") + .arg("--emit=toolchain-shared-resources") .out_dir("all-shared") .arg("--resource-suffix=-xxx") .args(&["--extend-css", "z.css"]) diff --git a/tests/run-make/rustdoc-default-output/output-default.stdout b/tests/run-make/rustdoc-default-output/output-default.stdout index badbc0b6d15b7..3afe0ca3ca8f5 100644 --- a/tests/run-make/rustdoc-default-output/output-default.stdout +++ b/tests/run-make/rustdoc-default-output/output-default.stdout @@ -150,7 +150,7 @@ Options: --generate-redirect-map Generate JSON file at the top level instead of generating HTML redirection files - --emit [unversioned-shared-resources,toolchain-shared-resources,invocation-specific,dep-info] + --emit [toolchain-shared-resources,invocation-specific,dep-info] Comma separated list of types of output for rustdoc to emit --no-run Compile doctests without running them From eb113533a3903bd2073755c92893f9a32e9f4131 Mon Sep 17 00:00:00 2001 From: tiif Date: Mon, 27 Oct 2025 13:50:51 +0000 Subject: [PATCH 4/6] Add test --- .../next-solver/opaques/stranded_opaque.rs | 50 ++++++++ .../opaques/stranded_opaque.stderr | 116 ++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 tests/ui/traits/next-solver/opaques/stranded_opaque.rs create mode 100644 tests/ui/traits/next-solver/opaques/stranded_opaque.stderr diff --git a/tests/ui/traits/next-solver/opaques/stranded_opaque.rs b/tests/ui/traits/next-solver/opaques/stranded_opaque.rs new file mode 100644 index 0000000000000..f600a1496b99c --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/stranded_opaque.rs @@ -0,0 +1,50 @@ +//@ compile-flags: -Znext-solver +#![feature(type_alias_impl_trait)] +use std::future::Future; + +// Test for https://github.com/rust-lang/trait-system-refactor-initiative/issues/235 + +// These are cases where an opaque types become "stranded" due to +// some errors. Make sure we don't ICE in either case. + +// Case 1: `impl Send` is stranded +fn foo() -> impl ?Future { + //~^ ERROR bound modifier `?` can only be applied to `Sized` + //~| ERROR bound modifier `?` can only be applied to `Sized` + () +} + +// Case 2: `Assoc = impl Trait` is stranded +trait Trait {} +impl Trait for i32 {} + +fn produce() -> impl Trait { + //~^ ERROR associated type `Assoc` not found for `Trait` + //~| ERROR associated type `Assoc` not found for `Trait` + 16 +} + +// Case 3: `impl Trait` is stranded +fn ill_formed_string() -> String { + //~^ ERROR struct takes 0 generic arguments but 1 generic argument was supplied + String::from("a string") +} + +// Case 4: TAIT variant of Case 1 to 3 +type Foo = impl ?Future; +//~^ ERROR unconstrained opaque type +//~| ERROR unconstrained opaque type +//~| ERROR bound modifier `?` can only be applied to `Sized` +//~| ERROR bound modifier `?` can only be applied to `Sized` + +type Produce = impl Trait; +//~^ ERROR unconstrained opaque type +//~| ERROR unconstrained opaque type +//~| ERROR associated type `Assoc` not found for `Trait` +//~| ERROR associated type `Assoc` not found for `Trait` + +type IllFormedString = String; +//~^ ERROR unconstrained opaque type +//~| ERROR struct takes 0 generic arguments but 1 generic argument was supplied + +fn main() {} diff --git a/tests/ui/traits/next-solver/opaques/stranded_opaque.stderr b/tests/ui/traits/next-solver/opaques/stranded_opaque.stderr new file mode 100644 index 0000000000000..bcb357eb69531 --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/stranded_opaque.stderr @@ -0,0 +1,116 @@ +error: bound modifier `?` can only be applied to `Sized` + --> $DIR/stranded_opaque.rs:11:18 + | +LL | fn foo() -> impl ?Future { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0220]: associated type `Assoc` not found for `Trait` + --> $DIR/stranded_opaque.rs:21:28 + | +LL | fn produce() -> impl Trait { + | ^^^^^ associated type `Assoc` not found + +error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/stranded_opaque.rs:28:27 + | +LL | fn ill_formed_string() -> String { + | ^^^^^^------------ help: remove the unnecessary generics + | | + | expected 0 generic arguments + +error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/stranded_opaque.rs:46:25 + | +LL | type IllFormedString = String; + | ^^^^^^------------ help: remove the unnecessary generics + | | + | expected 0 generic arguments + +error: bound modifier `?` can only be applied to `Sized` + --> $DIR/stranded_opaque.rs:11:18 + | +LL | fn foo() -> impl ?Future { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0220]: associated type `Assoc` not found for `Trait` + --> $DIR/stranded_opaque.rs:21:28 + | +LL | fn produce() -> impl Trait { + | ^^^^^ associated type `Assoc` not found + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: unconstrained opaque type + --> $DIR/stranded_opaque.rs:34:12 + | +LL | type Foo = impl ?Future; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Foo` must be used in combination with a concrete type within the same crate + +error: bound modifier `?` can only be applied to `Sized` + --> $DIR/stranded_opaque.rs:34:17 + | +LL | type Foo = impl ?Future; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: bound modifier `?` can only be applied to `Sized` + --> $DIR/stranded_opaque.rs:34:17 + | +LL | type Foo = impl ?Future; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: unconstrained opaque type + --> $DIR/stranded_opaque.rs:34:34 + | +LL | type Foo = impl ?Future; + | ^^^^^^^^^ + | + = note: `Foo` must be used in combination with a concrete type within the same crate + +error: unconstrained opaque type + --> $DIR/stranded_opaque.rs:40:17 + | +LL | type Produce = impl Trait; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Produce` must be used in combination with a concrete type within the same crate + +error[E0220]: associated type `Assoc` not found for `Trait` + --> $DIR/stranded_opaque.rs:40:28 + | +LL | type Produce = impl Trait; + | ^^^^^ associated type `Assoc` not found + +error[E0220]: associated type `Assoc` not found for `Trait` + --> $DIR/stranded_opaque.rs:40:28 + | +LL | type Produce = impl Trait; + | ^^^^^ associated type `Assoc` not found + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: unconstrained opaque type + --> $DIR/stranded_opaque.rs:40:36 + | +LL | type Produce = impl Trait; + | ^^^^^^^^^^ + | + = note: `Produce` must be used in combination with a concrete type within the same crate + +error: unconstrained opaque type + --> $DIR/stranded_opaque.rs:46:32 + | +LL | type IllFormedString = String; + | ^^^^^^^^^^ + | + = note: `IllFormedString` must be used in combination with a concrete type within the same crate + +error: aborting due to 15 previous errors + +Some errors have detailed explanations: E0107, E0220. +For more information about an error, try `rustc --explain E0107`. From c797724ed5a9f548aa40e6c10bd5557a94a04c48 Mon Sep 17 00:00:00 2001 From: tiif Date: Wed, 22 Oct 2025 14:10:42 +0000 Subject: [PATCH 5/6] Add delayed bug for stranded opaque --- .../rustc_hir_analysis/src/collect/type_of/opaque.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index a02990fe4abaf..870a7b6563860 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -242,6 +242,16 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>( owner_def_id: LocalDefId, opaque_types_from: DefiningScopeKind, ) -> Ty<'tcx> { + // When an opaque type is stranded, its hidden type cannot be inferred + // so we should not continue. + if !tcx.opaque_types_defined_by(owner_def_id).contains(&def_id) { + let opaque_type_span = tcx.def_span(def_id); + let guar = tcx + .dcx() + .span_delayed_bug(opaque_type_span, "cannot infer type for stranded opaque type"); + return Ty::new_error(tcx, guar); + } + match opaque_types_from { DefiningScopeKind::HirTypeck => { let tables = tcx.typeck(owner_def_id); From 9fc1378916ed3e2c45ff3476b5b169157979017e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 28 Oct 2025 14:15:19 +0000 Subject: [PATCH 6/6] Report correct unsupported crate type for the dummy codegen backend --- compiler/rustc_interface/src/util.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 801c144c811a7..5e9cb42365049 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -388,17 +388,16 @@ impl CodegenBackend for DummyCodegenBackend { ) { // JUSTIFICATION: TyCtxt no longer available here #[allow(rustc::bad_opt_access)] - if codegen_results + if let Some(&crate_type) = codegen_results .crate_info .crate_types .iter() - .any(|&crate_type| crate_type != CrateType::Rlib) + .find(|&&crate_type| crate_type != CrateType::Rlib) { #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] sess.dcx().fatal(format!( - "crate type {} not supported by the dummy codegen backend", - codegen_results.crate_info.crate_types[0], + "crate type {crate_type} not supported by the dummy codegen backend" )); }