Skip to content

Commit

Permalink
Merge pull request #18482 from regexident/hir_trait_supertraits_acces…
Browse files Browse the repository at this point in the history
…sors

internal: Add public `direct_supertraits(…)` & `all_supertraits(…)` accessor methods to `hir::Trait`
  • Loading branch information
lnicola authored Nov 11, 2024
2 parents 30e71b6 + e646152 commit aabab29
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 6 deletions.
2 changes: 1 addition & 1 deletion crates/hir-ty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ pub use mapping::{
};
pub use method_resolution::check_orphan_rules;
pub use traits::TraitEnvironment;
pub use utils::{all_super_traits, is_fn_unsafe_to_call};
pub use utils::{all_super_traits, direct_super_traits, is_fn_unsafe_to_call};

pub use chalk_ir::{
cast::Cast,
Expand Down
15 changes: 13 additions & 2 deletions crates/hir-ty/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ pub(crate) fn fn_traits(
.flat_map(|it| it.as_trait())
}

/// Returns an iterator over the direct super traits (including the trait itself).
pub fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> SmallVec<[TraitId; 4]> {
let mut result = smallvec![trait_];
direct_super_traits_cb(db, trait_, |tt| {
if !result.contains(&tt) {
result.push(tt);
}
});
result
}

/// Returns an iterator over the whole super trait hierarchy (including the
/// trait itself).
pub fn all_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> SmallVec<[TraitId; 4]> {
Expand All @@ -54,7 +65,7 @@ pub fn all_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> SmallVec<[Trai
while let Some(&t) = result.get(i) {
// yeah this is quadratic, but trait hierarchies should be flat
// enough that this doesn't matter
direct_super_traits(db, t, |tt| {
direct_super_traits_cb(db, t, |tt| {
if !result.contains(&tt) {
result.push(tt);
}
Expand Down Expand Up @@ -153,7 +164,7 @@ impl Iterator for ClauseElaborator<'_> {
}
}

fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId, cb: impl FnMut(TraitId)) {
fn direct_super_traits_cb(db: &dyn DefDatabase, trait_: TraitId, cb: impl FnMut(TraitId)) {
let resolver = trait_.resolver(db);
let generic_params = db.generic_params(trait_.into());
let trait_self = generic_params.trait_self_param();
Expand Down
15 changes: 12 additions & 3 deletions crates/hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ use hir_ty::{
all_super_traits, autoderef, check_orphan_rules,
consteval::{try_const_usize, unknown_const_as_generic, ConstExt},
diagnostics::BodyValidationDiagnostic,
error_lifetime, known_const_to_ast,
direct_super_traits, error_lifetime, known_const_to_ast,
layout::{Layout as TyLayout, RustcEnumVariantIdx, RustcFieldIdx, TagEncoding},
method_resolution,
mir::{interpret_mir, MutBorrowKind},
Expand Down Expand Up @@ -2704,13 +2704,22 @@ impl Trait {
db.trait_data(self.id).name.clone()
}

pub fn direct_supertraits(self, db: &dyn HirDatabase) -> Vec<Trait> {
let traits = direct_super_traits(db.upcast(), self.into());
traits.iter().map(|tr| Trait::from(*tr)).collect()
}

pub fn all_supertraits(self, db: &dyn HirDatabase) -> Vec<Trait> {
let traits = all_super_traits(db.upcast(), self.into());
traits.iter().map(|tr| Trait::from(*tr)).collect()
}

pub fn items(self, db: &dyn HirDatabase) -> Vec<AssocItem> {
db.trait_data(self.id).items.iter().map(|(_name, it)| (*it).into()).collect()
}

pub fn items_with_supertraits(self, db: &dyn HirDatabase) -> Vec<AssocItem> {
let traits = all_super_traits(db.upcast(), self.into());
traits.iter().flat_map(|tr| Trait::from(*tr).items(db)).collect()
self.all_supertraits(db).into_iter().flat_map(|tr| tr.items(db)).collect()
}

pub fn is_auto(self, db: &dyn HirDatabase) -> bool {
Expand Down

0 comments on commit aabab29

Please sign in to comment.