Skip to content

Commit 0b65d0d

Browse files
committed
Auto merge of #142074 - oli-obk:its-finally-gone, r=petrochenkov
Remove CollectItemTypesVisitor I always felt like we were very unnecessarily walking the HIR, let's see if perf agrees There is lots to ~~improve~~ consolidate further here, as we still have 3 item wfchecks: * check_item (matching on the hir::ItemKind) * actually doing trait solver based checks (by using HIR spans) * lower_item (matching on the hir::ItemKind after loading it again??) * just ensure_ok-ing a bunch of queries * check_item_type (matching on DefKind) * some type based checks, mostly ensure_ok-ing a bunch of queries fixes #121429
2 parents a5584a8 + fa282f4 commit 0b65d0d

File tree

11 files changed

+204
-230
lines changed

11 files changed

+204
-230
lines changed

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,29 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
702702
}
703703

704704
pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
705+
let generics = tcx.generics_of(def_id);
706+
707+
for param in &generics.own_params {
708+
match param.kind {
709+
ty::GenericParamDefKind::Lifetime { .. } => {}
710+
ty::GenericParamDefKind::Type { has_default, .. } => {
711+
if has_default {
712+
tcx.ensure_ok().type_of(param.def_id);
713+
}
714+
}
715+
ty::GenericParamDefKind::Const { has_default, .. } => {
716+
tcx.ensure_ok().type_of(param.def_id);
717+
if has_default {
718+
// need to store default and type of default
719+
let ct = tcx.const_param_default(param.def_id).skip_binder();
720+
if let ty::ConstKind::Unevaluated(uv) = ct.kind() {
721+
tcx.ensure_ok().type_of(uv.def);
722+
}
723+
}
724+
}
725+
}
726+
}
727+
705728
match tcx.def_kind(def_id) {
706729
DefKind::Static { .. } => {
707730
check_static_inhabited(tcx, def_id);
@@ -770,6 +793,16 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
770793
} else {
771794
check_opaque(tcx, def_id);
772795
}
796+
797+
tcx.ensure_ok().predicates_of(def_id);
798+
tcx.ensure_ok().explicit_item_bounds(def_id);
799+
tcx.ensure_ok().explicit_item_self_bounds(def_id);
800+
tcx.ensure_ok().item_bounds(def_id);
801+
tcx.ensure_ok().item_self_bounds(def_id);
802+
if tcx.is_conditionally_const(def_id) {
803+
tcx.ensure_ok().explicit_implied_const_bounds(def_id);
804+
tcx.ensure_ok().const_conditions(def_id);
805+
}
773806
}
774807
DefKind::TyAlias => {
775808
check_type_alias_type_params_are_used(tcx, def_id);
@@ -827,6 +860,15 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
827860
}
828861
}
829862
}
863+
DefKind::Closure => {
864+
// This is guaranteed to be called by metadata encoding,
865+
// we still call it in wfcheck eagerly to ensure errors in codegen
866+
// attrs prevent lints from spamming the output.
867+
tcx.ensure_ok().codegen_fn_attrs(def_id);
868+
// We do not call `type_of` for closures here as that
869+
// depends on typecheck and would therefore hide
870+
// any further errors in case one typeck fails.
871+
}
830872
_ => {}
831873
}
832874
}

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ use tracing::{debug, instrument};
4040
use {rustc_ast as ast, rustc_hir as hir};
4141

4242
use crate::autoderef::Autoderef;
43-
use crate::collect::CollectItemTypesVisitor;
4443
use crate::constrained_generic_params::{Parameter, identify_constrained_generic_params};
4544
use crate::errors::InvalidReceiverTyHint;
4645
use crate::{errors, fluent_generated as fluent};
@@ -195,7 +194,9 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGua
195194
hir::Node::TraitItem(item) => check_trait_item(tcx, item),
196195
hir::Node::ImplItem(item) => check_impl_item(tcx, item),
197196
hir::Node::ForeignItem(item) => check_foreign_item(tcx, item),
198-
hir::Node::OpaqueTy(_) => Ok(crate::check::check::check_item_type(tcx, def_id)),
197+
hir::Node::ConstBlock(_) | hir::Node::Expr(_) | hir::Node::OpaqueTy(_) => {
198+
Ok(crate::check::check::check_item_type(tcx, def_id))
199+
}
199200
_ => unreachable!("{node:?}"),
200201
};
201202

@@ -229,7 +230,8 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
229230
?item.owner_id,
230231
item.name = ? tcx.def_path_str(def_id)
231232
);
232-
CollectItemTypesVisitor { tcx }.visit_item(item);
233+
crate::collect::lower_item(tcx, item.item_id());
234+
crate::collect::reject_placeholder_type_signatures_in_item(tcx, item);
233235

