about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-02-24 20:48:24 +0000
committerbors <bors@rust-lang.org>2018-02-24 20:48:24 +0000
commit28a1e4ffefa2620ad9f4179ea339833448874fd3 (patch)
tree18a432b954cebc1cfdddc8f699e4be8e86bcac86
parent6070d3e47e5e9f15575a3bd33583358b52bc6eda (diff)
parent182f8820c4b53f811c140478a0105b2a7b77c5c3 (diff)
downloadrust-28a1e4ffefa2620ad9f4179ea339833448874fd3.tar.gz
rust-28a1e4ffefa2620ad9f4179ea339833448874fd3.zip
Auto merge of #48510 - Manishearth:rollup, r=Manishearth
Rollup of 15 pull requests

- Successful merges: #47987, #48056, #48061, #48084, #48143, #48185, #48206, #48208, #48232, #48246, #48258, #48317, #48353, #48356, #48402
- Failed merges:
-rw-r--r--src/librustc/dep_graph/dep_node.rs2
-rw-r--r--src/librustc/dep_graph/graph.rs148
-rw-r--r--src/librustc/dep_graph/prev.rs5
-rw-r--r--src/librustc/hir/map/mod.rs98
-rw-r--r--src/librustc/hir/mod.rs6
-rw-r--r--src/librustc/mir/mono.rs7
-rw-r--r--src/librustc/traits/error_reporting.rs15
-rw-r--r--src/librustc/ty/maps/mod.rs2
-rw-r--r--src/librustc/ty/maps/on_disk_cache.rs34
-rw-r--r--src/librustc/ty/maps/plumbing.rs10
-rw-r--r--src/librustc_data_structures/bitslice.rs3
-rw-r--r--src/librustc_data_structures/indexed_vec.rs6
-rw-r--r--src/librustc_driver/driver.rs10
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs6
-rw-r--r--src/librustc_mir/dataflow/move_paths/builder.rs9
-rw-r--r--src/librustc_mir/monomorphize/collector.rs12
-rw-r--r--src/librustc_mir/monomorphize/item.rs16
-rw-r--r--src/librustc_mir/monomorphize/partitioning.rs16
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs7
-rw-r--r--src/librustc_passes/ast_validation.rs135
-rw-r--r--src/librustc_passes/diagnostics.rs18
-rw-r--r--src/librustc_passes/lib.rs1
-rw-r--r--src/librustc_passes/static_recursion.rs280
-rw-r--r--src/librustc_save_analysis/span_utils.rs26
-rw-r--r--src/librustc_trans/base.rs5
-rw-r--r--src/librustc_trans/callee.rs2
-rw-r--r--src/librustc_trans/consts.rs43
-rw-r--r--src/librustc_trans/debuginfo/metadata.rs19
-rw-r--r--src/librustc_trans/debuginfo/mod.rs6
-rw-r--r--src/librustc_trans/debuginfo/namespace.rs11
-rw-r--r--src/librustc_trans/debuginfo/utils.rs4
-rw-r--r--src/librustc_trans/trans_item.rs42
-rw-r--r--src/libstd/lib.rs5
-rw-r--r--src/libstd/process.rs67
-rw-r--r--src/libstd/rt.rs2
-rw-r--r--src/libstd/termination.rs77
-rw-r--r--src/libsyntax/ext/build.rs10
-rw-r--r--src/libsyntax/feature_gate.rs70
-rw-r--r--src/libsyntax/parse/parser.rs2
-rw-r--r--src/libsyntax/test.rs191
-rw-r--r--src/libtest/lib.rs13
-rw-r--r--src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs12
-rw-r--r--src/test/compile-fail/coherence-inherited-assoc-ty-cycle-err.rs2
-rw-r--r--src/test/compile-fail/const-size_of-cycle.rs2
-rw-r--r--src/test/compile-fail/cycle-projection-based-on-where-clause.rs2
-rw-r--r--src/test/compile-fail/cycle-trait-default-type-trait.rs2
-rw-r--r--src/test/compile-fail/cycle-trait-supertrait-direct.rs2
-rw-r--r--src/test/compile-fail/impl-trait/where-allowed.rs4
-rw-r--r--src/test/compile-fail/infinite-vec-type-recursion.rs2
-rw-r--r--src/test/compile-fail/issue-12997-2.rs3
-rw-r--r--src/test/compile-fail/issue-17252.rs4
-rw-r--r--src/test/compile-fail/issue-20772.rs2
-rw-r--r--src/test/compile-fail/issue-20825.rs2
-rw-r--r--src/test/compile-fail/issue-21177.rs2
-rw-r--r--src/test/compile-fail/issue-22673.rs2
-rw-r--r--src/test/compile-fail/issue-26548.rs2
-rw-r--r--src/test/compile-fail/issue-34373.rs2
-rw-r--r--src/test/compile-fail/issue-44415.rs2
-rw-r--r--src/test/compile-fail/issue-48131.rs39
-rw-r--r--src/test/compile-fail/resolve-self-in-impl.rs10
-rw-r--r--src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs2
-rw-r--r--src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs2
-rw-r--r--src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs (renamed from src/test/run-pass/termination-trait-for-result-box-error_ok.rs)8
-rw-r--r--src/test/run-pass/impl-trait/lifetimes.rs11
-rw-r--r--src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs43
-rw-r--r--src/test/run-pass/rfc-2126-extern-absolute-paths/test.rs21
-rw-r--r--src/test/ui/cycle-trait-supertrait-indirect.rs2
-rw-r--r--src/test/ui/cycle-trait-supertrait-indirect.stderr2
-rw-r--r--src/test/ui/error-codes/E0657.rs6
-rw-r--r--src/test/ui/error-codes/E0657.stderr12
-rw-r--r--src/test/ui/impl-trait/auto-trait-leak.rs2
-rw-r--r--src/test/ui/impl-trait/auto-trait-leak.stderr2
-rw-r--r--src/test/ui/impl_trait_projections.rs50
-rw-r--r--src/test/ui/impl_trait_projections.stderr34
-rw-r--r--src/test/ui/issue-12511.rs2
-rw-r--r--src/test/ui/issue-12511.stderr2
-rw-r--r--src/test/ui/issue-23302-1.rs (renamed from src/test/ui/issue-23302.rs)13
-rw-r--r--src/test/ui/issue-23302-1.stderr15
-rw-r--r--src/test/ui/issue-23302-2.rs18
-rw-r--r--src/test/ui/issue-23302-2.stderr15
-rw-r--r--src/test/ui/issue-23302-3.rs (renamed from src/test/compile-fail/const-recursive.rs)10
-rw-r--r--src/test/ui/issue-23302-3.stderr20
-rw-r--r--src/test/ui/issue-23302.stderr26
-rw-r--r--src/test/ui/issue-36163.rs10
-rw-r--r--src/test/ui/issue-36163.stderr30
-rw-r--r--src/test/ui/issue-47706.rs15
-rw-r--r--src/test/ui/issue-47706.stderr21
-rw-r--r--src/test/ui/nested_impl_trait.rs (renamed from src/test/compile-fail/feature-gate-nested_impl_trait.rs)10
-rw-r--r--src/test/ui/nested_impl_trait.stderr50
-rw-r--r--src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr94
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr102
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr126
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr108
-rw-r--r--src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr228
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr28
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr126
-rw-r--r--src/test/ui/resolve/issue-23305.rs2
-rw-r--r--src/test/ui/resolve/issue-23305.stderr2
-rw-r--r--src/test/ui/unsafe-block-without-braces.rs (renamed from src/test/compile-fail/issue-17718-recursive.rs)12
-rw-r--r--src/test/ui/unsafe-block-without-braces.stderr10
100 files changed, 1607 insertions, 1224 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 4034055d041..aa678ba788a 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -625,7 +625,7 @@ define_dep_nodes!( <'tcx>
     [eval_always] CollectAndPartitionTranslationItems,
     [] ExportName(DefId),
     [] ContainsExternIndicator(DefId),
-    [] IsTranslatedFunction(DefId),
+    [] IsTranslatedItem(DefId),
     [] CodegenUnit(InternedString),
     [] CompileCodegenUnit(InternedString),
     [input] OutputFilenames,
diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs
index 55ec8adb5fb..b77431e806a 100644
--- a/src/librustc/dep_graph/graph.rs
+++ b/src/librustc/dep_graph/graph.rs
@@ -74,7 +74,7 @@ struct DepGraphData {
     /// nodes and edges as well as all fingerprints of nodes that have them.
     previous: PreviousDepGraph,
 
-    colors: RefCell<FxHashMap<DepNode, DepNodeColor>>,
+    colors: RefCell<DepNodeColorMap>,
 
     /// When we load, there may be `.o` files, cached mir, or other such
     /// things available to us. If we find that they are not dirty, we
@@ -97,8 +97,10 @@ impl DepGraph {
         // Pre-allocate the fingerprints array. We over-allocate a little so
         // that we hopefully don't have to re-allocate during this compilation
         // session.
+        let prev_graph_node_count = prev_graph.node_count();
+
         let fingerprints = IndexVec::from_elem_n(Fingerprint::ZERO,
-                                                 (prev_graph.node_count() * 115) / 100);
+                                                 (prev_graph_node_count * 115) / 100);
         DepGraph {
             data: Some(Rc::new(DepGraphData {
                 previous_work_products: RefCell::new(FxHashMap()),
@@ -106,7 +108,7 @@ impl DepGraph {
                 dep_node_debug: RefCell::new(FxHashMap()),
                 current: RefCell::new(CurrentDepGraph::new()),
                 previous: prev_graph,
-                colors: RefCell::new(FxHashMap()),
+                colors: RefCell::new(DepNodeColorMap::new(prev_graph_node_count)),
                 loaded_from_cache: RefCell::new(FxHashMap()),
             })),
             fingerprints: Rc::new(RefCell::new(fingerprints)),
@@ -213,8 +215,6 @@ impl DepGraph {
               R: HashStable<HCX>,
     {
         if let Some(ref data) = self.data {
-            debug_assert!(!data.colors.borrow().contains_key(&key));
-
             push(&data.current, key);
             if cfg!(debug_assertions) {
                 profq_msg(ProfileQueriesMsg::TaskBegin(key.clone()))
@@ -254,19 +254,21 @@ impl DepGraph {
             }
 
             // Determine the color of the new DepNode.
-            {
-                let prev_fingerprint = data.previous.fingerprint_of(&key);
+            if let Some(prev_index) = data.previous.node_to_index_opt(&key) {
+                let prev_fingerprint = data.previous.fingerprint_by_index(prev_index);
 
-                let color = if Some(current_fingerprint) == prev_fingerprint {
+                let color = if current_fingerprint == prev_fingerprint {
                     DepNodeColor::Green(dep_node_index)
                 } else {
                     DepNodeColor::Red
                 };
 
-                let old_value = data.colors.borrow_mut().insert(key, color);
-                debug_assert!(old_value.is_none(),
+                let mut colors = data.colors.borrow_mut();
+                debug_assert!(colors.get(prev_index).is_none(),
                               "DepGraph::with_task() - Duplicate DepNodeColor \
                                insertion for {:?}", key);
+
+                colors.insert(prev_index, color);
             }
 
             (result, dep_node_index)
@@ -281,9 +283,11 @@ impl DepGraph {
                 let mut fingerprints = self.fingerprints.borrow_mut();
                 let dep_node_index = DepNodeIndex::new(fingerprints.len());
                 fingerprints.push(fingerprint);
+
                 debug_assert!(fingerprints[dep_node_index] == fingerprint,
                               "DepGraph::with_task() - Assigned fingerprint to \
                                unexpected index for {:?}", key);
+
                 (result, dep_node_index)
             } else {
                 (task(cx, arg), DepNodeIndex::INVALID)
@@ -357,6 +361,15 @@ impl DepGraph {
     }
 
     #[inline]
+    pub fn dep_node_exists(&self, dep_node: &DepNode) -> bool {
+        if let Some(ref data) = self.data {
+            data.current.borrow_mut().node_to_node_index.contains_key(dep_node)
+        } else {
+            false
+        }
+    }
+
+    #[inline]
     pub fn fingerprint_of(&self, dep_node_index: DepNodeIndex) -> Fingerprint {
         match self.fingerprints.borrow().get(dep_node_index) {
             Some(&fingerprint) => fingerprint,
@@ -495,7 +508,17 @@ impl DepGraph {
     }
 
     pub fn node_color(&self, dep_node: &DepNode) -> Option<DepNodeColor> {
-        self.data.as_ref().and_then(|data| data.colors.borrow().get(dep_node).cloned())
+        if let Some(ref data) = self.data {
+            if let Some(prev_index) = data.previous.node_to_index_opt(dep_node) {
+                return data.colors.borrow().get(prev_index)
+            } else {
+                // This is a node that did not exist in the previous compilation
+                // session, so we consider it to be red.
+                return Some(DepNodeColor::Red)
+            }
+        }
+
+        None
     }
 
     pub fn try_mark_green<'tcx>(&self,
@@ -505,7 +528,6 @@ impl DepGraph {
         debug!("try_mark_green({:?}) - BEGIN", dep_node);
         let data = self.data.as_ref().unwrap();
 
-        debug_assert!(!data.colors.borrow().contains_key(dep_node));
         debug_assert!(!data.current.borrow().node_to_node_index.contains_key(dep_node));
 
         if dep_node.kind.is_input() {
@@ -535,19 +557,22 @@ impl DepGraph {
             }
         };
 
+        debug_assert!(data.colors.borrow().get(prev_dep_node_index).is_none());
+
         let mut current_deps = Vec::new();
 
         for &dep_dep_node_index in prev_deps {
-            let dep_dep_node = &data.previous.index_to_node(dep_dep_node_index);
+            let dep_dep_node_color = data.colors.borrow().get(dep_dep_node_index);
 
-            let dep_dep_node_color = data.colors.borrow().get(dep_dep_node).cloned();
             match dep_dep_node_color {
                 Some(DepNodeColor::Green(node_index)) => {
                     // This dependency has been marked as green before, we are
                     // still fine and can continue with checking the other
                     // dependencies.
                     debug!("try_mark_green({:?}) --- found dependency {:?} to \
-                            be immediately green", dep_node, dep_dep_node);
+                            be immediately green",
+                            dep_node,
+                            data.previous.index_to_node(dep_dep_node_index));
                     current_deps.push(node_index);
                 }
                 Some(DepNodeColor::Red) => {
@@ -556,10 +581,14 @@ impl DepGraph {
                     // mark the DepNode as green and also don't need to bother
                     // with checking any of the other dependencies.
                     debug!("try_mark_green({:?}) - END - dependency {:?} was \
-                            immediately red", dep_node, dep_dep_node);
+                            immediately red",
+                            dep_node,
+                            data.previous.index_to_node(dep_dep_node_index));
                     return None
                 }
                 None => {
+                    let dep_dep_node = &data.previous.index_to_node(dep_dep_node_index);
+
                     // We don't know the state of this dependency. If it isn't
                     // an input node, let's try to mark it green recursively.
                     if !dep_dep_node.kind.is_input() {
@@ -601,10 +630,8 @@ impl DepGraph {
                     debug!("try_mark_green({:?}) --- trying to force \
                             dependency {:?}", dep_node, dep_dep_node);
                     if ::ty::maps::force_from_dep_node(tcx, dep_dep_node) {
-                        let dep_dep_node_color = data.colors
-                                                     .borrow()
-                                                     .get(dep_dep_node)
-                                                     .cloned();
+                        let dep_dep_node_color = data.colors.borrow().get(dep_dep_node_index);
+
                         match dep_dep_node_color {
                             Some(DepNodeColor::Green(node_index)) => {
                                 debug!("try_mark_green({:?}) --- managed to \
@@ -681,26 +708,21 @@ impl DepGraph {
         }
 
         // ... and finally storing a "Green" entry in the color map.
-        let old_color = data.colors
-                            .borrow_mut()
-                            .insert(*dep_node, DepNodeColor::Green(dep_node_index));
-        debug_assert!(old_color.is_none(),
+        let mut colors = data.colors.borrow_mut();
+        debug_assert!(colors.get(prev_dep_node_index).is_none(),
                       "DepGraph::try_mark_green() - Duplicate DepNodeColor \
                       insertion for {:?}", dep_node);
 
+        colors.insert(prev_dep_node_index, DepNodeColor::Green(dep_node_index));
+
         debug!("try_mark_green({:?}) - END - successfully marked as green", dep_node);
         Some(dep_node_index)
     }
 
-    // Used in various assertions
-    pub fn is_green(&self, dep_node_index: DepNodeIndex) -> bool {
-        let dep_node = self.data.as_ref().unwrap().current.borrow().nodes[dep_node_index];
-        self.data.as_ref().unwrap().colors.borrow().get(&dep_node).map(|&color| {
-            match color {
-                DepNodeColor::Red => false,
-                DepNodeColor::Green(_) => true,
-            }
-        }).unwrap_or(false)
+    // Returns true if the given node has been marked as green during the
+    // current compilation session. Used in various assertions
+    pub fn is_green(&self, dep_node: &DepNode) -> bool {
+        self.node_color(dep_node).map(|c| c.is_green()).unwrap_or(false)
     }
 
     // This method loads all on-disk cacheable query results into memory, so
@@ -714,20 +736,25 @@ impl DepGraph {
     pub fn exec_cache_promotions<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) {
         let green_nodes: Vec<DepNode> = {
             let data = self.data.as_ref().unwrap();
-            data.colors.borrow().iter().filter_map(|(dep_node, color)| match color {
-                DepNodeColor::Green(_) => {
-                    if dep_node.cache_on_disk(tcx) {
-                        Some(*dep_node)
-                    } else {
+            let colors = data.colors.borrow();
+            colors.values.indices().filter_map(|prev_index| {
+                match colors.get(prev_index) {
+                    Some(DepNodeColor::Green(_)) => {
+                        let dep_node = data.previous.index_to_node(prev_index);
+                        if dep_node.cache_on_disk(tcx) {
+                            Some(dep_node)
+                        } else {
+                            None
+                        }
+                    }
+                    None |
+                    Some(DepNodeColor::Red) => {
+                        // We can skip red nodes because a node can only be marked
+                        // as red if the query result was recomputed and thus is
+                        // already in memory.
                         None
                     }
                 }
-                DepNodeColor::Red => {
-                    // We can skip red nodes because a node can only be marked
-                    // as red if the query result was recomputed and thus is
-                    // already in memory.
-                    None
-                }
             }).collect()
         };
 
@@ -1052,3 +1079,36 @@ enum OpenTask {
         node: DepNode,
     },
 }
+
+// A data structure that stores Option<DepNodeColor> values as a contiguous
+// array, using one u32 per entry.
+struct DepNodeColorMap {
+    values: IndexVec<SerializedDepNodeIndex, u32>,
+}
+
+const COMPRESSED_NONE: u32 = 0;
+const COMPRESSED_RED: u32 = 1;
+const COMPRESSED_FIRST_GREEN: u32 = 2;
+
+impl DepNodeColorMap {
+    fn new(size: usize) -> DepNodeColorMap {
+        DepNodeColorMap {
+            values: IndexVec::from_elem_n(COMPRESSED_NONE, size)
+        }
+    }
+
+    fn get(&self, index: SerializedDepNodeIndex) -> Option<DepNodeColor> {
+        match self.values[index] {
+            COMPRESSED_NONE => None,
+            COMPRESSED_RED => Some(DepNodeColor::Red),
+            value => Some(DepNodeColor::Green(DepNodeIndex(value - COMPRESSED_FIRST_GREEN)))
+        }
+    }
+
+    fn insert(&mut self, index: SerializedDepNodeIndex, color: DepNodeColor) {
+        self.values[index] = match color {
+            DepNodeColor::Red => COMPRESSED_RED,
+            DepNodeColor::Green(index) => index.0 + COMPRESSED_FIRST_GREEN,
+        }
+    }
+}
diff --git a/src/librustc/dep_graph/prev.rs b/src/librustc/dep_graph/prev.rs
index 50e1ee88a46..504b60e763e 100644
--- a/src/librustc/dep_graph/prev.rs
+++ b/src/librustc/dep_graph/prev.rs
@@ -50,6 +50,11 @@ impl PreviousDepGraph {
     }
 
     #[inline]
+    pub fn node_to_index_opt(&self, dep_node: &DepNode) -> Option<SerializedDepNodeIndex> {
+        self.index.get(dep_node).cloned()
+    }
+
+    #[inline]
     pub fn fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> {
         self.index
             .get(dep_node)
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index b6b3e895535..3799bdada88 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -22,6 +22,7 @@ use hir::def_id::{CRATE_DEF_INDEX, DefId, LocalDefId, DefIndexAddressSpace};
 use syntax::abi::Abi;
 use syntax::ast::{self, Name, NodeId, CRATE_NODE_ID};
 use syntax::codemap::Spanned;
+use syntax::ext::base::MacroKind;
 use syntax_pos::Span;
 
 use hir::*;
@@ -32,6 +33,7 @@ use util::nodemap::{DefIdMap, FxHashMap};
 use arena::TypedArena;
 use std::cell::RefCell;
 use std::io;
+use ty::TyCtxt;
 
 pub mod blocks;
 mod collector;
@@ -39,6 +41,7 @@ mod def_collector;
 pub mod definitions;
 mod hir_id_validator;
 
+
 pub const ITEM_LIKE_SPACE: DefIndexAddressSpace = DefIndexAddressSpace::Low;
 pub const REGULAR_SPACE: DefIndexAddressSpace = DefIndexAddressSpace::High;
 
@@ -373,6 +376,92 @@ impl<'hir> Map<'hir> {
         self.definitions.as_local_node_id(def_id.to_def_id()).unwrap()
     }
 
+    pub fn describe_def(&self, node_id: NodeId) -> Option<Def> {
+        let node = if let Some(node) = self.find(node_id) {
+            node
+        } else {
+            return None
+        };
+
+        match node {
+            NodeItem(item) => {
+                let def_id = || {
+                    self.local_def_id(item.id)
+                };
+
+                match item.node {
+                    ItemStatic(_, m, _) => Some(Def::Static(def_id(),
+                                                            m == MutMutable)),
+                    ItemConst(..) => Some(Def::Const(def_id())),
+                    ItemFn(..) => Some(Def::Fn(def_id())),
+                    ItemMod(..) => Some(Def::Mod(def_id())),
+                    ItemGlobalAsm(..) => Some(Def::GlobalAsm(def_id())),
+                    ItemTy(..) => Some(Def::TyAlias(def_id())),
+                    ItemEnum(..) => Some(Def::Enum(def_id())),
+                    ItemStruct(..) => Some(Def::Struct(def_id())),
+                    ItemUnion(..) => Some(Def::Union(def_id())),
+                    ItemTrait(..) => Some(Def::Trait(def_id())),
+                    ItemTraitAlias(..) => {
+                        bug!("trait aliases are not yet implemented (see issue #41517)")
+                    },
+                    ItemExternCrate(_) |
+                    ItemUse(..) |
+                    ItemForeignMod(..) |
+                    ItemImpl(..) => None,
+                }
+            }
+            NodeForeignItem(item) => {
+                let def_id = self.local_def_id(item.id);
+                match item.node {
+                    ForeignItemFn(..) => Some(Def::Fn(def_id)),
+                    ForeignItemStatic(_, m) => Some(Def::Static(def_id, m)),
+                    ForeignItemType => Some(Def::TyForeign(def_id)),
+                }
+            }
+            NodeTraitItem(item) => {
+                let def_id = self.local_def_id(item.id);
+                match item.node {
+                    TraitItemKind::Const(..) => Some(Def::AssociatedConst(def_id)),
+                    TraitItemKind::Method(..) => Some(Def::Method(def_id)),
+                    TraitItemKind::Type(..) => Some(Def::AssociatedTy(def_id)),
+                }
+            }
+            NodeImplItem(item) => {
+                let def_id = self.local_def_id(item.id);
+                match item.node {
+                    ImplItemKind::Const(..) => Some(Def::AssociatedConst(def_id)),
+                    ImplItemKind::Method(..) => Some(Def::Method(def_id)),
+                    ImplItemKind::Type(..) => Some(Def::AssociatedTy(def_id)),
+                }
+            }
+            NodeVariant(variant) => {
+                let def_id = self.local_def_id(variant.node.data.id());
+                Some(Def::Variant(def_id))
+            }
+            NodeField(_) |
+            NodeExpr(_) |
+            NodeStmt(_) |
+            NodeTy(_) |
+            NodeTraitRef(_) |
+            NodePat(_) |
+            NodeBinding(_) |
+            NodeStructCtor(_) |
+            NodeLifetime(_) |
+            NodeVisibility(_) |
+            NodeBlock(_) => None,
+            NodeLocal(local) => {
+                Some(Def::Local(local.id))
+            }
+            NodeMacroDef(macro_def) => {
+                Some(Def::Macro(self.local_def_id(macro_def.id),
+                                MacroKind::Bang))
+            }
+            NodeTyParam(param) => {
+                Some(Def::TyParam(self.local_def_id(param.id)))
+            }
+        }
+    }
+
     fn entry_count(&self) -> usize {
         self.map.len()
     }
@@ -1275,3 +1364,12 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
         }
     }
 }
+
+pub fn describe_def(tcx: TyCtxt, def_id: DefId) -> Option<Def> {
+    if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
+        tcx.hir.describe_def(node_id)
+    } else {
+        bug!("Calling local describe_def query provider for upstream DefId: {:?}",
+             def_id)
+    }
+}
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index bc03f7ead81..0fa1b95d8e7 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -43,6 +43,7 @@ use syntax::tokenstream::TokenStream;
 use syntax::util::ThinVec;
 use syntax::util::parser::ExprPrecedence;
 use ty::AdtKind;
+use ty::maps::Providers;
 
 use rustc_data_structures::indexed_vec;
 
@@ -2204,3 +2205,8 @@ pub type TraitMap = NodeMap<Vec<TraitCandidate>>;
 // Map from the NodeId of a glob import to a list of items which are actually
 // imported.
 pub type GlobMap = NodeMap<FxHashSet<Name>>;
+
+
+pub fn provide(providers: &mut Providers) {
+    providers.describe_def = map::describe_def;
+}
diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs
index 49e5c0dc21f..7f8f2e9b906 100644
--- a/src/librustc/mir/mono.rs
+++ b/src/librustc/mir/mono.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use hir::def_id::DefId;
 use syntax::ast::NodeId;
 use syntax::symbol::InternedString;
 use ty::{Instance, TyCtxt};
@@ -21,7 +22,7 @@ use std::hash::Hash;
 #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
 pub enum MonoItem<'tcx> {
     Fn(Instance<'tcx>),
-    Static(NodeId),
+    Static(DefId),
     GlobalAsm(NodeId),
 }
 
@@ -50,7 +51,9 @@ impl<'tcx> HashStable<StableHashingContext<'tcx>> for MonoItem<'tcx> {
             MonoItem::Fn(ref instance) => {
                 instance.hash_stable(hcx, hasher);
             }
-            MonoItem::Static(node_id)    |
+            MonoItem::Static(def_id) => {
+                def_id.hash_stable(hcx, hasher);
+            }
             MonoItem::GlobalAsm(node_id) => {
                 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
                     node_id.hash_stable(hcx, hasher);
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 12d8d6f3d74..118d4ddd445 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -756,7 +756,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                         }).collect(),
                     ref sty => vec![ArgKind::Arg("_".to_owned(), format!("{}", sty))],
                 };
-                if found.len()== expected.len() {
+                if found.len() == expected.len() {
                     self.report_closure_arg_mismatch(span,
                                                      found_span,
                                                      found_trait_ref,
@@ -874,6 +874,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                     _ => ArgKind::Arg("_".to_owned(), "_".to_owned())
                 }).collect::<Vec<ArgKind>>())
             }
+            hir::map::NodeVariant(&hir::Variant {
+                span,
+                node: hir::Variant_ {
+                    data: hir::VariantData::Tuple(ref fields, _),
+                    ..
+                },
+                ..
+            }) => {
+                (self.tcx.sess.codemap().def_span(span),
+                 fields.iter().map(|field| {
+                     ArgKind::Arg(format!("{}", field.name), "_".to_string())
+                 }).collect::<Vec<_>>())
+            }
             _ => panic!("non-FnLike node found: {:?}", node),
         }
     }
diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs
index 21ffe6b895e..be1d255afa1 100644
--- a/src/librustc/ty/maps/mod.rs
+++ b/src/librustc/ty/maps/mod.rs
@@ -349,7 +349,7 @@ define_maps! { <'tcx>
     [] fn export_name: ExportName(DefId) -> Option<Symbol>,
     [] fn contains_extern_indicator: ContainsExternIndicator(DefId) -> bool,
     [] fn symbol_export_level: GetSymbolExportLevel(DefId) -> SymbolExportLevel,
-    [] fn is_translated_function: IsTranslatedFunction(DefId) -> bool,
+    [] fn is_translated_item: IsTranslatedItem(DefId) -> bool,
     [] fn codegen_unit: CodegenUnit(InternedString) -> Arc<CodegenUnit<'tcx>>,
     [] fn compile_codegen_unit: CompileCodegenUnit(InternedString) -> Stats,
     [] fn output_filenames: output_filenames_node(CrateNum)
diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs
index 56ed0f9106f..17b44f6959f 100644
--- a/src/librustc/ty/maps/on_disk_cache.rs
+++ b/src/librustc/ty/maps/on_disk_cache.rs
@@ -347,22 +347,21 @@ impl<'sess> OnDiskCache<'sess> {
             return None
         };
 
-        let mut cnum_map = self.cnum_map.borrow_mut();
-        if cnum_map.is_none() {
+        // Initialize the cnum_map if it is not initialized yet.
+        if self.cnum_map.borrow().is_none() {
+            let mut cnum_map = self.cnum_map.borrow_mut();
             *cnum_map = Some(Self::compute_cnum_map(tcx, &self.prev_cnums[..]));
         }
-
-        let mut synthetic_expansion_infos = self.synthetic_expansion_infos.borrow_mut();
-        let mut file_index_to_file = self.file_index_to_file.borrow_mut();
+        let cnum_map = self.cnum_map.borrow();
 
         let mut decoder = CacheDecoder {
             tcx,
             opaque: opaque::Decoder::new(&self.serialized_data[..], pos.to_usize()),
             codemap: self.codemap,
             cnum_map: cnum_map.as_ref().unwrap(),
-            file_index_to_file: &mut file_index_to_file,
+            file_index_to_file: &self.file_index_to_file,
             file_index_to_stable_id: &self.file_index_to_stable_id,
-            synthetic_expansion_infos: &mut synthetic_expansion_infos,
+            synthetic_expansion_infos: &self.synthetic_expansion_infos,
         };
 
         match decode_tagged(&mut decoder, dep_node_index) {
@@ -421,21 +420,21 @@ struct CacheDecoder<'a, 'tcx: 'a, 'x> {
     opaque: opaque::Decoder<'x>,
     codemap: &'x CodeMap,
     cnum_map: &'x IndexVec<CrateNum, Option<CrateNum>>,
-    synthetic_expansion_infos: &'x mut FxHashMap<AbsoluteBytePos, SyntaxContext>,
-    file_index_to_file: &'x mut FxHashMap<FileMapIndex, Rc<FileMap>>,
+    synthetic_expansion_infos: &'x RefCell<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
+    file_index_to_file: &'x RefCell<FxHashMap<FileMapIndex, Rc<FileMap>>>,
     file_index_to_stable_id: &'x FxHashMap<FileMapIndex, StableFilemapId>,
 }
 
 impl<'a, 'tcx, 'x> CacheDecoder<'a, 'tcx, 'x> {
-    fn file_index_to_file(&mut self, index: FileMapIndex) -> Rc<FileMap> {
+    fn file_index_to_file(&self, index: FileMapIndex) -> Rc<FileMap> {
         let CacheDecoder {
-            ref mut file_index_to_file,
+            ref file_index_to_file,
             ref file_index_to_stable_id,
             ref codemap,
             ..
         } = *self;
 
-        file_index_to_file.entry(index).or_insert_with(|| {
+        file_index_to_file.borrow_mut().entry(index).or_insert_with(|| {
             let stable_id = file_index_to_stable_id[&index];
             codemap.filemap_by_stable_id(stable_id)
                    .expect("Failed to lookup FileMap in new context.")
@@ -572,19 +571,24 @@ impl<'a, 'tcx, 'x> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx, 'x> {
                 let pos = AbsoluteBytePos::new(self.opaque.position());
                 let expn_info: ExpnInfo = Decodable::decode(self)?;
                 let ctxt = SyntaxContext::allocate_directly(expn_info);
-                self.synthetic_expansion_infos.insert(pos, ctxt);
+                self.synthetic_expansion_infos.borrow_mut().insert(pos, ctxt);
                 ctxt
             }
             TAG_EXPANSION_INFO_SHORTHAND => {
                 let pos = AbsoluteBytePos::decode(self)?;
-                if let Some(ctxt) = self.synthetic_expansion_infos.get(&pos).cloned() {
+                let cached_ctxt = self.synthetic_expansion_infos
+                                      .borrow()
+                                      .get(&pos)
+                                      .cloned();
+
+                if let Some(ctxt) = cached_ctxt {
                     ctxt
                 } else {
                     let expn_info = self.with_position(pos.to_usize(), |this| {
                          ExpnInfo::decode(this)
                     })?;
                     let ctxt = SyntaxContext::allocate_directly(expn_info);
-                    self.synthetic_expansion_infos.insert(pos, ctxt);
+                    self.synthetic_expansion_infos.borrow_mut().insert(pos, ctxt);
                     ctxt
                 }
             }
diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs
index f02c7cbd0ea..b654b6bc42a 100644
--- a/src/librustc/ty/maps/plumbing.rs
+++ b/src/librustc/ty/maps/plumbing.rs
@@ -84,7 +84,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             let span = self.sess.codemap().def_span(span);
             let mut err =
                 struct_span_err!(self.sess, span, E0391,
-                                 "unsupported cyclic reference between types/traits detected");
+                                 "cyclic dependency detected");
             err.span_label(span, "cyclic reference");
 
             err.span_note(self.sess.codemap().def_span(stack[0].0),
@@ -147,7 +147,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 }
                 match self.dep_graph.try_mark_green(self.global_tcx(), &dep_node) {
                     Some(dep_node_index) => {
-                        debug_assert!(self.dep_graph.is_green(dep_node_index));
+                        debug_assert!(self.dep_graph.is_green(&dep_node));
                         self.dep_graph.read_index(dep_node_index);
                         Some(dep_node_index)
                     }
@@ -403,7 +403,7 @@ macro_rules! define_maps {
                                                   dep_node: &DepNode)
                                                   -> Result<$V, CycleError<'a, $tcx>>
             {
-                debug_assert!(tcx.dep_graph.is_green(dep_node_index));
+                debug_assert!(tcx.dep_graph.is_green(dep_node));
 
                 // First we try to load the result from the on-disk cache
                 let result = if Self::cache_on_disk(key) &&
@@ -491,7 +491,7 @@ macro_rules! define_maps {
                      span: Span,
                      dep_node: DepNode)
                      -> Result<($V, DepNodeIndex), CycleError<'a, $tcx>> {
-                debug_assert!(tcx.dep_graph.node_color(&dep_node).is_none());
+                debug_assert!(!tcx.dep_graph.dep_node_exists(&dep_node));
 
                 profq_msg!(tcx, ProfileQueriesMsg::ProviderBegin);
                 let res = tcx.cycle_check(span, Query::$name(key), || {
@@ -929,7 +929,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
         DepKind::ContainsExternIndicator => {
             force!(contains_extern_indicator, def_id!());
         }
-        DepKind::IsTranslatedFunction => { force!(is_translated_function, def_id!()); }
+        DepKind::IsTranslatedItem => { force!(is_translated_item, def_id!()); }
         DepKind::OutputFilenames => { force!(output_filenames, LOCAL_CRATE); }
 
         DepKind::TargetFeaturesWhitelist => { force!(target_features_whitelist, LOCAL_CRATE); }
diff --git a/src/librustc_data_structures/bitslice.rs b/src/librustc_data_structures/bitslice.rs
index 7665bfd5b11..2678861be06 100644
--- a/src/librustc_data_structures/bitslice.rs
+++ b/src/librustc_data_structures/bitslice.rs
@@ -24,6 +24,7 @@ pub trait BitSlice {
 
 impl BitSlice for [Word] {
     /// Clears bit at `idx` to 0; returns true iff this changed `self.`
+    #[inline]
     fn clear_bit(&mut self, idx: usize) -> bool {
         let words = self;
         debug!("clear_bit: words={} idx={}",
@@ -37,6 +38,7 @@ impl BitSlice for [Word] {
     }
 
     /// Sets bit at `idx` to 1; returns true iff this changed `self.`
+    #[inline]
     fn set_bit(&mut self, idx: usize) -> bool {
         let words = self;
         debug!("set_bit: words={} idx={}",
@@ -50,6 +52,7 @@ impl BitSlice for [Word] {
     }
 
     /// Extracts value of bit at `idx` in `self`.
+    #[inline]
     fn get_bit(&self, idx: usize) -> bool {
         let words = self;
         let BitLookup { word, bit_mask, .. } = bit_lookup(idx);
diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs
index 3e94b3f4d30..11c2bd73687 100644
--- a/src/librustc_data_structures/indexed_vec.rs
+++ b/src/librustc_data_structures/indexed_vec.rs
@@ -29,12 +29,16 @@ pub trait Idx: Copy + 'static + Eq + Debug {
 }
 
 impl Idx for usize {
+    #[inline]
     fn new(idx: usize) -> Self { idx }
+    #[inline]
     fn index(self) -> usize { self }
 }
 
 impl Idx for u32 {
+    #[inline]
     fn new(idx: usize) -> Self { assert!(idx <= u32::MAX as usize); idx as u32 }
+    #[inline]
     fn index(self) -> usize { self as usize }
 }
 
@@ -73,11 +77,13 @@ macro_rules! newtype_index {
         pub struct $type($($pub)* u32);
 
         impl Idx for $type {
+            #[inline]
             fn new(value: usize) -> Self {
                 assert!(value < ($max) as usize);
                 $type(value as u32)
             }
 
+            #[inline]
             fn index(self) -> usize {
                 self.0 as usize
             }
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index eb67c9ce4b7..b03108ed807 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -36,7 +36,7 @@ use rustc_typeck as typeck;
 use rustc_privacy;
 use rustc_plugin::registry::Registry;
 use rustc_plugin as plugin;
-use rustc_passes::{self, ast_validation, loops, consts, static_recursion, hir_stats};
+use rustc_passes::{self, ast_validation, loops, consts, hir_stats};
 use rustc_const_eval::{self, check_match};
 use super::Compilation;
 
@@ -818,7 +818,8 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
                                          &mut resolver,
                                          sess.opts.test,
                                          krate,
-                                         sess.diagnostic())
+                                         sess.diagnostic(),
+                                         &sess.features.borrow())
     });
 
     // If we're actually rustdoc then there's no need to actually compile
@@ -931,6 +932,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
 }
 
 pub fn default_provide(providers: &mut ty::maps::Providers) {
+    hir::provide(providers);
     borrowck::provide(providers);
     mir::provide(providers);
     reachable::provide(providers);
@@ -990,10 +992,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(trans: &TransCrate,
          "loop checking",
          || loops::check_crate(sess, &hir_map));
 
-    time(time_passes,
-              "static item recursion checking",
-              || static_recursion::check_crate(sess, &hir_map))?;
-
     let mut local_providers = ty::maps::Providers::default();
     default_provide(&mut local_providers);
     trans.provide(&mut local_providers);
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 7ca8d0bdd50..d57b8e78f18 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -1585,6 +1585,12 @@ impl MirPass for TypeckMir {
         let id = tcx.hir.as_local_node_id(def_id).unwrap();
         debug!("run_pass: {:?}", def_id);
 
+        // When NLL is enabled, the borrow checker runs the typeck
+        // itself, so we don't need this MIR pass anymore.
+        if tcx.sess.nll() {
+            return;
+        }
+
         if tcx.sess.err_count() > 0 {
             // compiling a broken program can obviously result in a
             // broken MIR, so try not to report duplicate errors.
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index 635d99e7737..d6f419f6cfb 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -353,9 +353,12 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
                 self.gather_move(&Place::Local(RETURN_PLACE));
             }
 
-            TerminatorKind::Assert { .. } |
-            TerminatorKind::SwitchInt { .. } => {
-                // branching terminators - these don't move anything
+            TerminatorKind::Assert { ref cond, .. } => {
+                self.gather_operand(cond);
+            }
+
+            TerminatorKind::SwitchInt { ref discr, .. } => {
+                self.gather_operand(discr);
             }
 
             TerminatorKind::Yield { ref value, .. } => {
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index a80dfaef0da..eb4ba21489c 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -368,8 +368,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let recursion_depth_reset;
 
     match starting_point {
-        MonoItem::Static(node_id) => {
-            let def_id = tcx.hir.local_def_id(node_id);
+        MonoItem::Static(def_id) => {
             let instance = Instance::mono(tcx, def_id);
 
             // Sanity check whether this ended up being collected accidentally
@@ -652,8 +651,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
         let tcx = self.tcx;
         let instance = Instance::mono(tcx, static_.def_id);
         if should_monomorphize_locally(tcx, &instance) {
-            let node_id = tcx.hir.as_local_node_id(static_.def_id).unwrap();
-            self.output.push(MonoItem::Static(node_id));
+            self.output.push(MonoItem::Static(static_.def_id));
         }
 
         self.super_static(static_, context, location);
@@ -946,10 +944,10 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
                 self.output.push(MonoItem::GlobalAsm(item.id));
             }
             hir::ItemStatic(..) => {
+                let def_id = self.tcx.hir.local_def_id(item.id);
                 debug!("RootCollector: ItemStatic({})",
-                       def_id_to_string(self.tcx,
-                                        self.tcx.hir.local_def_id(item.id)));
-                self.output.push(MonoItem::Static(item.id));
+                       def_id_to_string(self.tcx, def_id));
+                self.output.push(MonoItem::Static(def_id));
             }
             hir::ItemConst(..) => {
                 // const items only generate mono items if they are
diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs
index a5078187a57..549919a2c89 100644
--- a/src/librustc_mir/monomorphize/item.rs
+++ b/src/librustc_mir/monomorphize/item.rs
@@ -97,8 +97,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
     fn symbol_name(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::SymbolName {
         match *self.as_mono_item() {
             MonoItem::Fn(instance) => tcx.symbol_name(instance),
-            MonoItem::Static(node_id) => {
-                let def_id = tcx.hir.local_def_id(node_id);
+            MonoItem::Static(def_id) => {
                 tcx.symbol_name(Instance::mono(tcx, def_id))
             }
             MonoItem::GlobalAsm(node_id) => {
@@ -159,7 +158,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
     fn explicit_linkage(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<Linkage> {
         let def_id = match *self.as_mono_item() {
             MonoItem::Fn(ref instance) => instance.def_id(),
-            MonoItem::Static(node_id) => tcx.hir.local_def_id(node_id),
+            MonoItem::Static(def_id) => def_id,
             MonoItem::GlobalAsm(..) => return None,
         };
 
@@ -209,7 +208,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
         debug!("is_instantiable({:?})", self);
         let (def_id, substs) = match *self.as_mono_item() {
             MonoItem::Fn(ref instance) => (instance.def_id(), instance.substs),
-            MonoItem::Static(node_id) => (tcx.hir.local_def_id(node_id), Substs::empty()),
+            MonoItem::Static(def_id) => (def_id, Substs::empty()),
             // global asm never has predicates
             MonoItem::GlobalAsm(..) => return true
         };
@@ -218,14 +217,11 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
     }
 
     fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String {
-        let hir_map = &tcx.hir;
-
         return match *self.as_mono_item() {
             MonoItem::Fn(instance) => {
                 to_string_internal(tcx, "fn ", instance)
             },
-            MonoItem::Static(node_id) => {
-                let def_id = hir_map.local_def_id(node_id);
+            MonoItem::Static(def_id) => {
                 let instance = Instance::new(def_id, tcx.intern_substs(&[]));
                 to_string_internal(tcx, "static ", instance)
             },
@@ -251,7 +247,9 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
             MonoItem::Fn(Instance { def, .. }) => {
                 tcx.hir.as_local_node_id(def.def_id())
             }
-            MonoItem::Static(node_id) |
+            MonoItem::Static(def_id) => {
+                tcx.hir.as_local_node_id(def_id)
+            }
             MonoItem::GlobalAsm(node_id) => {
                 Some(node_id)
             }
diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index e9471cdb4f9..2b558e71483 100644
--- a/src/librustc_mir/monomorphize/partitioning.rs
+++ b/src/librustc_mir/monomorphize/partitioning.rs
@@ -180,7 +180,9 @@ pub trait CodegenUnitExt<'tcx> {
                         }
                     }
                 }
-                MonoItem::Static(node_id) |
+                MonoItem::Static(def_id) => {
+                    tcx.hir.as_local_node_id(def_id)
+                }
                 MonoItem::GlobalAsm(node_id) => {
                     Some(node_id)
                 }
@@ -382,7 +384,15 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                         };
                         (Linkage::External, visibility)
                     }
-                    MonoItem::Static(node_id) |
+                    MonoItem::Static(def_id) => {
+                        let visibility = if tcx.is_exported_symbol(def_id) {
+                            can_be_internalized = false;
+                            default_visibility(def_id)
+                        } else {
+                            Visibility::Hidden
+                        };
+                        (Linkage::External, visibility)
+                    }
                     MonoItem::GlobalAsm(node_id) => {
                         let def_id = tcx.hir.local_def_id(node_id);
                         let visibility = if tcx.is_exported_symbol(def_id) {
@@ -643,7 +653,7 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
             Some(def_id)
         }
-        MonoItem::Static(node_id) |
+        MonoItem::Static(def_id) => Some(def_id),
         MonoItem::GlobalAsm(node_id) => Some(tcx.hir.local_def_id(node_id)),
     }
 }
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index bbc7803b84d..3524255e037 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -386,10 +386,13 @@ fn is_enclosed(tcx: TyCtxt,
         if used_unsafe.contains(&parent_id) {
             Some(("block".to_string(), parent_id))
         } else if let Some(hir::map::NodeItem(&hir::Item {
-            node: hir::ItemFn(_, hir::Unsafety::Unsafe, _, _, _, _),
+            node: hir::ItemFn(_, fn_unsafety, _, _, _, _),
             ..
         })) = tcx.hir.find(parent_id) {
-            Some(("fn".to_string(), parent_id))
+            match fn_unsafety {
+                hir::Unsafety::Unsafe => Some(("fn".to_string(), parent_id)),
+                hir::Unsafety::Normal => None,
+            }
         } else {
             is_enclosed(tcx, used_unsafe, parent_id)
         }
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index bb6dbe632e3..a5dd8f1558e 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -419,6 +419,141 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
     }
 }
 
+// Bans nested `impl Trait`, e.g. `impl Into<impl Debug>`.
+// Nested `impl Trait` _is_ allowed in associated type position,
+// e.g `impl Iterator<Item=impl Debug>`
+struct NestedImplTraitVisitor<'a> {
+    session: &'a Session,
+    outer_impl_trait: Option<Span>,
+}
+
+impl<'a> NestedImplTraitVisitor<'a> {
+    fn with_impl_trait<F>(&mut self, outer_impl_trait: Option<Span>, f: F)
+        where F: FnOnce(&mut NestedImplTraitVisitor<'a>)
+    {
+        let old_outer_impl_trait = self.outer_impl_trait;
+        self.outer_impl_trait = outer_impl_trait;
+        f(self);
+        self.outer_impl_trait = old_outer_impl_trait;
+    }
+}
+
+
+impl<'a> Visitor<'a> for NestedImplTraitVisitor<'a> {
+    fn visit_ty(&mut self, t: &'a Ty) {
+        if let TyKind::ImplTrait(_) = t.node {
+            if let Some(outer_impl_trait) = self.outer_impl_trait {
+                struct_span_err!(self.session, t.span, E0666,
+                                 "nested `impl Trait` is not allowed")
+                    .span_label(outer_impl_trait, "outer `impl Trait`")
+                    .span_label(t.span, "nested `impl Trait` here")
+                    .emit();
+
+            }
+            self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t));
+        } else {
+            visit::walk_ty(self, t);
+        }
+    }
+    fn visit_path_parameters(&mut self, _: Span, path_parameters: &'a PathParameters) {
+        match *path_parameters {
+            PathParameters::AngleBracketed(ref params) => {
+                for type_ in &params.types {
+                    self.visit_ty(type_);
+                }
+                for type_binding in &params.bindings {
+                    // Type bindings such as `Item=impl Debug` in `Iterator<Item=Debug>`
+                    // are allowed to contain nested `impl Trait`.
+                    self.with_impl_trait(None, |this| visit::walk_ty(this, &type_binding.ty));
+                }
+            }
+            PathParameters::Parenthesized(ref params) => {
+                for type_ in &params.inputs {
+                    self.visit_ty(type_);
+                }
+                if let Some(ref type_) = params.output {
+                    // `-> Foo` syntax is essentially an associated type binding,
+                    // so it is also allowed to contain nested `impl Trait`.
+                    self.with_impl_trait(None, |this| visit::walk_ty(this, type_));
+                }
+            }
+        }
+    }
+}
+
+// Bans `impl Trait` in path projections like `<impl Iterator>::Item` or `Foo::Bar<impl Trait>`.
+struct ImplTraitProjectionVisitor<'a> {
+    session: &'a Session,
+    is_banned: bool,
+}
+
+impl<'a> ImplTraitProjectionVisitor<'a> {
+    fn with_ban<F>(&mut self, f: F)
+        where F: FnOnce(&mut ImplTraitProjectionVisitor<'a>)
+    {
+        let old_is_banned = self.is_banned;
+        self.is_banned = true;
+        f(self);
+        self.is_banned = old_is_banned;
+    }
+}
+
+impl<'a> Visitor<'a> for ImplTraitProjectionVisitor<'a> {
+    fn visit_ty(&mut self, t: &'a Ty) {
+        match t.node {
+            TyKind::ImplTrait(_) => {
+                if self.is_banned {
+                    struct_span_err!(self.session, t.span, E0667,
+                                 "`impl Trait` is not allowed in path parameters")
+                        .emit();
+                }
+            }
+            TyKind::Path(ref qself, ref path) => {
+                // We allow these:
+                //  - `Option<impl Trait>`
+                //  - `option::Option<impl Trait>`
+                //  - `option::Option<T>::Foo<impl Trait>
+                //
+                // But not these:
+                //  - `<impl Trait>::Foo`
+                //  - `option::Option<impl Trait>::Foo`.
+                //
+                // To implement this, we disallow `impl Trait` from `qself`
+                // (for cases like `<impl Trait>::Foo>`)
+                // but we allow `impl Trait` in `PathParameters`
+                // iff there are no more PathSegments.
+                if let Some(ref qself) = *qself {
+                    // `impl Trait` in `qself` is always illegal
+                    self.with_ban(|this| this.visit_ty(&qself.ty));
+                }
+
+                for (i, segment) in path.segments.iter().enumerate() {
+                    // Allow `impl Trait` iff we're on the final path segment
+                    if i == (path.segments.len() - 1) {
+                        visit::walk_path_segment(self, path.span, segment);
+                    } else {
+                        self.with_ban(|this|
+                            visit::walk_path_segment(this, path.span, segment));
+                    }
+                }
+            }
+            _ => visit::walk_ty(self, t),
+        }
+    }
+}
+
 pub fn check_crate(session: &Session, krate: &Crate) {
+    visit::walk_crate(
+        &mut NestedImplTraitVisitor {
+            session,
+            outer_impl_trait: None,
+        }, krate);
+
+    visit::walk_crate(
+        &mut ImplTraitProjectionVisitor {
+            session,
+            is_banned: false,
+        }, krate);
+
     visit::walk_crate(&mut AstValidator { session: session }, krate)
 }
diff --git a/src/librustc_passes/diagnostics.rs b/src/librustc_passes/diagnostics.rs
index 743f7b7326e..184fab778c6 100644
--- a/src/librustc_passes/diagnostics.rs
+++ b/src/librustc_passes/diagnostics.rs
@@ -128,22 +128,6 @@ impl !Enterprise for Foo { }
 Please note that negative impls are only allowed for auto traits.
 "##,
 
-E0265: r##"
-This error indicates that a static or constant references itself.
-All statics and constants need to resolve to a value in an acyclic manner.
-
-For example, neither of the following can be sensibly compiled:
-
-```compile_fail,E0265
-const X: u32 = X;
-```
-
-```compile_fail,E0265
-const X: u32 = Y;
-const Y: u32 = X;
-```
-"##,
-
 E0267: r##"
 This error indicates the use of a loop keyword (`break` or `continue`) inside a
 closure but outside of any loop. Erroneous code example:
@@ -320,4 +304,6 @@ register_diagnostics! {
     E0567, // auto traits can not have generic parameters
     E0568, // auto traits can not have super traits
     E0642, // patterns aren't allowed in methods without bodies
+    E0666, // nested `impl Trait` is illegal
+    E0667, // `impl Trait` in projections
 }
diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs
index 7db1f5665fb..6b9f407cbdb 100644
--- a/src/librustc_passes/lib.rs
+++ b/src/librustc_passes/lib.rs
@@ -42,7 +42,6 @@ pub mod consts;
 pub mod hir_stats;
 pub mod loops;
 mod mir_stats;
-pub mod static_recursion;
 
 __build_diagnostic_array! { librustc_passes, DIAGNOSTICS }
 
diff --git a/src/librustc_passes/static_recursion.rs b/src/librustc_passes/static_recursion.rs
deleted file mode 100644
index 987243b5234..00000000000
--- a/src/librustc_passes/static_recursion.rs
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This compiler pass detects constants that refer to themselves
-// recursively.
-
-use rustc::hir::map as hir_map;
-use rustc::session::Session;
-use rustc::hir::def::{Def, CtorKind};
-use rustc::util::common::ErrorReported;
-use rustc::util::nodemap::{NodeMap, NodeSet};
-
-use syntax::ast;
-use syntax_pos::Span;
-use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
-use rustc::hir;
-
-struct CheckCrateVisitor<'a, 'hir: 'a> {
-    sess: &'a Session,
-    hir_map: &'a hir_map::Map<'hir>,
-    // `discriminant_map` is a cache that associates the `NodeId`s of local
-    // variant definitions with the discriminant expression that applies to
-    // each one. If the variant uses the default values (starting from `0`),
-    // then `None` is stored.
-    discriminant_map: NodeMap<Option<hir::BodyId>>,
-    detected_recursive_ids: NodeSet,
-}
-
-impl<'a, 'hir: 'a> Visitor<'hir> for CheckCrateVisitor<'a, 'hir> {
-    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> {
-        NestedVisitorMap::None
-    }
-
-    fn visit_item(&mut self, it: &'hir hir::Item) {
-        match it.node {
-            hir::ItemStatic(..) |
-            hir::ItemConst(..) => {
-                let mut recursion_visitor = CheckItemRecursionVisitor::new(self);
-                recursion_visitor.visit_item(it);
-            }
-            hir::ItemEnum(ref enum_def, ref generics) => {
-                // We could process the whole enum, but handling the variants
-                // with discriminant expressions one by one gives more specific,
-                // less redundant output.
-                for variant in &enum_def.variants {
-                    if let Some(_) = variant.node.disr_expr {
-                        let mut recursion_visitor = CheckItemRecursionVisitor::new(self);
-                        recursion_visitor.populate_enum_discriminants(enum_def);
-                        recursion_visitor.visit_variant(variant, generics, it.id);
-                    }
-                }
-            }
-            _ => {}
-        }
-        intravisit::walk_item(self, it)
-    }
-
-    fn visit_trait_item(&mut self, ti: &'hir hir::TraitItem) {
-        match ti.node {
-            hir::TraitItemKind::Const(_, ref default) => {
-                if let Some(_) = *default {
-                    let mut recursion_visitor = CheckItemRecursionVisitor::new(self);
-                    recursion_visitor.visit_trait_item(ti);
-                }
-            }
-            _ => {}
-        }
-        intravisit::walk_trait_item(self, ti)
-    }
-
-    fn visit_impl_item(&mut self, ii: &'hir hir::ImplItem) {
-        match ii.node {
-            hir::ImplItemKind::Const(..) => {
-                let mut recursion_visitor = CheckItemRecursionVisitor::new(self);
-                recursion_visitor.visit_impl_item(ii);
-            }
-            _ => {}
-        }
-        intravisit::walk_impl_item(self, ii)
-    }
-}
-
-pub fn check_crate<'hir>(sess: &Session, hir_map: &hir_map::Map<'hir>)
-                         -> Result<(), ErrorReported>
-{
-    let mut visitor = CheckCrateVisitor {
-        sess,
-        hir_map,
-        discriminant_map: NodeMap(),
-        detected_recursive_ids: NodeSet(),
-    };
-    sess.track_errors(|| {
-        // FIXME(#37712) could use ItemLikeVisitor if trait items were item-like
-        hir_map.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
-    })
-}
-
-struct CheckItemRecursionVisitor<'a, 'b: 'a, 'hir: 'b> {
-    sess: &'b Session,
-    hir_map: &'b hir_map::Map<'hir>,
-    discriminant_map: &'a mut NodeMap<Option<hir::BodyId>>,
-    idstack: Vec<ast::NodeId>,
-    detected_recursive_ids: &'a mut NodeSet,
-}
-
-impl<'a, 'b: 'a, 'hir: 'b> CheckItemRecursionVisitor<'a, 'b, 'hir> {
-    fn new(v: &'a mut CheckCrateVisitor<'b, 'hir>) -> Self {
-        CheckItemRecursionVisitor {
-            sess: v.sess,
-            hir_map: v.hir_map,
-            discriminant_map: &mut v.discriminant_map,
-            idstack: Vec::new(),
-            detected_recursive_ids: &mut v.detected_recursive_ids,
-        }
-    }
-    fn with_item_id_pushed<F>(&mut self, id: ast::NodeId, f: F, span: Span)
-        where F: Fn(&mut Self)
-    {
-        if self.idstack.iter().any(|&x| x == id) {
-            if self.detected_recursive_ids.contains(&id) {
-                return;
-            }
-            self.detected_recursive_ids.insert(id);
-            let any_static = self.idstack.iter().any(|&x| {
-                if let hir_map::NodeItem(item) = self.hir_map.get(x) {
-                    if let hir::ItemStatic(..) = item.node {
-                        true
-                    } else {
-                        false
-                    }
-                } else {
-                    false
-                }
-            });
-            if !any_static {
-                struct_span_err!(self.sess, span, E0265, "recursive constant")
-                    .span_label(span, "recursion not allowed in constant")
-                    .emit();
-            }
-            return;
-        }
-        self.idstack.push(id);
-        f(self);
-        self.idstack.pop();
-    }
-    // If a variant has an expression specifying its discriminant, then it needs
-    // to be checked just like a static or constant. However, if there are more
-    // variants with no explicitly specified discriminant, those variants will
-    // increment the same expression to get their values.
-    //
-    // So for every variant, we need to track whether there is an expression
-    // somewhere in the enum definition that controls its discriminant. We do
-    // this by starting from the end and searching backward.
-    fn populate_enum_discriminants(&mut self, enum_definition: &'hir hir::EnumDef) {
-        // Get the map, and return if we already processed this enum or if it
-        // has no variants.
-        match enum_definition.variants.first() {
-            None => {
-                return;
-            }
-            Some(variant) if self.discriminant_map.contains_key(&variant.node.data.id()) => {
-                return;
-            }
-            _ => {}
-        }
-
-        // Go through all the variants.
-        let mut variant_stack: Vec<ast::NodeId> = Vec::new();
-        for variant in enum_definition.variants.iter().rev() {
-            variant_stack.push(variant.node.data.id());
-            // When we find an expression, every variant currently on the stack
-            // is affected by that expression.
-            if let Some(expr) = variant.node.disr_expr {
-                for id in &variant_stack {
-                    self.discriminant_map.insert(*id, Some(expr));
-                }
-                variant_stack.clear()
-            }
-        }
-        // If we are at the top, that always starts at 0, so any variant on the
-        // stack has a default value and does not need to be checked.
-        for id in &variant_stack {
-            self.discriminant_map.insert(*id, None);
-        }
-    }
-}
-
-impl<'a, 'b: 'a, 'hir: 'b> Visitor<'hir> for CheckItemRecursionVisitor<'a, 'b, 'hir> {
-    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> {
-        NestedVisitorMap::OnlyBodies(&self.hir_map)
-    }
-    fn visit_item(&mut self, it: &'hir hir::Item) {
-        self.with_item_id_pushed(it.id, |v| intravisit::walk_item(v, it), it.span);
-    }
-
-    fn visit_enum_def(&mut self,
-                      enum_definition: &'hir hir::EnumDef,
-                      generics: &'hir hir::Generics,
-                      item_id: ast::NodeId,
-                      _: Span) {
-        self.populate_enum_discriminants(enum_definition);
-        intravisit::walk_enum_def(self, enum_definition, generics, item_id);
-    }
-
-    fn visit_variant(&mut self,
-                     variant: &'hir hir::Variant,
-                     _: &'hir hir::Generics,
-                     _: ast::NodeId) {
-        let variant_id = variant.node.data.id();
-        let maybe_expr = *self.discriminant_map.get(&variant_id).unwrap_or_else(|| {
-            span_bug!(variant.span,
-                      "`check_static_recursion` attempted to visit \
-                      variant with unknown discriminant")
-        });
-        // If `maybe_expr` is `None`, that's because no discriminant is
-        // specified that affects this variant. Thus, no risk of recursion.
-        if let Some(expr) = maybe_expr {
-            let expr = &self.hir_map.body(expr).value;
-            self.with_item_id_pushed(expr.id, |v| intravisit::walk_expr(v, expr), expr.span);
-        }
-    }
-
-    fn visit_trait_item(&mut self, ti: &'hir hir::TraitItem) {
-        self.with_item_id_pushed(ti.id, |v| intravisit::walk_trait_item(v, ti), ti.span);
-    }
-
-    fn visit_impl_item(&mut self, ii: &'hir hir::ImplItem) {
-        self.with_item_id_pushed(ii.id, |v| intravisit::walk_impl_item(v, ii), ii.span);
-    }
-
-    fn visit_path(&mut self, path: &'hir hir::Path, _: ast::NodeId) {
-        match path.def {
-            Def::Static(def_id, _) |
-            Def::AssociatedConst(def_id) |
-            Def::Const(def_id) => {
-                if let Some(node_id) = self.hir_map.as_local_node_id(def_id) {
-                    match self.hir_map.get(node_id) {
-                        hir_map::NodeItem(item) => self.visit_item(item),
-                        hir_map::NodeTraitItem(item) => self.visit_trait_item(item),
-                        hir_map::NodeImplItem(item) => self.visit_impl_item(item),
-                        hir_map::NodeForeignItem(_) => {}
-                        _ => {
-                            span_bug!(path.span,
-                                      "expected item, found {}",
-                                      self.hir_map.node_to_string(node_id));
-                        }
-                    }
-                }
-            }
-            // For variants, we only want to check expressions that
-            // affect the specific variant used, but we need to check
-            // the whole enum definition to see what expression that
-            // might be (if any).
-            Def::VariantCtor(variant_id, CtorKind::Const) => {
-                if let Some(variant_id) = self.hir_map.as_local_node_id(variant_id) {
-                    let variant = self.hir_map.expect_variant(variant_id);
-                    let enum_id = self.hir_map.get_parent(variant_id);
-                    let enum_item = self.hir_map.expect_item(enum_id);
-                    if let hir::ItemEnum(ref enum_def, ref generics) = enum_item.node {
-                        self.populate_enum_discriminants(enum_def);
-                        self.visit_variant(variant, generics, enum_id);
-                    } else {
-                        span_bug!(path.span,
-                                  "`check_static_recursion` found \
-                                    non-enum in Def::VariantCtor");
-                    }
-                }
-            }
-            _ => (),
-        }
-        intravisit::walk_path(self, path);
-    }
-}
diff --git a/src/librustc_save_analysis/span_utils.rs b/src/librustc_save_analysis/span_utils.rs
index 25e81e6f326..d5a58c08cbe 100644
--- a/src/librustc_save_analysis/span_utils.rs
+++ b/src/librustc_save_analysis/span_utils.rs
@@ -115,7 +115,7 @@ impl<'a> SpanUtils<'a> {
         // We keep track of the following two counts - the depth of nesting of
         // angle brackets, and the depth of nesting of square brackets. For the
         // angle bracket count, we only count tokens which occur outside of any
-        // square brackets (i.e. bracket_count == 0). The intutition here is
+        // square brackets (i.e. bracket_count == 0). The intuition here is
         // that we want to count angle brackets in the type, but not any which
         // could be in expression context (because these could mean 'less than',
         // etc.).
@@ -151,18 +151,20 @@ impl<'a> SpanUtils<'a> {
             }
             prev = next;
         }
-        if angle_count != 0 || bracket_count != 0 {
-            let loc = self.sess.codemap().lookup_char_pos(span.lo());
-            span_bug!(
-                span,
-                "Mis-counted brackets when breaking path? Parsing '{}' \
-                 in {}, line {}",
-                self.snippet(span),
-                loc.file.name,
-                loc.line
-            );
+        #[cfg(debug_assertions)] {
+            if angle_count != 0 || bracket_count != 0 {
+                let loc = self.sess.codemap().lookup_char_pos(span.lo());
+                span_bug!(
+                    span,
+                    "Mis-counted brackets when breaking path? Parsing '{}' \
+                     in {}, line {}",
+                    self.snippet(span),
+                    loc.file.name,
+                    loc.line
+                );
+            }
         }
-        if result.is_none() && prev.tok.is_ident() && angle_count == 0 {
+        if result.is_none() && prev.tok.is_ident() {
             return Some(prev.sp);
         }
         result
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index 466a86e7ea5..c0785f53937 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -1004,6 +1004,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(
     let translation_items: DefIdSet = items.iter().filter_map(|trans_item| {
         match *trans_item {
             MonoItem::Fn(ref instance) => Some(instance.def_id()),
+            MonoItem::Static(def_id) => Some(def_id),
             _ => None,
         }
     }).collect();
@@ -1107,7 +1108,7 @@ impl CrateInfo {
     }
 }
 
-fn is_translated_function(tcx: TyCtxt, id: DefId) -> bool {
+fn is_translated_item(tcx: TyCtxt, id: DefId) -> bool {
     let (all_trans_items, _) =
         tcx.collect_and_partition_translation_items(LOCAL_CRATE);
     all_trans_items.contains(&id)
@@ -1222,7 +1223,7 @@ pub fn provide(providers: &mut Providers) {
     providers.collect_and_partition_translation_items =
         collect_and_partition_translation_items;
 
-    providers.is_translated_function = is_translated_function;
+    providers.is_translated_item = is_translated_item;
 
     providers.codegen_unit = |tcx, name| {
         let (_, all) = tcx.collect_and_partition_translation_items(LOCAL_CRATE);
diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs
index c3d5e08c73e..8c40aa6a2ac 100644
--- a/src/librustc_trans/callee.rs
+++ b/src/librustc_trans/callee.rs
@@ -149,7 +149,7 @@ pub fn get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
         unsafe {
             llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
 
-            if cx.tcx.is_translated_function(instance_def_id) {
+            if cx.tcx.is_translated_item(instance_def_id) {
                 if instance_def_id.is_local() {
                     if !cx.tcx.is_exported_symbol(instance_def_id) {
                         llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs
index d5b33d837c5..1608c4a87bf 100644
--- a/src/librustc_trans/consts.rs
+++ b/src/librustc_trans/consts.rs
@@ -16,7 +16,7 @@ use rustc::hir::map as hir_map;
 use rustc::middle::const_val::ConstEvalErr;
 use debuginfo;
 use base;
-use monomorphize::{MonoItem, MonoItemExt};
+use monomorphize::MonoItem;
 use common::{CodegenCx, val_ty};
 use declare;
 use monomorphize::Instance;
@@ -110,7 +110,17 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
         return g;
     }
 
+    let defined_in_current_codegen_unit = cx.codegen_unit
+                                            .items()
+                                            .contains_key(&MonoItem::Static(def_id));
+    assert!(!defined_in_current_codegen_unit,
+            "consts::get_static() should always hit the cache for \
+             statics defined in the same CGU, but did not for `{:?}`",
+             def_id);
+
     let ty = instance.ty(cx.tcx);
+    let sym = cx.tcx.symbol_name(instance);
+
     let g = if let Some(id) = cx.tcx.hir.as_local_node_id(def_id) {
 
         let llty = cx.layout_of(ty).llvm_type(cx);
@@ -118,13 +128,6 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
             hir_map::NodeItem(&hir::Item {
                 ref attrs, span, node: hir::ItemStatic(..), ..
             }) => {
-                let sym = MonoItem::Static(id).symbol_name(cx.tcx);
-
-                let defined_in_current_codegen_unit = cx.codegen_unit
-                                                         .items()
-                                                         .contains_key(&MonoItem::Static(id));
-                assert!(!defined_in_current_codegen_unit);
-
                 if declare::get_declared_value(cx, &sym[..]).is_some() {
                     span_bug!(span, "trans: Conflicting symbol names for static?");
                 }
@@ -143,7 +146,7 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
             hir_map::NodeForeignItem(&hir::ForeignItem {
                 ref attrs, span, node: hir::ForeignItemStatic(..), ..
             }) => {
-                let sym = cx.tcx.symbol_name(instance);
+
                 let g = if let Some(name) =
                         attr::first_attr_value_str_by_name(&attrs, "linkage") {
                     // If this is a static with a linkage specified, then we need to handle
@@ -203,8 +206,6 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
 
         g
     } else {
-        let sym = cx.tcx.symbol_name(instance);
-
         // FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
         // FIXME(nagisa): investigate whether it can be changed into define_global
         let g = declare::declare_global(cx, &sym, cx.layout_of(ty).llvm_type(cx));
@@ -225,8 +226,15 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
             // statically in the final application, we always mark such symbols as 'dllimport'.
             // If final linkage happens to be static, we rely on compiler-emitted __imp_ stubs to
             // make things work.
-            unsafe {
-                llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
+            //
+            // However, in some scenarios we defer emission of statics to downstream
+            // crates, so there are cases where a static with an upstream DefId
+            // is actually present in the current crate. We can find out via the
+            // is_translated_item query.
+            if !cx.tcx.is_translated_item(def_id) {
+                unsafe {
+                    llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
+                }
             }
         }
         g
@@ -245,12 +253,11 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
 }
 
 pub fn trans_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
-                              m: hir::Mutability,
-                              id: ast::NodeId,
+                              def_id: DefId,
+                              is_mutable: bool,
                               attrs: &[ast::Attribute])
                               -> Result<ValueRef, ConstEvalErr<'tcx>> {
     unsafe {
-        let def_id = cx.tcx.hir.local_def_id(id);
         let g = get_static(cx, def_id);
 
         let v = ::mir::trans_static_initializer(cx, def_id)?;
@@ -298,13 +305,13 @@ pub fn trans_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
 
         // As an optimization, all shared statics which do not have interior
         // mutability are placed into read-only memory.
-        if m != hir::MutMutable {
+        if !is_mutable {
             if cx.type_is_freeze(ty) {
                 llvm::LLVMSetGlobalConstant(g, llvm::True);
             }
         }
 
-        debuginfo::create_global_var_metadata(cx, id, g);
+        debuginfo::create_global_var_metadata(cx, def_id, g);
 
         if attr::contains_name(attrs, "thread_local") {
             llvm::set_thread_local_mode(g, cx.tls_model);
diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs
index 62ba91840d9..2c430d03c96 100644
--- a/src/librustc_trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/debuginfo/metadata.rs
@@ -14,7 +14,7 @@ use self::EnumDiscriminantInfo::*;
 
 use super::utils::{debug_context, DIB, span_start,
                    get_namespace_for_item, create_DIArray, is_node_local_to_unit};
-use super::namespace::mangled_name_of_item;
+use super::namespace::mangled_name_of_instance;
 use super::type_names::compute_debuginfo_type_name;
 use super::{CrateDebugContext};
 use abi;
@@ -1634,19 +1634,18 @@ fn create_union_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
 ///
 /// Adds the created metadata nodes directly to the crate's IR.
 pub fn create_global_var_metadata(cx: &CodegenCx,
-                                  node_id: ast::NodeId,
+                                  def_id: DefId,
                                   global: ValueRef) {
     if cx.dbg_cx.is_none() {
         return;
     }
 
     let tcx = cx.tcx;
-    let node_def_id = tcx.hir.local_def_id(node_id);
-    let no_mangle = attr::contains_name(&tcx.get_attrs(node_def_id), "no_mangle");
+    let no_mangle = attr::contains_name(&tcx.get_attrs(def_id), "no_mangle");
     // We may want to remove the namespace scope if we're in an extern block, see:
     // https://github.com/rust-lang/rust/pull/46457#issuecomment-351750952
-    let var_scope = get_namespace_for_item(cx, node_def_id);
-    let span = cx.tcx.def_span(node_def_id);
+    let var_scope = get_namespace_for_item(cx, def_id);
+    let span = cx.tcx.def_span(def_id);
 
     let (file_metadata, line_number) = if span != syntax_pos::DUMMY_SP {
         let loc = span_start(cx, span);
@@ -1655,15 +1654,15 @@ pub fn create_global_var_metadata(cx: &CodegenCx,
         (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)
     };
 
-    let is_local_to_unit = is_node_local_to_unit(cx, node_id);
-    let variable_type = Instance::mono(cx.tcx, node_def_id).ty(cx.tcx);
+    let is_local_to_unit = is_node_local_to_unit(cx, def_id);
+    let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx);
     let type_metadata = type_metadata(cx, variable_type, span);
-    let var_name = tcx.item_name(node_def_id).to_string();
+    let var_name = tcx.item_name(def_id).to_string();
     let var_name = CString::new(var_name).unwrap();
     let linkage_name = if no_mangle {
         None
     } else {
-        let linkage_name = mangled_name_of_item(cx, node_id);
+        let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id));
         Some(CString::new(linkage_name.to_string()).unwrap())
     };
 
diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs
index 9071eb776d5..16279f31836 100644
--- a/src/librustc_trans/debuginfo/mod.rs
+++ b/src/librustc_trans/debuginfo/mod.rs
@@ -254,14 +254,14 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
     let linkage_name = mangled_name_of_instance(cx, instance);
 
     let scope_line = span_start(cx, span).line;
-
-    let local_id = cx.tcx.hir.as_local_node_id(instance.def_id());
-    let is_local_to_unit = local_id.map_or(false, |id| is_node_local_to_unit(cx, id));
+    let is_local_to_unit = is_node_local_to_unit(cx, def_id);
 
     let function_name = CString::new(name).unwrap();
     let linkage_name = CString::new(linkage_name.to_string()).unwrap();
 
     let mut flags = DIFlags::FlagPrototyped;
+
+    let local_id = cx.tcx.hir.as_local_node_id(def_id);
     match *cx.sess().entry_fn.borrow() {
         Some((id, _)) => {
             if local_id == Some(id) {
diff --git a/src/librustc_trans/debuginfo/namespace.rs b/src/librustc_trans/debuginfo/namespace.rs
index 46067a43303..891bf649c38 100644
--- a/src/librustc_trans/debuginfo/namespace.rs
+++ b/src/librustc_trans/debuginfo/namespace.rs
@@ -14,7 +14,6 @@ use super::metadata::{unknown_file_metadata, UNKNOWN_LINE_NUMBER};
 use super::utils::{DIB, debug_context};
 use monomorphize::Instance;
 use rustc::ty;
-use syntax::ast;
 
 use llvm;
 use llvm::debuginfo::DIScope;
@@ -33,16 +32,6 @@ pub fn mangled_name_of_instance<'a, 'tcx>(
      tcx.symbol_name(instance)
 }
 
-pub fn mangled_name_of_item<'a, 'tcx>(
-    cx: &CodegenCx<'a, 'tcx>,
-    node_id: ast::NodeId,
-) -> ty::SymbolName {
-    let tcx = cx.tcx;
-    let node_def_id = tcx.hir.local_def_id(node_id);
-    let instance = Instance::mono(tcx, node_def_id);
-    tcx.symbol_name(instance)
-}
-
 pub fn item_namespace(cx: &CodegenCx, def_id: DefId) -> DIScope {
     if let Some(&scope) = debug_context(cx).namespace_map.borrow().get(&def_id) {
         return scope;
diff --git a/src/librustc_trans/debuginfo/utils.rs b/src/librustc_trans/debuginfo/utils.rs
index c571b84b8e9..9559cd4d9ea 100644
--- a/src/librustc_trans/debuginfo/utils.rs
+++ b/src/librustc_trans/debuginfo/utils.rs
@@ -21,9 +21,8 @@ use llvm::debuginfo::{DIScope, DIBuilderRef, DIDescriptor, DIArray};
 use common::{CodegenCx};
 
 use syntax_pos::{self, Span};
-use syntax::ast;
 
-pub fn is_node_local_to_unit(cx: &CodegenCx, node_id: ast::NodeId) -> bool
+pub fn is_node_local_to_unit(cx: &CodegenCx, def_id: DefId) -> bool
 {
     // The is_local_to_unit flag indicates whether a function is local to the
     // current compilation unit (i.e. if it is *static* in the C-sense). The
@@ -33,7 +32,6 @@ pub fn is_node_local_to_unit(cx: &CodegenCx, node_id: ast::NodeId) -> bool
     // visible). It might better to use the `exported_items` set from
     // `driver::CrateAnalysis` in the future, but (atm) this set is not
     // available in the translation pass.
-    let def_id = cx.tcx.hir.local_def_id(node_id);
     !cx.tcx.is_exported_symbol(def_id)
 }
 
diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs
index 5eb6679fe25..91c1097fc7f 100644
--- a/src/librustc_trans/trans_item.rs
+++ b/src/librustc_trans/trans_item.rs
@@ -24,10 +24,11 @@ use llvm;
 use monomorphize::Instance;
 use type_of::LayoutLlvmExt;
 use rustc::hir;
+use rustc::hir::def::Def;
+use rustc::hir::def_id::DefId;
 use rustc::mir::mono::{Linkage, Visibility};
 use rustc::ty::TypeFoldable;
 use rustc::ty::layout::LayoutOf;
-use syntax::ast;
 use syntax::attr;
 use std::fmt;
 
@@ -44,19 +45,25 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
                cx.codegen_unit.name());
 
         match *self.as_mono_item() {
-            MonoItem::Static(node_id) => {
+            MonoItem::Static(def_id) => {
                 let tcx = cx.tcx;
-                let item = tcx.hir.expect_item(node_id);
-                if let hir::ItemStatic(_, m, _) = item.node {
-                    match consts::trans_static(&cx, m, item.id, &item.attrs) {
-                        Ok(_) => { /* Cool, everything's alright. */ },
-                        Err(err) => {
-                            err.report(tcx, item.span, "static");
-                        }
-                    };
-                } else {
-                    span_bug!(item.span, "Mismatch between hir::Item type and TransItem type")
-                }
+                let is_mutable = match tcx.describe_def(def_id) {
+                    Some(Def::Static(_, is_mutable)) => is_mutable,
+                    Some(other) => {
+                        bug!("Expected Def::Static, found {:?}", other)
+                    }
+                    None => {
+                        bug!("Expected Def::Static for {:?}, found nothing", def_id)
+                    }
+                };
+                let attrs = tcx.get_attrs(def_id);
+
+                match consts::trans_static(&cx, def_id, is_mutable, &attrs) {
+                    Ok(_) => { /* Cool, everything's alright. */ },
+                    Err(err) => {
+                        err.report(tcx, tcx.def_span(def_id), "static");
+                    }
+                };
             }
             MonoItem::GlobalAsm(node_id) => {
                 let item = cx.tcx.hir.expect_item(node_id);
@@ -91,8 +98,8 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
         debug!("symbol {}", &symbol_name);
 
         match *self.as_mono_item() {
-            MonoItem::Static(node_id) => {
-                predefine_static(cx, node_id, linkage, visibility, &symbol_name);
+            MonoItem::Static(def_id) => {
+                predefine_static(cx, def_id, linkage, visibility, &symbol_name);
             }
             MonoItem::Fn(instance) => {
                 predefine_fn(cx, instance, linkage, visibility, &symbol_name);
@@ -126,17 +133,16 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
 impl<'a, 'tcx> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {}
 
 fn predefine_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
-                              node_id: ast::NodeId,
+                              def_id: DefId,
                               linkage: Linkage,
                               visibility: Visibility,
                               symbol_name: &str) {
-    let def_id = cx.tcx.hir.local_def_id(node_id);
     let instance = Instance::mono(cx.tcx, def_id);
     let ty = instance.ty(cx.tcx);
     let llty = cx.layout_of(ty).llvm_type(cx);
 
     let g = declare::define_global(cx, symbol_name, llty).unwrap_or_else(|| {
-        cx.sess().span_fatal(cx.tcx.hir.span(node_id),
+        cx.sess().span_fatal(cx.tcx.def_span(def_id),
             &format!("symbol `{}` is already defined", symbol_name))
     });
 
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 854cefcb597..d7d856fe3ad 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -500,11 +500,6 @@ mod memchr;
 // The runtime entry point and a few unstable public functions used by the
 // compiler
 pub mod rt;
-// The trait to support returning arbitrary types in the main function
-mod termination;
-
-#[unstable(feature = "termination_trait", issue = "43301")]
-pub use self::termination::Termination;
 
 // Include a number of private modules that exist solely to provide
 // the rustdoc documentation for primitive types. Using `include!`
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index 9b2f815b713..e25599b8bd8 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -1392,6 +1392,73 @@ pub fn id() -> u32 {
     ::sys::os::getpid()
 }
 
+#[cfg(target_arch = "wasm32")]
+mod exit {
+    pub const SUCCESS: i32 = 0;
+    pub const FAILURE: i32 = 1;
+}
+#[cfg(not(target_arch = "wasm32"))]
+mod exit {
+    use libc;
+    pub const SUCCESS: i32 = libc::EXIT_SUCCESS;
+    pub const FAILURE: i32 = libc::EXIT_FAILURE;
+}
+
+/// A trait for implementing arbitrary return types in the `main` function.
+///
+/// The c-main function only supports to return integers as return type.
+/// So, every type implementing the `Termination` trait has to be converted
+/// to an integer.
+///
+/// The default implementations are returning `libc::EXIT_SUCCESS` to indicate
+/// a successful execution. In case of a failure, `libc::EXIT_FAILURE` is returned.
+#[cfg_attr(not(test), lang = "termination")]
+#[unstable(feature = "termination_trait_lib", issue = "43301")]
+#[rustc_on_unimplemented =
+  "`main` can only return types that implement {Termination}, not `{Self}`"]
+pub trait Termination {
+    /// Is called to get the representation of the value as status code.
+    /// This status code is returned to the operating system.
+    fn report(self) -> i32;
+}
+
+#[unstable(feature = "termination_trait_lib", issue = "43301")]
+impl Termination for () {
+    fn report(self) -> i32 { exit::SUCCESS }
+}
+
+#[unstable(feature = "termination_trait_lib", issue = "43301")]
+impl<T: Termination, E: fmt::Debug> Termination for Result<T, E> {
+    fn report(self) -> i32 {
+        match self {
+            Ok(val) => val.report(),
+            Err(err) => {
+                eprintln!("Error: {:?}", err);
+                exit::FAILURE
+            }
+        }
+    }
+}
+
+#[unstable(feature = "termination_trait_lib", issue = "43301")]
+impl Termination for ! {
+    fn report(self) -> i32 { unreachable!(); }
+}
+
+#[unstable(feature = "termination_trait_lib", issue = "43301")]
+impl Termination for bool {
+    fn report(self) -> i32 {
+        if self { exit::SUCCESS } else { exit::FAILURE }
+    }
+}
+
+#[unstable(feature = "termination_trait_lib", issue = "43301")]
+impl Termination for i32 {
+    fn report(self) -> i32 {
+        self
+    }
+}
+
 #[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
 mod tests {
     use io::prelude::*;
diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs
index 9dbaf784f89..e1392762a59 100644
--- a/src/libstd/rt.rs
+++ b/src/libstd/rt.rs
@@ -68,7 +68,7 @@ fn lang_start_internal(main: &(Fn() -> i32 + Sync + ::panic::RefUnwindSafe),
 
 #[cfg(not(test))]
 #[lang = "start"]
-fn lang_start<T: ::termination::Termination + 'static>
+fn lang_start<T: ::process::Termination + 'static>
     (main: fn() -> T, argc: isize, argv: *const *const u8) -> isize
 {
     lang_start_internal(&move || main().report(), argc, argv)
diff --git a/src/libstd/termination.rs b/src/libstd/termination.rs
deleted file mode 100644
index dc7fa53aab6..00000000000
--- a/src/libstd/termination.rs
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use fmt::Debug;
-#[cfg(target_arch = "wasm32")]
-mod exit {
-    pub const SUCCESS: i32 = 0;
-    pub const FAILURE: i32 = 1;
-}
-#[cfg(not(target_arch = "wasm32"))]
-mod exit {
-    use libc;
-    pub const SUCCESS: i32 = libc::EXIT_SUCCESS;
-    pub const FAILURE: i32 = libc::EXIT_FAILURE;
-}
-
-/// A trait for implementing arbitrary return types in the `main` function.
-///
-/// The c-main function only supports to return integers as return type.
-/// So, every type implementing the `Termination` trait has to be converted
-/// to an integer.
-///
-/// The default implementations are returning `libc::EXIT_SUCCESS` to indicate
-/// a successful execution. In case of a failure, `libc::EXIT_FAILURE` is returned.
-#[cfg_attr(not(test), lang = "termination")]
-#[unstable(feature = "termination_trait", issue = "43301")]
-#[rustc_on_unimplemented =
-  "`main` can only return types that implement {Termination}, not `{Self}`"]
-pub trait Termination {
-    /// Is called to get the representation of the value as status code.
-    /// This status code is returned to the operating system.
-    fn report(self) -> i32;
-}
-
-#[unstable(feature = "termination_trait", issue = "43301")]
-impl Termination for () {
-    fn report(self) -> i32 { exit::SUCCESS }
-}
-
-#[unstable(feature = "termination_trait", issue = "43301")]
-impl<T: Termination, E: Debug> Termination for Result<T, E> {
-    fn report(self) -> i32 {
-        match self {
-            Ok(val) => val.report(),
-            Err(err) => {
-                eprintln!("Error: {:?}", err);
-                exit::FAILURE
-            }
-        }
-    }
-}
-
-#[unstable(feature = "termination_trait", issue = "43301")]
-impl Termination for ! {
-    fn report(self) -> i32 { unreachable!(); }
-}
-
-#[unstable(feature = "termination_trait", issue = "43301")]
-impl Termination for bool {
-    fn report(self) -> i32 {
-        if self { exit::SUCCESS } else { exit::FAILURE }
-    }
-}
-
-#[unstable(feature = "termination_trait", issue = "43301")]
-impl Termination for i32 {
-    fn report(self) -> i32 {
-        self
-    }
-}
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 7681f55bd8c..b88e064e7e5 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -319,14 +319,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
                 types: Vec<P<ast::Ty>>,
                 bindings: Vec<ast::TypeBinding> )
                 -> ast::Path {
-        use syntax::parse::token;
-
         let last_identifier = idents.pop().unwrap();
         let mut segments: Vec<ast::PathSegment> = Vec::new();
-        if global &&
-           !idents.first().map_or(false, |&ident| token::Ident(ident).is_path_segment_keyword()) {
-            segments.push(ast::PathSegment::crate_root(span));
-        }
 
         segments.extend(idents.into_iter().map(|i| ast::PathSegment::from_ident(i, span)));
         let parameters = if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() {
@@ -335,7 +329,9 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
             None
         };
         segments.push(ast::PathSegment { identifier: last_identifier, span, parameters });
-        ast::Path { span, segments }
+        let path = ast::Path { span, segments };
+
+        if global { path.default_to_global() } else { path }
     }
 
     /// Constructs a qualified path.
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index f7cebed5f62..ba24d7f914b 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -432,9 +432,6 @@ declare_features! (
     // `foo.rs` as an alternative to `foo/mod.rs`
     (active, non_modrs_mods, "1.24.0", Some(44660)),
 
-    // Nested `impl Trait`
-    (active, nested_impl_trait, "1.24.0", Some(34511)),
-
     // Termination trait in main (RFC 1937)
     (active, termination_trait, "1.24.0", Some(43301)),
 
@@ -1352,73 +1349,8 @@ fn contains_novel_literal(item: &ast::MetaItem) -> bool {
     }
 }
 
-// Bans nested `impl Trait`, e.g. `impl Into<impl Debug>`.
-// Nested `impl Trait` _is_ allowed in associated type position,
-// e.g `impl Iterator<Item=impl Debug>`
-struct NestedImplTraitVisitor<'a> {
-    context: &'a Context<'a>,
-    is_in_impl_trait: bool,
-}
-
-impl<'a> NestedImplTraitVisitor<'a> {
-    fn with_impl_trait<F>(&mut self, is_in_impl_trait: bool, f: F)
-        where F: FnOnce(&mut NestedImplTraitVisitor<'a>)
-    {
-        let old_is_in_impl_trait = self.is_in_impl_trait;
-        self.is_in_impl_trait = is_in_impl_trait;
-        f(self);
-        self.is_in_impl_trait = old_is_in_impl_trait;
-    }
-}
-
-
-impl<'a> Visitor<'a> for NestedImplTraitVisitor<'a> {
-    fn visit_ty(&mut self, t: &'a ast::Ty) {
-        if let ast::TyKind::ImplTrait(_) = t.node {
-            if self.is_in_impl_trait {
-                gate_feature_post!(&self, nested_impl_trait, t.span,
-                    "nested `impl Trait` is experimental"
-                );
-            }
-            self.with_impl_trait(true, |this| visit::walk_ty(this, t));
-        } else {
-            visit::walk_ty(self, t);
-        }
-    }
-    fn visit_path_parameters(&mut self, _: Span, path_parameters: &'a ast::PathParameters) {
-        match *path_parameters {
-            ast::PathParameters::AngleBracketed(ref params) => {
-                for type_ in &params.types {
-                    self.visit_ty(type_);
-                }
-                for type_binding in &params.bindings {
-                    // Type bindings such as `Item=impl Debug` in `Iterator<Item=Debug>`
-                    // are allowed to contain nested `impl Trait`.
-                    self.with_impl_trait(false, |this| visit::walk_ty(this, &type_binding.ty));
-                }
-            }
-            ast::PathParameters::Parenthesized(ref params) => {
-                for type_ in &params.inputs {
-                    self.visit_ty(type_);
-                }
-                if let Some(ref type_) = params.output {
-                    // `-> Foo` syntax is essentially an associated type binding,
-                    // so it is also allowed to contain nested `impl Trait`.
-                    self.with_impl_trait(false, |this| visit::walk_ty(this, type_));
-                }
-            }
-        }
-    }
-}
-
 impl<'a> PostExpansionVisitor<'a> {
-    fn whole_crate_feature_gates(&mut self, krate: &ast::Crate) {
-        visit::walk_crate(
-            &mut NestedImplTraitVisitor {
-                context: self.context,
-                is_in_impl_trait: false,
-            }, krate);
-
+    fn whole_crate_feature_gates(&mut self, _krate: &ast::Crate) {
         for &(ident, span) in &*self.context.parse_sess.non_modrs_mods.borrow() {
             if !span.allows_unstable() {
                 let cx = &self.context;
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 1a33de84429..efc191f24ac 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -6482,6 +6482,8 @@ impl<'a> Parser<'a> {
             && self.look_ahead(1, |t| *t != token::OpenDelim(token::Brace)) {
             // UNSAFE FUNCTION ITEM
             self.bump(); // `unsafe`
+            // `{` is also expected after `unsafe`, in case of error, include it in the diagnostic
+            self.check(&token::OpenDelim(token::Brace));
             let abi = if self.eat_keyword(keywords::Extern) {
                 self.parse_opt_abi()?.unwrap_or(Abi::C)
             } else {
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index 7b119c576db..e732ac3a635 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -32,6 +32,7 @@ use ext::build::AstBuilder;
 use ext::expand::ExpansionConfig;
 use ext::hygiene::{Mark, SyntaxContext};
 use fold::Folder;
+use feature_gate::Features;
 use util::move_map::MoveMap;
 use fold;
 use parse::{token, ParseSess};
@@ -63,6 +64,7 @@ struct TestCtxt<'a> {
     reexport_test_harness_main: Option<Symbol>,
     is_libtest: bool,
     ctxt: SyntaxContext,
+    features: &'a Features,
 
     // top-level re-export submodule, filled out after folding is finished
     toplevel_reexport: Option<Ident>,
@@ -74,7 +76,8 @@ pub fn modify_for_testing(sess: &ParseSess,
                           resolver: &mut Resolver,
                           should_test: bool,
                           krate: ast::Crate,
-                          span_diagnostic: &errors::Handler) -> ast::Crate {
+                          span_diagnostic: &errors::Handler,
+                          features: &Features) -> ast::Crate {
     // Check for #[reexport_test_harness_main = "some_name"] which
     // creates a `use some_name = __test::main;`. This needs to be
     // unconditional, so that the attribute is still marked as used in
@@ -84,7 +87,8 @@ pub fn modify_for_testing(sess: &ParseSess,
                                            "reexport_test_harness_main");
 
     if should_test {
-        generate_test_harness(sess, resolver, reexport_test_harness_main, krate, span_diagnostic)
+        generate_test_harness(sess, resolver, reexport_test_harness_main,
+                              krate, span_diagnostic, features)
     } else {
         krate
     }
@@ -265,16 +269,20 @@ fn generate_test_harness(sess: &ParseSess,
                          resolver: &mut Resolver,
                          reexport_test_harness_main: Option<Symbol>,
                          krate: ast::Crate,
-                         sd: &errors::Handler) -> ast::Crate {
+                         sd: &errors::Handler,
+                         features: &Features) -> ast::Crate {
     // Remove the entry points
     let mut cleaner = EntryPointCleaner { depth: 0 };
     let krate = cleaner.fold_crate(krate);
 
     let mark = Mark::fresh(Mark::root());
 
+    let mut econfig = ExpansionConfig::default("test".to_string());
+    econfig.features = Some(features);
+
     let cx = TestCtxt {
         span_diagnostic: sd,
-        ext_cx: ExtCtxt::new(sess, ExpansionConfig::default("test".to_string()), resolver),
+        ext_cx: ExtCtxt::new(sess, econfig, resolver),
         path: Vec::new(),
         testfns: Vec::new(),
         reexport_test_harness_main,
@@ -282,6 +290,7 @@ fn generate_test_harness(sess: &ParseSess,
         is_libtest: attr::find_crate_name(&krate.attrs).map(|s| s == "test").unwrap_or(false),
         toplevel_reexport: None,
         ctxt: SyntaxContext::empty().apply_mark(mark),
+        features,
     };
 
     mark.set_expn_info(ExpnInfo {
@@ -318,71 +327,105 @@ enum HasTestSignature {
 fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
     let has_test_attr = attr::contains_name(&i.attrs, "test");
 
-    fn has_test_signature(i: &ast::Item) -> HasTestSignature {
+    fn has_test_signature(cx: &TestCtxt, i: &ast::Item) -> HasTestSignature {
         match i.node {
-          ast::ItemKind::Fn(ref decl, _, _, _, ref generics, _) => {
-            let no_output = match decl.output {
-                ast::FunctionRetTy::Default(..) => true,
-                ast::FunctionRetTy::Ty(ref t) if t.node == ast::TyKind::Tup(vec![]) => true,
-                _ => false
-            };
-            if decl.inputs.is_empty()
-                   && no_output
-                   && !generics.is_parameterized() {
-                Yes
-            } else {
-                No
+            ast::ItemKind::Fn(ref decl, _, _, _, ref generics, _) => {
+                // If the termination trait is active, the compiler will check that the output
+                // type implements the `Termination` trait as `libtest` enforces that.
+                let output_matches = if cx.features.termination_trait {
+                    true
+                } else {
+                    let no_output = match decl.output {
+                        ast::FunctionRetTy::Default(..) => true,
+                        ast::FunctionRetTy::Ty(ref t) if t.node == ast::TyKind::Tup(vec![]) => true,
+                        _ => false
+                    };
+
+                    no_output && !generics.is_parameterized()
+                };
+
+                if decl.inputs.is_empty() && output_matches {
+                    Yes
+                } else {
+                    No
+                }
             }
-          }
-          _ => NotEvenAFunction,
+            _ => NotEvenAFunction,
         }
     }
 
-    if has_test_attr {
+    let has_test_signature = if has_test_attr {
         let diag = cx.span_diagnostic;
-        match has_test_signature(i) {
-            Yes => {},
-            No => diag.span_err(i.span, "functions used as tests must have signature fn() -> ()"),
-            NotEvenAFunction => diag.span_err(i.span,
-                                              "only functions may be used as tests"),
+        match has_test_signature(cx, i) {
+            Yes => true,
+            No => {
+                if cx.features.termination_trait {
+                    diag.span_err(i.span, "functions used as tests can not have any arguments");
+                } else {
+                    diag.span_err(i.span, "functions used as tests must have signature fn() -> ()");
+                }
+                false
+            },
+            NotEvenAFunction => {
+                diag.span_err(i.span, "only functions may be used as tests");
+                false
+            },
         }
-    }
+    } else {
+        false
+    };
 
-    has_test_attr && has_test_signature(i) == Yes
+    has_test_attr && has_test_signature
 }
 
 fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
     let has_bench_attr = attr::contains_name(&i.attrs, "bench");
 
-    fn has_test_signature(i: &ast::Item) -> bool {
+    fn has_bench_signature(cx: &TestCtxt, i: &ast::Item) -> bool {
         match i.node {
             ast::ItemKind::Fn(ref decl, _, _, _, ref generics, _) => {
                 let input_cnt = decl.inputs.len();
-                let no_output = match decl.output {
-                    ast::FunctionRetTy::Default(..) => true,
-                    ast::FunctionRetTy::Ty(ref t) if t.node == ast::TyKind::Tup(vec![]) => true,
-                    _ => false
+
+                // If the termination trait is active, the compiler will check that the output
+                // type implements the `Termination` trait as `libtest` enforces that.
+                let output_matches = if cx.features.termination_trait {
+                    true
+                } else {
+                    let no_output = match decl.output {
+                        ast::FunctionRetTy::Default(..) => true,
+                        ast::FunctionRetTy::Ty(ref t) if t.node == ast::TyKind::Tup(vec![]) => true,
+                        _ => false
+                    };
+                    let tparm_cnt = generics.params.iter()
+                        .filter(|param| param.is_type_param())
+                        .count();
+
+                    no_output && tparm_cnt == 0
                 };
-                let tparm_cnt = generics.params.iter()
-                    .filter(|param| param.is_type_param())
-                    .count();
 
                 // NB: inadequate check, but we're running
                 // well before resolve, can't get too deep.
-                input_cnt == 1
-                    && no_output && tparm_cnt == 0
+                input_cnt == 1 && output_matches
             }
           _ => false
         }
     }
 
-    if has_bench_attr && !has_test_signature(i) {
+    let has_bench_signature = has_bench_signature(cx, i);
+
+    if has_bench_attr && !has_bench_signature {
         let diag = cx.span_diagnostic;
-        diag.span_err(i.span, "functions used as benches must have signature \
-                      `fn(&mut Bencher) -> ()`");
+
+        if cx.features.termination_trait {
+            diag.span_err(i.span, "functions used as benches must have signature \
+                                   `fn(&mut Bencher) -> impl Termination`");
+        } else {
+            diag.span_err(i.span, "functions used as benches must have signature \
+                                   `fn(&mut Bencher) -> ()`");
+        }
     }
 
-    has_bench_attr && has_test_signature(i)
+    has_bench_attr && has_bench_signature
 }
 
 fn is_ignored(i: &ast::Item) -> bool {
@@ -690,9 +733,12 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
              field("should_panic", fail_expr),
              field("allow_fail", allow_fail_expr)]);
 
-
-    let mut visible_path = match cx.toplevel_reexport {
-        Some(id) => vec![id],
+    let mut visible_path = vec![];
+    if cx.features.extern_absolute_paths {
+        visible_path.push(keywords::Crate.ident());
+    }
+    match cx.toplevel_reexport {
+        Some(id) => visible_path.push(id),
         None => {
             let diag = cx.span_diagnostic;
             diag.bug("expected to find top-level re-export name, but found None");
@@ -700,9 +746,64 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
     };
     visible_path.extend(path);
 
-    let fn_expr = ecx.expr_path(ecx.path_global(span, visible_path));
+    // Rather than directly give the test function to the test
+    // harness, we create a wrapper like one of the following:
+    //
+    //     || test::assert_test_result(real_function()) // for test
+    //     |b| test::assert_test_result(real_function(b)) // for bench
+    //
+    // this will coerce into a fn pointer that is specialized to the
+    // actual return type of `real_function` (Typically `()`, but not always).
+    let fn_expr = {
+        // construct `real_function()` (this will be inserted into the overall expr)
+        let real_function_expr = ecx.expr_path(ecx.path_global(span, visible_path));
+        // construct path `test::assert_test_result`
+        let assert_test_result = test_path("assert_test_result");
+        if test.bench {
+            // construct `|b| {..}`
+            let b_ident = Ident::with_empty_ctxt(Symbol::gensym("b"));
+            let b_expr = ecx.expr_ident(span, b_ident);
+            ecx.lambda(
+                span,
+                vec![b_ident],
+                // construct `assert_test_result(..)`
+                ecx.expr_call(
+                    span,
+                    ecx.expr_path(assert_test_result),
+                    vec![
+                        // construct `real_function(b)`
+                        ecx.expr_call(
+                            span,
+                            real_function_expr,
+                            vec![b_expr],
+                        )
+                    ],
+                ),
+            )
+        } else {
+            // construct `|| {..}`
+            ecx.lambda(
+                span,
+                vec![],
+                // construct `assert_test_result(..)`
+                ecx.expr_call(
+                    span,
+                    ecx.expr_path(assert_test_result),
+                    vec![
+                        // construct `real_function()`
+                        ecx.expr_call(
+                            span,
+                            real_function_expr,
+                            vec![],
+                        )
+                    ],
+                ),
+            )
+        }
+    };
 
     let variant_name = if test.bench { "StaticBenchFn" } else { "StaticTestFn" };
+
     // self::test::$variant_name($fn_expr)
     let testfn_expr = ecx.expr_call(span, ecx.expr_path(test_path(variant_name)), vec![fn_expr]);
 
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 9ea5f39b71f..82077bc4cd4 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -40,6 +40,7 @@
 #![feature(set_stdio)]
 #![feature(panic_unwind)]
 #![feature(staged_api)]
+#![feature(termination_trait_lib)]
 
 extern crate getopts;
 extern crate term;
@@ -67,6 +68,7 @@ use std::io::prelude::*;
 use std::io;
 use std::iter::repeat;
 use std::path::PathBuf;
+use std::process::Termination;
 use std::sync::mpsc::{channel, Sender};
 use std::sync::{Arc, Mutex};
 use std::thread;
@@ -81,8 +83,8 @@ const QUIET_MODE_MAX_COLUMN: usize = 100; // insert a '\n' after 100 tests in qu
 pub mod test {
     pub use {Bencher, TestName, TestResult, TestDesc, TestDescAndFn, TestOpts, TrFailed,
              TrFailedMsg, TrIgnored, TrOk, Metric, MetricMap, StaticTestFn, StaticTestName,
-             DynTestName, DynTestFn, run_test, test_main, test_main_static, filter_tests,
-             parse_opts, StaticBenchFn, ShouldPanic, Options};
+             DynTestName, DynTestFn, assert_test_result, run_test, test_main, test_main_static,
+             filter_tests, parse_opts, StaticBenchFn, ShouldPanic, Options};
 }
 
 pub mod stats;
@@ -322,6 +324,13 @@ pub fn test_main_static(tests: &[TestDescAndFn]) {
     test_main(&args, owned_tests, Options::new())
 }
 
+/// Invoked when unit tests terminate. Should panic if the unit
+/// test is considered a failure. By default, invokes `report()`
+/// and checks for a `0` result.
+pub fn assert_test_result<T: Termination>(result: T) {
+    assert_eq!(result.report(), 0);
+}
+
 #[derive(Copy, Clone, Debug)]
 pub enum ColorConfig {
     AutoColor,
diff --git a/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs b/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs
index 795d45a776d..c425ed554a6 100644
--- a/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs
+++ b/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs
@@ -105,14 +105,10 @@ fn overloaded_call_traits() {
         //[lxl]~^^^           ERROR use of moved value: `*f`
         //[nll]~^^^^          ERROR cannot move a value of type
         //[nll]~^^^^^         ERROR cannot move a value of type
-        //[nll]~^^^^^^        ERROR cannot move a value of type
-        //[nll]~^^^^^^^       ERROR cannot move a value of type
-        //[nll]~^^^^^^^^      ERROR use of moved value: `*f`
-        //[g2p]~^^^^^^^^^     ERROR cannot move a value of type
-        //[g2p]~^^^^^^^^^^    ERROR cannot move a value of type
-        //[g2p]~^^^^^^^^^^^   ERROR cannot move a value of type
-        //[g2p]~^^^^^^^^^^^^  ERROR cannot move a value of type
-        //[g2p]~^^^^^^^^^^^^^ ERROR use of moved value: `*f`
+        //[nll]~^^^^^^        ERROR use of moved value: `*f`
+        //[g2p]~^^^^^^^       ERROR cannot move a value of type
+        //[g2p]~^^^^^^^^      ERROR cannot move a value of type
+        //[g2p]~^^^^^^^^^     ERROR use of moved value: `*f`
     }
 
     twice_ten_sm(&mut |x| x + 1);
diff --git a/src/test/compile-fail/coherence-inherited-assoc-ty-cycle-err.rs b/src/test/compile-fail/coherence-inherited-assoc-ty-cycle-err.rs
index 5d7f3396740..2f4d82e2ef5 100644
--- a/src/test/compile-fail/coherence-inherited-assoc-ty-cycle-err.rs
+++ b/src/test/compile-fail/coherence-inherited-assoc-ty-cycle-err.rs
@@ -17,7 +17,7 @@
 #![feature(specialization)]
 
 trait Trait<T> { type Assoc; }
-//~^ unsupported cyclic reference between types/traits detected [E0391]
+//~^ cyclic dependency detected [E0391]
 
 impl<T> Trait<T> for Vec<T> {
     type Assoc = ();
diff --git a/src/test/compile-fail/const-size_of-cycle.rs b/src/test/compile-fail/const-size_of-cycle.rs
index cbeafdfe6ac..6218dcbf5f2 100644
--- a/src/test/compile-fail/const-size_of-cycle.rs
+++ b/src/test/compile-fail/const-size_of-cycle.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: unsupported cyclic reference between types/traits detected
+// error-pattern: cyclic dependency detected
 
 #![feature(const_fn)]
 
diff --git a/src/test/compile-fail/cycle-projection-based-on-where-clause.rs b/src/test/compile-fail/cycle-projection-based-on-where-clause.rs
index 7af2f11bd28..ee4722c010f 100644
--- a/src/test/compile-fail/cycle-projection-based-on-where-clause.rs
+++ b/src/test/compile-fail/cycle-projection-based-on-where-clause.rs
@@ -25,7 +25,7 @@ trait Trait { type Item; }
 struct A<T>
     where T : Trait,
           T : Add<T::Item>
-    //~^ ERROR unsupported cyclic reference between types/traits detected
+    //~^ ERROR cyclic dependency detected
     //~| ERROR associated type `Item` not found for `T`
 {
     data: T
diff --git a/src/test/compile-fail/cycle-trait-default-type-trait.rs b/src/test/compile-fail/cycle-trait-default-type-trait.rs
index e6caeb34a8c..88672088bcb 100644
--- a/src/test/compile-fail/cycle-trait-default-type-trait.rs
+++ b/src/test/compile-fail/cycle-trait-default-type-trait.rs
@@ -12,7 +12,7 @@
 // again references the trait.
 
 trait Foo<X = Box<Foo>> {
-    //~^ ERROR unsupported cyclic reference
+    //~^ ERROR cyclic dependency detected
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/cycle-trait-supertrait-direct.rs b/src/test/compile-fail/cycle-trait-supertrait-direct.rs
index ef3fead18f6..626567ccc0e 100644
--- a/src/test/compile-fail/cycle-trait-supertrait-direct.rs
+++ b/src/test/compile-fail/cycle-trait-supertrait-direct.rs
@@ -11,7 +11,7 @@
 // Test a supertrait cycle where a trait extends itself.
 
 trait Chromosome: Chromosome {
-    //~^ ERROR unsupported cyclic reference
+    //~^ ERROR cyclic dependency detected
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/impl-trait/where-allowed.rs b/src/test/compile-fail/impl-trait/where-allowed.rs
index a9fe1e04664..52c5471681d 100644
--- a/src/test/compile-fail/impl-trait/where-allowed.rs
+++ b/src/test/compile-fail/impl-trait/where-allowed.rs
@@ -10,7 +10,7 @@
 
 //! A simple test for testing many permutations of allowedness of
 //! impl Trait
-#![feature(conservative_impl_trait, nested_impl_trait, universal_impl_trait, dyn_trait)]
+#![feature(conservative_impl_trait, universal_impl_trait, dyn_trait)]
 use std::fmt::Debug;
 
 // Allowed
@@ -60,6 +60,7 @@ fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
 // Disallowed
 fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
 //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^^ ERROR nested `impl Trait` is not allowed
 
 // Disallowed
 fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
@@ -68,6 +69,7 @@ fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
 // Disallowed
 fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
 //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^^ ERROR nested `impl Trait` is not allowed
 
 // Disallowed
 fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
diff --git a/src/test/compile-fail/infinite-vec-type-recursion.rs b/src/test/compile-fail/infinite-vec-type-recursion.rs
index e5120840f76..25d0590db1b 100644
--- a/src/test/compile-fail/infinite-vec-type-recursion.rs
+++ b/src/test/compile-fail/infinite-vec-type-recursion.rs
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 type x = Vec<x>;
-//~^ ERROR unsupported cyclic reference
+//~^ ERROR cyclic dependency detected
 
 fn main() { let b: x = Vec::new(); }
diff --git a/src/test/compile-fail/issue-12997-2.rs b/src/test/compile-fail/issue-12997-2.rs
index 85d91bb2db2..8d3df68577b 100644
--- a/src/test/compile-fail/issue-12997-2.rs
+++ b/src/test/compile-fail/issue-12997-2.rs
@@ -15,6 +15,3 @@
 #[bench]
 fn bar(x: isize) { }
 //~^ ERROR mismatched types
-//~| expected type `for<'r> fn(&'r mut __test::test::Bencher)`
-//~| found type `fn(isize) {bar}`
-//~| expected mutable reference, found isize
diff --git a/src/test/compile-fail/issue-17252.rs b/src/test/compile-fail/issue-17252.rs
index 0c04e295e14..1c3e6890c8e 100644
--- a/src/test/compile-fail/issue-17252.rs
+++ b/src/test/compile-fail/issue-17252.rs
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-const FOO: usize = FOO; //~ ERROR recursive constant
+const FOO: usize = FOO; //~ ERROR E0391
 
 fn main() {
     let _x: [u8; FOO]; // caused stack overflow prior to fix
     let _y: usize = 1 + {
-        const BAR: usize = BAR; //~ ERROR recursive constant
+        const BAR: usize = BAR;
         let _z: [u8; BAR]; // caused stack overflow prior to fix
         1
     };
diff --git a/src/test/compile-fail/issue-20772.rs b/src/test/compile-fail/issue-20772.rs
index 7ae4250d420..88395e5f1ea 100644
--- a/src/test/compile-fail/issue-20772.rs
+++ b/src/test/compile-fail/issue-20772.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 trait T : Iterator<Item=Self::Item>
-//~^ ERROR unsupported cyclic reference between types/traits detected
+//~^ ERROR cyclic dependency detected
 //~| ERROR associated type `Item` not found for `Self`
 {}
 
diff --git a/src/test/compile-fail/issue-20825.rs b/src/test/compile-fail/issue-20825.rs
index 7d082a3148f..aeb798b3828 100644
--- a/src/test/compile-fail/issue-20825.rs
+++ b/src/test/compile-fail/issue-20825.rs
@@ -13,7 +13,7 @@ pub trait Subscriber {
 }
 
 pub trait Processor: Subscriber<Input = Self::Input> {
-    //~^ ERROR unsupported cyclic reference between types/traits detected [E0391]
+    //~^ ERROR cyclic dependency detected [E0391]
     type Input;
 }
 
diff --git a/src/test/compile-fail/issue-21177.rs b/src/test/compile-fail/issue-21177.rs
index f49b7195383..40c95b98f12 100644
--- a/src/test/compile-fail/issue-21177.rs
+++ b/src/test/compile-fail/issue-21177.rs
@@ -14,7 +14,7 @@ trait Trait {
 }
 
 fn foo<T: Trait<A = T::B>>() { }
-//~^ ERROR unsupported cyclic reference between types/traits detected
+//~^ ERROR cyclic dependency detected
 //~| ERROR associated type `B` not found for `T`
 
 fn main() { }
diff --git a/src/test/compile-fail/issue-22673.rs b/src/test/compile-fail/issue-22673.rs
index 442e6bcda5a..fde2d001542 100644
--- a/src/test/compile-fail/issue-22673.rs
+++ b/src/test/compile-fail/issue-22673.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 trait Expr : PartialEq<Self::Item> {
-    //~^ ERROR: unsupported cyclic reference between types/traits detected
+    //~^ ERROR: cyclic dependency detected
     type Item;
 }
 
diff --git a/src/test/compile-fail/issue-26548.rs b/src/test/compile-fail/issue-26548.rs
index 39c6e97268f..16a650cc6d8 100644
--- a/src/test/compile-fail/issue-26548.rs
+++ b/src/test/compile-fail/issue-26548.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: unsupported cyclic reference between types/traits detected
+// error-pattern: cyclic dependency detected
 // note-pattern: the cycle begins when computing layout of
 // note-pattern: ...which then requires computing layout of
 // note-pattern: ...which then again requires computing layout of
diff --git a/src/test/compile-fail/issue-34373.rs b/src/test/compile-fail/issue-34373.rs
index 7bbc680197e..b18e05af47c 100644
--- a/src/test/compile-fail/issue-34373.rs
+++ b/src/test/compile-fail/issue-34373.rs
@@ -15,7 +15,7 @@ trait Trait<T> {
 }
 
 pub struct Foo<T = Box<Trait<DefaultFoo>>>;
-type DefaultFoo = Foo; //~ ERROR unsupported cyclic reference
+type DefaultFoo = Foo; //~ ERROR cyclic dependency detected
 
 fn main() {
 }
diff --git a/src/test/compile-fail/issue-44415.rs b/src/test/compile-fail/issue-44415.rs
index 3b7089f4975..930a427e9a5 100644
--- a/src/test/compile-fail/issue-44415.rs
+++ b/src/test/compile-fail/issue-44415.rs
@@ -15,7 +15,7 @@ use std::intrinsics;
 
 struct Foo {
     bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
-    //~^ ERROR unsupported cyclic reference between types/traits detected
+    //~^ ERROR cyclic dependency detected
     x: usize,
 }
 
diff --git a/src/test/compile-fail/issue-48131.rs b/src/test/compile-fail/issue-48131.rs
new file mode 100644
index 00000000000..9eb567a5d3e
--- /dev/null
+++ b/src/test/compile-fail/issue-48131.rs
@@ -0,0 +1,39 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This note is annotated because the purpose of the test
+// is to ensure that certain other notes are not generated.
+#![deny(unused_unsafe)] //~ NOTE
+
+// (test that no note is generated on this unsafe fn)
+pub unsafe fn a() {
+    fn inner() {
+        unsafe { /* unnecessary */ } //~ ERROR unnecessary `unsafe`
+                                     //~^ NOTE
+    }
+
+    inner()
+}
+
+pub fn b() {
+    // (test that no note is generated on this unsafe block)
+    unsafe {
+        fn inner() {
+            unsafe { /* unnecessary */ } //~ ERROR unnecessary `unsafe`
+                                         //~^ NOTE
+        }
+
+        let () = ::std::mem::uninitialized();
+
+        inner()
+    }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/resolve-self-in-impl.rs b/src/test/compile-fail/resolve-self-in-impl.rs
index 55ae37404a9..7210c857125 100644
--- a/src/test/compile-fail/resolve-self-in-impl.rs
+++ b/src/test/compile-fail/resolve-self-in-impl.rs
@@ -21,10 +21,10 @@ impl Tr for S where Self: Copy {} // OK
 impl Tr for S where S<Self>: Copy {} // OK
 impl Tr for S where Self::A: Copy {} // OK
 
-impl Tr for Self {} //~ ERROR unsupported cyclic reference between types/traits detected
-impl Tr for S<Self> {} //~ ERROR unsupported cyclic reference between types/traits detected
-impl Self {} //~ ERROR unsupported cyclic reference between types/traits detected
-impl S<Self> {} //~ ERROR unsupported cyclic reference between types/traits detected
-impl Tr<Self::A> for S {} //~ ERROR unsupported cyclic reference between types/traits detected
+impl Tr for Self {} //~ ERROR cyclic dependency detected
+impl Tr for S<Self> {} //~ ERROR cyclic dependency detected
+impl Self {} //~ ERROR cyclic dependency detected
+impl S<Self> {} //~ ERROR cyclic dependency detected
+impl Tr<Self::A> for S {} //~ ERROR cyclic dependency detected
 
 fn main() {}
diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs
index a63162cf73d..93e2561adf7 100644
--- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs
+++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs
@@ -10,6 +10,6 @@
 #![feature(termination_trait)]
 
 fn main() -> char {
-//~^ ERROR: the trait bound `char: std::Termination` is not satisfied
+//~^ ERROR: the trait bound `char: std::process::Termination` is not satisfied
     ' '
 }
diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs
index 788c38c55be..e87e0ceebf1 100644
--- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs
+++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs
@@ -12,6 +12,6 @@
 
 struct ReturnType {}
 
-fn main() -> ReturnType { //~ ERROR `ReturnType: std::Termination` is not satisfied
+fn main() -> ReturnType { //~ ERROR `ReturnType: std::process::Termination` is not satisfied
     ReturnType {}
 }
diff --git a/src/test/run-pass/termination-trait-for-result-box-error_ok.rs b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs
index 269ac451cf4..c1dd44a9176 100644
--- a/src/test/run-pass/termination-trait-for-result-box-error_ok.rs
+++ b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs
@@ -1,4 +1,4 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -10,8 +10,8 @@
 
 #![feature(termination_trait)]
 
-use std::io::Error;
+// error-pattern:oh, dear
 
-fn main() -> Result<(), Box<Error>> {
-    Ok(())
+fn main() -> ! {
+    panic!("oh, dear");
 }
diff --git a/src/test/run-pass/impl-trait/lifetimes.rs b/src/test/run-pass/impl-trait/lifetimes.rs
index 213a46ded8e..2d5dfb045db 100644
--- a/src/test/run-pass/impl-trait/lifetimes.rs
+++ b/src/test/run-pass/impl-trait/lifetimes.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait, underscore_lifetimes, universal_impl_trait, nested_impl_trait)]
+#![feature(conservative_impl_trait, underscore_lifetimes, universal_impl_trait)]
 #![allow(warnings)]
 
 use std::fmt::Debug;
@@ -63,12 +63,11 @@ fn pass_through_elision_with_fn_ptr(x: &fn(&u32) -> &u32) -> impl Into<&fn(&u32)
 
 fn pass_through_elision_with_fn_path<T: Fn(&u32) -> &u32>(
     x: &T
-) -> impl Into<&impl Fn(&u32) -> &u32> { x }
+) -> &impl Fn(&u32) -> &u32 { x }
 
-fn foo(x: &impl Debug) -> impl Into<&impl Debug> { x }
-fn foo_explicit_lifetime<'a>(x: &'a impl Debug) -> impl Into<&'a impl Debug> { x }
-fn foo_no_outer_impl(x: &impl Debug) -> &impl Debug { x }
-fn foo_explicit_arg<T: Debug>(x: &T) -> impl Into<&impl Debug> { x }
+fn foo(x: &impl Debug) -> &impl Debug { x }
+fn foo_explicit_lifetime<'a>(x: &'a impl Debug) -> &'a impl Debug { x }
+fn foo_explicit_arg<T: Debug>(x: &T) -> &impl Debug { x }
 
 fn mixed_lifetimes<'a>() -> impl for<'b: 'a> Fn(&'b u32) { |_| () }
 fn mixed_as_static() -> impl Fn(&'static u32) { mixed_lifetimes() }
diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs
new file mode 100644
index 00000000000..494500d522a
--- /dev/null
+++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs
@@ -0,0 +1,43 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: --test
+
+#![feature(termination_trait)]
+#![feature(test)]
+
+extern crate test;
+use std::num::ParseIntError;
+use test::Bencher;
+
+#[test]
+fn is_a_num() -> Result<(), ParseIntError> {
+    let _: u32 = "22".parse()?;
+    Ok(())
+}
+
+#[test]
+#[should_panic]
+fn not_a_num() -> Result<(), ParseIntError> {
+    let _: u32 = "abc".parse()?;
+    Ok(())
+}
+
+#[bench]
+fn test_a_positive_bench(_: &mut Bencher) -> Result<(), ParseIntError> {
+    Ok(())
+}
+
+#[bench]
+#[should_panic]
+fn test_a_neg_bench(_: &mut Bencher) -> Result<(), ParseIntError> {
+    let _: u32 = "abc".parse()?;
+    Ok(())
+}
diff --git a/src/test/run-pass/rfc-2126-extern-absolute-paths/test.rs b/src/test/run-pass/rfc-2126-extern-absolute-paths/test.rs
new file mode 100644
index 00000000000..796f652d6b5
--- /dev/null
+++ b/src/test/run-pass/rfc-2126-extern-absolute-paths/test.rs
@@ -0,0 +1,21 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Check that `#[test]` works with extern-absolute-paths enabled.
+//
+// Regression test for #47075.
+
+// compile-flags: --test
+
+#![feature(extern_absolute_paths)]
+
+#[test]
+fn test() {
+}
diff --git a/src/test/ui/cycle-trait-supertrait-indirect.rs b/src/test/ui/cycle-trait-supertrait-indirect.rs
index c3b0276bcf9..447505e886f 100644
--- a/src/test/ui/cycle-trait-supertrait-indirect.rs
+++ b/src/test/ui/cycle-trait-supertrait-indirect.rs
@@ -18,7 +18,7 @@ trait B: C {
 }
 
 trait C: B { }
-    //~^ ERROR unsupported cyclic reference
+    //~^ ERROR cyclic dependency detected
     //~| cyclic reference
 
 fn main() { }
diff --git a/src/test/ui/cycle-trait-supertrait-indirect.stderr b/src/test/ui/cycle-trait-supertrait-indirect.stderr
index 107644037a9..a0156554646 100644
--- a/src/test/ui/cycle-trait-supertrait-indirect.stderr
+++ b/src/test/ui/cycle-trait-supertrait-indirect.stderr
@@ -1,4 +1,4 @@
-error[E0391]: unsupported cyclic reference between types/traits detected
+error[E0391]: cyclic dependency detected
   --> $DIR/cycle-trait-supertrait-indirect.rs:20:1
    |
 20 | trait C: B { }
diff --git a/src/test/ui/error-codes/E0657.rs b/src/test/ui/error-codes/E0657.rs
index 4595e413081..31b3acd86ef 100644
--- a/src/test/ui/error-codes/E0657.rs
+++ b/src/test/ui/error-codes/E0657.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 #![allow(warnings)]
-#![feature(conservative_impl_trait, nested_impl_trait)]
+#![feature(conservative_impl_trait)]
 
 trait Id<T> {}
 trait Lt<'a> {}
@@ -17,7 +17,7 @@ impl<'a> Lt<'a> for () {}
 impl<T> Id<T> for T {}
 
 fn free_fn_capture_hrtb_in_impl_trait()
-    -> impl for<'a> Id<impl Lt<'a>>
+    -> Box<for<'a> Id<impl Lt<'a>>>
         //~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level [E0657]
 {
     ()
@@ -26,7 +26,7 @@ fn free_fn_capture_hrtb_in_impl_trait()
 struct Foo;
 impl Foo {
     fn impl_fn_capture_hrtb_in_impl_trait()
-        -> impl for<'a> Id<impl Lt<'a>>
+        -> Box<for<'a> Id<impl Lt<'a>>>
             //~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level
     {
         ()
diff --git a/src/test/ui/error-codes/E0657.stderr b/src/test/ui/error-codes/E0657.stderr
index d3b53d37a30..e039d645fa6 100644
--- a/src/test/ui/error-codes/E0657.stderr
+++ b/src/test/ui/error-codes/E0657.stderr
@@ -1,14 +1,14 @@
 error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
-  --> $DIR/E0657.rs:20:32
+  --> $DIR/E0657.rs:20:31
    |
-20 |     -> impl for<'a> Id<impl Lt<'a>>
-   |                                ^^
+20 |     -> Box<for<'a> Id<impl Lt<'a>>>
+   |                               ^^
 
 error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
-  --> $DIR/E0657.rs:29:36
+  --> $DIR/E0657.rs:29:35
    |
-29 |         -> impl for<'a> Id<impl Lt<'a>>
-   |                                    ^^
+29 |         -> Box<for<'a> Id<impl Lt<'a>>>
+   |                                   ^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/impl-trait/auto-trait-leak.rs b/src/test/ui/impl-trait/auto-trait-leak.rs
index 705390e3b96..5a6aac43ec7 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.rs
+++ b/src/test/ui/impl-trait/auto-trait-leak.rs
@@ -42,7 +42,7 @@ fn after() -> impl Fn(i32) {
 // independently resolved and only require the concrete
 // return type, which can't depend on the obligation.
 fn cycle1() -> impl Clone {
-    //~^ ERROR unsupported cyclic reference between types/traits detected
+    //~^ ERROR cyclic dependency detected
     //~| cyclic reference
     send(cycle2().clone());
 
diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr
index 838a3002e3a..d6e31ba1e1f 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.stderr
+++ b/src/test/ui/impl-trait/auto-trait-leak.stderr
@@ -28,7 +28,7 @@ note: required by `send`
 24 | fn send<T: Send>(_: T) {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0391]: unsupported cyclic reference between types/traits detected
+error[E0391]: cyclic dependency detected
   --> $DIR/auto-trait-leak.rs:44:1
    |
 44 | fn cycle1() -> impl Clone {
diff --git a/src/test/ui/impl_trait_projections.rs b/src/test/ui/impl_trait_projections.rs
new file mode 100644
index 00000000000..f69a78b1450
--- /dev/null
+++ b/src/test/ui/impl_trait_projections.rs
@@ -0,0 +1,50 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+#![feature(dyn_trait, conservative_impl_trait, universal_impl_trait)]
+
+use std::fmt::Debug;
+use std::option;
+
+fn parametrized_type_is_allowed() -> Option<impl Debug> {
+    Some(5i32)
+}
+
+fn path_parametrized_type_is_allowed() -> option::Option<impl Debug> {
+    Some(5i32)
+}
+
+fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item {
+//~^ ERROR `impl Trait` is not allowed in path parameters
+//~^^ ERROR ambiguous associated type
+    x.next().unwrap()
+}
+
+fn projection_with_named_trait_is_disallowed(x: impl Iterator)
+    -> <impl Iterator as Iterator>::Item
+//~^ ERROR `impl Trait` is not allowed in path parameters
+{
+    x.next().unwrap()
+}
+
+fn projection_with_named_trait_inside_path_is_disallowed()
+    -> <::std::ops::Range<impl Debug> as Iterator>::Item
+//~^ ERROR `impl Trait` is not allowed in path parameters
+{
+    (1i32..100).next().unwrap()
+}
+
+fn projection_from_impl_trait_inside_dyn_trait_is_disallowed()
+    -> <dyn Iterator<Item = impl Debug> as Iterator>::Item
+//~^ ERROR `impl Trait` is not allowed in path parameters
+{
+    panic!()
+}
+
+fn main() {}
diff --git a/src/test/ui/impl_trait_projections.stderr b/src/test/ui/impl_trait_projections.stderr
new file mode 100644
index 00000000000..08de0eb99a3
--- /dev/null
+++ b/src/test/ui/impl_trait_projections.stderr
@@ -0,0 +1,34 @@
+error[E0667]: `impl Trait` is not allowed in path parameters
+  --> $DIR/impl_trait_projections.rs:23:51
+   |
+23 | fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item {
+   |                                                   ^^^^^^^^^^^^^
+
+error[E0667]: `impl Trait` is not allowed in path parameters
+  --> $DIR/impl_trait_projections.rs:30:9
+   |
+30 |     -> <impl Iterator as Iterator>::Item
+   |         ^^^^^^^^^^^^^
+
+error[E0667]: `impl Trait` is not allowed in path parameters
+  --> $DIR/impl_trait_projections.rs:37:27
+   |
+37 |     -> <::std::ops::Range<impl Debug> as Iterator>::Item
+   |                           ^^^^^^^^^^
+
+error[E0667]: `impl Trait` is not allowed in path parameters
+  --> $DIR/impl_trait_projections.rs:44:29
+   |
+44 |     -> <dyn Iterator<Item = impl Debug> as Iterator>::Item
+   |                             ^^^^^^^^^^
+
+error[E0223]: ambiguous associated type
+  --> $DIR/impl_trait_projections.rs:23:50
+   |
+23 | fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item {
+   |                                                  ^^^^^^^^^^^^^^^^^^^^^ ambiguous associated type
+   |
+   = note: specify the type using the syntax `<impl std::iter::Iterator as Trait>::Item`
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/issue-12511.rs b/src/test/ui/issue-12511.rs
index e1335c7d558..e4d60768687 100644
--- a/src/test/ui/issue-12511.rs
+++ b/src/test/ui/issue-12511.rs
@@ -12,7 +12,7 @@ trait t1 : t2 {
 }
 
 trait t2 : t1 {
-//~^ ERROR unsupported cyclic reference between types/traits detected
+//~^ ERROR cyclic dependency detected
 //~| cyclic reference
 }
 
diff --git a/src/test/ui/issue-12511.stderr b/src/test/ui/issue-12511.stderr
index cbf005a70b0..aec828a90d1 100644
--- a/src/test/ui/issue-12511.stderr
+++ b/src/test/ui/issue-12511.stderr
@@ -1,4 +1,4 @@
-error[E0391]: unsupported cyclic reference between types/traits detected
+error[E0391]: cyclic dependency detected
   --> $DIR/issue-12511.rs:14:1
    |
 14 | trait t2 : t1 {
diff --git a/src/test/ui/issue-23302.rs b/src/test/ui/issue-23302-1.rs
index 2d93ab0c30c..10a53830116 100644
--- a/src/test/ui/issue-23302.rs
+++ b/src/test/ui/issue-23302-1.rs
@@ -11,18 +11,7 @@
 // Check that an enum with recursion in the discriminant throws
 // the appropriate error (rather than, say, blowing the stack).
 enum X {
-    A = X::A as isize, //~ ERROR E0265
+    A = X::A as isize, //~ ERROR E0391
 }
 
-// Since `Y::B` here defaults to `Y::A+1`, this is also a
-// recursive definition.
-enum Y {
-    A = Y::B as isize, //~ ERROR E0265
-    B,
-}
-
-const A: i32 = B; //~ ERROR E0265
-
-const B: i32 = A; //~ ERROR E0265
-
 fn main() { }
diff --git a/src/test/ui/issue-23302-1.stderr b/src/test/ui/issue-23302-1.stderr
new file mode 100644
index 00000000000..0658c07fb1d
--- /dev/null
+++ b/src/test/ui/issue-23302-1.stderr
@@ -0,0 +1,15 @@
+error[E0391]: cyclic dependency detected
+  --> $DIR/issue-23302-1.rs:14:9
+   |
+14 |     A = X::A as isize, //~ ERROR E0391
+   |         ^^^^^^^^^^^^^ cyclic reference
+   |
+note: the cycle begins when const-evaluating `X::A::{{initializer}}`...
+  --> $DIR/issue-23302-1.rs:14:5
+   |
+14 |     A = X::A as isize, //~ ERROR E0391
+   |     ^^^^^^^^^^^^^^^^^
+   = note: ...which then again requires const-evaluating `X::A::{{initializer}}`, completing the cycle.
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/issue-23302-2.rs b/src/test/ui/issue-23302-2.rs
new file mode 100644
index 00000000000..d1af19eb579
--- /dev/null
+++ b/src/test/ui/issue-23302-2.rs
@@ -0,0 +1,18 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Since `Y::B` here defaults to `Y::A+1`, this is also a
+// recursive definition.
+enum Y {
+    A = Y::B as isize, //~ ERROR E0391
+    B,
+}
+
+fn main() { }
diff --git a/src/test/ui/issue-23302-2.stderr b/src/test/ui/issue-23302-2.stderr
new file mode 100644
index 00000000000..c4a1c4f80c8
--- /dev/null
+++ b/src/test/ui/issue-23302-2.stderr
@@ -0,0 +1,15 @@
+error[E0391]: cyclic dependency detected
+  --> $DIR/issue-23302-2.rs:14:9
+   |
+14 |     A = Y::B as isize, //~ ERROR E0391
+   |         ^^^^^^^^^^^^^ cyclic reference
+   |
+note: the cycle begins when const-evaluating `Y::A::{{initializer}}`...
+  --> $DIR/issue-23302-2.rs:14:5
+   |
+14 |     A = Y::B as isize, //~ ERROR E0391
+   |     ^^^^^^^^^^^^^^^^^
+   = note: ...which then again requires const-evaluating `Y::A::{{initializer}}`, completing the cycle.
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail/const-recursive.rs b/src/test/ui/issue-23302-3.rs
index 7c05a817243..1d750b09025 100644
--- a/src/test/compile-fail/const-recursive.rs
+++ b/src/test/ui/issue-23302-3.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-const a: isize = b; //~ ERROR recursive constant
-const b: isize = a; //~ ERROR recursive constant
+const A: i32 = B; //~ ERROR E0391
 
-fn main() {
-}
+const B: i32 = A;
+
+fn main() { }
diff --git a/src/test/ui/issue-23302-3.stderr b/src/test/ui/issue-23302-3.stderr
new file mode 100644
index 00000000000..76f543cff79
--- /dev/null
+++ b/src/test/ui/issue-23302-3.stderr
@@ -0,0 +1,20 @@
+error[E0391]: cyclic dependency detected
+  --> $DIR/issue-23302-3.rs:11:16
+   |
+11 | const A: i32 = B; //~ ERROR E0391
+   |                ^ cyclic reference
+   |
+note: the cycle begins when processing `B`...
+  --> $DIR/issue-23302-3.rs:13:1
+   |
+13 | const B: i32 = A;
+   | ^^^^^^^^^^^^^^^^^
+note: ...which then requires processing `A`...
+  --> $DIR/issue-23302-3.rs:13:16
+   |
+13 | const B: i32 = A;
+   |                ^
+   = note: ...which then again requires processing `B`, completing the cycle.
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/issue-23302.stderr b/src/test/ui/issue-23302.stderr
deleted file mode 100644
index 4e93809fac3..00000000000
--- a/src/test/ui/issue-23302.stderr
+++ /dev/null
@@ -1,26 +0,0 @@
-error[E0265]: recursive constant
-  --> $DIR/issue-23302.rs:14:9
-   |
-14 |     A = X::A as isize, //~ ERROR E0265
-   |         ^^^^^^^^^^^^^ recursion not allowed in constant
-
-error[E0265]: recursive constant
-  --> $DIR/issue-23302.rs:20:9
-   |
-20 |     A = Y::B as isize, //~ ERROR E0265
-   |         ^^^^^^^^^^^^^ recursion not allowed in constant
-
-error[E0265]: recursive constant
-  --> $DIR/issue-23302.rs:24:1
-   |
-24 | const A: i32 = B; //~ ERROR E0265
-   | ^^^^^^^^^^^^^^^^^ recursion not allowed in constant
-
-error[E0265]: recursive constant
-  --> $DIR/issue-23302.rs:26:1
-   |
-26 | const B: i32 = A; //~ ERROR E0265
-   | ^^^^^^^^^^^^^^^^^ recursion not allowed in constant
-
-error: aborting due to 4 previous errors
-
diff --git a/src/test/ui/issue-36163.rs b/src/test/ui/issue-36163.rs
index 2337f82afa4..4c74d9d9173 100644
--- a/src/test/ui/issue-36163.rs
+++ b/src/test/ui/issue-36163.rs
@@ -8,16 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-const A: i32 = Foo::B; //~ ERROR E0265
+const A: isize = Foo::B as isize;
 
 enum Foo {
-    B = A, //~ ERROR E0265
+    B = A, //~ ERROR E0391
 }
 
-enum Bar {
-    C = Bar::C, //~ ERROR E0265
-}
-
-const D: i32 = A;
-
 fn main() {}
diff --git a/src/test/ui/issue-36163.stderr b/src/test/ui/issue-36163.stderr
index 5a107d88f2e..d0337fc32b0 100644
--- a/src/test/ui/issue-36163.stderr
+++ b/src/test/ui/issue-36163.stderr
@@ -1,20 +1,20 @@
-error[E0265]: recursive constant
-  --> $DIR/issue-36163.rs:11:1
-   |
-11 | const A: i32 = Foo::B; //~ ERROR E0265
-   | ^^^^^^^^^^^^^^^^^^^^^^ recursion not allowed in constant
-
-error[E0265]: recursive constant
+error[E0391]: cyclic dependency detected
   --> $DIR/issue-36163.rs:14:9
    |
-14 |     B = A, //~ ERROR E0265
-   |         ^ recursion not allowed in constant
-
-error[E0265]: recursive constant
-  --> $DIR/issue-36163.rs:18:9
+14 |     B = A, //~ ERROR E0391
+   |         ^ cyclic reference
+   |
+note: the cycle begins when const-evaluating `Foo::B::{{initializer}}`...
+  --> $DIR/issue-36163.rs:14:5
+   |
+14 |     B = A, //~ ERROR E0391
+   |     ^^^^^
+note: ...which then requires const-evaluating `A`...
+  --> $DIR/issue-36163.rs:14:9
    |
-18 |     C = Bar::C, //~ ERROR E0265
-   |         ^^^^^^ recursion not allowed in constant
+14 |     B = A, //~ ERROR E0391
+   |         ^
+   = note: ...which then again requires const-evaluating `Foo::B::{{initializer}}`, completing the cycle.
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
diff --git a/src/test/ui/issue-47706.rs b/src/test/ui/issue-47706.rs
index 24a0f66f5b1..9c521dd6479 100644
--- a/src/test/ui/issue-47706.rs
+++ b/src/test/ui/issue-47706.rs
@@ -22,3 +22,18 @@ impl Foo {
     }
     //~^^ ERROR function is expected to take 1 argument, but it takes 2 arguments [E0593]
 }
+
+enum Qux {
+    Bar(i32),
+}
+
+fn foo<F>(f: F)
+where
+    F: Fn(),
+{
+}
+
+fn main() {
+    foo(Qux::Bar);
+}
+//~^^ ERROR function is expected to take 0 arguments, but it takes 1 argument [E0593]
diff --git a/src/test/ui/issue-47706.stderr b/src/test/ui/issue-47706.stderr
index 0916dc64292..e197c09062d 100644
--- a/src/test/ui/issue-47706.stderr
+++ b/src/test/ui/issue-47706.stderr
@@ -1,5 +1,3 @@
-error[E0601]: main function not found
-
 error[E0593]: function is expected to take 1 argument, but it takes 2 arguments
   --> $DIR/issue-47706.rs:21:18
    |
@@ -9,5 +7,24 @@ error[E0593]: function is expected to take 1 argument, but it takes 2 arguments
 21 |         self.foo.map(Foo::new)
    |                  ^^^ expected function that takes 1 argument
 
+error[E0593]: function is expected to take 0 arguments, but it takes 1 argument
+  --> $DIR/issue-47706.rs:37:5
+   |
+27 |     Bar(i32),
+   |     -------- takes 1 argument
+...
+37 |     foo(Qux::Bar);
+   |     ^^^ expected function that takes 0 arguments
+   |
+note: required by `foo`
+  --> $DIR/issue-47706.rs:30:1
+   |
+30 | / fn foo<F>(f: F)
+31 | | where
+32 | |     F: Fn(),
+33 | | {
+34 | | }
+   | |_^
+
 error: aborting due to 2 previous errors
 
diff --git a/src/test/compile-fail/feature-gate-nested_impl_trait.rs b/src/test/ui/nested_impl_trait.rs
index 7c35263d05d..f6302c0f3b3 100644
--- a/src/test/compile-fail/feature-gate-nested_impl_trait.rs
+++ b/src/test/ui/nested_impl_trait.rs
@@ -14,18 +14,19 @@ use std::fmt::Debug;
 fn fine(x: impl Into<u32>) -> impl Into<u32> { x }
 
 fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
-//~^ ERROR nested `impl Trait` is experimental
+//~^ ERROR nested `impl Trait` is not allowed
 
 fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
-//~^ ERROR nested `impl Trait` is experimental
+//~^ ERROR nested `impl Trait` is not allowed
+//~^^ `impl Trait` not allowed
 
 fn bad_in_arg_position(_: impl Into<impl Debug>) { }
-//~^ ERROR nested `impl Trait` is experimental
+//~^ ERROR nested `impl Trait` is not allowed
 
 struct X;
 impl X {
     fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
-    //~^ ERROR nested `impl Trait` is experimental
+    //~^ ERROR nested `impl Trait` is not allowed
 }
 
 fn allowed_in_assoc_type() -> impl Iterator<Item=impl Fn()> {
@@ -33,6 +34,7 @@ fn allowed_in_assoc_type() -> impl Iterator<Item=impl Fn()> {
 }
 
 fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
+//~^ `impl Trait` not allowed
     || 5
 }
 
diff --git a/src/test/ui/nested_impl_trait.stderr b/src/test/ui/nested_impl_trait.stderr
new file mode 100644
index 00000000000..094926120cd
--- /dev/null
+++ b/src/test/ui/nested_impl_trait.stderr
@@ -0,0 +1,50 @@
+error[E0666]: nested `impl Trait` is not allowed
+  --> $DIR/nested_impl_trait.rs:16:56
+   |
+16 | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
+   |                                              ----------^^^^^^^^^^-
+   |                                              |         |
+   |                                              |         nested `impl Trait` here
+   |                                              outer `impl Trait`
+
+error[E0666]: nested `impl Trait` is not allowed
+  --> $DIR/nested_impl_trait.rs:19:42
+   |
+19 | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
+   |                                ----------^^^^^^^^^^-
+   |                                |         |
+   |                                |         nested `impl Trait` here
+   |                                outer `impl Trait`
+
+error[E0666]: nested `impl Trait` is not allowed
+  --> $DIR/nested_impl_trait.rs:23:37
+   |
+23 | fn bad_in_arg_position(_: impl Into<impl Debug>) { }
+   |                           ----------^^^^^^^^^^-
+   |                           |         |
+   |                           |         nested `impl Trait` here
+   |                           outer `impl Trait`
+
+error[E0666]: nested `impl Trait` is not allowed
+  --> $DIR/nested_impl_trait.rs:28:44
+   |
+28 |     fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
+   |                                  ----------^^^^^^^^^^-
+   |                                  |         |
+   |                                  |         nested `impl Trait` here
+   |                                  outer `impl Trait`
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/nested_impl_trait.rs:19:32
+   |
+19 | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
+   |                                ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/nested_impl_trait.rs:36:42
+   |
+36 | fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
+   |                                          ^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
index b2e98b7c2f6..30669dc4c2f 100644
--- a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
@@ -25,53 +25,6 @@ note: External requirements
    = note: number of external vids: 3
    = note: where <T as std::iter::Iterator>::Item: '_#2r
 
-note: External requirements
-  --> $DIR/projection-no-regions-closure.rs:46:23
-   |
-46 |     with_signature(x, |mut y| Box::new(y.next()))
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: defining type: DefId(0/1:18 ~ projection_no_regions_closure[317d]::correct_region[0]::{{closure}}[0]) with closure substs [
-               '_#1r,
-               T,
-               i32,
-               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#2r>
-           ]
-   = note: number of external vids: 3
-   = note: where <T as std::iter::Iterator>::Item: '_#2r
-
-note: External requirements
-  --> $DIR/projection-no-regions-closure.rs:54:23
-   |
-54 |     with_signature(x, |mut y| Box::new(y.next()))
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: defining type: DefId(0/1:22 ~ projection_no_regions_closure[317d]::wrong_region[0]::{{closure}}[0]) with closure substs [
-               '_#1r,
-               '_#2r,
-               T,
-               i32,
-               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#3r>
-           ]
-   = note: number of external vids: 4
-   = note: where <T as std::iter::Iterator>::Item: '_#3r
-
-note: External requirements
-  --> $DIR/projection-no-regions-closure.rs:65:23
-   |
-65 |     with_signature(x, |mut y| Box::new(y.next()))
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: defining type: DefId(0/1:26 ~ projection_no_regions_closure[317d]::outlives_region[0]::{{closure}}[0]) with closure substs [
-               '_#1r,
-               '_#2r,
-               T,
-               i32,
-               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#3r>
-           ]
-   = note: number of external vids: 4
-   = note: where <T as std::iter::Iterator>::Item: '_#3r
-
 error[E0309]: the associated type `<T as std::iter::Iterator>::Item` may not live long enough
   --> $DIR/projection-no-regions-closure.rs:36:23
    |
@@ -97,6 +50,21 @@ note: No external requirements
                T
            ]
 
+note: External requirements
+  --> $DIR/projection-no-regions-closure.rs:46:23
+   |
+46 |     with_signature(x, |mut y| Box::new(y.next()))
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:18 ~ projection_no_regions_closure[317d]::correct_region[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               T,
+               i32,
+               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#2r>
+           ]
+   = note: number of external vids: 3
+   = note: where <T as std::iter::Iterator>::Item: '_#2r
+
 note: No external requirements
   --> $DIR/projection-no-regions-closure.rs:42:1
    |
@@ -113,6 +81,22 @@ note: No external requirements
                T
            ]
 
+note: External requirements
+  --> $DIR/projection-no-regions-closure.rs:54:23
+   |
+54 |     with_signature(x, |mut y| Box::new(y.next()))
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:22 ~ projection_no_regions_closure[317d]::wrong_region[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               T,
+               i32,
+               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#3r>
+           ]
+   = note: number of external vids: 4
+   = note: where <T as std::iter::Iterator>::Item: '_#3r
+
 error[E0309]: the associated type `<T as std::iter::Iterator>::Item` may not live long enough
   --> $DIR/projection-no-regions-closure.rs:54:23
    |
@@ -139,6 +123,22 @@ note: No external requirements
                T
            ]
 
+note: External requirements
+  --> $DIR/projection-no-regions-closure.rs:65:23
+   |
+65 |     with_signature(x, |mut y| Box::new(y.next()))
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:26 ~ projection_no_regions_closure[317d]::outlives_region[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               T,
+               i32,
+               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#3r>
+           ]
+   = note: number of external vids: 4
+   = note: where <T as std::iter::Iterator>::Item: '_#3r
+
 note: No external requirements
   --> $DIR/projection-no-regions-closure.rs:60:1
    |
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
index bfe408342a8..946c1a8f372 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
@@ -32,57 +32,6 @@ note: External requirements
    = note: where T: '_#2r
    = note: where '_#1r: '_#2r
 
-note: External requirements
-  --> $DIR/projection-one-region-closure.rs:68:29
-   |
-68 |     with_signature(cell, t, |cell, t| require(cell, t));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: defining type: DefId(0/1:23 ~ projection_one_region_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [
-               '_#1r,
-               '_#2r,
-               T,
-               i32,
-               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
-           ]
-   = note: number of external vids: 4
-   = note: where T: '_#3r
-   = note: where '_#2r: '_#3r
-
-note: External requirements
-  --> $DIR/projection-one-region-closure.rs:90:29
-   |
-90 |     with_signature(cell, t, |cell, t| require(cell, t));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: defining type: DefId(0/1:27 ~ projection_one_region_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [
-               '_#1r,
-               '_#2r,
-               T,
-               i32,
-               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
-           ]
-   = note: number of external vids: 4
-   = note: where T: '_#3r
-   = note: where '_#2r: '_#3r
-
-note: External requirements
-   --> $DIR/projection-one-region-closure.rs:103:29
-    |
-103 |     with_signature(cell, t, |cell, t| require(cell, t));
-    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-    |
-    = note: defining type: DefId(0/1:31 ~ projection_one_region_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [
-                '_#1r,
-                '_#2r,
-                T,
-                i32,
-                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
-            ]
-    = note: number of external vids: 4
-    = note: where T: '_#3r
-    = note: where '_#2r: '_#3r
-
 error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/projection-one-region-closure.rs:56:29
    |
@@ -114,6 +63,23 @@ note: No external requirements
                T
            ]
 
+note: External requirements
+  --> $DIR/projection-one-region-closure.rs:68:29
+   |
+68 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:23 ~ projection_one_region_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
+           ]
+   = note: number of external vids: 4
+   = note: where T: '_#3r
+   = note: where '_#2r: '_#3r
+
 error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/projection-one-region-closure.rs:68:29
    |
@@ -146,6 +112,23 @@ note: No external requirements
                T
            ]
 
+note: External requirements
+  --> $DIR/projection-one-region-closure.rs:90:29
+   |
+90 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:27 ~ projection_one_region_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
+           ]
+   = note: number of external vids: 4
+   = note: where T: '_#3r
+   = note: where '_#2r: '_#3r
+
 error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/projection-one-region-closure.rs:90:29
    |
@@ -178,6 +161,23 @@ note: No external requirements
                T
            ]
 
+note: External requirements
+   --> $DIR/projection-one-region-closure.rs:103:29
+    |
+103 |     with_signature(cell, t, |cell, t| require(cell, t));
+    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+    |
+    = note: defining type: DefId(0/1:31 ~ projection_one_region_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [
+                '_#1r,
+                '_#2r,
+                T,
+                i32,
+                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
+            ]
+    = note: number of external vids: 4
+    = note: where T: '_#3r
+    = note: where '_#2r: '_#3r
+
 note: No external requirements
    --> $DIR/projection-one-region-closure.rs:97:1
     |
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr
index 6cb54170d7a..b26fa96fe63 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr
@@ -31,69 +31,6 @@ note: External requirements
    = note: number of external vids: 3
    = note: where '_#1r: '_#2r
 
-note: External requirements
-  --> $DIR/projection-one-region-trait-bound-closure.rs:59:29
-   |
-59 |     with_signature(cell, t, |cell, t| require(cell, t));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: defining type: DefId(0/1:23 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [
-               '_#1r,
-               '_#2r,
-               T,
-               i32,
-               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
-           ]
-   = note: number of external vids: 4
-   = note: where '_#2r: '_#3r
-
-note: External requirements
-  --> $DIR/projection-one-region-trait-bound-closure.rs:80:29
-   |
-80 |     with_signature(cell, t, |cell, t| require(cell, t));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: defining type: DefId(0/1:27 ~ projection_one_region_trait_bound_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [
-               '_#1r,
-               '_#2r,
-               T,
-               i32,
-               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
-           ]
-   = note: number of external vids: 4
-   = note: where '_#2r: '_#3r
-
-note: External requirements
-  --> $DIR/projection-one-region-trait-bound-closure.rs:91:29
-   |
-91 |     with_signature(cell, t, |cell, t| require(cell, t));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: defining type: DefId(0/1:31 ~ projection_one_region_trait_bound_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [
-               '_#1r,
-               '_#2r,
-               T,
-               i32,
-               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
-           ]
-   = note: number of external vids: 4
-   = note: where '_#2r: '_#3r
-
-note: External requirements
-   --> $DIR/projection-one-region-trait-bound-closure.rs:103:29
-    |
-103 |     with_signature(cell, t, |cell, t| require(cell, t));
-    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-    |
-    = note: defining type: DefId(0/1:34 ~ projection_one_region_trait_bound_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [
-                '_#1r,
-                T,
-                i32,
-                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
-            ]
-    = note: number of external vids: 3
-    = note: where '_#1r: '_#2r
-
 error: free region `ReEarlyBound(0, 'b)` does not outlive free region `ReFree(DefId(0/0:8 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a))`
   --> $DIR/projection-one-region-trait-bound-closure.rs:48:20
    |
@@ -117,6 +54,22 @@ note: No external requirements
                T
            ]
 
+note: External requirements
+  --> $DIR/projection-one-region-trait-bound-closure.rs:59:29
+   |
+59 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:23 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
+           ]
+   = note: number of external vids: 4
+   = note: where '_#2r: '_#3r
+
 error: free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)`
   --> $DIR/projection-one-region-trait-bound-closure.rs:59:20
    |
@@ -141,6 +94,22 @@ note: No external requirements
                T
            ]
 
+note: External requirements
+  --> $DIR/projection-one-region-trait-bound-closure.rs:80:29
+   |
+80 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:27 ~ projection_one_region_trait_bound_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
+           ]
+   = note: number of external vids: 4
+   = note: where '_#2r: '_#3r
+
 error: free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)`
   --> $DIR/projection-one-region-trait-bound-closure.rs:80:20
    |
@@ -165,6 +134,22 @@ note: No external requirements
                T
            ]
 
+note: External requirements
+  --> $DIR/projection-one-region-trait-bound-closure.rs:91:29
+   |
+91 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:31 ~ projection_one_region_trait_bound_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
+           ]
+   = note: number of external vids: 4
+   = note: where '_#2r: '_#3r
+
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-closure.rs:86:1
    |
@@ -183,6 +168,21 @@ note: No external requirements
                T
            ]
 
+note: External requirements
+   --> $DIR/projection-one-region-trait-bound-closure.rs:103:29
+    |
+103 |     with_signature(cell, t, |cell, t| require(cell, t));
+    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+    |
+    = note: defining type: DefId(0/1:34 ~ projection_one_region_trait_bound_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [
+                '_#1r,
+                T,
+                i32,
+                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
+            ]
+    = note: number of external vids: 3
+    = note: where '_#1r: '_#2r
+
 note: No external requirements
    --> $DIR/projection-one-region-trait-bound-closure.rs:95:1
     |
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr
index 986676d28d9..98b033b6a06 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr
@@ -12,40 +12,28 @@ note: No external requirements
            ]
 
 note: No external requirements
-  --> $DIR/projection-one-region-trait-bound-static-closure.rs:56:29
-   |
-56 |     with_signature(cell, t, |cell, t| require(cell, t));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: defining type: DefId(0/1:23 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [
-               '_#1r,
-               '_#2r,
-               T,
-               i32,
-               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
-           ]
-
-note: No external requirements
-  --> $DIR/projection-one-region-trait-bound-static-closure.rs:75:29
+  --> $DIR/projection-one-region-trait-bound-static-closure.rs:43:1
    |
-75 |     with_signature(cell, t, |cell, t| require(cell, t));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+43 | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+44 | | where
+45 | |     T: Anything<'b>,
+46 | | {
+47 | |     with_signature(cell, t, |cell, t| require(cell, t));
+48 | | }
+   | |_^
    |
-   = note: defining type: DefId(0/1:27 ~ projection_one_region_trait_bound_static_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0/0:8 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_late[0]) with substs [
                '_#1r,
-               '_#2r,
-               T,
-               i32,
-               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
+               T
            ]
 
 note: No external requirements
-  --> $DIR/projection-one-region-trait-bound-static-closure.rs:84:29
+  --> $DIR/projection-one-region-trait-bound-static-closure.rs:56:29
    |
-84 |     with_signature(cell, t, |cell, t| require(cell, t));
+56 |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0/1:31 ~ projection_one_region_trait_bound_static_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0/1:23 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                T,
@@ -54,35 +42,6 @@ note: No external requirements
            ]
 
 note: No external requirements
-  --> $DIR/projection-one-region-trait-bound-static-closure.rs:96:29
-   |
-96 |     with_signature(cell, t, |cell, t| require(cell, t));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: defining type: DefId(0/1:34 ~ projection_one_region_trait_bound_static_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [
-               '_#1r,
-               T,
-               i32,
-               extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
-           ]
-
-note: No external requirements
-  --> $DIR/projection-one-region-trait-bound-static-closure.rs:43:1
-   |
-43 | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
-44 | | where
-45 | |     T: Anything<'b>,
-46 | | {
-47 | |     with_signature(cell, t, |cell, t| require(cell, t));
-48 | | }
-   | |_^
-   |
-   = note: defining type: DefId(0/0:8 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_late[0]) with substs [
-               '_#1r,
-               T
-           ]
-
-note: No external requirements
   --> $DIR/projection-one-region-trait-bound-static-closure.rs:51:1
    |
 51 | / fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
@@ -101,6 +60,20 @@ note: No external requirements
            ]
 
 note: No external requirements
+  --> $DIR/projection-one-region-trait-bound-static-closure.rs:75:29
+   |
+75 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:27 ~ projection_one_region_trait_bound_static_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
+           ]
+
+note: No external requirements
   --> $DIR/projection-one-region-trait-bound-static-closure.rs:60:1
    |
 60 | / fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
@@ -119,6 +92,20 @@ note: No external requirements
            ]
 
 note: No external requirements
+  --> $DIR/projection-one-region-trait-bound-static-closure.rs:84:29
+   |
+84 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:31 ~ projection_one_region_trait_bound_static_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
+           ]
+
+note: No external requirements
   --> $DIR/projection-one-region-trait-bound-static-closure.rs:79:1
    |
 79 | / fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
@@ -137,6 +124,19 @@ note: No external requirements
            ]
 
 note: No external requirements
+  --> $DIR/projection-one-region-trait-bound-static-closure.rs:96:29
+   |
+96 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:34 ~ projection_one_region_trait_bound_static_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
+           ]
+
+note: No external requirements
   --> $DIR/projection-one-region-trait-bound-static-closure.rs:88:1
    |
 88 | / fn one_region<'a, T>(cell: Cell<&'a ()>, t: T)
diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
index 21487899d3b..78775ce94ad 100644
--- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
@@ -38,120 +38,6 @@ note: External requirements
    = note: number of external vids: 4
    = note: where <T as Anything<ReClosureBound('_#1r), ReClosureBound('_#2r)>>::AssocType: '_#3r
 
-note: External requirements
-  --> $DIR/projection-two-region-trait-bound-closure.rs:60:29
-   |
-60 |     with_signature(cell, t, |cell, t| require(cell, t));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: defining type: DefId(0/1:27 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [
-               '_#1r,
-               '_#2r,
-               '_#3r,
-               T,
-               i32,
-               extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T))
-           ]
-   = note: number of external vids: 5
-   = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#3r)>>::AssocType: '_#4r
-
-note: External requirements
-  --> $DIR/projection-two-region-trait-bound-closure.rs:81:29
-   |
-81 |     with_signature(cell, t, |cell, t| require(cell, t));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: defining type: DefId(0/1:32 ~ projection_two_region_trait_bound_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [
-               '_#1r,
-               '_#2r,
-               '_#3r,
-               T,
-               i32,
-               extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T))
-           ]
-   = note: number of external vids: 5
-   = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#3r)>>::AssocType: '_#4r
-
-note: External requirements
-  --> $DIR/projection-two-region-trait-bound-closure.rs:92:29
-   |
-92 |     with_signature(cell, t, |cell, t| require(cell, t));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: defining type: DefId(0/1:37 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive1[0]::{{closure}}[0]) with closure substs [
-               '_#1r,
-               '_#2r,
-               '_#3r,
-               T,
-               i32,
-               extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T))
-           ]
-   = note: number of external vids: 5
-   = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#3r)>>::AssocType: '_#4r
-
-note: External requirements
-   --> $DIR/projection-two-region-trait-bound-closure.rs:101:29
-    |
-101 |     with_signature(cell, t, |cell, t| require(cell, t));
-    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-    |
-    = note: defining type: DefId(0/1:42 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive2[0]::{{closure}}[0]) with closure substs [
-                '_#1r,
-                '_#2r,
-                '_#3r,
-                T,
-                i32,
-                extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T))
-            ]
-    = note: number of external vids: 5
-    = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#3r)>>::AssocType: '_#4r
-
-note: External requirements
-   --> $DIR/projection-two-region-trait-bound-closure.rs:109:29
-    |
-109 |     with_signature(cell, t, |cell, t| require(cell, t));
-    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-    |
-    = note: defining type: DefId(0/1:46 ~ projection_two_region_trait_bound_closure[317d]::two_regions[0]::{{closure}}[0]) with closure substs [
-                '_#1r,
-                T,
-                i32,
-                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
-            ]
-    = note: number of external vids: 3
-    = note: where <T as Anything<ReClosureBound('_#1r), ReClosureBound('_#1r)>>::AssocType: '_#2r
-
-note: External requirements
-   --> $DIR/projection-two-region-trait-bound-closure.rs:120:29
-    |
-120 |     with_signature(cell, t, |cell, t| require(cell, t));
-    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-    |
-    = note: defining type: DefId(0/1:50 ~ projection_two_region_trait_bound_closure[317d]::two_regions_outlive[0]::{{closure}}[0]) with closure substs [
-                '_#1r,
-                '_#2r,
-                T,
-                i32,
-                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
-            ]
-    = note: number of external vids: 4
-    = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#2r)>>::AssocType: '_#3r
-
-note: External requirements
-   --> $DIR/projection-two-region-trait-bound-closure.rs:132:29
-    |
-132 |     with_signature(cell, t, |cell, t| require(cell, t));
-    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-    |
-    = note: defining type: DefId(0/1:53 ~ projection_two_region_trait_bound_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [
-                '_#1r,
-                T,
-                i32,
-                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
-            ]
-    = note: number of external vids: 3
-    = note: where <T as Anything<ReClosureBound('_#1r), ReClosureBound('_#1r)>>::AssocType: '_#2r
-
 error[E0309]: the associated type `<T as Anything<'_#5r, '_#6r>>::AssocType` may not live long enough
   --> $DIR/projection-two-region-trait-bound-closure.rs:49:29
    |
@@ -178,6 +64,23 @@ note: No external requirements
                T
            ]
 
+note: External requirements
+  --> $DIR/projection-two-region-trait-bound-closure.rs:60:29
+   |
+60 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:27 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               '_#3r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T))
+           ]
+   = note: number of external vids: 5
+   = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#3r)>>::AssocType: '_#4r
+
 error[E0309]: the associated type `<T as Anything<'_#6r, '_#7r>>::AssocType` may not live long enough
   --> $DIR/projection-two-region-trait-bound-closure.rs:60:29
    |
@@ -205,6 +108,23 @@ note: No external requirements
                T
            ]
 
+note: External requirements
+  --> $DIR/projection-two-region-trait-bound-closure.rs:81:29
+   |
+81 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:32 ~ projection_two_region_trait_bound_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               '_#3r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T))
+           ]
+   = note: number of external vids: 5
+   = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#3r)>>::AssocType: '_#4r
+
 error[E0309]: the associated type `<T as Anything<'_#6r, '_#7r>>::AssocType` may not live long enough
   --> $DIR/projection-two-region-trait-bound-closure.rs:81:29
    |
@@ -232,6 +152,23 @@ note: No external requirements
                T
            ]
 
+note: External requirements
+  --> $DIR/projection-two-region-trait-bound-closure.rs:92:29
+   |
+92 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:37 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive1[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               '_#3r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T))
+           ]
+   = note: number of external vids: 5
+   = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#3r)>>::AssocType: '_#4r
+
 note: No external requirements
   --> $DIR/projection-two-region-trait-bound-closure.rs:87:1
    |
@@ -251,6 +188,23 @@ note: No external requirements
                T
            ]
 
+note: External requirements
+   --> $DIR/projection-two-region-trait-bound-closure.rs:101:29
+    |
+101 |     with_signature(cell, t, |cell, t| require(cell, t));
+    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+    |
+    = note: defining type: DefId(0/1:42 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive2[0]::{{closure}}[0]) with closure substs [
+                '_#1r,
+                '_#2r,
+                '_#3r,
+                T,
+                i32,
+                extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T))
+            ]
+    = note: number of external vids: 5
+    = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#3r)>>::AssocType: '_#4r
+
 note: No external requirements
    --> $DIR/projection-two-region-trait-bound-closure.rs:96:1
     |
@@ -270,6 +224,21 @@ note: No external requirements
                 T
             ]
 
+note: External requirements
+   --> $DIR/projection-two-region-trait-bound-closure.rs:109:29
+    |
+109 |     with_signature(cell, t, |cell, t| require(cell, t));
+    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+    |
+    = note: defining type: DefId(0/1:46 ~ projection_two_region_trait_bound_closure[317d]::two_regions[0]::{{closure}}[0]) with closure substs [
+                '_#1r,
+                T,
+                i32,
+                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
+            ]
+    = note: number of external vids: 3
+    = note: where <T as Anything<ReClosureBound('_#1r), ReClosureBound('_#1r)>>::AssocType: '_#2r
+
 error: free region `ReEarlyBound(0, 'b)` does not outlive free region `ReFree(DefId(0/0:13 ~ projection_two_region_trait_bound_closure[317d]::two_regions[0]), BrNamed(crate0:DefIndex(1:43), 'a))`
    --> $DIR/projection-two-region-trait-bound-closure.rs:109:20
     |
@@ -293,6 +262,22 @@ note: No external requirements
                 T
             ]
 
+note: External requirements
+   --> $DIR/projection-two-region-trait-bound-closure.rs:120:29
+    |
+120 |     with_signature(cell, t, |cell, t| require(cell, t));
+    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+    |
+    = note: defining type: DefId(0/1:50 ~ projection_two_region_trait_bound_closure[317d]::two_regions_outlive[0]::{{closure}}[0]) with closure substs [
+                '_#1r,
+                '_#2r,
+                T,
+                i32,
+                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
+            ]
+    = note: number of external vids: 4
+    = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#2r)>>::AssocType: '_#3r
+
 note: No external requirements
    --> $DIR/projection-two-region-trait-bound-closure.rs:115:1
     |
@@ -311,6 +296,21 @@ note: No external requirements
                 T
             ]
 
+note: External requirements
+   --> $DIR/projection-two-region-trait-bound-closure.rs:132:29
+    |
+132 |     with_signature(cell, t, |cell, t| require(cell, t));
+    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+    |
+    = note: defining type: DefId(0/1:53 ~ projection_two_region_trait_bound_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [
+                '_#1r,
+                T,
+                i32,
+                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
+            ]
+    = note: number of external vids: 3
+    = note: where <T as Anything<ReClosureBound('_#1r), ReClosureBound('_#1r)>>::AssocType: '_#2r
+
 note: No external requirements
    --> $DIR/projection-two-region-trait-bound-closure.rs:124:1
     |
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
index 023b58c927d..f68a76c3d0d 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
@@ -30,20 +30,6 @@ note: External requirements
    = note: number of external vids: 2
    = note: where T: '_#1r
 
-note: External requirements
-  --> $DIR/ty-param-closure-approximate-lower-bound.rs:43:24
-   |
-43 |     twice(cell, value, |a, b| invoke(a, b));
-   |                        ^^^^^^^^^^^^^^^^^^^
-   |
-   = note: defining type: DefId(0/1:17 ~ ty_param_closure_approximate_lower_bound[317d]::generic_fail[0]::{{closure}}[0]) with closure substs [
-               T,
-               i16,
-               for<'r, 's> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) ()>>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) T))
-           ]
-   = note: number of external vids: 2
-   = note: where T: '_#1r
-
 note: No external requirements
   --> $DIR/ty-param-closure-approximate-lower-bound.rs:33:1
    |
@@ -60,6 +46,20 @@ note: No external requirements
                T
            ]
 
+note: External requirements
+  --> $DIR/ty-param-closure-approximate-lower-bound.rs:43:24
+   |
+43 |     twice(cell, value, |a, b| invoke(a, b));
+   |                        ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:17 ~ ty_param_closure_approximate_lower_bound[317d]::generic_fail[0]::{{closure}}[0]) with closure substs [
+               T,
+               i16,
+               for<'r, 's> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) ()>>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) T))
+           ]
+   = note: number of external vids: 2
+   = note: where T: '_#1r
+
 error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/ty-param-closure-approximate-lower-bound.rs:43:24
    |
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
index 2dd13810ae4..ed4d4b1e68f 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
@@ -31,69 +31,6 @@ note: External requirements
    = note: number of external vids: 2
    = note: where T: '_#1r
 
-note: External requirements
-  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:55:26
-   |
-55 |       with_signature(a, b, |x, y| {
-   |  __________________________^
-56 | |         // Key point of this test:
-57 | |         //
-58 | |         // The *closure* is being type-checked with all of its free
-...  |
-67 | |         require(&x, &y)
-68 | |     })
-   | |_____^
-   |
-   = note: defining type: DefId(0/1:19 ~ ty_param_closure_outlives_from_where_clause[317d]::correct_region[0]::{{closure}}[0]) with closure substs [
-               '_#1r,
-               T,
-               i32,
-               extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
-           ]
-   = note: number of external vids: 3
-   = note: where T: '_#2r
-
-note: External requirements
-  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:76:26
-   |
-76 |       with_signature(a, b, |x, y| {
-   |  __________________________^
-77 | |         //~^ ERROR the parameter type `T` may not live long enough
-78 | |         // See `correct_region`
-79 | |         require(&x, &y)
-80 | |         //~^ WARNING not reporting region error due to -Znll
-81 | |     })
-   | |_____^
-   |
-   = note: defining type: DefId(0/1:23 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]::{{closure}}[0]) with closure substs [
-               '_#1r,
-               T,
-               i32,
-               extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
-           ]
-   = note: number of external vids: 3
-   = note: where T: '_#2r
-
-note: External requirements
-  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:90:26
-   |
-90 |       with_signature(a, b, |x, y| {
-   |  __________________________^
-91 | |         // See `correct_region`
-92 | |         require(&x, &y)
-93 | |     })
-   | |_____^
-   |
-   = note: defining type: DefId(0/1:27 ~ ty_param_closure_outlives_from_where_clause[317d]::outlives_region[0]::{{closure}}[0]) with closure substs [
-               '_#1r,
-               '_#2r,
-               T,
-               i32,
-               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
-           ]
-   = note: number of external vids: 4
-   = note: where T: '_#3r
-
 error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/ty-param-closure-outlives-from-where-clause.rs:38:26
    |
@@ -125,6 +62,28 @@ note: No external requirements
                T
            ]
 
+note: External requirements
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:55:26
+   |
+55 |       with_signature(a, b, |x, y| {
+   |  __________________________^
+56 | |         // Key point of this test:
+57 | |         //
+58 | |         // The *closure* is being type-checked with all of its free
+...  |
+67 | |         require(&x, &y)
+68 | |     })
+   | |_____^
+   |
+   = note: defining type: DefId(0/1:19 ~ ty_param_closure_outlives_from_where_clause[317d]::correct_region[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
+           ]
+   = note: number of external vids: 3
+   = note: where T: '_#2r
+
 note: No external requirements
   --> $DIR/ty-param-closure-outlives-from-where-clause.rs:51:1
    |
@@ -142,6 +101,27 @@ note: No external requirements
                T
            ]
 
+note: External requirements
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:76:26
+   |
+76 |       with_signature(a, b, |x, y| {
+   |  __________________________^
+77 | |         //~^ ERROR the parameter type `T` may not live long enough
+78 | |         // See `correct_region`
+79 | |         require(&x, &y)
+80 | |         //~^ WARNING not reporting region error due to -Znll
+81 | |     })
+   | |_____^
+   |
+   = note: defining type: DefId(0/1:23 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
+           ]
+   = note: number of external vids: 3
+   = note: where T: '_#2r
+
 error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/ty-param-closure-outlives-from-where-clause.rs:76:26
    |
@@ -173,6 +153,26 @@ note: No external requirements
                T
            ]
 
+note: External requirements
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:90:26
+   |
+90 |       with_signature(a, b, |x, y| {
+   |  __________________________^
+91 | |         // See `correct_region`
+92 | |         require(&x, &y)
+93 | |     })
+   | |_____^
+   |
+   = note: defining type: DefId(0/1:27 ~ ty_param_closure_outlives_from_where_clause[317d]::outlives_region[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
+           ]
+   = note: number of external vids: 4
+   = note: where T: '_#3r
+
 note: No external requirements
   --> $DIR/ty-param-closure-outlives-from-where-clause.rs:85:1
    |
diff --git a/src/test/ui/resolve/issue-23305.rs b/src/test/ui/resolve/issue-23305.rs
index f249e0e1127..34f8a0a4843 100644
--- a/src/test/ui/resolve/issue-23305.rs
+++ b/src/test/ui/resolve/issue-23305.rs
@@ -13,6 +13,6 @@ pub trait ToNbt<T> {
 }
 
 impl ToNbt<Self> {}
-//~^ ERROR unsupported cyclic reference
+//~^ ERROR cyclic dependency detected
 
 fn main() {}
diff --git a/src/test/ui/resolve/issue-23305.stderr b/src/test/ui/resolve/issue-23305.stderr
index 5bba9fc41e2..a0b4d424ec9 100644
--- a/src/test/ui/resolve/issue-23305.stderr
+++ b/src/test/ui/resolve/issue-23305.stderr
@@ -1,4 +1,4 @@
-error[E0391]: unsupported cyclic reference between types/traits detected
+error[E0391]: cyclic dependency detected
   --> $DIR/issue-23305.rs:15:12
    |
 15 | impl ToNbt<Self> {}
diff --git a/src/test/compile-fail/issue-17718-recursive.rs b/src/test/ui/unsafe-block-without-braces.rs
index 9959b0c6fc5..b6fb3ec5c44 100644
--- a/src/test/compile-fail/issue-17718-recursive.rs
+++ b/src/test/ui/unsafe-block-without-braces.rs
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-const A: usize = B; //~ ERROR: recursive constant
-const B: usize = A; //~ ERROR: recursive constant
-
-fn main() {}
+fn main() {
+    unsafe //{
+        std::mem::transmute::<f32, u32>(1.0);
+    //}
+}
+//~^^^ ERROR expected one of `extern`, `fn`, or `{`, found `std`
diff --git a/src/test/ui/unsafe-block-without-braces.stderr b/src/test/ui/unsafe-block-without-braces.stderr
new file mode 100644
index 00000000000..fc6ddba3823
--- /dev/null
+++ b/src/test/ui/unsafe-block-without-braces.stderr
@@ -0,0 +1,10 @@
+error: expected one of `extern`, `fn`, or `{`, found `std`
+  --> $DIR/unsafe-block-without-braces.rs:13:9
+   |
+12 |     unsafe //{
+   |           - expected one of `extern`, `fn`, or `{` here
+13 |         std::mem::transmute::<f32, u32>(1.0);
+   |         ^^^ unexpected token
+
+error: aborting due to previous error
+