From 760ea07840f7eb78664355a52150a64964f57c47 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 8 Oct 2025 14:10:13 +0200 Subject: [PATCH] cmse: more accurate span for generic arguments --- .../src/hir_ty_lowering/cmse.rs | 46 +++++++++---------- .../cmse-nonsecure-call/generics.stderr | 8 ++-- .../cmse-nonsecure-entry/generics.rs | 6 +-- .../cmse-nonsecure-entry/generics.stderr | 45 ++++++------------ 4 files changed, 43 insertions(+), 62 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs index 9a31119c7f5a..b6c6e43b1d95 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs @@ -4,6 +4,7 @@ use rustc_hir::{self as hir, HirId}; use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutError, TyAndLayout}; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; +use rustc_span::Span; use crate::errors; @@ -20,11 +21,7 @@ pub(crate) fn validate_cmse_abi<'tcx>( match abi { ExternAbi::CmseNonSecureCall => { let hir_node = tcx.hir_node(hir_id); - let hir::Node::Ty(hir::Ty { - span: fn_ptr_span, - kind: hir::TyKind::FnPtr(fn_ptr_ty), - .. - }) = hir_node + let hir::Node::Ty(hir::Ty { kind: hir::TyKind::FnPtr(fn_ptr_ty), .. }) = hir_node else { let span = match tcx.parent_hir_node(hir_id) { hir::Node::Item(hir::Item { @@ -44,24 +41,24 @@ pub(crate) fn validate_cmse_abi<'tcx>( return; }; - match is_valid_cmse_inputs(tcx, dcx, fn_sig, fn_ptr_ty.decl, abi) { - Ok(()) => {} - Err(layout_err) => { - if should_emit_generic_error(abi, layout_err) { - dcx.emit_err(errors::CmseGeneric { span: *fn_ptr_span, abi }); - } + if let Err((span, layout_err)) = + is_valid_cmse_inputs(tcx, dcx, fn_sig, fn_ptr_ty.decl, abi) + { + if should_emit_layout_error(abi, layout_err) { + dcx.emit_err(errors::CmseGeneric { span, abi }); } } if let Err(layout_err) = is_valid_cmse_output(tcx, dcx, fn_sig, fn_ptr_ty.decl, abi) { - if should_emit_generic_error(abi, layout_err) { - dcx.emit_err(errors::CmseGeneric { span: *fn_ptr_span, abi }); + if should_emit_layout_error(abi, layout_err) { + let span = fn_ptr_ty.decl.output.span(); + dcx.emit_err(errors::CmseGeneric { span, abi }); } } } ExternAbi::CmseNonSecureEntry => { let hir_node = tcx.hir_node(hir_id); - let Some(hir::FnSig { decl, span: fn_sig_span, .. }) = hir_node.fn_sig() else { + let Some(hir::FnSig { decl, .. }) = hir_node.fn_sig() else { // might happen when this ABI is used incorrectly. That will be handled elsewhere return; }; @@ -72,18 +69,15 @@ pub(crate) fn validate_cmse_abi<'tcx>( return; } - match is_valid_cmse_inputs(tcx, dcx, fn_sig, decl, abi) { - Ok(()) => {} - Err(layout_err) => { - if should_emit_generic_error(abi, layout_err) { - dcx.emit_err(errors::CmseGeneric { span: *fn_sig_span, abi }); - } + if let Err((span, layout_err)) = is_valid_cmse_inputs(tcx, dcx, fn_sig, decl, abi) { + if should_emit_layout_error(abi, layout_err) { + dcx.emit_err(errors::CmseGeneric { span, abi }); } } if let Err(layout_err) = is_valid_cmse_output(tcx, dcx, fn_sig, decl, abi) { - if should_emit_generic_error(abi, layout_err) { - dcx.emit_err(errors::CmseGeneric { span: *fn_sig_span, abi }); + if should_emit_layout_error(abi, layout_err) { + dcx.emit_err(errors::CmseGeneric { span: decl.output.span(), abi }); } } } @@ -98,7 +92,7 @@ fn is_valid_cmse_inputs<'tcx>( fn_sig: ty::PolyFnSig<'tcx>, fn_decl: &hir::FnDecl<'tcx>, abi: ExternAbi, -) -> Result<(), &'tcx LayoutError<'tcx>> { +) -> Result<(), (Span, &'tcx LayoutError<'tcx>)> { let mut accum = 0u64; let mut excess_argument_spans = Vec::new(); @@ -107,7 +101,9 @@ fn is_valid_cmse_inputs<'tcx>( let fn_sig = tcx.erase_and_anonymize_regions(fn_sig); for (ty, hir_ty) in fn_sig.inputs().iter().zip(fn_decl.inputs) { - let layout = tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(*ty))?; + let layout = tcx + .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(*ty)) + .map_err(|e| (hir_ty.span, e))?; let align = layout.layout.align().bytes(); let size = layout.layout.size().bytes(); @@ -189,7 +185,7 @@ fn is_valid_cmse_output_layout<'tcx>(layout: TyAndLayout<'tcx>) -> bool { matches!(value, Primitive::Int(Integer::I64, _) | Primitive::Float(Float::F64)) } -fn should_emit_generic_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError<'tcx>) -> bool { +fn should_emit_layout_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError<'tcx>) -> bool { use LayoutError::*; match layout_err { diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr index d70369c46fbe..75da78b0b75a 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr @@ -55,16 +55,16 @@ LL | f3: extern "cmse-nonsecure-call" fn((impl Copy, u32), u32, u32, u32) -> = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0798]: generics are not allowed in `extern "cmse-nonsecure-call"` signatures - --> $DIR/generics.rs:23:9 + --> $DIR/generics.rs:23:41 | LL | f4: extern "cmse-nonsecure-call" fn(T, u32, u32, u32) -> u64, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-call"` signatures - --> $DIR/generics.rs:24:9 + --> $DIR/generics.rs:24:41 | LL | f5: extern "cmse-nonsecure-call" fn(Wrapper, u32, u32, u32) -> u64, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^ error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers --> $DIR/generics.rs:30:71 diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs index 2b4ddf5e31d3..d01934929d97 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs @@ -17,8 +17,8 @@ impl Wrapper { } extern "cmse-nonsecure-entry" fn ambient_generic_nested( - //~^ ERROR [E0798] _: Wrapper, + //~^ ERROR [E0798] _: u32, _: u32, _: u32, @@ -28,8 +28,8 @@ impl Wrapper { } extern "cmse-nonsecure-entry" fn introduced_generic( - //~^ ERROR [E0798] _: U, + //~^ ERROR [E0798] _: u32, _: u32, _: u32, @@ -83,8 +83,8 @@ extern "cmse-nonsecure-entry" fn identity_impl_trait(v: impl Copy) -> impl Copy } extern "cmse-nonsecure-entry" fn identity_impl_trait_nested( - //~^ ERROR generics are not allowed in `extern "cmse-nonsecure-entry"` signatures v: (impl Copy, i32), + //~^ ERROR generics are not allowed in `extern "cmse-nonsecure-entry"` signatures ) -> (impl Copy, i32) { //~^ ERROR `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures v diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr index e61051a4a26f..5ddd29883f86 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr @@ -1,26 +1,20 @@ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:30:1 + --> $DIR/generics.rs:31:8 | -LL | / extern "cmse-nonsecure-entry" fn introduced_generic( -LL | | -LL | | _: U, -LL | | _: u32, -LL | | _: u32, -LL | | _: u32, -LL | | ) -> u64 { - | |________^ +LL | _: U, + | ^ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:64:1 + --> $DIR/generics.rs:64:48 | LL | extern "cmse-nonsecure-entry" fn impl_trait(_: impl Copy, _: u32, _: u32, _: u32) -> u64 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:79:1 + --> $DIR/generics.rs:79:57 | LL | extern "cmse-nonsecure-entry" fn identity_impl_trait(v: impl Copy) -> impl Copy { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures --> $DIR/generics.rs:79:71 @@ -29,13 +23,10 @@ LL | extern "cmse-nonsecure-entry" fn identity_impl_trait(v: impl Copy) -> impl | ^^^^^^^^^ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:85:1 + --> $DIR/generics.rs:86:8 | -LL | / extern "cmse-nonsecure-entry" fn identity_impl_trait_nested( -LL | | -LL | | v: (impl Copy, i32), -LL | | ) -> (impl Copy, i32) { - | |_____________________^ +LL | v: (impl Copy, i32), + | ^^^^^^^^^^^^^^^^ error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures --> $DIR/generics.rs:88:6 @@ -44,22 +35,16 @@ LL | ) -> (impl Copy, i32) { | ^^^^^^^^^^^^^^^^ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:14:5 + --> $DIR/generics.rs:14:57 | LL | extern "cmse-nonsecure-entry" fn ambient_generic(_: T, _: u32, _: u32, _: u32) -> u64 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:19:5 + --> $DIR/generics.rs:20:12 | -LL | / extern "cmse-nonsecure-entry" fn ambient_generic_nested( -LL | | -LL | | _: Wrapper, -LL | | _: u32, -LL | | _: u32, -LL | | _: u32, -LL | | ) -> u64 { - | |____________^ +LL | _: Wrapper, + | ^^^^^^^^^^ error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers --> $DIR/generics.rs:46:65