mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-24 07:44:10 +00:00
Exclude inherent traits from flyimports
This commit is contained in:
parent
75371eb0fa
commit
739edfd5cf
@ -2066,6 +2066,18 @@ impl Type {
|
||||
self.ty.dyn_trait().map(Into::into)
|
||||
}
|
||||
|
||||
/// If a type can be represented as `dyn Trait`, returns all traits accessible via this type,
|
||||
/// or an empty iterator otherwise.
|
||||
pub fn applicable_inherent_traits<'a>(
|
||||
&'a self,
|
||||
db: &'a dyn HirDatabase,
|
||||
) -> impl Iterator<Item = Trait> + 'a {
|
||||
self.autoderef(db)
|
||||
.filter_map(|derefed_type| derefed_type.ty.dyn_trait())
|
||||
.flat_map(move |dyn_trait_id| hir_ty::all_super_traits(db.upcast(), dyn_trait_id))
|
||||
.map(Trait::from)
|
||||
}
|
||||
|
||||
pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> {
|
||||
self.ty.impl_trait_bounds(db).map(|it| {
|
||||
it.into_iter()
|
||||
|
@ -56,6 +56,7 @@ pub use mapping::{
|
||||
to_foreign_def_id, to_placeholder_idx,
|
||||
};
|
||||
pub use traits::TraitEnvironment;
|
||||
pub use utils::all_super_traits;
|
||||
pub use walk::TypeWalk;
|
||||
|
||||
pub use chalk_ir::{
|
||||
|
@ -78,7 +78,7 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr
|
||||
|
||||
/// Returns an iterator over the whole super trait hierarchy (including the
|
||||
/// trait itself).
|
||||
pub(super) fn all_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
|
||||
pub fn all_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
|
||||
// we need to take care a bit here to avoid infinite loops in case of cycles
|
||||
// (i.e. if we have `trait A: B; trait B: A;`)
|
||||
let mut result = vec![trait_];
|
||||
|
@ -1127,4 +1127,27 @@ impl Bar for Foo {
|
||||
expect![[r#""#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_inherent_candidates_proposed() {
|
||||
check(
|
||||
r#"
|
||||
mod baz {
|
||||
pub trait DefDatabase {
|
||||
fn method1(&self);
|
||||
}
|
||||
pub trait HirDatabase: DefDatabase {
|
||||
fn method2(&self);
|
||||
}
|
||||
}
|
||||
|
||||
mod bar {
|
||||
fn test(db: &dyn crate::baz::HirDatabase) {
|
||||
db.metho$0
|
||||
}
|
||||
}
|
||||
"#,
|
||||
expect![[r#""#]],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -436,6 +436,8 @@ fn trait_applicable_items(
|
||||
})
|
||||
.collect();
|
||||
|
||||
let related_dyn_traits =
|
||||
trait_candidate.receiver_ty.applicable_inherent_traits(db).collect::<FxHashSet<_>>();
|
||||
let mut located_imports = FxHashSet::default();
|
||||
|
||||
if trait_assoc_item {
|
||||
@ -451,12 +453,16 @@ fn trait_applicable_items(
|
||||
return None;
|
||||
}
|
||||
}
|
||||
let located_trait = assoc.containing_trait(db)?;
|
||||
if related_dyn_traits.contains(&located_trait) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let item = ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?));
|
||||
let trait_item = ItemInNs::from(ModuleDef::from(located_trait));
|
||||
let original_item = assoc_to_item(assoc);
|
||||
located_imports.insert(LocatedImport::new(
|
||||
mod_path(item)?,
|
||||
item,
|
||||
mod_path(trait_item)?,
|
||||
trait_item,
|
||||
original_item,
|
||||
mod_path(original_item),
|
||||
));
|
||||
@ -473,11 +479,15 @@ fn trait_applicable_items(
|
||||
|_, function| {
|
||||
let assoc = function.as_assoc_item(db)?;
|
||||
if required_assoc_items.contains(&assoc) {
|
||||
let item = ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?));
|
||||
let located_trait = assoc.containing_trait(db)?;
|
||||
if related_dyn_traits.contains(&located_trait) {
|
||||
return None;
|
||||
}
|
||||
let trait_item = ItemInNs::from(ModuleDef::from(located_trait));
|
||||
let original_item = assoc_to_item(assoc);
|
||||
located_imports.insert(LocatedImport::new(
|
||||
mod_path(item)?,
|
||||
item,
|
||||
mod_path(trait_item)?,
|
||||
trait_item,
|
||||
original_item,
|
||||
mod_path(original_item),
|
||||
));
|
||||
|
Loading…
Reference in New Issue
Block a user