mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 21:05:02 +00:00
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.
This commit is contained in:
parent
1fee60181f
commit
6a2127be28
2 changed files with 24 additions and 48 deletions
|
@ -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<CallableDef> {
|
||||
Some(self.ty.value.as_callable()?.0)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue