Skip to content

Commit cb6c139

Browse files
committed
Make error message for malformed fn/fn_mut lang item more specific
1 parent 4337089 commit cb6c139

File tree

3 files changed

+34
-15
lines changed

3 files changed

+34
-15
lines changed

Diff for: compiler/rustc_typeck/src/check/wfcheck.rs

+30-11
Original file line numberDiff line numberDiff line change
@@ -203,33 +203,52 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
203203

204204
let encl_trait_hir_id = tcx.hir().get_parent_item(hir_id);
205205
let encl_trait = tcx.hir().expect_item(encl_trait_hir_id);
206-
if [tcx.lang_items().fn_trait(), tcx.lang_items().fn_mut_trait()]
207-
.contains(&Some(encl_trait.def_id.to_def_id()))
208-
&& trait_item.ident.name.to_ident_string() == "call"
206+
let encl_trait_def_id = encl_trait.def_id.to_def_id();
207+
let fn_lang_item_name = if Some(encl_trait_def_id) == tcx.lang_items().fn_trait() {
208+
Some("fn")
209+
} else if Some(encl_trait_def_id) == tcx.lang_items().fn_mut_trait() {
210+
Some("fn_mut")
211+
} else {
212+
None
213+
};
214+
215+
if let (Some(fn_lang_item_name), "call") =
216+
(fn_lang_item_name, trait_item.ident.name.to_ident_string().as_str())
209217
{
210218
// We are looking at the `call` function of the `fn` or `fn_mut` lang item.
211219
// Do some rudimentary sanity checking to avoid an ICE later (issue #83471).
212-
if let Some(method_sig @ hir::FnSig { decl, .. }) = method_sig {
220+
if let Some(hir::FnSig { decl, span, .. }) = method_sig {
213221
if let &[self_ty, _] = &decl.inputs {
214222
if !matches!(self_ty.kind, hir::TyKind::Rptr(_, _)) {
215-
tcx.sess.struct_span_err(
216-
self_ty.span,
217-
"first argument of `call` in `fn`/`fn_mut` lang item must be a reference",
218-
).emit();
223+
tcx.sess
224+
.struct_span_err(
225+
self_ty.span,
226+
&format!(
227+
"first argument of `call` in `{}` lang item must be a reference",
228+
fn_lang_item_name
229+
),
230+
)
231+
.emit();
219232
}
220233
} else {
221234
tcx.sess
222235
.struct_span_err(
223-
method_sig.span,
224-
"`call` function in `fn`/`fn_mut` lang item takes exactly two arguments",
236+
*span,
237+
&format!(
238+
"`call` function in `{}` lang item takes exactly two arguments",
239+
fn_lang_item_name
240+
),
225241
)
226242
.emit();
227243
}
228244
} else {
229245
tcx.sess
230246
.struct_span_err(
231247
trait_item.span,
232-
"`call` trait item in `fn`/`fn_mut` lang item must be a function",
248+
&format!(
249+
"`call` trait item in `{}` lang item must be a function",
250+
fn_lang_item_name
251+
),
233252
)
234253
.emit();
235254
}

Diff for: src/test/ui/lang-items/fn-fn_mut-call-ill-formed.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
#[lang = "fn"]
99
trait MyFn<T> {
1010
const call: i32 = 42;
11-
//~^ ERROR: `call` trait item in `fn`/`fn_mut` lang item must be a function
11+
//~^ ERROR: `call` trait item in `fn` lang item must be a function
1212
}
1313

1414
#[lang = "fn_mut"]
1515
trait MyFnMut<T> {
1616
fn call(i: i32, j: i32) -> i32 { i + j }
17-
//~^ ERROR: first argument of `call` in `fn`/`fn_mut` lang item must be a reference
17+
//~^ ERROR: first argument of `call` in `fn_mut` lang item must be a reference
1818
}
1919

2020
fn main() {

Diff for: src/test/ui/lang-items/fn-fn_mut-call-ill-formed.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error: `call` trait item in `fn`/`fn_mut` lang item must be a function
1+
error: `call` trait item in `fn` lang item must be a function
22
--> $DIR/fn-fn_mut-call-ill-formed.rs:10:5
33
|
44
LL | const call: i32 = 42;
55
| ^^^^^^^^^^^^^^^^^^^^^
66

7-
error: first argument of `call` in `fn`/`fn_mut` lang item must be a reference
7+
error: first argument of `call` in `fn_mut` lang item must be a reference
88
--> $DIR/fn-fn_mut-call-ill-formed.rs:16:16
99
|
1010
LL | fn call(i: i32, j: i32) -> i32 { i + j }

0 commit comments

Comments
 (0)