@@ -91,22 +91,16 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> {
9191 // Closures in thir look something akin to
9292 // `for<'a> extern "rust-call" fn(&'a [closure@...], ()) -> <[closure@...] as FnOnce<()>>::Output {<[closure@...] as Fn<()>>::call}`
9393 // So we have to check for them in this weird way...
94- if let & ty:: FnDef ( did, substs ) = ty. kind ( ) {
94+ if let & ty:: FnDef ( did, args ) = ty. kind ( ) {
9595 let parent = self . tcx . parent ( did) ;
96- let fn_ = self . tcx . require_lang_item ( LangItem :: Fn , Some ( expr. span ) ) ;
97- let fn_once = self . tcx . require_lang_item ( LangItem :: FnOnce , Some ( expr. span ) ) ;
98- let fn_mut = self . tcx . require_lang_item ( LangItem :: FnMut , Some ( expr. span ) ) ;
99- if [ fn_, fn_once, fn_mut] . contains ( & parent) {
100- if substs. first ( ) . and_then ( |arg| arg. as_type ( ) ) . is_some_and ( |t| t. is_closure ( ) ) {
101- self . report_calling_closure (
102- & self . thir [ fun] ,
103- substs[ 1 ] . as_type ( ) . unwrap ( ) ,
104- expr,
105- ) ;
106-
107- // Tail calling is likely to cause unrelated errors (ABI, argument mismatches)
108- return ;
109- }
96+ if self . tcx . fn_trait_kind_from_def_id ( parent) . is_some ( )
97+ && args. first ( ) . and_then ( |arg| arg. as_type ( ) ) . is_some_and ( Ty :: is_closure)
98+ {
99+ self . report_calling_closure ( & self . thir [ fun] , args[ 1 ] . as_type ( ) . unwrap ( ) , expr) ;
100+
101+ // Tail calling is likely to cause unrelated errors (ABI, argument mismatches),
102+ // skip them, producing an error about calling a closure is enough.
103+ return ;
110104 } ;
111105 }
112106
0 commit comments