aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
authorMatthew Hall <[email protected]>2020-04-02 18:42:30 +0100
committerMatthew Hall <[email protected]>2020-04-02 18:42:30 +0100
commit6a2127be28a837215801f4ac3cd7d46ef7c4485b (patch)
tree2bacfb7f92c7059a5975fd5f256122b08190f93d /crates/ra_hir/src
parent1fee60181fea56ebe6b5e4aeb11cf9df25a1d087 (diff)
Cleanup checking for existing impls in impl From assist
Use the trait solver to check if there's an existing implementation of From<type_in_enum_variant> for the enum.
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/code_model.rs54
1 files changed, 21 insertions, 33 deletions
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::{
23}; 23};
24use hir_ty::{ 24use hir_ty::{
25 autoderef, display::HirFormatter, expr::ExprValidator, method_resolution, ApplicationTy, 25 autoderef, display::HirFormatter, expr::ExprValidator, method_resolution, ApplicationTy,
26 Canonical, InEnvironment, Substs, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk, 26 Canonical, InEnvironment, Substs, TraitEnvironment, Ty, TyDefId, TypeCtor,
27}; 27};
28use ra_db::{CrateId, Edition, FileId}; 28use ra_db::{CrateId, Edition, FileId};
29use ra_prof::profile; 29use ra_prof::profile;
@@ -960,38 +960,6 @@ impl ImplDef {
960 db.impl_data(self.id).target_trait.clone() 960 db.impl_data(self.id).target_trait.clone()
961 } 961 }
962 962
963 pub fn target_trait_substs_matches(&self, db: &dyn HirDatabase, typs: &[Type]) -> bool {
964 let type_ref = match self.target_trait(db) {
965 Some(typ_ref) => typ_ref,
966 None => return false,
967 };
968 let resolver = self.id.resolver(db.upcast());
969 let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
970 let ty = Ty::from_hir(&ctx, &type_ref);
971 let d = match ty.dyn_trait_ref() {
972 Some(d) => d,
973 None => return false,
974 };
975 let mut matches = true;
976 let mut i = 0;
977 d.substs.walk(&mut |t| {
978 if matches {
979 if i >= typs.len() {
980 matches = false;
981 return;
982 }
983 match t {
984 Ty::Bound(_) => matches = i == 0,
985 _ => {
986 matches = *t == typs[i].ty.value;
987 i += 1;
988 }
989 }
990 }
991 });
992 matches
993 }
994
995 pub fn target_type(&self, db: &dyn HirDatabase) -> TypeRef { 963 pub fn target_type(&self, db: &dyn HirDatabase) -> TypeRef {
996 db.impl_data(self.id).target_type.clone() 964 db.impl_data(self.id).target_type.clone()
997 } 965 }
@@ -1116,6 +1084,26 @@ impl Type {
1116 ) 1084 )
1117 } 1085 }
1118 1086
1087 pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool {
1088 let trait_ref = hir_ty::TraitRef {
1089 trait_: trait_.id,
1090 substs: Substs::build_for_def(db, trait_.id)
1091 .push(self.ty.value.clone())
1092 .fill(args.iter().map(|t| t.ty.value.clone()))
1093 .build(),
1094 };
1095
1096 let goal = Canonical {
1097 value: hir_ty::InEnvironment::new(
1098 self.ty.environment.clone(),
1099 hir_ty::Obligation::Trait(trait_ref),
1100 ),
1101 num_vars: 0,
1102 };
1103
1104 db.trait_solve(self.krate, goal).is_some()
1105 }
1106
1119 // FIXME: this method is broken, as it doesn't take closures into account. 1107 // FIXME: this method is broken, as it doesn't take closures into account.
1120 pub fn as_callable(&self) -> Option<CallableDef> { 1108 pub fn as_callable(&self) -> Option<CallableDef> {
1121 Some(self.ty.value.as_callable()?.0) 1109 Some(self.ty.value.as_callable()?.0)