Skip to content
Draft
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
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1550,7 +1550,7 @@ impl Attribute {
}

/// Attributes owned by a HIR owner.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct AttributeMap<'tcx> {
pub map: SortedMap<ItemLocalId, &'tcx [Attribute]>,
/// Preprocessed `#[define_opaque]` attribute.
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_incremental/src/assert_dep_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,7 @@ impl<'tcx> IfThisChanged<'tcx> {
for attr in attrs {
if let Attribute::Parsed(AttributeKind::RustcIfThisChanged(span, dep_node)) = *attr {
let dep_node = match dep_node {
None => DepNode::from_def_path_hash(
self.tcx,
def_path_hash,
DepKind::opt_hir_owner_nodes,
),
None => DepNode::from_def_path_hash(self.tcx, def_path_hash, DepKind::owner),
Some(n) => {
match DepNode::from_label_string(self.tcx, n.as_str(), def_path_hash) {
Ok(n) => n,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_incremental/src/persist/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const BASE_FN: &[&str] = &[
/// DepNodes for Hir, which is pretty much everything
const BASE_HIR: &[&str] = &[
// opt_hir_owner_nodes should be computed for all nodes
label_strs::opt_hir_owner_nodes,
label_strs::owner,
];

/// `impl` implementation of struct/trait
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_middle/src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ macro_rules! arena_types {
[] crate_inherent_impls: rustc_middle::ty::CrateInherentImpls,
[] hir_owner_nodes: rustc_hir::OwnerNodes<'tcx>,
[decode] token_stream: rustc_ast::tokenstream::TokenStream,
[] maybe_owner: rustc_middle::hir::ProjectedMaybeOwner<'tcx>,
[] owner_info: rustc_middle::hir::ProjectedOwnerInfo<'tcx>,
[] parenting: rustc_hir::def_id::LocalDefIdMap<rustc_hir::ItemLocalId>,
[] trait_candidates: rustc_hir::ItemLocalMap<&'tcx [rustc_hir::TraitCandidate<'tcx>]>,
[] delayed_lints: rustc_hir::lints::DelayedLints,
]);
)
}
Expand Down
28 changes: 26 additions & 2 deletions compiler/rustc_middle/src/hir/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalModDefId};
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
use rustc_hir::intravisit::Visitor;
use rustc_hir::lints::DelayedLints;
use rustc_hir::*;
use rustc_hir_pretty as pprust_hir;
use rustc_span::def_id::StableCrateId;
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, with_metavar_spans};

use crate::hir::{ModuleItems, nested_filter};
use crate::hir::{ModuleItems, ProjectedMaybeOwner, nested_filter};
use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
use crate::query::LocalCrate;
use crate::query::{IntoQueryKey, LocalCrate};
use crate::ty::TyCtxt;

/// An iterator that walks up the ancestor tree of a given `HirId`.
Expand Down Expand Up @@ -101,6 +102,29 @@ impl<'tcx> Iterator for ParentOwnerIterator<'tcx> {
}

impl<'tcx> TyCtxt<'tcx> {
pub fn local_def_id_to_hir_id(self, def_id: impl IntoQueryKey<LocalDefId>) -> HirId {
let def_id = def_id.into_query_key();
match self.owner(def_id) {
ProjectedMaybeOwner::Owner(_) => HirId::make_owner(def_id),
ProjectedMaybeOwner::NonOwner(hir_id) => *hir_id,
}
}

pub fn opt_ast_lowering_delayed_lints(self, id: OwnerId) -> Option<&'tcx DelayedLints> {
self.owner(id.def_id).as_owner().map(|o| o.delayed_lints)
}

pub fn in_scope_traits_map(
self,
id: OwnerId,
) -> Option<&'tcx ItemLocalMap<&'tcx [TraitCandidate<'tcx>]>> {
self.owner(id.def_id).as_owner().map(|owner_info| owner_info.trait_map)
}

pub fn opt_hir_owner_nodes(self, def_id: LocalDefId) -> Option<&'tcx OwnerNodes<'tcx>> {
self.owner(def_id).as_owner().map(|i| i.nodes)
}

#[inline]
fn expect_hir_owner_nodes(self, def_id: LocalDefId) -> &'tcx OwnerNodes<'tcx> {
self.opt_hir_owner_nodes(def_id)
Expand Down
73 changes: 56 additions & 17 deletions compiler/rustc_middle/src/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use rustc_data_structures::sync::{DynSend, DynSync, try_par_for_each_in};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap, LocalModDefId};
use rustc_hir::definitions::PerParentDisambiguatorState;
use rustc_hir::lints::DelayedLints;
use rustc_hir::*;
use rustc_index::IndexVec;
use rustc_macros::{Decodable, Encodable, HashStable};
Expand Down Expand Up @@ -67,14 +68,14 @@ impl<'hir> Crate<'hir> {
/// `owners` of `hir_crate` or it can be delayed AST owner (i.e., delegations)
/// we need to firstly check in `hir_crate` and then delayed AST owners.
/// This method can be invoked when not all delayed AST owners are lowered.
pub fn owner(&self, tcx: TyCtxt<'hir>, def_id: LocalDefId) -> MaybeOwner<'hir> {
pub fn owner(&'hir self, tcx: TyCtxt<'hir>, def_id: LocalDefId) -> &'hir MaybeOwner<'hir> {
// Delayed LocalDefId can be in `self.owners` if there exists non-delayed LocalDefId
// which is greater than delayed LocalDefId, we use IndexVec for owners,
// so we will call ensure_contains_elem which will grow it.
if let Some(owner) = self.owners.get(def_id)
&& (self.delayed_ids.is_empty() || !matches!(owner, MaybeOwner::Phantom))
{
return *owner;
return owner;
}

if self.delayed_ids.contains(&def_id) {
Expand Down Expand Up @@ -431,8 +432,7 @@ impl<'tcx> TyCtxt<'tcx> {
HirId {
owner: parent_owner_id,
local_id: self
.hir_crate(())
.owner(self, parent_owner_id.def_id)
.owner(parent_owner_id.def_id)
.unwrap()
.parenting
.get(&owner_id.def_id)
Expand Down Expand Up @@ -461,23 +461,65 @@ pub struct Hashes {
pub attrs_hash: Option<Fingerprint>,
}

#[derive(Debug, HashStable)]
pub struct ProjectedOwnerInfo<'tcx> {
/// Contents of the HIR.
pub nodes: &'tcx OwnerNodes<'tcx>,

/// Map from each nested owner to its parent's local id.
pub parenting: &'tcx LocalDefIdMap<ItemLocalId>,

/// Map indicating what traits are in scope for places where this
/// is relevant; generated by resolve.
pub trait_map: &'tcx ItemLocalMap<&'tcx [TraitCandidate<'tcx>]>,

#[stable_hasher(ignore)]
pub delayed_lints: &'tcx DelayedLints,
}

#[derive(Debug, HashStable)]
pub enum ProjectedMaybeOwner<'tcx> {
Owner(ProjectedOwnerInfo<'tcx>),
NonOwner(HirId),
}

impl<'tcx> From<&'tcx MaybeOwner<'tcx>> for ProjectedMaybeOwner<'tcx> {
fn from(value: &'tcx MaybeOwner<'tcx>) -> Self {
match value {
MaybeOwner::Owner(o) => ProjectedMaybeOwner::Owner(ProjectedOwnerInfo {
nodes: &o.nodes,
parenting: &o.parenting,
trait_map: &o.trait_map,
delayed_lints: &o.delayed_lints,
}),
MaybeOwner::NonOwner(hir_id) => ProjectedMaybeOwner::NonOwner(*hir_id),
MaybeOwner::Phantom => panic!(),
}
}
}

impl<'tcx> ProjectedMaybeOwner<'tcx> {
pub fn as_owner(&'tcx self) -> Option<&'tcx ProjectedOwnerInfo<'tcx>> {
match self {
ProjectedMaybeOwner::Owner(i) => Some(i),
ProjectedMaybeOwner::NonOwner(_) => None,
}
}

pub fn unwrap(&'tcx self) -> &'tcx ProjectedOwnerInfo<'tcx> {
self.as_owner().unwrap_or_else(|| panic!("Not a HIR owner"))
}
}

pub fn provide(providers: &mut Providers) {
providers.hir_crate_items = map::hir_crate_items;
providers.crate_hash = map::crate_hash;
providers.hir_module_items = map::hir_module_items;
providers.local_def_id_to_hir_id = |tcx, def_id| match tcx.hir_crate(()).owner(tcx, def_id) {
MaybeOwner::Owner(_) => HirId::make_owner(def_id),
MaybeOwner::NonOwner(hir_id) => hir_id,
MaybeOwner::Phantom => bug!("No HirId for {:?}", def_id),
};
providers.opt_hir_owner_nodes =
|tcx, id| tcx.hir_crate(()).owner(tcx, id).as_owner().map(|i| &i.nodes);
providers.hir_owner_parent_q = |tcx, owner_id| tcx.hir_owner_parent_impl(owner_id);
providers.hir_attr_map = |tcx, id| {
tcx.hir_crate(()).owner(tcx, id.def_id).as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs)
};
providers.opt_ast_lowering_delayed_lints =
|tcx, id| tcx.hir_crate(()).owner(tcx, id.def_id).as_owner().map(|o| &o.delayed_lints);
providers.owner = |tcx, def_id| ProjectedMaybeOwner::from(tcx.hir_crate(()).owner(tcx, def_id));
providers.hir_owner_parent_q = |tcx, owner_id| tcx.hir_owner_parent_impl(owner_id);
providers.def_span = |tcx, def_id| tcx.hir_span(tcx.local_def_id_to_hir_id(def_id));
providers.def_ident_span = |tcx, def_id| {
let hir_id = tcx.local_def_id_to_hir_id(def_id);
Expand Down Expand Up @@ -517,7 +559,4 @@ pub fn provide(providers: &mut Providers) {
|tcx, trait_id| tcx.resolutions(()).trait_impls.get(&trait_id).map_or(&[], |xs| &xs[..]);
providers.expn_that_defined =
|tcx, id| tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root());
providers.in_scope_traits_map = |tcx, id| {
tcx.hir_crate(()).owner(tcx, id.def_id).as_owner().map(|owner_info| &owner_info.trait_map)
};
}
42 changes: 9 additions & 33 deletions compiler/rustc_middle/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ use rustc_hir::def_id::{
CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap, LocalDefIdSet, LocalModDefId,
};
use rustc_hir::lang_items::{LangItem, LanguageItems};
use rustc_hir::{ItemLocalId, ItemLocalMap, PreciseCapturingArgKind, TraitCandidate};
use rustc_hir::{ItemLocalId, PreciseCapturingArgKind};
use rustc_index::IndexVec;
use rustc_lint_defs::LintId;
use rustc_macros::rustc_queries;
Expand Down Expand Up @@ -216,8 +216,15 @@ rustc_queries! {
desc { "lowering the delayed AST owner `{}`", tcx.def_path_str(def_id) }
}

query delayed_owner(def_id: LocalDefId) -> hir::MaybeOwner<'tcx> {
query owner(def_id: LocalDefId) -> &'tcx rustc_middle::hir::ProjectedMaybeOwner<'tcx> {
desc { "getting owner for `{}`", tcx.def_path_str(def_id) }
arena_cache
feedable
}

query delayed_owner(def_id: LocalDefId) -> &'tcx hir::MaybeOwner<'tcx> {
feedable
arena_cache
desc { "getting child of lowered delayed AST owner `{}`", tcx.def_path_str(def_id) }
}

Expand All @@ -238,12 +245,6 @@ rustc_queries! {
cache_on_disk
}

/// Returns HIR ID for the given `LocalDefId`.
query local_def_id_to_hir_id(key: LocalDefId) -> hir::HirId {
desc { "getting HIR ID of `{}`", tcx.def_path_str(key) }
feedable
}

/// Gives access to the HIR node's parent for the HIR owner `key`.
///
/// This can be conveniently accessed by `tcx.hir_*` methods.
Expand All @@ -252,15 +253,6 @@ rustc_queries! {
desc { "getting HIR parent of `{}`", tcx.def_path_str(key) }
}

/// Gives access to the HIR nodes and bodies inside `key` if it's a HIR owner.
///
/// This can be conveniently accessed by `tcx.hir_*` methods.
/// Avoid calling this query directly.
query opt_hir_owner_nodes(key: LocalDefId) -> Option<&'tcx hir::OwnerNodes<'tcx>> {
desc { "getting HIR owner items in `{}`", tcx.def_path_str(key) }
feedable
}

/// Gives access to the HIR attributes inside the HIR owner `key`.
///
/// This can be conveniently accessed by `tcx.hir_*` methods.
Expand All @@ -270,18 +262,6 @@ rustc_queries! {
feedable
}

/// Gives access to lints emitted during ast lowering.
///
/// This can be conveniently accessed by `tcx.hir_*` methods.
/// Avoid calling this query directly.
query opt_ast_lowering_delayed_lints(key: hir::OwnerId) -> Option<&'tcx hir::lints::DelayedLints> {
desc { "getting AST lowering delayed lints in `{}`", tcx.def_path_str(key) }
// This query has to be `no_hash` and `eval_always`,
// because it accesses `delayed_lints` which is not hashed as part of the HIR
no_hash
eval_always
}

/// Returns the *default* of the const pararameter given by `DefId`.
///
/// E.g., given `struct Ty<const N: usize = 3>;` this returns `3` for `N`.
Expand Down Expand Up @@ -1884,10 +1864,6 @@ rustc_queries! {
query specializes(_: (DefId, DefId)) -> bool {
desc { "computing whether impls specialize one another" }
}
query in_scope_traits_map(_: hir::OwnerId)
-> Option<&'tcx ItemLocalMap<&'tcx [TraitCandidate<'tcx>]>> {
desc { "getting traits in scope at a block" }
}

/// Returns whether the impl or associated function has the `default` keyword.
/// Note: This will ICE on inherent impl items. Consider using `AssocItem::defaultness`.
Expand Down
26 changes: 16 additions & 10 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ use tracing::{debug, instrument};
use crate::arena::Arena;
use crate::dep_graph::dep_node::make_metadata;
use crate::dep_graph::{DepGraph, DepKindVTable, DepNodeIndex};
use crate::hir::{ProjectedMaybeOwner, ProjectedOwnerInfo};
use crate::ich::StableHashingContext;
use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind};
use crate::lint::emit_lint_base;
Expand Down Expand Up @@ -759,23 +760,28 @@ impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {

// Fills in all the important parts needed by HIR queries
pub fn feed_hir(&self) {
self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));

let node = hir::OwnerNode::Synthetic;
let bodies = Default::default();
let attrs = hir::AttributeMap::EMPTY;

let rustc_middle::hir::Hashes { opt_hash_including_bodies, .. } =
self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, attrs.define_opaque);
let node = node.into();
self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
opt_hash_including_bodies,
nodes: IndexVec::from_elem_n(
hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
1,
),
bodies,
})));

self.owner(ProjectedMaybeOwner::Owner(ProjectedOwnerInfo {
nodes: self.tcx.arena.alloc(hir::OwnerNodes {
opt_hash_including_bodies,
nodes: IndexVec::from_elem_n(
hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
1,
),
bodies,
}),
parenting: self.tcx.arena.alloc(Default::default()),
delayed_lints: self.tcx.arena.alloc(Default::default()),
trait_map: self.tcx.arena.alloc(Default::default()),
}));

self.feed_owner_id().hir_attr_map(attrs);
}
}
Expand Down
4 changes: 2 additions & 2 deletions tests/incremental/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ mod y {
use x;

#[rustc_clean(
except="opt_hir_owner_nodes,generics_of,predicates_of,type_of,fn_sig",
except="owner,generics_of,predicates_of,type_of,fn_sig",
cfg="bfail2",
)]
pub fn y() {
//[bfail2]~^ ERROR `opt_hir_owner_nodes(y)` should be dirty but is not
//[bfail2]~^ ERROR `owner(y)` should be dirty but is not
//[bfail2]~| ERROR `generics_of(y)` should be dirty but is not
//[bfail2]~| ERROR `predicates_of(y)` should be dirty but is not
//[bfail2]~| ERROR `type_of(y)` should be dirty but is not
Expand Down
4 changes: 2 additions & 2 deletions tests/incremental/hash-module-order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
#![feature(rustc_attrs)]

#[cfg(rpass1)]
#[rustc_clean(cfg="rpass1",except="opt_hir_owner_nodes")]
#[rustc_clean(cfg="rpass1",except="owner")]
mod foo {
struct First;
struct Second;
}

#[cfg(rpass2)]
#[rustc_clean(cfg="rpass2",except="opt_hir_owner_nodes")]
#[rustc_clean(cfg="rpass2",except="owner")]
mod foo {
struct Second;
struct First;
Expand Down
Loading
Loading