Change:
let node = self.infcx.tcx.hir_node(fn_call_id); let def_id = hir.enclosing_body_owner(fn_call_id); let mut look_at_return = true; <del> // If we can detect the expression to be an `fn` call where the closure was an argument, // we point at the `fn` definition argument... if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Call(func, args), .. }) = node { let arg_pos = args </del> <ins> // If the HIR node is a function or method call gets the def ID // of the called function or method and the span and args of the call expr let get_call_details = || { let hir::Node::Expr(hir::Expr { hir_id, kind, .. }) = node else { return None; }; let typeck_results = self.infcx.tcx.typeck(def_id); match kind { hir::ExprKind::Call(expr, args) => { if let Some(ty::FnDef(def_id, _)) = typeck_results.node_type_opt(expr.hir_id).as_ref().map(|ty| ty.kind()) { Some((*def_id, expr.span, *args)) } else { None } } hir::ExprKind::MethodCall(_, _, args, span) => { if let Some(def_id) = typeck_results.type_dependent_def_id(*hir_id) { Some((def_id, *span, *args)) } else { None } } _ => None, } }; // If we can detect the expression to be an function or method call where the closure was an argument, // we point at the function or method definition argument... if let Some((callee_def_id, call_span, call_args)) = get_call_details() { let arg_pos = call_args </ins> .iter() .enumerate() .filter(|(_, arg)| arg.hir_id == closure_id) .map(|(pos, _)| pos) .next(); <del> let tables = self.infcx.tcx.typeck(def_id); if let Some(ty::FnDef(def_id, _)) = tables.node_type_opt(func.hir_id).as_ref().map(|ty| ty.kind()) { let arg = match hir.get_if_local(*def_id) { Some( hir::Node::Item(hir::Item { ident, kind: hir::ItemKind::Fn(sig, ..), .. }) | hir::Node::TraitItem(hir::TraitItem { ident, kind: hir::TraitItemKind::Fn(sig, _), .. </del> <ins> let arg = match hir.get_if_local(callee_def_id) { Some( hir::Node::Item(hir::Item { ident, kind: hir::ItemKind::Fn(sig, ..), .. }) | hir::Node::TraitItem(hir::TraitItem { ident, kind: hir::TraitItemKind::Fn(sig, _), .. }) | hir::Node::ImplItem(hir::ImplItem { ident, kind: hir::ImplItemKind::Fn(sig, _), .. }), ) => Some( arg_pos .and_then(|pos| { sig.decl.inputs.get( pos + if sig.decl.implicit_self.has_implicit_self() { 1 } else { 0 }, ) </ins> }) <del> | hir::Node::ImplItem(hir::ImplItem { ident, kind: hir::ImplItemKind::Fn(sig, _), .. }), ) => Some( arg_pos .and_then(|pos| { sig.decl.inputs.get( pos + if sig.decl.implicit_self.has_implicit_self() { 1 } else { 0 }, ) }) .map(|arg| arg.span) .unwrap_or(ident.span), ), _ => None, }; if let Some(span) = arg { err.span_label(span, "change this to accept `FnMut` instead of `Fn`"); err.span_label(func.span, "expects `Fn` instead of `FnMut`"); err.span_label(closure_span, "in this closure"); look_at_return = false; } </del> <ins> .map(|arg| arg.span) .unwrap_or(ident.span), ), _ => None, }; if let Some(span) = arg { err.span_label(span, "change this to accept `FnMut` instead of `Fn`"); err.span_label(call_span, "expects `Fn` instead of `FnMut`"); err.span_label(closure_span, "in this closure"); look_at_return = false; </ins> } }

Discussion:
I tried this code: I expected to see this happen: Code compilation, or at least a sensible error. Instead, this happened: I tried to make a reproducer using the following code that expresses the same type and fn signatures on Rust Playground, but I'm unable to trigger it. : tested on Nightly as well. <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summaryBacktrace</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
- and even smaller example
Thank you!!
claim