Skip to content

Commit 4ce8c13

Browse files
committed
Port OpaqueTypeCollector to be prepared for lazy span computation
1 parent 67bc544 commit 4ce8c13

File tree

1 file changed

+32
-16
lines changed

1 file changed

+32
-16
lines changed

compiler/rustc_ty_utils/src/opaque_types.rs

+32-16
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_trait_selection::traits::check_args_compatible;
1212
use crate::errors::{DuplicateArg, NotParam};
1313
use crate::sig_types::SpannedTypeVisitor;
1414

15-
struct OpaqueTypeCollector<'tcx> {
15+
struct OpaqueTypeCollector<'tcx, 'a> {
1616
tcx: TyCtxt<'tcx>,
1717
opaques: Vec<LocalDefId>,
1818
/// The `DefId` of the item which we are collecting opaque types for.
@@ -21,31 +21,39 @@ struct OpaqueTypeCollector<'tcx> {
2121
/// Avoid infinite recursion due to recursive declarations.
2222
seen: FxHashSet<LocalDefId>,
2323

24-
span: Option<Span>,
24+
get_span: &'a dyn Fn(&Self) -> Span,
2525

2626
mode: CollectionMode,
2727
}
2828

29+
#[derive(Copy, Clone)]
2930
enum CollectionMode {
3031
/// For impl trait in assoc types we only permit collecting them from
3132
/// associated types of the same impl block.
3233
ImplTraitInAssocTypes,
3334
TypeAliasImplTraitTransition,
3435
}
3536

36-
impl<'tcx> OpaqueTypeCollector<'tcx> {
37+
impl<'tcx> OpaqueTypeCollector<'tcx, '_> {
3738
fn new(tcx: TyCtxt<'tcx>, item: LocalDefId) -> Self {
3839
let mode = match tcx.def_kind(tcx.local_parent(item)) {
3940
DefKind::Impl { of_trait: true } => CollectionMode::ImplTraitInAssocTypes,
4041
_ => CollectionMode::TypeAliasImplTraitTransition,
4142
};
42-
Self { tcx, opaques: Vec::new(), item, seen: Default::default(), span: None, mode }
43+
Self {
44+
tcx,
45+
opaques: Vec::new(),
46+
item,
47+
seen: Default::default(),
48+
get_span: &|this| {
49+
this.tcx.def_ident_span(this.item).unwrap_or_else(|| this.tcx.def_span(this.item))
50+
},
51+
mode,
52+
}
4353
}
4454

4555
fn span(&self) -> Span {
46-
self.span.unwrap_or_else(|| {
47-
self.tcx.def_ident_span(self.item).unwrap_or_else(|| self.tcx.def_span(self.item))
48-
})
56+
(self.get_span)(self)
4957
}
5058

5159
fn parent_trait_ref(&self) -> Option<ty::TraitRef<'tcx>> {
@@ -105,10 +113,10 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
105113
// Some things not necessarily have bodies, like method declarations in traits.
106114
let Some(body_owner) = self.tcx.hir().maybe_body_owned_by(self.item) else { return };
107115
let body = self.tcx.hir().body(body_owner).value;
108-
struct TaitInBodyFinder<'a, 'tcx> {
109-
collector: &'a mut OpaqueTypeCollector<'tcx>,
116+
struct TaitInBodyFinder<'a, 'b, 'tcx> {
117+
collector: &'a mut OpaqueTypeCollector<'tcx, 'b>,
110118
}
111-
impl<'v> intravisit::Visitor<'v> for TaitInBodyFinder<'_, '_> {
119+
impl<'v> intravisit::Visitor<'v> for TaitInBodyFinder<'_, '_, '_> {
112120
#[instrument(level = "trace", skip(self))]
113121
fn visit_nested_item(&mut self, id: rustc_hir::ItemId) {
114122
let id = id.owner_id.def_id;
@@ -191,17 +199,25 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
191199
}
192200
}
193201

194-
impl<'tcx> SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx> {
202+
impl<'tcx> SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx, '_> {
195203
#[instrument(skip(self), ret, level = "trace")]
196204
fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) {
197-
let old = self.span;
198-
self.span = Some(span);
199-
value.visit_with(self);
200-
self.span = old;
205+
let get_span = |_this: &_| span;
206+
let mut nested = OpaqueTypeCollector {
207+
get_span: &get_span,
208+
tcx: self.tcx,
209+
opaques: std::mem::take(&mut self.opaques),
210+
item: self.item,
211+
seen: std::mem::take(&mut self.seen),
212+
mode: self.mode,
213+
};
214+
value.visit_with(&mut nested);
215+
self.opaques = nested.opaques;
216+
self.seen = nested.seen;
201217
}
202218
}
203219

204-
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
220+
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx, '_> {
205221
#[instrument(skip(self), ret, level = "trace")]
206222
fn visit_ty(&mut self, t: Ty<'tcx>) {
207223
t.super_visit_with(self);

0 commit comments

Comments
 (0)