diff options
author | Matthew Hall <[email protected]> | 2020-04-02 18:42:30 +0100 |
---|---|---|
committer | Matthew Hall <[email protected]> | 2020-04-02 18:42:30 +0100 |
commit | 6a2127be28a837215801f4ac3cd7d46ef7c4485b (patch) | |
tree | 2bacfb7f92c7059a5975fd5f256122b08190f93d /crates/ra_hir/src | |
parent | 1fee60181fea56ebe6b5e4aeb11cf9df25a1d087 (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.rs | 54 |
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 | }; |
24 | use hir_ty::{ | 24 | use 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 | }; |
28 | use ra_db::{CrateId, Edition, FileId}; | 28 | use ra_db::{CrateId, Edition, FileId}; |
29 | use ra_prof::profile; | 29 | use 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) |