Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,23 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn feed_delayed_owner(self, key: LocalDefId, owner: MaybeOwner<'tcx>) {
TyCtxtFeed { tcx: self, key }.delayed_owner(owner);
}

// Trait impl item visibility is inherited from its trait when not specified
// explicitly. In that case we cannot determine it in early resolve,
// but instead are feeding it in late resolve, where we don't have access to the
// `TyCtxtFeed` anymore.
// To avoid having to hash the `LocalDefId` multiple times for inserting and removing the
// `TyCtxtFeed` from a hash table, we add this hack to feed the visibility.
// Do not use outside of the resolver query.
pub fn feed_visibility_for_trait_impl_item(self, key: LocalDefId, vis: ty::Visibility) {
if cfg!(debug_assertions) {
match self.def_kind(self.local_parent(key)) {
DefKind::Impl { of_trait: true } => {}
other => bug!("{key:?} is not an assoc item of a trait impl: {other:?}"),
}
}
TyCtxtFeed { tcx: self, key }.visibility(vis.to_def_id())
}
}

impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
Expand Down
77 changes: 51 additions & 26 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
use rustc_index::bit_set::DenseBitSet;
use rustc_metadata::creader::LoadedMacro;
use rustc_middle::metadata::{ModChild, Reexport};
use rustc_middle::ty::{Feed, Visibility};
use rustc_middle::ty::{TyCtxtFeed, Visibility};
use rustc_middle::{bug, span_bug};
use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind};
use rustc_span::{Ident, Span, Symbol, kw, sym};
Expand Down Expand Up @@ -563,6 +563,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
item: &Item,
vis: Visibility,
root_span: Span,
feed: TyCtxtFeed<'tcx, LocalDefId>,
) {
debug!(
"build_reduced_graph_for_use_tree(parent_prefix={:?}, use_tree={:?}, nested={})",
Expand All @@ -572,7 +573,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
// Top level use tree reuses the item's id and list stems reuse their parent
// use tree's ids, so in both cases their visibilities are already filled.
if nested && !list_stem {
self.r.feed_visibility(self.r.feed(id), vis);
self.r.feed_visibility(feed, vis);
}

let mut prefix_iter = parent_prefix
Expand Down Expand Up @@ -735,11 +736,11 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
}
ast::UseTreeKind::Nested { ref items, .. } => {
for &(ref tree, id) in items {
self.create_def(id, None, DefKind::Use, use_tree.span());
let feed = self.create_def(id, None, DefKind::Use, use_tree.span());
self.build_reduced_graph_for_use_tree(
// This particular use tree
tree, id, &prefix, true, false, // The whole `use` item
item, vis, root_span,
item, vis, root_span, feed,
);
}

Expand Down Expand Up @@ -768,6 +769,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
self.parent_scope.module.nearest_parent_mod().expect_local(),
),
root_span,
feed,
);
}
}
Expand All @@ -778,7 +780,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
&mut self,
fields: &[ast::FieldDef],
ident: Ident,
feed: Feed<'tcx, LocalDefId>,
feed: TyCtxtFeed<'tcx, LocalDefId>,
adt_res: Res,
adt_vis: Visibility,
adt_span: Span,
Expand All @@ -798,13 +800,12 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
}

/// Constructs the reduced graph for one item.
fn build_reduced_graph_for_item(&mut self, item: &'a Item) {
fn build_reduced_graph_for_item(&mut self, item: &'a Item, feed: TyCtxtFeed<'tcx, LocalDefId>) {
let parent_scope = &self.parent_scope;
let parent = parent_scope.module.expect_local();
let expansion = parent_scope.expansion;
let sp = item.span;
let vis = self.resolve_visibility(&item.vis);
let feed = self.r.feed(item.id);
let local_def_id = feed.key();
let def_id = local_def_id.to_def_id();
let def_kind = self.r.tcx.def_kind(def_id);
Expand All @@ -825,6 +826,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
item,
vis,
use_tree.span(),
feed,
);
}

Expand Down Expand Up @@ -867,7 +869,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {

// Functions introducing procedural macros reserve a slot
// in the macro namespace as well (see #52225).
self.define_macro(item);
self.define_macro(item, feed);
}

// These items live in the type namespace.
Expand Down Expand Up @@ -902,7 +904,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {

// If this is a tuple or unit struct, define a name
// in the value namespace as well.
if let Some(ctor_node_id) = vdata.ctor_node_id() {
if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(vdata) {
// If the structure is marked as non_exhaustive then lower the visibility
// to within the crate.
let mut ctor_vis = if vis.is_public()
Expand All @@ -927,7 +929,14 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
}
field_visibilities.push(field_vis.to_def_id());
}
let feed = self.r.feed(ctor_node_id);
// If this is a unit or tuple-like struct, register the constructor.
let feed = self.create_def(
ctor_node_id,
None,
DefKind::Ctor(CtorOf::Struct, ctor_kind),
item.span,
);

let ctor_def_id = feed.key();
let ctor_res = self.res(ctor_def_id);
self.r.define_local(parent, ident, ValueNS, ctor_res, ctor_vis, sp, expansion);
Expand Down Expand Up @@ -1062,8 +1071,8 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
&mut self,
item: &ForeignItem,
ident: Ident,
feed: TyCtxtFeed<'tcx, LocalDefId>,
) {
let feed = self.r.feed(item.id);
let local_def_id = feed.key();
let def_id = local_def_id.to_def_id();
let ns = match item.kind {
Expand Down Expand Up @@ -1259,10 +1268,13 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
}
}

