use crate::RustIrDatabase;
use chalk_ir::{
interner::Interner,
- visit::{ControlFlow, Visitor},
- visit::{SuperVisit, Visit},
+ visit::TypeVisitor,
+ visit::{TypeSuperVisitable, TypeVisitable},
AliasTy, DebruijnIndex, TyKind, WhereClause,
};
-use std::collections::BTreeSet;
+use std::ops::ControlFlow;
+
+use indexmap::IndexSet;
/// Collects the identifiers needed to resolve all the names for a given
/// set of identifers, excluding identifiers we already have.
/// references parent. IdCollector solves this by collecting all of the directly
/// related identifiers, allowing those to be rendered as well, ensuring name
/// resolution is successful.
-pub fn collect_unrecorded_ids<'i, I: Interner, DB: RustIrDatabase<I>>(
- db: &'i DB,
- identifiers: &'_ BTreeSet<RecordedItemId<I>>,
-) -> BTreeSet<RecordedItemId<I>> {
+pub fn collect_unrecorded_ids<I: Interner, DB: RustIrDatabase<I>>(
+ db: &DB,
+ identifiers: &'_ IndexSet<RecordedItemId<I>>,
+) -> IndexSet<RecordedItemId<I>> {
let mut collector = IdCollector {
db,
- found_identifiers: BTreeSet::new(),
+ found_identifiers: IndexSet::new(),
};
for id in identifiers {
match *id {
struct IdCollector<'i, I: Interner, DB: RustIrDatabase<I>> {
db: &'i DB,
- found_identifiers: BTreeSet<RecordedItemId<I>>,
+ found_identifiers: IndexSet<RecordedItemId<I>>,
}
impl<'i, I: Interner, DB: RustIrDatabase<I>> IdCollector<'i, I, DB> {
fn record(&mut self, id: impl Into<RecordedItemId<I>>) {
self.found_identifiers.insert(id.into());
}
+
+ fn visit_alias(&mut self, alias: &AliasTy<I>) {
+ match alias {
+ AliasTy::Projection(projection_ty) => {
+ let assoc_ty_datum = self.db.associated_ty_data(projection_ty.associated_ty_id);
+ self.record(assoc_ty_datum.trait_id)
+ }
+ AliasTy::Opaque(opaque_ty) => self.record(opaque_ty.opaque_ty_id),
+ }
+ }
}
-impl<'i, I: Interner, DB: RustIrDatabase<I>> Visitor<'i, I> for IdCollector<'i, I, DB>
-where
- I: 'i,
-{
+impl<'i, I: Interner, DB: RustIrDatabase<I>> TypeVisitor<I> for IdCollector<'i, I, DB> {
type BreakTy = ();
- fn as_dyn(&mut self) -> &mut dyn Visitor<'i, I, BreakTy = Self::BreakTy> {
+ fn as_dyn(&mut self) -> &mut dyn TypeVisitor<I, BreakTy = Self::BreakTy> {
self
}
- fn interner(&self) -> &'i I {
+ fn interner(&self) -> I {
self.db.interner()
}
TyKind::Adt(adt, _) => self.record(*adt),
TyKind::FnDef(fn_def, _) => self.record(*fn_def),
TyKind::OpaqueType(opaque, _) => self.record(*opaque),
- TyKind::Alias(alias) => match alias {
- AliasTy::Projection(projection_ty) => {
- let assoc_ty_datum = self.db.associated_ty_data(projection_ty.associated_ty_id);
- self.record(assoc_ty_datum.trait_id)
- }
- AliasTy::Opaque(opaque_ty) => {
- self.record(opaque_ty.opaque_ty_id);
- }
- },
+ TyKind::Alias(alias) => self.visit_alias(alias),
TyKind::BoundVar(..) => (),
TyKind::Dyn(..) => (),
TyKind::Function(..) => (),
) -> ControlFlow<()> {
match where_clause {
WhereClause::Implemented(trait_ref) => self.record(trait_ref.trait_id),
- WhereClause::AliasEq(alias_eq) => match &alias_eq.alias {
- AliasTy::Projection(projection_ty) => {
- let assoc_ty_datum = self.db.associated_ty_data(projection_ty.associated_ty_id);
- self.record(assoc_ty_datum.trait_id)
- }
- AliasTy::Opaque(opaque_ty) => {
- self.record(opaque_ty.opaque_ty_id);
- }
- },
+ WhereClause::AliasEq(alias_eq) => self.visit_alias(&alias_eq.alias),
WhereClause::LifetimeOutlives(_lifetime_outlives) => (),
WhereClause::TypeOutlives(_type_outlives) => (),
}