Skip to content

Commit 4fbae3e

Browse files
committed
Auto merge of #154945 - oli-obk:merge-visitors-def-collector-brg, r=petrochenkov
Merge BuildReducedGraphVisitor into DefPathVisitor These two visitors run right after each other on the same immutable AST. There's also a hash map for transferring the TyCtxtFeed created in the def collector to the BRG when it visits the same items. There are possibly more avenues for sharing logic, but I want to keep this PR simple. only opening for perf runs for now. I'm still investigating how to ensure that future changes don't introduce subtle bugs by forgetting that def collection and reduced graph building are one pass now Best reviewed commit-by-commit. I took a lot of care for making the individual changes reviewable, but all the `Merge *` commits aren't able to compile libcore until the last one.
2 parents 66da6ca + f2c79f3 commit 4fbae3e

4 files changed

Lines changed: 158 additions & 240 deletions

File tree

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 49 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@ use rustc_ast::{
1212
self as ast, AssocItem, AssocItemKind, Block, ConstItem, Delegation, Fn, ForeignItem,
1313
ForeignItemKind, Inline, Item, ItemKind, NodeId, StaticItem, StmtKind, TraitAlias, TyAlias,
1414
};
15-
use rustc_attr_parsing as attr;
1615
use rustc_attr_parsing::AttributeParser;
1716
use rustc_expand::base::ResolverExpand;
18-
use rustc_expand::expand::AstFragment;
1917
use rustc_hir::Attribute;
2018
use rustc_hir::attrs::{AttributeKind, MacroUseArgs};
2119
use rustc_hir::def::{self, *};
@@ -31,7 +29,7 @@ use thin_vec::ThinVec;
3129
use tracing::debug;
3230

3331
use crate::Namespace::{MacroNS, TypeNS, ValueNS};
34-
use crate::def_collector::collect_definitions;
32+
use crate::def_collector::DefCollector;
3533
use crate::diagnostics::StructCtor;
3634
use crate::imports::{ImportData, ImportKind, OnUnknownData};
3735
use crate::macros::{MacroRulesDecl, MacroRulesScope, MacroRulesScopeRef};
@@ -237,17 +235,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
237235
}
238236
}
239237

240-
pub(crate) fn build_reduced_graph(
241-
&mut self,
242-
fragment: &AstFragment,
243-
parent_scope: ParentScope<'ra>,
244-
) -> MacroRulesScopeRef<'ra> {
245-
collect_definitions(self, fragment, parent_scope.expansion);
246-
let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope };
247-
fragment.visit_with(&mut visitor);
248-
visitor.parent_scope.macro_rules
249-
}
250-
251238
pub(crate) fn build_reduced_graph_external(&self, module: ExternModule<'ra>) {
252239
let def_id = module.def_id();
253240
let children = self.tcx.module_children(def_id);
@@ -362,18 +349,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
362349
}
363350
}
364351

365-
struct BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
366-
r: &'a mut Resolver<'ra, 'tcx>,
367-
parent_scope: ParentScope<'ra>,
368-
}
369-
370-
impl<'ra, 'tcx> AsMut<Resolver<'ra, 'tcx>> for BuildReducedGraphVisitor<'_, 'ra, 'tcx> {
352+
impl<'ra, 'tcx> AsMut<Resolver<'ra, 'tcx>> for DefCollector<'_, 'ra, 'tcx> {
371353
fn as_mut(&mut self) -> &mut Resolver<'ra, 'tcx> {
372354
self.r
373355
}
374356
}
375357

