-macro_rules! define_dep_nodes {
- (<$tcx:tt>
- $(
- [$($attrs:tt)*]
- $variant:ident $(( $tuple_arg_ty:ty $(,)? ))*
- ,)*
- ) => (
- #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
- RustcEncodable, RustcDecodable)]
- #[allow(non_camel_case_types)]
- pub enum DepKind {
- $($variant),*
- }
-
- impl DepKind {
- #[allow(unreachable_code)]
- pub fn can_reconstruct_query_key<$tcx>(&self) -> bool {
- match *self {
- $(
- DepKind :: $variant => {
- if contains_anon_attr!($($attrs)*) {
- return false;
- }
-
- // tuple args
- $({
- return <$tuple_arg_ty as DepNodeParams>
- ::CAN_RECONSTRUCT_QUERY_KEY;
- })*
-
- true
- }
- )*
- }
- }
-
- pub fn is_anon(&self) -> bool {
- match *self {
- $(
- DepKind :: $variant => { contains_anon_attr!($($attrs)*) }
- )*
- }
- }
-
- pub fn is_eval_always(&self) -> bool {
- match *self {
- $(
- DepKind :: $variant => { contains_eval_always_attr!($($attrs)*) }
- )*
- }
- }
-
- #[allow(unreachable_code)]
- pub fn has_params(&self) -> bool {
- match *self {
- $(
- DepKind :: $variant => {
- // tuple args
- $({
- erase!($tuple_arg_ty);
- return true;
- })*
-
- false
- }
- )*
- }
- }
- }
-
- pub struct DepConstructor;
-
- #[allow(non_camel_case_types)]
- impl DepConstructor {
- $(
- #[inline(always)]
- #[allow(unreachable_code, non_snake_case)]
- pub fn $variant(_tcx: TyCtxt<'_>, $(arg: $tuple_arg_ty)*) -> DepNode {
- // tuple args
- $({
- erase!($tuple_arg_ty);
- let hash = DepNodeParams::to_fingerprint(&arg, _tcx);
- let dep_node = DepNode {
- kind: DepKind::$variant,
- hash
- };
-
- #[cfg(debug_assertions)]
- {
- if !dep_node.kind.can_reconstruct_query_key() &&
- (_tcx.sess.opts.debugging_opts.incremental_info ||
- _tcx.sess.opts.debugging_opts.query_dep_graph)
- {
- _tcx.dep_graph.register_dep_node_debug_str(dep_node, || {
- arg.to_debug_str(_tcx)
- });
- }
- }
-
- return dep_node;
- })*
-
- DepNode {
- kind: DepKind::$variant,
- hash: Fingerprint::ZERO,
- }
- }
- )*
- }
-
- #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
- RustcEncodable, RustcDecodable)]
- pub struct DepNode {
- pub kind: DepKind,
- pub hash: Fingerprint,
- }
-
- impl DepNode {
- /// Construct a DepNode from the given DepKind and DefPathHash. This
- /// method will assert that the given DepKind actually requires a
- /// single DefId/DefPathHash parameter.
- pub fn from_def_path_hash(def_path_hash: DefPathHash,
- kind: DepKind)
- -> DepNode {
- debug_assert!(kind.can_reconstruct_query_key() && kind.has_params());
- DepNode {
- kind,
- hash: def_path_hash.0,
- }
- }
-
- /// Creates a new, parameterless DepNode. This method will assert
- /// that the DepNode corresponding to the given DepKind actually
- /// does not require any parameters.
- pub fn new_no_params(kind: DepKind) -> DepNode {
- debug_assert!(!kind.has_params());
- DepNode {
- kind,
- hash: Fingerprint::ZERO,
- }
- }
-
- /// Extracts the DefId corresponding to this DepNode. This will work
- /// if two conditions are met:
- ///
- /// 1. The Fingerprint of the DepNode actually is a DefPathHash, and
- /// 2. the item that the DefPath refers to exists in the current tcx.
- ///
- /// Condition (1) is determined by the DepKind variant of the
- /// DepNode. Condition (2) might not be fulfilled if a DepNode
- /// refers to something from the previous compilation session that
- /// has been removed.
- pub fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
- if self.kind.can_reconstruct_query_key() {
- let def_path_hash = DefPathHash(self.hash);
- tcx.def_path_hash_to_def_id.as_ref()?
- .get(&def_path_hash).cloned()
- } else {
- None
- }
- }
-
- /// Used in testing
- pub fn from_label_string(label: &str,
- def_path_hash: DefPathHash)
- -> Result<DepNode, ()> {
- let kind = match label {
- $(
- stringify!($variant) => DepKind::$variant,
- )*
- _ => return Err(()),
- };
-
- if !kind.can_reconstruct_query_key() {
- return Err(());
- }
-
- if kind.has_params() {
- Ok(DepNode::from_def_path_hash(def_path_hash, kind))
- } else {
- Ok(DepNode::new_no_params(kind))
- }
- }
-
- /// Used in testing
- pub fn has_label_string(label: &str) -> bool {
- match label {
- $(
- stringify!($variant) => true,
- )*
- _ => false,
- }
- }
- }
-
- /// Contains variant => str representations for constructing
- /// DepNode groups for tests.
- #[allow(dead_code, non_upper_case_globals)]
- pub mod label_strs {
- $(
- pub const $variant: &str = stringify!($variant);
- )*
- }
- );