]>
git.proxmox.com Git - rustc.git/blob - vendor/chalk-solve-0.55.0/src/logging_db/id_collector.rs
1 use super::RecordedItemId
;
2 use crate::RustIrDatabase
;
5 visit
::{ControlFlow, Visitor}
,
6 visit
::{SuperVisit, Visit}
,
7 AliasTy
, DebruijnIndex
, TyKind
, WhereClause
,
9 use std
::collections
::BTreeSet
;
11 /// Collects the identifiers needed to resolve all the names for a given
12 /// set of identifers, excluding identifiers we already have.
14 /// When recording identifiers to print, the `LoggingRustIrDatabase` only
15 /// records identifiers the solver uses. But the solver assumes well-formedness,
16 /// and thus skips over many names referenced in the definitions.
18 /// For instance, if we have:
24 /// trait Child where Self: Parent {}
25 /// impl Parent for S {}
26 /// impl Child for S {}
29 /// And our goal is `S: Child`, we will only render `S`, `impl Child for S`, and
30 /// `trait Child`. This will not parse because the `Child` trait's definition
31 /// references parent. IdCollector solves this by collecting all of the directly
32 /// related identifiers, allowing those to be rendered as well, ensuring name
33 /// resolution is successful.
34 pub fn collect_unrecorded_ids
<'i
, I
: Interner
, DB
: RustIrDatabase
<I
>>(
36 identifiers
: &'_ BTreeSet
<RecordedItemId
<I
>>,
37 ) -> BTreeSet
<RecordedItemId
<I
>> {
38 let mut collector
= IdCollector
{
40 found_identifiers
: BTreeSet
::new(),
42 for id
in identifiers
{
44 RecordedItemId
::Adt(adt_id
) => {
48 .visit_with(&mut collector
, DebruijnIndex
::INNERMOST
);
50 RecordedItemId
::FnDef(fn_def
) => {
54 .visit_with(&mut collector
, DebruijnIndex
::INNERMOST
);
56 RecordedItemId
::Generator(_generator_id
) => unimplemented
!(),
57 RecordedItemId
::Trait(trait_id
) => {
58 let trait_datum
= collector
.db
.trait_datum(trait_id
);
60 trait_datum
.visit_with(&mut collector
, DebruijnIndex
::INNERMOST
);
61 for assoc_ty_id
in &trait_datum
.associated_ty_ids
{
62 let assoc_ty_datum
= collector
.db
.associated_ty_data(*assoc_ty_id
);
64 .bounds_on_self(collector
.db
.interner())
65 .visit_with(&mut collector
, DebruijnIndex
::INNERMOST
);
66 assoc_ty_datum
.visit_with(&mut collector
, DebruijnIndex
::INNERMOST
);
69 RecordedItemId
::OpaqueTy(opaque_id
) => {
72 .opaque_ty_data(opaque_id
)
73 .visit_with(&mut collector
, DebruijnIndex
::INNERMOST
);
76 .hidden_opaque_type(opaque_id
)
77 .visit_with(&mut collector
, DebruijnIndex
::INNERMOST
);
79 RecordedItemId
::Impl(impl_id
) => {
80 let impl_datum
= collector
.db
.impl_datum(impl_id
);
81 for id
in &impl_datum
.associated_ty_value_ids
{
82 let assoc_ty_value
= collector
.db
.associated_ty_value(*id
);
83 assoc_ty_value
.visit_with(&mut collector
, DebruijnIndex
::INNERMOST
);
85 impl_datum
.visit_with(&mut collector
, DebruijnIndex
::INNERMOST
);
91 .difference(identifiers
)
96 struct IdCollector
<'i
, I
: Interner
, DB
: RustIrDatabase
<I
>> {
98 found_identifiers
: BTreeSet
<RecordedItemId
<I
>>,
101 impl<'i
, I
: Interner
, DB
: RustIrDatabase
<I
>> IdCollector
<'i
, I
, DB
> {
102 fn record(&mut self, id
: impl Into
<RecordedItemId
<I
>>) {
103 self.found_identifiers
.insert(id
.into());
107 impl<'i
, I
: Interner
, DB
: RustIrDatabase
<I
>> Visitor
<'i
, I
> for IdCollector
<'i
, I
, DB
>
113 fn as_dyn(&mut self) -> &mut dyn Visitor
<'i
, I
, BreakTy
= Self::BreakTy
> {
116 fn interner(&self) -> &'i I
{
122 ty
: &chalk_ir
::Ty
<I
>,
123 outer_binder
: chalk_ir
::DebruijnIndex
,
124 ) -> ControlFlow
<()> {
125 match ty
.kind(self.db
.interner()) {
126 TyKind
::Adt(adt
, _
) => self.record(*adt
),
127 TyKind
::FnDef(fn_def
, _
) => self.record(*fn_def
),
128 TyKind
::OpaqueType(opaque
, _
) => self.record(*opaque
),
129 TyKind
::Alias(alias
) => match alias
{
130 AliasTy
::Projection(projection_ty
) => {
131 let assoc_ty_datum
= self.db
.associated_ty_data(projection_ty
.associated_ty_id
);
132 self.record(assoc_ty_datum
.trait_id
)
134 AliasTy
::Opaque(opaque_ty
) => {
135 self.record(opaque_ty
.opaque_ty_id
);
138 TyKind
::BoundVar(..) => (),
139 TyKind
::Dyn(..) => (),
140 TyKind
::Function(..) => (),
141 TyKind
::InferenceVar(..) => (),
142 TyKind
::Placeholder(..) => (),
145 ty
.super_visit_with(self, outer_binder
)
148 fn visit_where_clause(
150 where_clause
: &WhereClause
<I
>,
151 outer_binder
: DebruijnIndex
,
152 ) -> ControlFlow
<()> {
154 WhereClause
::Implemented(trait_ref
) => self.record(trait_ref
.trait_id
),
155 WhereClause
::AliasEq(alias_eq
) => match &alias_eq
.alias
{
156 AliasTy
::Projection(projection_ty
) => {
157 let assoc_ty_datum
= self.db
.associated_ty_data(projection_ty
.associated_ty_id
);
158 self.record(assoc_ty_datum
.trait_id
)
160 AliasTy
::Opaque(opaque_ty
) => {
161 self.record(opaque_ty
.opaque_ty_id
);
164 WhereClause
::LifetimeOutlives(_lifetime_outlives
) => (),
165 WhereClause
::TypeOutlives(_type_outlives
) => (),
167 where_clause
.super_visit_with(self.as_dyn(), outer_binder
)