@@ -31,8 +31,7 @@ use hir_ty::{
3131 autoderef,
3232 display:: { HirDisplayError , HirFormatter } ,
3333 method_resolution,
34- traits:: Solution ,
35- traits:: SolutionVariables ,
34+ traits:: { FnTrait , Solution , SolutionVariables } ,
3635 ApplicationTy , BoundVar , CallableDefId , Canonical , DebruijnIndex , FnSig , GenericPredicate ,
3736 InEnvironment , Obligation , ProjectionPredicate , ProjectionTy , Substs , TraitEnvironment , Ty ,
3837 TyDefId , TyKind , TypeCtor ,
@@ -1385,6 +1384,28 @@ impl Type {
13851384 )
13861385 }
13871386
1387+ /// Checks that particular type `ty` implements `std::ops::FnOnce`.
1388+ ///
1389+ /// This function can be used to check if a particular type is callable, since FnOnce is a
1390+ /// supertrait of Fn and FnMut, so all callable types implements at least FnOnce.
1391+ pub fn impls_fnonce ( & self , db : & dyn HirDatabase ) -> bool {
1392+ let krate = self . krate ;
1393+
1394+ let fnonce_trait = match FnTrait :: FnOnce . get_id ( db, krate) {
1395+ Some ( it) => it,
1396+ None => return false ,
1397+ } ;
1398+
1399+ let canonical_ty = Canonical { value : self . ty . value . clone ( ) , kinds : Arc :: new ( [ ] ) } ;
1400+ method_resolution:: implements_trait (
1401+ & canonical_ty,
1402+ db,
1403+ self . ty . environment . clone ( ) ,
1404+ krate,
1405+ fnonce_trait,
1406+ )
1407+ }
1408+
13881409 pub fn impls_trait ( & self , db : & dyn HirDatabase , trait_ : Trait , args : & [ Type ] ) -> bool {
13891410 let trait_ref = hir_ty:: TraitRef {
13901411 trait_ : trait_. id ,
0 commit comments