From 6a2127be28a837215801f4ac3cd7d46ef7c4485b Mon Sep 17 00:00:00 2001 From: Matthew Hall Date: Thu, 2 Apr 2020 18:42:30 +0100 Subject: Cleanup checking for existing impls in impl From assist Use the trait solver to check if there's an existing implementation of From for the enum. --- crates/ra_hir/src/code_model.rs | 54 ++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 33 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 3889a7e5a..c6f3bdb8e 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -23,7 +23,7 @@ use hir_expand::{ }; use hir_ty::{ autoderef, display::HirFormatter, expr::ExprValidator, method_resolution, ApplicationTy, - Canonical, InEnvironment, Substs, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk, + Canonical, InEnvironment, Substs, TraitEnvironment, Ty, TyDefId, TypeCtor, }; use ra_db::{CrateId, Edition, FileId}; use ra_prof::profile; @@ -960,38 +960,6 @@ impl ImplDef { db.impl_data(self.id).target_trait.clone() } - pub fn target_trait_substs_matches(&self, db: &dyn HirDatabase, typs: &[Type]) -> bool { - let type_ref = match self.target_trait(db) { - Some(typ_ref) => typ_ref, - None => return false, - }; - let resolver = self.id.resolver(db.upcast()); - let ctx = hir_ty::TyLoweringContext::new(db, &resolver); - let ty = Ty::from_hir(&ctx, &type_ref); - let d = match ty.dyn_trait_ref() { - Some(d) => d, - None => return false, - }; - let mut matches = true; - let mut i = 0; - d.substs.walk(&mut |t| { - if matches { - if i >= typs.len() { - matches = false; - return; - } - match t { - Ty::Bound(_) => matches = i == 0, - _ => { - matches = *t == typs[i].ty.value; - i += 1; - } - } - } - }); - matches - } - pub fn target_type(&self, db: &dyn HirDatabase) -> TypeRef { db.impl_data(self.id).target_type.clone() } @@ -1116,6 +1084,26 @@ impl Type { ) } + pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool { + let trait_ref = hir_ty::TraitRef { + trait_: trait_.id, + substs: Substs::build_for_def(db, trait_.id) + .push(self.ty.value.clone()) + .fill(args.iter().map(|t| t.ty.value.clone())) + .build(), + }; + + let goal = Canonical { + value: hir_ty::InEnvironment::new( + self.ty.environment.clone(), + hir_ty::Obligation::Trait(trait_ref), + ), + num_vars: 0, + }; + + db.trait_solve(self.krate, goal).is_some() + } + // FIXME: this method is broken, as it doesn't take closures into account. pub fn as_callable(&self) -> Option { Some(self.ty.value.as_callable()?.0) -- cgit v1.2.3