234236
let res = match item.kind {
235237
// Right now we check that every default trait implementation
@@ -350,8 +352,6 @@ fn check_foreign_item<'tcx>(
350352
) -> Result<(), ErrorGuaranteed> {
351353
let def_id = item.owner_id.def_id;
352354

353-
CollectItemTypesVisitor { tcx }.visit_foreign_item(item);
354-
355355
debug!(
356356
?item.owner_id,
357357
item.name = ? tcx.def_path_str(def_id)
@@ -374,7 +374,7 @@ fn check_trait_item<'tcx>(
374374
) -> Result<(), ErrorGuaranteed> {
375375
let def_id = trait_item.owner_id.def_id;
376376

377-
CollectItemTypesVisitor { tcx }.visit_trait_item(trait_item);
377+
crate::collect::lower_trait_item(tcx, trait_item.trait_item_id());
378378

379379
let (method_sig, span) = match trait_item.kind {
380380
hir::TraitItemKind::Fn(ref sig, _) => (Some(sig), trait_item.span),
@@ -939,7 +939,7 @@ fn check_impl_item<'tcx>(
939939
tcx: TyCtxt<'tcx>,
940940
impl_item: &'tcx hir::ImplItem<'tcx>,
941941
) -> Result<(), ErrorGuaranteed> {
942-
CollectItemTypesVisitor { tcx }.visit_impl_item(impl_item);
942+
crate::collect::lower_impl_item(tcx, impl_item.impl_item_id());
943943

944944
let (method_sig, span) = match impl_item.kind {
945945
hir::ImplItemKind::Fn(ref sig, _) => (Some(sig), impl_item.span),
@@ -2411,6 +2411,7 @@ fn check_type_wf(tcx: TyCtxt<'_>, (): ()) -> Result<(), ErrorGuaranteed> {
24112411
.and(
24122412
items.par_foreign_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)),
24132413
)
2414+
.and(items.par_nested_bodies(|item| tcx.ensure_ok().check_well_formed(item)))
24142415
.and(items.par_opaques(|item| tcx.ensure_ok().check_well_formed(item)));
24152416
super::entry::check_for_entry_fn(tcx);
24162417

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 5 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,10 @@ use rustc_errors::{
2828
};
2929
use rustc_hir::def::DefKind;
3030
use rustc_hir::def_id::{DefId, LocalDefId};
31-
use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt, walk_generics};
31+
use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_generics};
3232
use rustc_hir::{self as hir, GenericParamKind, HirId, Node, PreciseCapturingArgKind};
3333
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
3434
use rustc_infer::traits::{DynCompatibilityViolation, ObligationCause};
35-
use rustc_middle::hir::nested_filter;
3635
use rustc_middle::query::Providers;
3736
use rustc_middle::ty::util::{Discr, IntTypeExt};
3837
use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypingMode, fold_regions};
@@ -148,10 +147,6 @@ impl<'v> Visitor<'v> for HirPlaceholderCollector {
148147
}
149148
}
150149

151-
pub(crate) struct CollectItemTypesVisitor<'tcx> {
152-
pub tcx: TyCtxt<'tcx>,
153-
}
154-
155150
/// If there are any placeholder types (`_`), emit an error explaining that this is not allowed
156151
/// and suggest adding type parameters in the appropriate place, taking into consideration any and
157152
/// all already existing generic type parameters to avoid suggesting a name that is already in use.
@@ -243,7 +238,7 @@ pub(crate) fn placeholder_type_error_diag<'cx, 'tcx>(
243238
err
244239
}
245240

246-
fn reject_placeholder_type_signatures_in_item<'tcx>(
241+
pub(super) fn reject_placeholder_type_signatures_in_item<'tcx>(
247242
tcx: TyCtxt<'tcx>,
248243
item: &'tcx hir::Item<'tcx>,
249244
) {
@@ -274,81 +269,6 @@ fn reject_placeholder_type_signatures_in_item<'tcx>(
274269
);
275270
}
276271

