diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 6993ef3768a79..53a6b688a0faa 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -90,6 +90,11 @@ macro_rules! is_input_attr {
     ($attr:ident) => (false);
 }
 
+macro_rules! is_eval_always_attr {
+    (eval_always) => (true);
+    ($attr:ident) => (false);
+}
+
 macro_rules! contains_anon_attr {
     ($($attr:ident),*) => ({$(is_anon_attr!($attr) | )* false});
 }
@@ -98,6 +103,10 @@ macro_rules! contains_input_attr {
     ($($attr:ident),*) => ({$(is_input_attr!($attr) | )* false});
 }
 
+macro_rules! contains_eval_always_attr {
+    ($($attr:ident),*) => ({$(is_eval_always_attr!($attr) | )* false});
+}
+
 macro_rules! define_dep_nodes {
     (<$tcx:tt>
     $(
@@ -160,6 +169,15 @@ macro_rules! define_dep_nodes {
                 }
             }
 
+            #[inline]
+            pub fn is_eval_always(&self) -> bool {
+                match *self {
+                    $(
+                        DepKind :: $variant => { contains_eval_always_attr!($($attr), *) }
+                    )*
+                }
+            }
+
             #[allow(unreachable_code)]
             #[inline]
             pub fn has_params(&self) -> bool {
@@ -447,10 +465,10 @@ define_dep_nodes!( <'tcx>
 
     // Represents different phases in the compiler.
     [] RegionScopeTree(DefId),
-    [] Coherence,
-    [] CoherenceInherentImplOverlapCheck,
+    [eval_always] Coherence,
+    [eval_always] CoherenceInherentImplOverlapCheck,
     [] CoherenceCheckTrait(DefId),
-    [] PrivacyAccessLevels(CrateNum),
+    [eval_always] PrivacyAccessLevels(CrateNum),
 
     // Represents the MIR for a fn; also used as the task node for
     // things read/modify that MIR.
@@ -467,7 +485,7 @@ define_dep_nodes!( <'tcx>
 
     [] Reachability,
     [] MirKeys,
-    [] CrateVariances,
+    [eval_always] CrateVariances,
 
     // Nodes representing bits of computed IR in the tcx. Each shared
     // table in the tcx (or elsewhere) maps to one of these
@@ -497,7 +515,7 @@ define_dep_nodes!( <'tcx>
     [] DtorckConstraint(DefId),
     [] AdtDestructor(DefId),
     [] AssociatedItemDefIds(DefId),
-    [] InherentImpls(DefId),
+    [eval_always] InherentImpls(DefId),
     [] TypeckBodiesKrate,
     [] TypeckTables(DefId),
     [] HasTypeckTables(DefId),
@@ -566,7 +584,7 @@ define_dep_nodes!( <'tcx>
     [] IsCompilerBuiltins(CrateNum),
     [] HasGlobalAllocator(CrateNum),
     [] ExternCrate(DefId),
-    [] LintLevels,
+    [eval_always] LintLevels,
     [] Specializes { impl1: DefId, impl2: DefId },
     [input] InScopeTraits(DefIndex),
     [] ModuleExports(DefId),
@@ -625,7 +643,7 @@ define_dep_nodes!( <'tcx>
     [] StabilityIndex,
     [] AllCrateNums,
     [] ExportedSymbols(CrateNum),
-    [] CollectAndPartitionTranslationItems,
+    [eval_always] CollectAndPartitionTranslationItems,
     [] ExportName(DefId),
     [] ContainsExternIndicator(DefId),
     [] IsTranslatedFunction(DefId),
diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs
index 0fdb6dc068dd9..ec709b301eb73 100644
--- a/src/librustc/dep_graph/graph.rs
+++ b/src/librustc/dep_graph/graph.rs
@@ -199,11 +199,27 @@ impl DepGraph {
                                    -> (R, DepNodeIndex)
         where C: DepGraphSafe + StableHashingContextProvider<ContextType=HCX>,
               R: HashStable<HCX>,
+    {
+        self.with_task_impl(key, cx, arg, task,
+            |data, key| data.borrow_mut().push_task(key),
+            |data, key| data.borrow_mut().pop_task(key))
+    }
+
+    fn with_task_impl<C, A, R, HCX>(&self,
+                                    key: DepNode,
+                                    cx: C,
+                                    arg: A,
+                                    task: fn(C, A) -> R,
+                                    push: fn(&RefCell<CurrentDepGraph>, DepNode),
+                                    pop: fn(&RefCell<CurrentDepGraph>, DepNode) -> DepNodeIndex)
+                                    -> (R, DepNodeIndex)
+        where C: DepGraphSafe + StableHashingContextProvider<ContextType=HCX>,
+              R: HashStable<HCX>,
     {
         if let Some(ref data) = self.data {
             debug_assert!(!data.colors.borrow().contains_key(&key));
 
-            data.current.borrow_mut().push_task(key);
+            push(&data.current, key);
             if cfg!(debug_assertions) {
                 profq_msg(ProfileQueriesMsg::TaskBegin(key.clone()))
             };
@@ -220,7 +236,7 @@ impl DepGraph {
                 profq_msg(ProfileQueriesMsg::TaskEnd)
             };
 
-            let dep_node_index = data.current.borrow_mut().pop_task(key);
+            let dep_node_index = pop(&data.current, key);
 
             let mut stable_hasher = StableHasher::new();
             result.hash_stable(&mut hcx, &mut stable_hasher);
@@ -290,6 +306,22 @@ impl DepGraph {
         }
     }
 
+    /// Execute something within an "eval-always" task which is a task
+    // that runs whenever anything changes.
+    pub fn with_eval_always_task<C, A, R, HCX>(&self,
+                                   key: DepNode,
+                                   cx: C,
+                                   arg: A,
+                                   task: fn(C, A) -> R)
+                                   -> (R, DepNodeIndex)
+        where C: DepGraphSafe + StableHashingContextProvider<ContextType=HCX>,
+              R: HashStable<HCX>,
+    {
+        self.with_task_impl(key, cx, arg, task,
+            |data, key| data.borrow_mut().push_eval_always_task(key),
+            |data, key| data.borrow_mut().pop_eval_always_task(key))
+    }
+
     #[inline]
     pub fn read(&self, v: DepNode) {
         if let Some(ref data) = self.data {
@@ -788,6 +820,24 @@ impl CurrentDepGraph {
         }
     }
 
+    fn push_eval_always_task(&mut self, key: DepNode) {
+        self.task_stack.push(OpenTask::EvalAlways { node: key });
+    }
+
+    fn pop_eval_always_task(&mut self, key: DepNode) -> DepNodeIndex {
+        let popped_node = self.task_stack.pop().unwrap();
+
+        if let OpenTask::EvalAlways {
+            node,
+        } = popped_node {
+            debug_assert_eq!(node, key);
+            let krate_idx = self.node_to_node_index[&DepNode::new_no_params(DepKind::Krate)];
+            self.alloc_node(node, vec![krate_idx])
+        } else {
+            bug!("pop_eval_always_task() - Expected eval always task to be popped");
+        }
+    }
+
     fn read_index(&mut self, source: DepNodeIndex) {
         match self.task_stack.last_mut() {
             Some(&mut OpenTask::Regular {
@@ -818,7 +868,8 @@ impl CurrentDepGraph {
                     reads.push(source);
                 }
             }
-            Some(&mut OpenTask::Ignore) | None => {
+            Some(&mut OpenTask::Ignore) |
+            Some(&mut OpenTask::EvalAlways { .. }) | None => {
                 // ignore
             }
         }
@@ -851,4 +902,7 @@ enum OpenTask {
         read_set: FxHashSet<DepNodeIndex>,
     },
     Ignore,
+    EvalAlways {
+        node: DepNode,
+    },
 }
diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs
index 5f93c3de336cc..e8f1ee10d6dbf 100644
--- a/src/librustc/ty/maps/plumbing.rs
+++ b/src/librustc/ty/maps/plumbing.rs
@@ -433,10 +433,17 @@ macro_rules! define_maps {
                 profq_msg!(tcx, ProfileQueriesMsg::ProviderBegin);
                 let res = tcx.cycle_check(span, Query::$name(key), || {
                     tcx.sess.diagnostic().track_diagnostics(|| {
-                        tcx.dep_graph.with_task(dep_node,
-                                                tcx,
-                                                key,
-                                                Self::compute_result)
+                        if dep_node.kind.is_eval_always() {
+                            tcx.dep_graph.with_eval_always_task(dep_node,
+                                                                tcx,
+                                                                key,
+                                                                Self::compute_result)
+                        } else {
+                            tcx.dep_graph.with_task(dep_node,
+                                                    tcx,
+                                                    key,
+                                                    Self::compute_result)
+                        }
                     })
                 })?;
                 profq_msg!(tcx, ProfileQueriesMsg::ProviderEnd);
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index e7a1dd6b043b1..8abf7d3d09cd8 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -1563,9 +1563,7 @@ pub fn provide(providers: &mut Providers) {
 }
 
 pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Rc<AccessLevels> {
-    tcx.dep_graph.with_ignore(|| { // FIXME
-        tcx.privacy_access_levels(LOCAL_CRATE)
-    })
+    tcx.privacy_access_levels(LOCAL_CRATE)
 }
 
 fn privacy_access_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,