376-
impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
358+
impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
377359
fn res(&self, def_id: impl Into<DefId>) -> Res {
378360
let def_id = def_id.into();
379361
Res::Def(self.r.tcx.def_kind(def_id), def_id)
@@ -753,6 +735,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
753735
}
754736
ast::UseTreeKind::Nested { ref items, .. } => {
755737
for &(ref tree, id) in items {
738+
self.create_def(id, None, DefKind::Use, use_tree.span());
756739
self.build_reduced_graph_for_use_tree(
757740
// This particular use tree
758741
tree, id, &prefix, true, false, // The whole `use` item
@@ -1075,7 +1058,11 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
10751058
}
10761059

10771060
/// Constructs the reduced graph for one foreign item.
1078-
fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem, ident: Ident) {
1061+
pub(crate) fn build_reduced_graph_for_foreign_item(
1062+
&mut self,
1063+
item: &ForeignItem,
1064+
ident: Ident,
1065+
) {
10791066
let feed = self.r.feed(item.id);
10801067
let local_def_id = feed.key();
10811068
let def_id = local_def_id.to_def_id();
@@ -1207,7 +1194,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
12071194
}
12081195

12091196
/// Returns `true` if this attribute list contains `macro_use`.
1210-
fn contains_macro_use(&self, attrs: &[ast::Attribute]) -> bool {
1197+
pub(crate) fn contains_macro_use(&self, attrs: &[ast::Attribute]) -> bool {
12111198
for attr in attrs {
12121199
if attr.has_name(sym::macro_escape) {
12131200
let inner_attribute = matches!(attr.style, ast::AttrStyle::Inner);
@@ -1227,7 +1214,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
12271214
false
12281215
}
12291216

1230-
fn visit_invoc(&mut self, id: NodeId) -> LocalExpnId {
1217+
pub(crate) fn visit_invoc(&mut self, id: NodeId) -> LocalExpnId {
12311218
let invoc_id = id.placeholder_to_expn_id();
12321219
let old_parent_scope = self.r.invocation_parent_scopes.insert(invoc_id, self.parent_scope);
12331220
assert!(old_parent_scope.is_none(), "invocation data is reset for an invocation");
@@ -1236,7 +1223,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
12361223

12371224
/// Visit invocation in context in which it can emit a named item (possibly `macro_rules`)
12381225
/// directly into its parent scope's module.
1239-
fn visit_invoc_in_module(&mut self, id: NodeId) -> MacroRulesScopeRef<'ra> {
1226+
pub(crate) fn visit_invoc_in_module(&mut self, id: NodeId) -> MacroRulesScopeRef<'ra> {
12401227
let invoc_id = self.visit_invoc(id);
12411228
self.parent_scope.module.unexpanded_invocations.borrow_mut(self.r).insert(invoc_id);
12421229
self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Invocation(invoc_id))
@@ -1373,24 +1360,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
13731360
}
13741361
}
13751362

1376-
macro_rules! method {
1377-
($visit:ident: $ty:ty, $invoc:path, $walk:ident) => {
1378-
fn $visit(&mut self, node: &'a $ty) {
1379-
if let $invoc(..) = node.kind {
1380-
self.visit_invoc(node.id);
1381-
} else {
1382-
visit::$walk(self, node);
1383-
}
1384-
}
1385-
};
1386-
}
1387-
1388-
impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
1389-
method!(visit_expr: ast::Expr, ast::ExprKind::MacCall, walk_expr);
1390-
method!(visit_pat: ast::Pat, ast::PatKind::MacCall, walk_pat);
1391-
method!(visit_ty: ast::Ty, ast::TyKind::MacCall, walk_ty);
1392-
1393-
fn visit_item(&mut self, item: &'a Item) {
1363+
impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
1364+
pub(crate) fn brg_visit_item(&mut self, item: &'a Item) {
13941365
let orig_module_scope = self.parent_scope.module;
13951366
self.parent_scope.macro_rules = match item.kind {
13961367
ItemKind::MacroDef(..) => {
@@ -1423,30 +1394,11 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
14231394
self.parent_scope.module = orig_module_scope;
14241395
}
14251396

1426-
fn visit_stmt(&mut self, stmt: &'a ast::Stmt) {
1427-
if let ast::StmtKind::MacCall(..) = stmt.kind {
1428-
self.parent_scope.macro_rules = self.visit_invoc_in_module(stmt.id);
1429-
} else {
1430-
visit::walk_stmt(self, stmt);
1431-
}
1397+
pub(crate) fn brg_visit_stmt_mac_call(&mut self, stmt: &'a ast::Stmt) {
1398+
self.parent_scope.macro_rules = self.visit_invoc_in_module(stmt.id);
14321399
}
14331400

1434-
fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
1435-
let ident = match foreign_item.kind {
1436-
ForeignItemKind::Static(box StaticItem { ident, .. })
1437-
| ForeignItemKind::Fn(box Fn { ident, .. })
1438-
| ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => ident,
1439-
ForeignItemKind::MacCall(_) => {
1440-
self.visit_invoc_in_module(foreign_item.id);
1441-
return;
1442-
}
1443-
};
1444-
1445-
self.build_reduced_graph_for_foreign_item(foreign_item, ident);
1446-
visit::walk_item(self, foreign_item);
1447-
}
1448-
1449-
fn visit_block(&mut self, block: &'a Block) {
1401+
pub(crate) fn brg_visit_block(&mut self, block: &'a Block) {
14501402
let orig_current_module = self.parent_scope.module;
14511403
let orig_current_macro_rules_scope = self.parent_scope.macro_rules;
14521404
self.build_reduced_graph_for_block(block);
@@ -1455,38 +1407,13 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
14551407
self.parent_scope.macro_rules = orig_current_macro_rules_scope;
14561408
}
14571409

1458-
fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
1459-
let (ident, ns) = match item.kind {
1460-
AssocItemKind::Const(box ConstItem { ident, .. })
1461-
| AssocItemKind::Fn(box Fn { ident, .. })
1462-
| AssocItemKind::Delegation(box Delegation { ident, .. }) => (ident, ValueNS),
1463-
1464-
AssocItemKind::Type(box TyAlias { ident, .. }) => (ident, TypeNS),
1465-
1466-
AssocItemKind::MacCall(_) => {
1467-
match ctxt {
1468-
AssocCtxt::Trait => {
1469-
self.visit_invoc_in_module(item.id);
1470-
}
1471-
AssocCtxt::Impl { .. } => {
1472-
let invoc_id = item.id.placeholder_to_expn_id();
1473-
if !self.r.glob_delegation_invoc_ids.contains(&invoc_id) {
1474-
self.r
1475-
.impl_unexpanded_invocations
1476-
.entry(self.r.invocation_parent(invoc_id))
1477-
.or_default()
1478-
.insert(invoc_id);
1479-
}
1480-
self.visit_invoc(item.id);
1481-
}
1482-
}
1483-
return;
1484-
}
1485-
1486-
AssocItemKind::DelegationMac(..) => {
1487-
span_bug!(item.span, "delegation mac should already have been removed")
1488-
}
1489-
};
1410+
pub(crate) fn brg_visit_assoc_item(
1411+
&mut self,
1412+
item: &'a AssocItem,
1413+
ctxt: AssocCtxt,
1414+
ident: Ident,
1415+
ns: Namespace,
1416+
) {
14901417
let vis = self.resolve_visibility(&item.vis);
14911418
let feed = self.r.feed(item.id);
14921419
let local_def_id = feed.key();
@@ -1517,73 +1444,38 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
15171444
visit::walk_assoc_item(self, item, ctxt);
15181445
}
15191446

1520-
fn visit_attribute(&mut self, attr: &'a ast::Attribute) {
1521-
if !attr.is_doc_comment() && attr::is_builtin_attr(attr) {
1522-
self.r
1523-
.builtin_attrs
1524-
.push((attr.get_normal_item().path.segments[0].ident, self.parent_scope));
1525-
}
1526-
visit::walk_attribute(self, attr);
1527-
}
1528-
1529-
fn visit_arm(&mut self, arm: &'a ast::Arm) {
1530-
if arm.is_placeholder {
1531-
self.visit_invoc(arm.id);
1532-
} else {
1533-
visit::walk_arm(self, arm);
1534-
}
1535-
}
1536-
1537-
fn visit_expr_field(&mut self, f: &'a ast::ExprField) {
1538-
if f.is_placeholder {
1539-
self.visit_invoc(f.id);
1540-
} else {
1541-
visit::walk_expr_field(self, f);
1542-
}
1543-
}
1544-
1545-
fn visit_pat_field(&mut self, fp: &'a ast::PatField) {
1546-
if fp.is_placeholder {
1547-
self.visit_invoc(fp.id);
1548-
} else {
1549-
visit::walk_pat_field(self, fp);
1550-
}
1551-
}
1552-
1553-
fn visit_generic_param(&mut self, param: &'a ast::GenericParam) {
1554-
if param.is_placeholder {
1555-
self.visit_invoc(param.id);
1556-
} else {
1557-
visit::walk_generic_param(self, param);
1558-
}
1559-
}
1560-
1561-
fn visit_param(&mut self, p: &'a ast::Param) {
1562-
if p.is_placeholder {
1563-
self.visit_invoc(p.id);
1564-
} else {
1565-
visit::walk_param(self, p);
1447+
pub(crate) fn visit_assoc_item_mac_call(
1448+
&mut self,
1449+
item: &'a Item<AssocItemKind>,
1450+
ctxt: AssocCtxt,
1451+
) {
1452+
match ctxt {
1453+
AssocCtxt::Trait => {
1454+
self.visit_invoc_in_module(item.id);
1455+
}
1456+
AssocCtxt::Impl { .. } => {
1457+
let invoc_id = item.id.placeholder_to_expn_id();
1458+
if !self.r.glob_delegation_invoc_ids.contains(&invoc_id) {
1459+
self.r
1460+
.impl_unexpanded_invocations
1461+
.entry(self.r.invocation_parent(invoc_id))
1462+
.or_default()
1463+
.insert(invoc_id);
1464+
}
1465+
self.visit_invoc(item.id);
1466+
}
15661467
}
15671468
}
15681469

1569-
fn visit_field_def(&mut self, sf: &'a ast::FieldDef) {
1570-
if sf.is_placeholder {
1571-
self.visit_invoc(sf.id);
1572-
} else {
1573-
let vis = self.resolve_visibility(&sf.vis);
1574-
self.r.feed_visibility(self.r.feed(sf.id), vis);
1575-
visit::walk_field_def(self, sf);
1576-
}
1470+
pub(crate) fn brg_visit_field_def(&mut self, sf: &'a ast::FieldDef) {
1471+
let vis = self.resolve_visibility(&sf.vis);
1472+
self.r.feed_visibility(self.r.feed(sf.id), vis);
1473+
visit::walk_field_def(self, sf);
15771474
}
15781475

15791476
// Constructs the reduced graph for one variant. Variants exist in the
15801477
// type and value namespaces.
1581-
fn visit_variant(&mut self, variant: &'a ast::Variant) {
1582-
if variant.is_placeholder {
1583-
self.visit_invoc_in_module(variant.id);
1584-
return;
1585-
}
1586-
1478+
pub(crate) fn brg_visit_variant(&mut self, variant: &'a ast::Variant) {
15871479
let parent = self.parent_scope.module.expect_local();
15881480
let expn_id = self.parent_scope.expansion;
15891481
let ident = variant.ident;
@@ -1618,24 +1510,4 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
16181510

16191511
visit::walk_variant(self, variant);
16201512
}
1621-
1622-
fn visit_where_predicate(&mut self, p: &'a ast::WherePredicate) {
1623-
if p.is_placeholder {
1624-
self.visit_invoc(p.id);
1625-
} else {
1626-
visit::walk_where_predicate(self, p);
1627-
}
1628-
}
1629-
1630-
fn visit_crate(&mut self, krate: &'a ast::Crate) {
1631-
if krate.is_placeholder {
1632-
self.visit_invoc_in_module(krate.id);
1633-
} else {
1634-
// Visit attributes after items for backward compatibility.
1635-
// This way they can use `macro_rules` defined later.
1636-
visit::walk_list!(self, visit_item, &krate.items);
1637-
visit::walk_list!(self, visit_attribute, &krate.attrs);
1638-
self.contains_macro_use(&krate.attrs);
1639-
}
1640-
}
16411513
}

0 commit comments

Comments
 (0)