@@ -91,22 +91,16 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> {
91
91
// Closures in thir look something akin to
92
92
// `for<'a> extern "rust-call" fn(&'a [closure@...], ()) -> <[closure@...] as FnOnce<()>>::Output {<[closure@...] as Fn<()>>::call}`
93
93
// 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 ( ) {
95
95
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 ;
110
104
} ;
111
105
}
112
106
0 commit comments