]>
git.proxmox.com Git - rustc.git/blob - vendor/chalk-solve/src/logging_db/id_collector.rs
1 use super::RecordedItemId
;
2 use crate::RustIrDatabase
;
6 visit
::{SuperVisit, Visit}
,
7 AliasTy
, DebruijnIndex
, TyData
, TypeName
, 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
::Trait(trait_id
) => {
57 let trait_datum
= collector
.db
.trait_datum(trait_id
);
59 trait_datum
.visit_with(&mut collector
, DebruijnIndex
::INNERMOST
);
60 for assoc_ty_id
in &trait_datum
.associated_ty_ids
{
61 let assoc_ty_datum
= collector
.db
.associated_ty_data(*assoc_ty_id
);
63 .bounds_on_self(collector
.db
.interner())
64 .visit_with(&mut collector
, DebruijnIndex
::INNERMOST
);
65 assoc_ty_datum
.visit_with(&mut collector
, DebruijnIndex
::INNERMOST
)
68 RecordedItemId
::OpaqueTy(opaque_id
) => {
71 .opaque_ty_data(opaque_id
)
72 .visit_with(&mut collector
, DebruijnIndex
::INNERMOST
);
75 .hidden_opaque_type(opaque_id
)
76 .visit_with(&mut collector
, DebruijnIndex
::INNERMOST
);
78 RecordedItemId
::Impl(impl_id
) => {
79 let impl_datum
= collector
.db
.impl_datum(impl_id
);
80 for id
in &impl_datum
.associated_ty_value_ids
{
81 let assoc_ty_value
= collector
.db
.associated_ty_value(*id
);
82 assoc_ty_value
.visit_with(&mut collector
, DebruijnIndex
::INNERMOST
);
84 impl_datum
.visit_with(&mut collector
, DebruijnIndex
::INNERMOST
);
90 .difference(identifiers
)
95 struct IdCollector
<'i
, I
: Interner
, DB
: RustIrDatabase
<I
>> {
97 found_identifiers
: BTreeSet
<RecordedItemId
<I
>>,
100 impl<'i
, I
: Interner
, DB
: RustIrDatabase
<I
>> IdCollector
<'i
, I
, DB
> {
101 fn record(&mut self, id
: impl Into
<RecordedItemId
<I
>>) {
102 self.found_identifiers
.insert(id
.into());
106 impl<'i
, I
: Interner
, DB
: RustIrDatabase
<I
>> Visitor
<'i
, I
> for IdCollector
<'i
, I
, DB
>
111 fn as_dyn(&mut self) -> &mut dyn Visitor
<'i
, I
, Result
= Self::Result
> {
114 fn interner(&self) -> &'i I
{
120 ty
: &chalk_ir
::Ty
<I
>,
121 outer_binder
: chalk_ir
::DebruijnIndex
,
123 let ty_data
= ty
.data(self.db
.interner());
125 TyData
::Apply(apply_ty
) => match apply_ty
.name
{
126 TypeName
::Adt(adt
) => self.record(adt
),
127 TypeName
::FnDef(fn_def
) => self.record(fn_def
),
128 TypeName
::OpaqueType(opaque
) => self.record(opaque
),
131 TyData
::Alias(alias
) => match alias
{
132 AliasTy
::Projection(projection_ty
) => {
133 let assoc_ty_datum
= self.db
.associated_ty_data(projection_ty
.associated_ty_id
);
134 self.record(assoc_ty_datum
.trait_id
)
136 AliasTy
::Opaque(opaque_ty
) => {
137 self.record(opaque_ty
.opaque_ty_id
);
140 TyData
::BoundVar(..) => (),
141 TyData
::Dyn(..) => (),
142 TyData
::Function(..) => (),
143 TyData
::InferenceVar(..) => (),
144 TyData
::Placeholder(..) => (),
146 ty
.super_visit_with(self, outer_binder
)
149 fn visit_where_clause(
151 where_clause
: &WhereClause
<I
>,
152 outer_binder
: DebruijnIndex
,
155 WhereClause
::Implemented(trait_ref
) => self.record(trait_ref
.trait_id
),
156 WhereClause
::AliasEq(alias_eq
) => match &alias_eq
.alias
{
157 AliasTy
::Projection(projection_ty
) => {
158 let assoc_ty_datum
= self.db
.associated_ty_data(projection_ty
.associated_ty_id
);
159 self.record(assoc_ty_datum
.trait_id
)
161 AliasTy
::Opaque(opaque_ty
) => {
162 self.record(opaque_ty
.opaque_ty_id
);
165 WhereClause
::LifetimeOutlives(_lifetime_outlives
) => (),
166 WhereClause
::TypeOutlives(_type_outlives
) => (),
168 where_clause
.super_visit_with(self.as_dyn(), outer_binder
)