fn define_macro(&mut self, item: &ast::Item) -> MacroRulesScopeRef<'ra> {
fn define_macro(
&mut self,
item: &ast::Item,
feed: TyCtxtFeed<'tcx, LocalDefId>,
) -> MacroRulesScopeRef<'ra> {
let parent_scope = self.parent_scope;
let expansion = parent_scope.expansion;
let feed = self.r.feed(item.id);
let def_id = feed.key();
let (res, orig_ident, span, macro_rules) = match &item.kind {
ItemKind::MacroDef(ident, def) => {
Expand Down Expand Up @@ -1361,18 +1373,17 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
}

impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
pub(crate) fn brg_visit_item(&mut self, item: &'a Item) {
pub(crate) fn brg_visit_item(&mut self, item: &'a Item, feed: TyCtxtFeed<'tcx, LocalDefId>) {
let orig_module_scope = self.parent_scope.module;
self.parent_scope.macro_rules = match item.kind {
ItemKind::MacroDef(..) => {
let macro_rules_scope = self.define_macro(item);
let macro_rules_scope = self.define_macro(item, feed);
visit::walk_item(self, item);
macro_rules_scope
}
ItemKind::MacCall(..) => self.visit_invoc_in_module(item.id),
_ => {
let orig_macro_rules_scope = self.parent_scope.macro_rules;
self.build_reduced_graph_for_item(item);
self.build_reduced_graph_for_item(item, feed);
match item.kind {
ItemKind::Mod(..) => {
// Visit attributes after items for backward compatibility.
Expand All @@ -1394,8 +1405,10 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
self.parent_scope.module = orig_module_scope;
}

pub(crate) fn brg_visit_stmt_mac_call(&mut self, stmt: &'a ast::Stmt) {
self.parent_scope.macro_rules = self.visit_invoc_in_module(stmt.id);
/// Handle a macro call that itself can produce new `macro_rules` items
/// in the current module.
pub(crate) fn brg_visit_mac_call_in_module(&mut self, id: NodeId) {
self.parent_scope.macro_rules = self.visit_invoc_in_module(id);
}

pub(crate) fn brg_visit_block(&mut self, block: &'a Block) {
Expand All @@ -1413,9 +1426,9 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
ctxt: AssocCtxt,
ident: Ident,
ns: Namespace,
feed: TyCtxtFeed<'tcx, LocalDefId>,
) {
let vis = self.resolve_visibility(&item.vis);
let feed = self.r.feed(item.id);
let local_def_id = feed.key();
let def_id = local_def_id.to_def_id();

Expand Down Expand Up @@ -1467,21 +1480,28 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
}
}

pub(crate) fn brg_visit_field_def(&mut self, sf: &'a ast::FieldDef) {
pub(crate) fn brg_visit_field_def(
&mut self,
sf: &'a ast::FieldDef,
feed: TyCtxtFeed<'tcx, LocalDefId>,
) {
let vis = self.resolve_visibility(&sf.vis);
self.r.feed_visibility(self.r.feed(sf.id), vis);
self.r.feed_visibility(feed, vis);
visit::walk_field_def(self, sf);
}

// Constructs the reduced graph for one variant. Variants exist in the
// type and value namespaces.
pub(crate) fn brg_visit_variant(&mut self, variant: &'a ast::Variant) {
pub(crate) fn brg_visit_variant(
&mut self,
variant: &'a ast::Variant,
feed: TyCtxtFeed<'tcx, LocalDefId>,
) {
let parent = self.parent_scope.module.expect_local();
let expn_id = self.parent_scope.expansion;
let ident = variant.ident;

// Define a name in the type namespace.
let feed = self.r.feed(variant.id);
let def_id = feed.key();
let vis = self.resolve_visibility(&variant.vis);
self.r.define_local(parent, ident, TypeNS, self.res(def_id), vis, variant.span, expn_id);
Expand All @@ -1496,8 +1516,13 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
};

// Define a constructor name in the value namespace.
if let Some(ctor_node_id) = variant.data.ctor_node_id() {
let feed = self.r.feed(ctor_node_id);
if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(&variant.data) {
let feed = self.create_def(
ctor_node_id,
None,
DefKind::Ctor(CtorOf::Variant, ctor_kind),
variant.span,
);
let ctor_def_id = feed.key();
let ctor_res = self.res(ctor_def_id);
self.r.define_local(parent, ident, ValueNS, ctor_res, ctor_vis, variant.span, expn_id);
Expand Down
Loading
Loading