From a483b5545dad2d36336c1e9a4f5dc991d2c8460b Mon Sep 17 00:00:00 2001 From: GrayJack Date: Fri, 16 Oct 2020 07:52:18 -0300 Subject: Add Callable modifier for variables that implements Fnonce --- crates/hir/src/code_model.rs | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'crates/hir/src') diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index b65be4fe1..8ecf72bd9 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs @@ -31,8 +31,7 @@ use hir_ty::{ autoderef, display::{HirDisplayError, HirFormatter}, method_resolution, - traits::Solution, - traits::SolutionVariables, + traits::{FnTrait, Solution, SolutionVariables}, ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, Ty, TyDefId, TyKind, TypeCtor, @@ -1385,6 +1384,28 @@ impl Type { ) } + /// Checks that particular type `ty` implements `std::ops::FnOnce`. + /// + /// This function can be used to check if a particular type is callable, since FnOnce is a + /// supertrait of Fn and FnMut, so all callable types implements at least FnOnce. + pub fn impls_fnonce(&self, db: &dyn HirDatabase) -> bool { + let krate = self.krate; + + let fnonce_trait = match FnTrait::FnOnce.get_id(db, krate) { + Some(it) => it, + None => return false, + }; + + let canonical_ty = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; + method_resolution::implements_trait( + &canonical_ty, + db, + self.ty.environment.clone(), + krate, + fnonce_trait, + ) + } + pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool { let trait_ref = hir_ty::TraitRef { trait_: trait_.id, -- cgit v1.2.3