Skip to content

Commit fc87132

Browse files
committed
Port OpaqueTypeCollector to be prepared for lazy span computation
1 parent 71aa03a commit fc87132

File tree

1 file changed

+26
-18
lines changed

1 file changed

+26
-18
lines changed

compiler/rustc_ty_utils/src/opaque_types.rs

+26-18
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,30 @@ 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() -> 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-
fn new(tcx: TyCtxt<'tcx>, item: LocalDefId) -> Self {
37+
impl<'tcx, 'a> OpaqueTypeCollector<'tcx, 'a> {
38+
fn new(tcx: TyCtxt<'tcx>, item: LocalDefId, get_span: &'a dyn Fn() -> Span) -> 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 { tcx, opaques: Vec::new(), item, seen: Default::default(), get_span, mode }
4344
}
4445

4546
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-
})
47+
(self.get_span)()
4948
}
5049

5150
fn parent_trait_ref(&self) -> Option<ty::TraitRef<'tcx>> {
@@ -103,10 +102,10 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
103102
#[instrument(level = "trace", skip(self))]
104103
fn collect_taits_declared_in_body(&mut self) {
105104
let body = self.tcx.hir().body(self.tcx.hir().body_owned_by(self.item)).value;
106-
struct TaitInBodyFinder<'a, 'tcx> {
107-
collector: &'a mut OpaqueTypeCollector<'tcx>,
105+
struct TaitInBodyFinder<'a, 'b, 'tcx> {
106+
collector: &'a mut OpaqueTypeCollector<'tcx, 'b>,
108107
}
109-
impl<'v> intravisit::Visitor<'v> for TaitInBodyFinder<'_, '_> {
108+
impl<'v> intravisit::Visitor<'v> for TaitInBodyFinder<'_, '_, '_> {
110109
#[instrument(level = "trace", skip(self))]
111110
fn visit_nested_item(&mut self, id: rustc_hir::ItemId) {
112111
let id = id.owner_id.def_id;
@@ -189,17 +188,25 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
189188
}
190189
}
191190

192-
impl<'tcx> SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx> {
191+
impl<'tcx> SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx, '_> {
193192
#[instrument(skip(self), ret, level = "trace")]
194193
fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) {
195-
let old = self.span;
196-
self.span = Some(span);
197-
value.visit_with(self);
198-
self.span = old;
194+
let get_span = || span;
195+
let mut nested = OpaqueTypeCollector {
196+
get_span: &get_span,
197+
tcx: self.tcx,
198+
opaques: std::mem::take(&mut self.opaques),
199+
item: self.item,
200+
seen: std::mem::take(&mut self.seen),
201+
mode: self.mode,
202+
};
203+
value.visit_with(&mut nested);
204+
self.opaques = nested.opaques;
205+
self.seen = nested.seen;
199206
}
200207
}
201208

202-
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
209+
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx, '_> {
203210
#[instrument(skip(self), ret, level = "trace")]
204211
fn visit_ty(&mut self, t: Ty<'tcx>) {
205212
t.super_visit_with(self);
@@ -291,7 +298,8 @@ fn opaque_types_defined_by<'tcx>(
291298
) -> &'tcx ty::List<LocalDefId> {
292299
let kind = tcx.def_kind(item);
293300
trace!(?kind);
294-
let mut collector = OpaqueTypeCollector::new(tcx, item);
301+
let default_span = || tcx.def_ident_span(item).unwrap_or_else(|| tcx.def_span(item));
302+
let mut collector = OpaqueTypeCollector::new(tcx, item, &default_span);
295303
super::sig_types::walk_types(tcx, item, &mut collector);
296304
match kind {
297305
DefKind::AssocFn

0 commit comments

Comments
 (0)