277-
impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
278-
type NestedFilter = nested_filter::OnlyBodies;
279-
280-
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
281-
self.tcx
282-
}
283-
284-
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
285-
lower_item(self.tcx, item.item_id());
286-
reject_placeholder_type_signatures_in_item(self.tcx, item);
287-
intravisit::walk_item(self, item);
288-
}
289-
290-
fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
291-
for param in generics.params {
292-
match param.kind {
293-
hir::GenericParamKind::Lifetime { .. } => {}
294-
hir::GenericParamKind::Type { default: Some(_), .. } => {
295-
self.tcx.ensure_ok().type_of(param.def_id);
296-
}
297-
hir::GenericParamKind::Type { .. } => {}
298-
hir::GenericParamKind::Const { default, .. } => {
299-
self.tcx.ensure_ok().type_of(param.def_id);
300-
if let Some(default) = default {
301-
// need to store default and type of default
302-
self.tcx.ensure_ok().const_param_default(param.def_id);
303-
if let hir::ConstArgKind::Anon(ac) = default.kind {
304-
self.tcx.ensure_ok().type_of(ac.def_id);
305-
}
306-
}
307-
}
308-
}
309-
}
310-
intravisit::walk_generics(self, generics);
311-
}
312-
313-
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
314-
if let hir::ExprKind::Closure(closure) = expr.kind {
315-
self.tcx.ensure_ok().generics_of(closure.def_id);
316-
self.tcx.ensure_ok().codegen_fn_attrs(closure.def_id);
317-
// We do not call `type_of` for closures here as that
318-
// depends on typecheck and would therefore hide
319-
// any further errors in case one typeck fails.
320-
}
321-
intravisit::walk_expr(self, expr);
322-
}
323-
324-
/// Don't call `type_of` on opaque types, since that depends on type checking function bodies.
325-
/// `check_item_type` ensures that it's called instead.
326-
fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) {
327-
let def_id = opaque.def_id;
328-
self.tcx.ensure_ok().generics_of(def_id);
329-
self.tcx.ensure_ok().predicates_of(def_id);
330-
self.tcx.ensure_ok().explicit_item_bounds(def_id);
331-
self.tcx.ensure_ok().explicit_item_self_bounds(def_id);
332-
self.tcx.ensure_ok().item_bounds(def_id);
333-
self.tcx.ensure_ok().item_self_bounds(def_id);
334-
if self.tcx.is_conditionally_const(def_id) {
335-
self.tcx.ensure_ok().explicit_implied_const_bounds(def_id);
336-
self.tcx.ensure_ok().const_conditions(def_id);
337-
}
338-
intravisit::walk_opaque_ty(self, opaque);
339-
}
340-
341-
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
342-
lower_trait_item(self.tcx, trait_item.trait_item_id());
343-
intravisit::walk_trait_item(self, trait_item);
344-
}
345-
346-
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
347-
lower_impl_item(self.tcx, impl_item.impl_item_id());
348-
intravisit::walk_impl_item(self, impl_item);
349-
}
350-
}
351-
352272
///////////////////////////////////////////////////////////////////////////
353273
// Utility types and common code for the above passes.
354274

@@ -669,7 +589,7 @@ fn get_new_lifetime_name<'tcx>(
669589
}
670590

671591
#[instrument(level = "debug", skip_all)]
672-
fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
592+
pub(super) fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
673593
let it = tcx.hir_item(item_id);
674594
debug!(item = ?it.kind.ident(), id = %it.hir_id());
675595
let def_id = item_id.owner_id.def_id;
@@ -790,7 +710,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
790710
}
791711
}
792712

793-
fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
713+
pub(crate) fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
794714
let trait_item = tcx.hir_trait_item(trait_item_id);
795715
let def_id = trait_item_id.owner_id;
796716
tcx.ensure_ok().generics_of(def_id);
@@ -861,7 +781,7 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
861781
tcx.ensure_ok().predicates_of(def_id);
862782
}
863783

864-
fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
784+
pub(super) fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
865785
let def_id = impl_item_id.owner_id;
866786
tcx.ensure_ok().generics_of(def_id);
867787
tcx.ensure_ok().type_of(def_id);

compiler/rustc_middle/src/hir/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ impl ModuleItems {
7171
self.opaques.iter().copied()
7272
}
7373

74+
/// Closures and inline consts
7475
pub fn nested_bodies(&self) -> impl Iterator<Item = LocalDefId> {
7576
self.nested_bodies.iter().copied()
7677
}
@@ -79,6 +80,14 @@ impl ModuleItems {
7980
self.owners().map(|id| id.def_id)
8081
}
8182

83+
/// Closures and inline consts
84+
pub fn par_nested_bodies(
85+
&self,
86+
f: impl Fn(LocalDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
87+
) -> Result<(), ErrorGuaranteed> {
88+
try_par_for_each_in(&self.nested_bodies[..], |&&id| f(id))
89+
}
90+
8291
pub fn par_items(
8392
&self,
8493
f: impl Fn(ItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,

tests/crashes/121429.rs

Lines changed: 0 additions & 14 deletions
This file was deleted.

tests/ui/associated-inherent-types/issue-109299-1.stderr

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
error: unconstrained opaque type
2+
--> $DIR/issue-109299-1.rs:10:10
3+
|
4+
LL | type X = impl for<T> Fn() -> Lexer<T>::Cursor;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `X` must be used in combination with a concrete type within the same crate
8+
19
error[E0220]: associated type `Cursor` not found for `Lexer<T>` in the current scope
210
--> $DIR/issue-109299-1.rs:10:40
311
|
@@ -23,14 +31,6 @@ LL | type X = impl for<T> Fn() -> Lexer<T>::Cursor;
2331
- `Lexer<i32>`
2432
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
2533

26-
error: unconstrained opaque type
27-
--> $DIR/issue-109299-1.rs:10:10
28-
|
29-
LL | type X = impl for<T> Fn() -> Lexer<T>::Cursor;
30-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31-
|
32-
= note: `X` must be used in combination with a concrete type within the same crate
33-
3434
error: aborting due to 3 previous errors
3535

3636
For more information about this error, try `rustc --explain E0220`.

0 commit comments

Comments
 (0)