Skip to content

Commit a3ef588

Browse files
committed
Enable opaque_types_defined_by to lazily compute spans only in the error case.
This significantly reduces the dependencies on HIR, and will hopefully lead to better caching
1 parent fc87132 commit a3ef588

File tree

4 files changed

+70
-31
lines changed

4 files changed

+70
-31
lines changed

compiler/rustc_hir/src/hir.rs

+4
Original file line numberDiff line numberDiff line change
@@ -3605,6 +3605,10 @@ impl<'hir> Node<'hir> {
36053605
ImplItemKind::Type(ty) => Some(ty),
36063606
_ => None,
36073607
},
3608+
Node::ForeignItem(it) => match it.kind {
3609+
ForeignItemKind::Static(ty, _) => Some(ty),
3610+
_ => None,
3611+
},
36083612
_ => None,
36093613
}
36103614
}

compiler/rustc_privacy/src/lib.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1066,8 +1066,12 @@ impl<'tcx> TypePrivacyVisitor<'tcx> {
10661066

10671067
impl<'tcx> rustc_ty_utils::sig_types::SpannedTypeVisitor<'tcx> for TypePrivacyVisitor<'tcx> {
10681068
type Result = ControlFlow<()>;
1069-
fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> Self::Result {
1070-
self.span = span;
1069+
fn visit(
1070+
&mut self,
1071+
get_span: impl Fn() -> Span,
1072+
value: impl TypeVisitable<TyCtxt<'tcx>>,
1073+
) -> Self::Result {
1074+
self.span = get_span();
10711075
value.visit_with(&mut self.skeleton())
10721076
}
10731077
}

compiler/rustc_ty_utils/src/opaque_types.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ impl<'tcx, 'a> OpaqueTypeCollector<'tcx, 'a> {
167167
.instantiate_identity_iter_copied()
168168
{
169169
trace!(?pred);
170-
self.visit(span, pred);
170+
self.visit(|| span, pred);
171171
}
172172
}
173173
Err(NotUniqueParam::NotParam(arg)) => {
@@ -189,9 +189,12 @@ impl<'tcx, 'a> OpaqueTypeCollector<'tcx, 'a> {
189189
}
190190

191191
impl<'tcx> SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx, '_> {
192-
#[instrument(skip(self), ret, level = "trace")]
193-
fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) {
194-
let get_span = || span;
192+
#[instrument(skip(self, get_span), ret, level = "trace")]
193+
fn visit(
194+
&mut self,
195+
get_span: impl Fn() -> Span,
196+
value: impl TypeVisitable<TyCtxt<'tcx>>,
197+
) -> Self::Result {
195198
let mut nested = OpaqueTypeCollector {
196199
get_span: &get_span,
197200
tcx: self.tcx,
@@ -204,6 +207,8 @@ impl<'tcx> SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx, '_> {
204207
self.opaques = nested.opaques;
205208
self.seen = nested.seen;
206209
}
210+
211+
type Result = ();
207212
}
208213

209214
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx, '_> {
@@ -283,7 +288,8 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx, '_> {
283288
// would have to walk all generic parameters of an Adt, which can quickly
284289
// degenerate into looking at an exponential number of types.
285290
let ty = self.tcx.type_of(field.did).instantiate_identity();
286-
self.visit(self.tcx.def_span(field.did), ty);
291+
let tcx = self.tcx;
292+
self.visit(|| tcx.def_span(field.did), ty);
287293
}
288294
}
289295
}

compiler/rustc_ty_utils/src/sig_types.rs

+49-24
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@ use rustc_middle::ty::{self, TyCtxt};
88
use rustc_span::Span;
99
use rustc_type_ir::visit::TypeVisitable;
1010

11-
pub trait SpannedTypeVisitor<'tcx> {
11+
pub trait SpannedTypeVisitor<'tcx>: Sized {
1212
type Result: VisitorResult = ();
13-
fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> Self::Result;
13+
fn visit(
14+
&mut self,
15+
get_span: impl Fn() -> Span,
16+
value: impl TypeVisitable<TyCtxt<'tcx>>,
17+
) -> Self::Result;
1418
}
1519

