diff options
Diffstat (limited to 'compiler/rustc_monomorphize')
| -rw-r--r-- | compiler/rustc_monomorphize/Cargo.toml | 2 | ||||
| -rw-r--r-- | compiler/rustc_monomorphize/messages.ftl | 48 | ||||
| -rw-r--r-- | compiler/rustc_monomorphize/src/collector.rs | 24 | ||||
| -rw-r--r-- | compiler/rustc_monomorphize/src/errors.rs | 36 | ||||
| -rw-r--r-- | compiler/rustc_monomorphize/src/mono_checks/abi_check.rs | 112 | ||||
| -rw-r--r-- | compiler/rustc_monomorphize/src/partitioning.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_monomorphize/src/partitioning/autodiff.rs | 2 |
7 files changed, 130 insertions, 96 deletions
diff --git a/compiler/rustc_monomorphize/Cargo.toml b/compiler/rustc_monomorphize/Cargo.toml index 5462105e5e8..36b76d261de 100644 --- a/compiler/rustc_monomorphize/Cargo.toml +++ b/compiler/rustc_monomorphize/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_monomorphize" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_monomorphize/messages.ftl b/compiler/rustc_monomorphize/messages.ftl index 540ce7cc4ce..bdeab12ab50 100644 --- a/compiler/rustc_monomorphize/messages.ftl +++ b/compiler/rustc_monomorphize/messages.ftl @@ -1,18 +1,40 @@ -monomorphize_abi_error_disabled_vector_type_call = - this function call uses a SIMD vector type that (with the chosen ABI) requires the `{$required_feature}` target feature, which is not enabled in the caller - .label = function called here - .help = consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable="{$required_feature}")]`) -monomorphize_abi_error_disabled_vector_type_def = - this function definition uses a SIMD vector type that (with the chosen ABI) requires the `{$required_feature}` target feature, which is not enabled - .label = function defined here +monomorphize_abi_error_disabled_vector_type = + this function {$is_call -> + [true] call + *[false] definition + } uses SIMD vector type `{$ty}` which (with the chosen ABI) requires the `{$required_feature}` target feature, which is not enabled{$is_call -> + [true] {" "}in the caller + *[false] {""} + } + .label = function {$is_call -> + [true] called + *[false] defined + } here .help = consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable="{$required_feature}")]`) -monomorphize_abi_error_unsupported_vector_type_call = - this function call uses a SIMD vector type that is not currently supported with the chosen ABI - .label = function called here -monomorphize_abi_error_unsupported_vector_type_def = - this function definition uses a SIMD vector type that is not currently supported with the chosen ABI - .label = function defined here +monomorphize_abi_error_unsupported_vector_type = + this function {$is_call -> + [true] call + *[false] definition + } uses SIMD vector type `{$ty}` which is not currently supported with the chosen ABI + .label = function {$is_call -> + [true] called + *[false] defined + } here + +monomorphize_abi_required_target_feature = + this function {$is_call -> + [true] call + *[false] definition + } uses ABI "{$abi}" which requires the `{$required_feature}` target feature, which is not enabled{$is_call -> + [true] {" "}in the caller + *[false] {""} + } + .label = function {$is_call -> + [true] called + *[false] defined + } here + .help = consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable="{$required_feature}")]`) monomorphize_couldnt_dump_mono_stats = unexpected error occurred while dumping monomorphization stats: {$error} diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index ae31ed59391..d7cb8f18f82 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -323,7 +323,7 @@ impl<'tcx> MonoItems<'tcx> { self.items.entry(item.node).or_insert(item.span); } - fn items(&self) -> impl Iterator<Item = MonoItem<'tcx>> + '_ { + fn items(&self) -> impl Iterator<Item = MonoItem<'tcx>> { self.items.keys().cloned() } } @@ -478,25 +478,24 @@ fn collect_items_rec<'tcx>( ); recursion_depth_reset = None; - let item = tcx.hir().item(item_id); - if let hir::ItemKind::GlobalAsm(asm) = item.kind { + let item = tcx.hir_item(item_id); + if let hir::ItemKind::GlobalAsm { asm, .. } = item.kind { for (op, op_sp) in asm.operands { - match op { + match *op { hir::InlineAsmOperand::Const { .. } => { // Only constants which resolve to a plain integer // are supported. Therefore the value should not // depend on any other items. } - hir::InlineAsmOperand::SymFn { anon_const } => { - let fn_ty = - tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id); + hir::InlineAsmOperand::SymFn { expr } => { + let fn_ty = tcx.typeck(item_id.owner_id).expr_ty(expr); visit_fn_use(tcx, fn_ty, false, *op_sp, &mut used_items); } hir::InlineAsmOperand::SymStatic { path: _, def_id } => { - let instance = Instance::mono(tcx, *def_id); + let instance = Instance::mono(tcx, def_id); if tcx.should_codegen_locally(instance) { trace!("collecting static {:?}", def_id); - used_items.push(dummy_spanned(MonoItem::Static(*def_id))); + used_items.push(dummy_spanned(MonoItem::Static(def_id))); } } hir::InlineAsmOperand::In { .. } @@ -1509,6 +1508,13 @@ impl<'v> RootCollector<'_, 'v> { } _ => unreachable!(), }; + let Ok(instance) = self.tcx.try_normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + instance, + ) else { + // Don't ICE on an impossible-to-normalize closure. + return; + }; let mono_item = create_fn_mono_item(self.tcx, instance, DUMMY_SP); if mono_item.node.is_instantiable(self.tcx) { self.output.push(mono_item); diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index fc8d63b5888..8dafbbca905 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -1,6 +1,7 @@ use std::path::PathBuf; use rustc_macros::{Diagnostic, LintDiagnostic}; +use rustc_middle::ty::Ty; use rustc_span::{Span, Symbol}; #[derive(Diagnostic)] @@ -69,33 +70,36 @@ pub(crate) struct UnknownCguCollectionMode<'a> { } #[derive(LintDiagnostic)] -#[diag(monomorphize_abi_error_disabled_vector_type_def)] +#[diag(monomorphize_abi_error_disabled_vector_type)] #[help] -pub(crate) struct AbiErrorDisabledVectorTypeDef<'a> { +pub(crate) struct AbiErrorDisabledVectorType<'a> { #[label] pub span: Span, pub required_feature: &'a str, + pub ty: Ty<'a>, + /// Whether this is a problem at a call site or at a declaration. + pub is_call: bool, } #[derive(LintDiagnostic)] -#[diag(monomorphize_abi_error_disabled_vector_type_call)] -#[help] -pub(crate) struct AbiErrorDisabledVectorTypeCall<'a> { - #[label] - pub span: Span, - pub required_feature: &'a str, -} - -#[derive(LintDiagnostic)] -#[diag(monomorphize_abi_error_unsupported_vector_type_def)] -pub(crate) struct AbiErrorUnsupportedVectorTypeDef { +#[diag(monomorphize_abi_error_unsupported_vector_type)] +pub(crate) struct AbiErrorUnsupportedVectorType<'a> { #[label] pub span: Span, + pub ty: Ty<'a>, + /// Whether this is a problem at a call site or at a declaration. + pub is_call: bool, } -#[derive(LintDiagnostic)] -#[diag(monomorphize_abi_error_unsupported_vector_type_call)] -pub(crate) struct AbiErrorUnsupportedVectorTypeCall { +#[derive(Diagnostic)] +#[diag(monomorphize_abi_required_target_feature)] +#[help] +pub(crate) struct AbiRequiredTargetFeature<'a> { + #[primary_span] #[label] pub span: Span, + pub required_feature: &'a str, + pub abi: &'a str, + /// Whether this is a problem at a call site or at a declaration. + pub is_call: bool, } diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs index a0be7f11d70..4c8dd933317 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs @@ -1,19 +1,15 @@ //! This module ensures that if a function's ABI requires a particular target feature, //! that target feature is enabled both on the callee and all callers. -use rustc_abi::{BackendRepr, RegKind}; +use rustc_abi::{BackendRepr, ExternAbi, RegKind}; use rustc_hir::CRATE_HIR_ID; use rustc_middle::mir::{self, traversal}; -use rustc_middle::ty::inherent::*; use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt}; use rustc_session::lint::builtin::ABI_UNSUPPORTED_VECTOR_TYPES; use rustc_span::def_id::DefId; -use rustc_span::{DUMMY_SP, Span, Symbol}; -use rustc_target::callconv::{FnAbi, PassMode}; +use rustc_span::{DUMMY_SP, Span, Symbol, sym}; +use rustc_target::callconv::{Conv, FnAbi, PassMode}; -use crate::errors::{ - AbiErrorDisabledVectorTypeCall, AbiErrorDisabledVectorTypeDef, - AbiErrorUnsupportedVectorTypeCall, AbiErrorUnsupportedVectorTypeDef, -}; +use crate::errors; fn uses_vector_registers(mode: &PassMode, repr: &BackendRepr) -> bool { match mode { @@ -28,16 +24,21 @@ fn uses_vector_registers(mode: &PassMode, repr: &BackendRepr) -> bool { /// Checks whether a certain function ABI is compatible with the target features currently enabled /// for a certain function. -/// If not, `emit_err` is called, with `Some(feature)` if a certain feature should be enabled and -/// with `None` if no feature is known that would make the ABI compatible. +/// `is_call` indicates whether this is a call-site check or a definition-site check; +/// this is only relevant for the wording in the emitted error. fn do_check_abi<'tcx>( tcx: TyCtxt<'tcx>, abi: &FnAbi<'tcx, Ty<'tcx>>, - target_feature_def: DefId, - mut emit_err: impl FnMut(Option<&'static str>), + def_id: DefId, + is_call: bool, + span: impl Fn() -> Span, ) { let feature_def = tcx.sess.target.features_for_correct_vector_abi(); - let codegen_attrs = tcx.codegen_fn_attrs(target_feature_def); + let codegen_attrs = tcx.codegen_fn_attrs(def_id); + let have_feature = |feat: Symbol| { + tcx.sess.unstable_target_features.contains(&feat) + || codegen_attrs.target_features.iter().any(|x| x.name == feat) + }; for arg_abi in abi.args.iter().chain(std::iter::once(&abi.ret)) { let size = arg_abi.layout.size; if uses_vector_registers(&arg_abi.mode, &arg_abi.layout.backend_repr) { @@ -45,18 +46,46 @@ fn do_check_abi<'tcx>( let feature = match feature_def.iter().find(|(bits, _)| size.bits() <= *bits) { Some((_, feature)) => feature, None => { - emit_err(None); + let span = span(); + tcx.emit_node_span_lint( + ABI_UNSUPPORTED_VECTOR_TYPES, + CRATE_HIR_ID, + span, + errors::AbiErrorUnsupportedVectorType { + span, + ty: arg_abi.layout.ty, + is_call, + }, + ); continue; } }; - let feature_sym = Symbol::intern(feature); - if !tcx.sess.unstable_target_features.contains(&feature_sym) - && !codegen_attrs.target_features.iter().any(|x| x.name == feature_sym) - { - emit_err(Some(&feature)); + if !have_feature(Symbol::intern(feature)) { + // Emit error. + let span = span(); + tcx.emit_node_span_lint( + ABI_UNSUPPORTED_VECTOR_TYPES, + CRATE_HIR_ID, + span, + errors::AbiErrorDisabledVectorType { + span, + required_feature: feature, + ty: arg_abi.layout.ty, + is_call, + }, + ); } } } + // The `vectorcall` ABI is special in that it requires SSE2 no matter which types are being passed. + if abi.conv == Conv::X86VectorCall && !have_feature(sym::sse2) { + tcx.dcx().emit_err(errors::AbiRequiredTargetFeature { + span: span(), + required_feature: "sse2", + abi: "vectorcall", + is_call, + }); + } } /// Checks that the ABI of a given instance of a function does not contain vector-passed arguments @@ -69,24 +98,13 @@ fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { // function. return; }; - do_check_abi(tcx, abi, instance.def_id(), |required_feature| { - let span = tcx.def_span(instance.def_id()); - if let Some(required_feature) = required_feature { - tcx.emit_node_span_lint( - ABI_UNSUPPORTED_VECTOR_TYPES, - CRATE_HIR_ID, - span, - AbiErrorDisabledVectorTypeDef { span, required_feature }, - ); - } else { - tcx.emit_node_span_lint( - ABI_UNSUPPORTED_VECTOR_TYPES, - CRATE_HIR_ID, - span, - AbiErrorUnsupportedVectorTypeDef { span }, - ); - } - }) + do_check_abi( + tcx, + abi, + instance.def_id(), + /*is_call*/ false, + || tcx.def_span(instance.def_id()), + ) } /// Checks that a call expression does not try to pass a vector-passed argument which requires a @@ -97,7 +115,7 @@ fn check_call_site_abi<'tcx>( span: Span, caller: InstanceKind<'tcx>, ) { - if callee.fn_sig(tcx).abi().is_rust() { + if callee.fn_sig(tcx).abi() == ExternAbi::Rust { // "Rust" ABI never passes arguments in vector registers. return; } @@ -123,23 +141,7 @@ fn check_call_site_abi<'tcx>( // ABI failed to compute; this will not get through codegen. return; }; - do_check_abi(tcx, callee_abi, caller.def_id(), |required_feature| { - if let Some(required_feature) = required_feature { - tcx.emit_node_span_lint( - ABI_UNSUPPORTED_VECTOR_TYPES, - CRATE_HIR_ID, - span, - AbiErrorDisabledVectorTypeCall { span, required_feature }, - ); - } else { - tcx.emit_node_span_lint( - ABI_UNSUPPORTED_VECTOR_TYPES, - CRATE_HIR_ID, - span, - AbiErrorUnsupportedVectorTypeCall { span }, - ); - } - }); + do_check_abi(tcx, callee_abi, caller.def_id(), /*is_call*/ true, || span); } fn check_callees_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, body: &mir::Body<'tcx>) { diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index d826d03918e..b1b6f10e0fe 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -1269,7 +1269,7 @@ fn dump_mono_items_stats<'tcx>( output_directory: &Option<PathBuf>, crate_name: Symbol, ) -> Result<(), Box<dyn std::error::Error>> { - let output_directory = if let Some(ref directory) = output_directory { + let output_directory = if let Some(directory) = output_directory { fs::create_dir_all(directory)?; directory } else { diff --git a/compiler/rustc_monomorphize/src/partitioning/autodiff.rs b/compiler/rustc_monomorphize/src/partitioning/autodiff.rs index bce31bf0748..0c855508434 100644 --- a/compiler/rustc_monomorphize/src/partitioning/autodiff.rs +++ b/compiler/rustc_monomorphize/src/partitioning/autodiff.rs @@ -66,7 +66,7 @@ pub(crate) fn find_autodiff_source_functions<'tcx>( let mut autodiff_items: Vec<AutoDiffItem> = vec![]; for (item, instance) in autodiff_mono_items { let target_id = instance.def_id(); - let cg_fn_attr = tcx.codegen_fn_attrs(target_id).autodiff_item.clone(); + let cg_fn_attr = &tcx.codegen_fn_attrs(target_id).autodiff_item; let Some(target_attrs) = cg_fn_attr else { continue; }; |
