mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-17 17:33:07 +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)
|
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>> {
|
pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> {
|
||||||
self.ty.impl_trait_bounds(db).map(|it| {
|
self.ty.impl_trait_bounds(db).map(|it| {
|
||||||
it.into_iter()
|
it.into_iter()
|
||||||
|
@ -56,6 +56,7 @@ pub use mapping::{
|
|||||||
to_foreign_def_id, to_placeholder_idx,
|
to_foreign_def_id, to_placeholder_idx,
|
||||||
};
|
};
|
||||||
pub use traits::TraitEnvironment;
|
pub use traits::TraitEnvironment;
|
||||||
|
pub use utils::all_super_traits;
|
||||||
pub use walk::TypeWalk;
|
pub use walk::TypeWalk;
|
||||||
|
|
||||||
pub use chalk_ir::{
|
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
|
/// Returns an iterator over the whole super trait hierarchy (including the
|
||||||
/// trait itself).
|
/// 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
|
// 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;`)
|
// (i.e. if we have `trait A: B; trait B: A;`)
|
||||||
let mut result = vec![trait_];
|
let mut result = vec![trait_];
|
||||||
|
@ -1127,4 +1127,27 @@ impl Bar for Foo {
|
|||||||
expect![[r#""#]],
|
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();
|
.collect();
|
||||||
|
|
||||||
|
let related_dyn_traits =
|
||||||
|
trait_candidate.receiver_ty.applicable_inherent_traits(db).collect::<FxHashSet<_>>();
|
||||||
let mut located_imports = FxHashSet::default();
|
let mut located_imports = FxHashSet::default();
|
||||||
|
|
||||||
if trait_assoc_item {
|
if trait_assoc_item {
|
||||||
@ -451,12 +453,16 @@ fn trait_applicable_items(
|
|||||||
return None;
|
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);
|
let original_item = assoc_to_item(assoc);
|
||||||
located_imports.insert(LocatedImport::new(
|
located_imports.insert(LocatedImport::new(
|
||||||
mod_path(item)?,
|
mod_path(trait_item)?,
|
||||||
item,
|
trait_item,
|
||||||
original_item,
|
original_item,
|
||||||
mod_path(original_item),
|
mod_path(original_item),
|
||||||
));
|
));
|
||||||
@ -473,11 +479,15 @@ fn trait_applicable_items(
|
|||||||
|_, function| {
|
|_, function| {
|
||||||
let assoc = function.as_assoc_item(db)?;
|
let assoc = function.as_assoc_item(db)?;
|
||||||
if required_assoc_items.contains(&assoc) {
|
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);
|
let original_item = assoc_to_item(assoc);
|
||||||
located_imports.insert(LocatedImport::new(
|
located_imports.insert(LocatedImport::new(
|
||||||
mod_path(item)?,
|
mod_path(trait_item)?,
|
||||||
item,
|
trait_item,
|
||||||
original_item,
|
original_item,
|
||||||
mod_path(original_item),
|
mod_path(original_item),
|
||||||
));
|
));
|
||||||
|
Loading…
Reference in New Issue
Block a user