1620
pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
@@ -24,48 +28,61 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
2428
// Walk over the signature of the function
2529
DefKind::AssocFn | DefKind::Fn => {
2630
let ty_sig = tcx.fn_sig(item).instantiate_identity();
27-
let hir_sig = tcx.hir_node_by_def_id(item).fn_decl().unwrap();
31+
let hir_sig = || tcx.hir_node_by_def_id(item).fn_decl().unwrap();
2832
// Walk over the inputs and outputs manually in order to get good spans for them.
29-
try_visit!(visitor.visit(hir_sig.output.span(), ty_sig.output()));
30-
for (hir, ty) in hir_sig.inputs.iter().zip(ty_sig.inputs().iter()) {
31-
try_visit!(visitor.visit(hir.span, ty.map_bound(|x| *x)));
33+
try_visit!(visitor.visit(|| hir_sig().output.span(), ty_sig.output()));
34+
for (hir, ty) in ty_sig.inputs().iter().enumerate() {
35+
try_visit!(visitor.visit(|| hir_sig().inputs[hir].span, ty.map_bound(|x| *x)));
3236
}
3337
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
34-
try_visit!(visitor.visit(span, pred));
38+
try_visit!(visitor.visit(||span, pred));
3539
}
3640
}
37-
// Walk over the type behind the alias
38-
DefKind::TyAlias {..} | DefKind::AssocTy |
39-
// Walk over the type of the item
40-
DefKind::Static(_) | DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => {
41+
DefKind::AssocTy => {
4142
if let Some(ty) = tcx.hir_node_by_def_id(item).ty() {
4243
// Associated types in traits don't necessarily have a type that we can visit
43-
try_visit!(visitor.visit(ty.span, tcx.type_of(item).instantiate_identity()));
44+
try_visit!(visitor.visit(|| ty.span, tcx.type_of(item).instantiate_identity()));
45+
}
46+
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
47+
try_visit!(visitor.visit(|| span, pred));
48+
}
49+
}
50+
// Walk over the type behind the alias
51+
DefKind::TyAlias { .. } |
52+
// Walk over the type of the item
53+
DefKind::Static(_) | DefKind::Const | DefKind::AssocConst => {
54+
let span = || tcx.hir_node_by_def_id(item).ty().unwrap().span;
55+
try_visit!(visitor.visit(span, tcx.type_of(item).instantiate_identity()));
56+
57+
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
58+
try_visit!(visitor.visit(|| span, pred));
4459
}
60+
}
61+
DefKind::AnonConst => {
4562
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
46-
try_visit!(visitor.visit(span, pred));
63+
try_visit!(visitor.visit(|| span, pred));
4764
}
4865
}
4966
DefKind::OpaqueTy => {
5067
for (pred, span) in tcx.explicit_item_bounds(item).instantiate_identity_iter_copied() {
51-
try_visit!(visitor.visit(span, pred));
68+
try_visit!(visitor.visit(||span, pred));
5269
}
5370
}
5471
// Look at field types
5572
DefKind::Struct | DefKind::Union | DefKind::Enum => {
56-
let span = tcx.def_ident_span(item).unwrap();
73+
let span = || tcx.def_ident_span(item).unwrap();
5774
let ty = tcx.type_of(item).instantiate_identity();
5875
try_visit!(visitor.visit(span, ty));
5976
let ty::Adt(def, args) = ty.kind() else {
60-
span_bug!(span, "invalid type for {kind:?}: {:#?}", ty.kind())
77+
span_bug!(span(), "invalid type for {kind:?}: {:#?}", ty.kind())
6178
};
6279
for field in def.all_fields() {
63-
let span = tcx.def_ident_span(field.did).unwrap();
80+
let span = || tcx.def_ident_span(field.did).unwrap();
6481
let ty = field.ty(tcx, args);
6582
try_visit!(visitor.visit(span, ty));
6683
}
6784
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
68-
try_visit!(visitor.visit(span, pred));
85+
try_visit!(visitor.visit(|| span, pred));
6986
}
7087
}
7188
// These are not part of a public API, they can only appear as hidden types, and there
@@ -74,25 +91,33 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
7491
DefKind::InlineConst | DefKind::Closure => {}
7592
DefKind::Impl { of_trait } => {
7693
if of_trait {
77-
let span = tcx.hir_node_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().path.span;
94+
let span = || {
95+
tcx.hir_node_by_def_id(item)
96+
.expect_item()
97+
.expect_impl()
98+
.of_trait
99+
.unwrap()
100+
.path
101+
.span
102+
};
78103
let args = &tcx.impl_trait_ref(item).unwrap().instantiate_identity().args[1..];
79104
try_visit!(visitor.visit(span, args));
80105
}
81-
let span = match tcx.hir_node_by_def_id(item).ty() {
106+
let span = || match tcx.hir_node_by_def_id(item).ty() {
82107
Some(ty) => ty.span,
83108
_ => tcx.def_span(item),
84109
};
85110
try_visit!(visitor.visit(span, tcx.type_of(item).instantiate_identity()));
86111
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
87-
try_visit!(visitor.visit(span, pred));
112+
try_visit!(visitor.visit(|| span, pred));
88113
}
89114
}
90115
DefKind::TraitAlias | DefKind::Trait => {
91116
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
92-
try_visit!(visitor.visit(span, pred));
117+
try_visit!(visitor.visit(|| span, pred));
93118
}
94119
}
95-
| DefKind::Variant
120+
DefKind::Variant
96121
| DefKind::TyParam
97122
| DefKind::ConstParam
98123
| DefKind::Ctor(_, _)
@@ -104,7 +129,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
104129
)
105130
}
106131
// These don't have any types.
107-
| DefKind::ExternCrate
132+
DefKind::ExternCrate
108133
| DefKind::ForeignMod
109134
| DefKind::ForeignTy
110135
| DefKind::Macro(_)

0 commit comments

Comments
 (0)