diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index d9f9d9dafff..df9399c56c7 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -203,25 +203,41 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { let encl_trait_hir_id = tcx.hir().get_parent_item(hir_id); let encl_trait = tcx.hir().expect_item(encl_trait_hir_id); - if [tcx.lang_items().fn_trait(), tcx.lang_items().fn_mut_trait()] - .contains(&Some(encl_trait.def_id.to_def_id())) - && trait_item.ident.name.to_ident_string() == "call" + let encl_trait_def_id = encl_trait.def_id.to_def_id(); + let fn_lang_item_name = if Some(encl_trait_def_id) == tcx.lang_items().fn_trait() { + Some("fn") + } else if Some(encl_trait_def_id) == tcx.lang_items().fn_mut_trait() { + Some("fn_mut") + } else { + None + }; + + if let (Some(fn_lang_item_name), "call") = + (fn_lang_item_name, trait_item.ident.name.to_ident_string().as_str()) { // We are looking at the `call` function of the `fn` or `fn_mut` lang item. // Do some rudimentary sanity checking to avoid an ICE later (issue #83471). - if let Some(method_sig @ hir::FnSig { decl, .. }) = method_sig { + if let Some(hir::FnSig { decl, span, .. }) = method_sig { if let &[self_ty, _] = &decl.inputs { if !matches!(self_ty.kind, hir::TyKind::Rptr(_, _)) { - tcx.sess.struct_span_err( - self_ty.span, - "first argument of `call` in `fn`/`fn_mut` lang item must be a reference", - ).emit(); + tcx.sess + .struct_span_err( + self_ty.span, + &format!( + "first argument of `call` in `{}` lang item must be a reference", + fn_lang_item_name + ), + ) + .emit(); } } else { tcx.sess .struct_span_err( - method_sig.span, - "`call` function in `fn`/`fn_mut` lang item takes exactly two arguments", + *span, + &format!( + "`call` function in `{}` lang item takes exactly two arguments", + fn_lang_item_name + ), ) .emit(); } @@ -229,7 +245,10 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { tcx.sess .struct_span_err( trait_item.span, - "`call` trait item in `fn`/`fn_mut` lang item must be a function", + &format!( + "`call` trait item in `{}` lang item must be a function", + fn_lang_item_name + ), ) .emit(); } diff --git a/src/test/ui/lang-items/fn-fn_mut-call-ill-formed.rs b/src/test/ui/lang-items/fn-fn_mut-call-ill-formed.rs index 90dc972d8a8..52bd8136d9c 100644 --- a/src/test/ui/lang-items/fn-fn_mut-call-ill-formed.rs +++ b/src/test/ui/lang-items/fn-fn_mut-call-ill-formed.rs @@ -8,13 +8,13 @@ #[lang = "fn"] trait MyFn { const call: i32 = 42; - //~^ ERROR: `call` trait item in `fn`/`fn_mut` lang item must be a function + //~^ ERROR: `call` trait item in `fn` lang item must be a function } #[lang = "fn_mut"] trait MyFnMut { fn call(i: i32, j: i32) -> i32 { i + j } - //~^ ERROR: first argument of `call` in `fn`/`fn_mut` lang item must be a reference + //~^ ERROR: first argument of `call` in `fn_mut` lang item must be a reference } fn main() { diff --git a/src/test/ui/lang-items/fn-fn_mut-call-ill-formed.stderr b/src/test/ui/lang-items/fn-fn_mut-call-ill-formed.stderr index fea8e52b891..82bdae270c8 100644 --- a/src/test/ui/lang-items/fn-fn_mut-call-ill-formed.stderr +++ b/src/test/ui/lang-items/fn-fn_mut-call-ill-formed.stderr @@ -1,10 +1,10 @@ -error: `call` trait item in `fn`/`fn_mut` lang item must be a function +error: `call` trait item in `fn` lang item must be a function --> $DIR/fn-fn_mut-call-ill-formed.rs:10:5 | LL | const call: i32 = 42; | ^^^^^^^^^^^^^^^^^^^^^ -error: first argument of `call` in `fn`/`fn_mut` lang item must be a reference +error: first argument of `call` in `fn_mut` lang item must be a reference --> $DIR/fn-fn_mut-call-ill-formed.rs:16:16 | LL | fn call(i: i32, j: i32) -> i32 { i + j }