about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-02-28 23:10:14 +0000
committerbors <bors@rust-lang.org>2018-02-28 23:10:14 +0000
commit0e3c9bba8ec6b8c5f8c66868ba6c47d3d38b20b2 (patch)
treedeea138e5eaca89ac78992162eae1c37a5cee807
parent0ff9872b2280009f094af0df3dcdc542cc46a5fd (diff)
parentb2b970769635d2aefcb6fa75d885c541d3a8a132 (diff)
downloadrust-0e3c9bba8ec6b8c5f8c66868ba6c47d3d38b20b2.tar.gz
rust-0e3c9bba8ec6b8c5f8c66868ba6c47d3d38b20b2.zip
Auto merge of #48615 - Manishearth:rollup, r=Manishearth
Rollup of 10 pull requests

- Successful merges: #48355, #48359, #48380, #48419, #48420, #48461, #48522, #48570, #48572, #48603
- Failed merges:
-rw-r--r--src/doc/man/rustc.110
-rw-r--r--src/doc/unstable-book/src/compiler-flags/remap-path-prefix.md37
-rw-r--r--src/libcore/iter/iterator.rs4
-rw-r--r--src/libcore/panicking.rs3
-rw-r--r--src/libpanic_unwind/gcc.rs3
-rw-r--r--src/libpanic_unwind/lib.rs3
-rw-r--r--src/libpanic_unwind/seh64_gnu.rs3
-rw-r--r--src/libpanic_unwind/windows.rs9
-rw-r--r--src/libproc_macro/lib.rs2
-rw-r--r--src/librustc/hir/lowering.rs24
-rw-r--r--src/librustc/lib.rs2
-rw-r--r--src/librustc/lint/builtin.rs39
-rw-r--r--src/librustc/lint/context.rs48
-rw-r--r--src/librustc/lint/levels.rs17
-rw-r--r--src/librustc/lint/mod.rs34
-rw-r--r--src/librustc/session/config.rs96
-rw-r--r--src/librustc/session/mod.rs18
-rw-r--r--src/librustc/ty/context.rs2
-rw-r--r--src/librustc_driver/driver.rs2
-rw-r--r--src/librustc_driver/lib.rs20
-rw-r--r--src/librustc_lint/lib.rs23
-rw-r--r--src/librustc_metadata/encoder.rs2
-rw-r--r--src/librustc_mir/build/mod.rs19
-rw-r--r--src/librustc_mir/lib.rs1
-rw-r--r--src/librustc_mir/transform/mod.rs1
-rw-r--r--src/librustc_mir/transform/uniform_array_move_out.rs198
-rw-r--r--src/libstd/panicking.rs6
-rw-r--r--src/libstd/path.rs75
-rw-r--r--src/libsyntax/attr.rs45
-rw-r--r--src/libsyntax/codemap.rs2
-rw-r--r--src/libsyntax/diagnostic_list.rs27
-rw-r--r--src/libsyntax/feature_gate.rs2
-rw-r--r--src/libsyntax_pos/lib.rs2
-rw-r--r--src/libunwind/libunwind.rs9
-rw-r--r--src/test/codegen/extern-functions.rs2
-rw-r--r--src/test/codegen/remap_path_prefix/auxiliary/remap_path_prefix_aux.rs2
-rw-r--r--src/test/codegen/remap_path_prefix/main.rs2
-rw-r--r--src/test/compile-fail/trait-bounds-not-on-struct.rs1
-rw-r--r--src/test/incremental/remapped_paths_cc/auxiliary/extern_crate.rs2
-rw-r--r--src/test/mir-opt/uniform_array_move_out.rs25
-rw-r--r--src/test/run-pass/abort-on-c-abi.rs3
41 files changed, 677 insertions, 148 deletions
diff --git a/src/doc/man/rustc.1 b/src/doc/man/rustc.1
index 19f6cc9ac61..39d10539959 100644
--- a/src/doc/man/rustc.1
+++ b/src/doc/man/rustc.1
@@ -125,6 +125,16 @@ Print version info and exit.
 \fB\-v\fR, \fB\-\-verbose\fR
 Use verbose output.
 .TP
+\fB\-\-remap\-path\-prefix\fR \fIfrom\fR=\fIto\fR
+Remap source path prefixes in all output, including compiler diagnostics, debug information,
+macro expansions, etc. The \fIfrom\fR=\fIto\fR parameter is scanned from right to left, so \fIfrom\fR
+may contain '=', but \fIto\fR may not.
+
+This is useful for normalizing build products, for example by removing the current directory out of
+pathnames emitted into the object files. The replacement is purely textual, with no consideration of
+the current system's pathname syntax. For example \fI\-\-remap\-path\-prefix foo=bar\fR will
+match \fBfoo/lib.rs\fR but not \fB./foo/lib.rs\fR.
+.TP
 \fB\-\-extern\fR \fINAME\fR=\fIPATH\fR
 Specify where an external rust library is located. These should match
 \fIextern\fR declarations in the crate's source code.
diff --git a/src/doc/unstable-book/src/compiler-flags/remap-path-prefix.md b/src/doc/unstable-book/src/compiler-flags/remap-path-prefix.md
deleted file mode 100644
index 8ca04d25325..00000000000
--- a/src/doc/unstable-book/src/compiler-flags/remap-path-prefix.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# `remap-path-prefix`
-
-The tracking issue for this feature is: [#41555](https://github.com/rust-lang/rust/issues/41555)
-
-------------------------
-
-The `-Z remap-path-prefix-from`, `-Z remap-path-prefix-to` commandline option
-pair allows to replace prefixes of any file paths the compiler emits in various
-places. This is useful for bringing debuginfo paths into a well-known form and
-for achieving reproducible builds independent of the directory the compiler was
-executed in. All paths emitted by the compiler are affected, including those in
-error messages.
-
-In order to map all paths starting with `/home/foo/my-project/src` to
-`/sources/my-project`, one would invoke the compiler as follows:
-
-```text
-rustc -Zremap-path-prefix-from="/home/foo/my-project/src" -Zremap-path-prefix-to="/sources/my-project"
-```
-
-Debuginfo for code from the file `/home/foo/my-project/src/foo/mod.rs`,
-for example, would then point debuggers to `/sources/my-project/foo/mod.rs`
-instead of the original file.
-
-The options can be specified multiple times when multiple prefixes should be
-mapped:
-
-```text
-rustc -Zremap-path-prefix-from="/home/foo/my-project/src" \
-      -Zremap-path-prefix-to="/sources/my-project" \
-      -Zremap-path-prefix-from="/home/foo/my-project/build-dir" \
-      -Zremap-path-prefix-to="/stable-build-dir"
-```
-
-When the options are given multiple times, the nth `-from` will be matched up
-with the nth `-to` and they can appear anywhere on the commandline. Mappings
-specified later on the line will take precedence over earlier ones.
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index 9d8a71250f8..b06534c9c1e 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -1062,8 +1062,8 @@ pub trait Iterator {
     /// assert_eq!(merged, "alphabetagamma");
     /// ```
     ///
-    /// You can also rewrite this in terms of [`flat_map()`] which is preferable
-    /// in this case since that conveys intent clearer:
+    /// You can also rewrite this in terms of [`flat_map()`], which is preferable
+    /// in this case since it conveys intent more clearly:
     ///
     /// ```
     /// let words = ["alpha", "beta", "gamma"];
diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs
index 4170d91e5fc..94db0baa3f9 100644
--- a/src/libcore/panicking.rs
+++ b/src/libcore/panicking.rs
@@ -64,7 +64,8 @@ pub fn panic_fmt(fmt: fmt::Arguments, file_line_col: &(&'static str, u32, u32))
     #[allow(improper_ctypes)]
     extern {
         #[lang = "panic_fmt"]
-        #[unwind]
+        #[cfg_attr(stage0, unwind)]
+        #[cfg_attr(not(stage0), unwind(allowed))]
         fn panic_impl(fmt: fmt::Arguments, file: &'static str, line: u32, col: u32) -> !;
     }
     let (file, line, col) = *file_line_col;
diff --git a/src/libpanic_unwind/gcc.rs b/src/libpanic_unwind/gcc.rs
index 63e44f71a3a..ca2fd561cad 100644
--- a/src/libpanic_unwind/gcc.rs
+++ b/src/libpanic_unwind/gcc.rs
@@ -286,7 +286,8 @@ unsafe fn find_eh_action(context: *mut uw::_Unwind_Context)
 // See docs in the `unwind` module.
 #[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))]
 #[lang = "eh_unwind_resume"]
-#[unwind]
+#[cfg_attr(stage0, unwind)]
+#[cfg_attr(not(stage0), unwind(allowed))]
 unsafe extern "C" fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! {
     uw::_Unwind_Resume(panic_ctx as *mut uw::_Unwind_Exception);
 }
diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs
index 92e40e8f26d..a5cebc3e4d0 100644
--- a/src/libpanic_unwind/lib.rs
+++ b/src/libpanic_unwind/lib.rs
@@ -112,7 +112,8 @@ pub unsafe extern "C" fn __rust_maybe_catch_panic(f: fn(*mut u8),
 // Entry point for raising an exception, just delegates to the platform-specific
 // implementation.
 #[no_mangle]
-#[unwind]
+#[cfg_attr(stage0, unwind)]
+#[cfg_attr(not(stage0), unwind(allowed))]
 pub unsafe extern "C" fn __rust_start_panic(data: usize, vtable: usize) -> u32 {
     imp::panic(mem::transmute(raw::TraitObject {
         data: data as *mut (),
diff --git a/src/libpanic_unwind/seh64_gnu.rs b/src/libpanic_unwind/seh64_gnu.rs
index 0a9fa7d9a80..090cd095380 100644
--- a/src/libpanic_unwind/seh64_gnu.rs
+++ b/src/libpanic_unwind/seh64_gnu.rs
@@ -108,7 +108,8 @@ unsafe extern "C" fn rust_eh_personality(exceptionRecord: *mut c::EXCEPTION_RECO
 }
 
 #[lang = "eh_unwind_resume"]
-#[unwind]
+#[cfg_attr(stage0, unwind)]
+#[cfg_attr(not(stage0), unwind(allowed))]
 unsafe extern "C" fn rust_eh_unwind_resume(panic_ctx: c::LPVOID) -> ! {
     let params = [panic_ctx as c::ULONG_PTR];
     c::RaiseException(RUST_PANIC,
diff --git a/src/libpanic_unwind/windows.rs b/src/libpanic_unwind/windows.rs
index a7e90071cea..50fba5faee7 100644
--- a/src/libpanic_unwind/windows.rs
+++ b/src/libpanic_unwind/windows.rs
@@ -79,18 +79,21 @@ pub enum EXCEPTION_DISPOSITION {
 pub use self::EXCEPTION_DISPOSITION::*;
 
 extern "system" {
-    #[unwind]
+    #[cfg_attr(stage0, unwind)]
+    #[cfg_attr(not(stage0), unwind(allowed))]
     pub fn RaiseException(dwExceptionCode: DWORD,
                           dwExceptionFlags: DWORD,
                           nNumberOfArguments: DWORD,
                           lpArguments: *const ULONG_PTR);
-    #[unwind]
+    #[cfg_attr(stage0, unwind)]
+    #[cfg_attr(not(stage0), unwind(allowed))]
     pub fn RtlUnwindEx(TargetFrame: LPVOID,
                        TargetIp: LPVOID,
                        ExceptionRecord: *const EXCEPTION_RECORD,
                        ReturnValue: LPVOID,
                        OriginalContext: *const CONTEXT,
                        HistoryTable: *const UNWIND_HISTORY_TABLE);
-    #[unwind]
+    #[cfg_attr(stage0, unwind)]
+    #[cfg_attr(not(stage0), unwind(allowed))]
     pub fn _CxxThrowException(pExceptionObject: *mut c_void, pThrowInfo: *mut u8);
 }
diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs
index 878a536836d..b18bb5a24b6 100644
--- a/src/libproc_macro/lib.rs
+++ b/src/libproc_macro/lib.rs
@@ -316,7 +316,7 @@ impl SourceFile {
     /// If the code span associated with this `SourceFile` was generated by an external macro, this
     /// may not be an actual path on the filesystem. Use [`is_real`] to check.
     ///
-    /// Also note that even if `is_real` returns `true`, if `-Z remap-path-prefix-*` was passed on
+    /// Also note that even if `is_real` returns `true`, if `--remap-path-prefix` was passed on
     /// the command line, the path as given may not actually be valid.
     ///
     /// [`is_real`]: #method.is_real
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 89ed47ea194..b15ee53e225 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -46,7 +46,7 @@ use hir::HirVec;
 use hir::map::{Definitions, DefKey, DefPathData};
 use hir::def_id::{DefIndex, DefId, CRATE_DEF_INDEX, DefIndexAddressSpace};
 use hir::def::{Def, PathResolution};
-use lint::builtin::PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES;
+use lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES};
 use middle::cstore::CrateStore;
 use rustc_data_structures::indexed_vec::IndexVec;
 use session::Session;
@@ -912,7 +912,11 @@ impl<'a> LoweringContext<'a> {
             TyKind::Path(ref qself, ref path) => {
                 let id = self.lower_node_id(t.id);
                 let qpath = self.lower_qpath(t.id, qself, path, ParamMode::Explicit, itctx);
-                return self.ty_path(id, t.span, qpath);
+                let ty = self.ty_path(id, t.span, qpath);
+                if let hir::TyTraitObject(..) = ty.node {
+                    self.maybe_lint_bare_trait(t.span, t.id, qself.is_none() && path.is_global());
+                }
+                return ty;
             }
             TyKind::ImplicitSelf => {
                 hir::TyPath(hir::QPath::Resolved(None, P(hir::Path {
@@ -931,7 +935,7 @@ impl<'a> LoweringContext<'a> {
                 let expr = self.lower_body(None, |this| this.lower_expr(expr));
                 hir::TyTypeof(expr)
             }
-            TyKind::TraitObject(ref bounds, ..) => {
+            TyKind::TraitObject(ref bounds, kind) => {
                 let mut lifetime_bound = None;
                 let bounds = bounds.iter().filter_map(|bound| {
                     match *bound {
@@ -950,6 +954,9 @@ impl<'a> LoweringContext<'a> {
                 let lifetime_bound = lifetime_bound.unwrap_or_else(|| {
                     self.elided_lifetime(t.span)
                 });
+                if kind != TraitObjectSyntax::Dyn {
+                    self.maybe_lint_bare_trait(t.span, t.id, false);
+                }
                 hir::TyTraitObject(bounds, lifetime_bound)
             }
             TyKind::ImplTrait(ref bounds) => {
@@ -3685,7 +3692,6 @@ impl<'a> LoweringContext<'a> {
                     // The original ID is taken by the `PolyTraitRef`,
                     // so the `Ty` itself needs a different one.
                     id = self.next_id();
-
                     hir::TyTraitObject(hir_vec![principal], self.elided_lifetime(span))
                 } else {
                     hir::TyPath(hir::QPath::Resolved(None, path))
@@ -3703,6 +3709,16 @@ impl<'a> LoweringContext<'a> {
             name: hir::LifetimeName::Implicit,
         }
     }
+
+    fn maybe_lint_bare_trait(&self, span: Span, id: NodeId, is_global: bool) {
+        if self.sess.features.borrow().dyn_trait {
+            self.sess.buffer_lint_with_diagnostic(
+                builtin::BARE_TRAIT_OBJECT, id, span,
+                "trait objects without an explicit `dyn` are deprecated",
+                builtin::BuiltinLintDiagnostics::BareTraitObject(span, is_global)
+            )
+        }
+    }
 }
 
 fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body>) -> Vec<hir::BodyId> {
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index d08a41010ab..f05ed0a460d 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -41,6 +41,8 @@
        html_root_url = "https://doc.rust-lang.org/nightly/")]
 #![deny(warnings)]
 
+#![cfg_attr(not(stage0), allow(bare_trait_object))]
+
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(conservative_impl_trait)]
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 0577800f3f4..b68b7dc6c06 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -14,7 +14,11 @@
 //! compiler code, rather than using their own custom pass. Those
 //! lints are all available in `rustc_lint::builtin`.
 
+use errors::DiagnosticBuilder;
 use lint::{LintPass, LateLintPass, LintArray};
+use session::Session;
+use session::config::Epoch;
+use syntax::codemap::Span;
 
 declare_lint! {
     pub CONST_ERR,
@@ -252,6 +256,13 @@ declare_lint! {
     "hidden lifetime parameters are deprecated, try `Foo<'_>`"
 }
 
+declare_lint! {
+    pub BARE_TRAIT_OBJECT,
+    Warn,
+    "suggest using `dyn Trait` for trait objects",
+    Epoch::Epoch2018
+}
+
 /// Does nothing as a lint pass, but registers some `Lint`s
 /// which are used by other parts of the compiler.
 #[derive(Copy, Clone)]
@@ -298,10 +309,34 @@ impl LintPass for HardwiredLints {
             COERCE_NEVER,
             SINGLE_USE_LIFETIME,
             TYVAR_BEHIND_RAW_POINTER,
-            ELIDED_LIFETIME_IN_PATH
-
+            ELIDED_LIFETIME_IN_PATH,
+            BARE_TRAIT_OBJECT
         )
     }
 }
 
+// this could be a closure, but then implementing derive traits
+// becomes hacky (and it gets allocated)
+#[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)]
+pub enum BuiltinLintDiagnostics {
+    Normal,
+    BareTraitObject(Span, /* is_global */ bool)
+}
+
+impl BuiltinLintDiagnostics {
+    pub fn run(self, sess: &Session, db: &mut DiagnosticBuilder) {
+        match self {
+            BuiltinLintDiagnostics::Normal => (),
+            BuiltinLintDiagnostics::BareTraitObject(span, is_global) => {
+                let sugg = match sess.codemap().span_to_snippet(span) {
+                    Ok(ref s) if is_global => format!("dyn ({})", s),
+                    Ok(s) => format!("dyn {}", s),
+                    Err(_) => format!("dyn <type>")
+                };
+                db.span_suggestion(span, "use `dyn`", sugg);
+            }
+        }
+    }
+}
+
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {}
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index ed937046e5e..bfd2034dd6c 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -29,6 +29,7 @@ use self::TargetLint::*;
 use std::slice;
 use lint::{EarlyLintPassObject, LateLintPassObject};
 use lint::{Level, Lint, LintId, LintPass, LintBuffer};
+use lint::builtin::BuiltinLintDiagnostics;
 use lint::levels::{LintLevelSets, LintLevelsBuilder};
 use middle::privacy::AccessLevels;
 use rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
@@ -92,6 +93,7 @@ pub struct BufferedEarlyLint {
     pub ast_id: ast::NodeId,
     pub span: MultiSpan,
     pub msg: String,
+    pub diagnostic: BuiltinLintDiagnostics,
 }
 
 /// Extra information for a future incompatibility lint. See the call
@@ -99,7 +101,11 @@ pub struct BufferedEarlyLint {
 /// guidelines.
 pub struct FutureIncompatibleInfo {
     pub id: LintId,
-    pub reference: &'static str // e.g., a URL for an issue/PR/RFC or error code
+    /// e.g., a URL for an issue/PR/RFC or error code
+    pub reference: &'static str,
+    /// If this is an epoch fixing lint, the epoch in which
+    /// this lint becomes obsolete
+    pub epoch: Option<config::Epoch>,
 }
 
 /// The target of the `by_name` map, which accounts for renaming/deprecation.
@@ -194,11 +200,24 @@ impl LintStore {
     pub fn register_future_incompatible(&mut self,
                                         sess: Option<&Session>,
                                         lints: Vec<FutureIncompatibleInfo>) {
-        let ids = lints.iter().map(|f| f.id).collect();
-        self.register_group(sess, false, "future_incompatible", ids);
-        for info in lints {
-            self.future_incompatible.insert(info.id, info);
+
+        for epoch in config::ALL_EPOCHS {
+            let lints = lints.iter().filter(|f| f.epoch == Some(*epoch)).map(|f| f.id)
+                             .collect::<Vec<_>>();
+            if !lints.is_empty() {
+                self.register_group(sess, false, epoch.lint_name(), lints)
+            }
         }
+
+        let mut future_incompatible = vec![];
+        for lint in lints {
+            future_incompatible.push(lint.id);
+            self.future_incompatible.insert(lint.id, lint);
+        }
+
+        self.register_group(sess, false, "future_incompatible", future_incompatible);
+
+
     }
 
     pub fn future_incompatible(&self, id: LintId) -> Option<&FutureIncompatibleInfo> {
@@ -429,6 +448,16 @@ pub trait LintContext<'tcx>: Sized {
         self.lookup(lint, span, msg).emit();
     }
 
+    fn lookup_and_emit_with_diagnostics<S: Into<MultiSpan>>(&self,
+                                                            lint: &'static Lint,
+                                                            span: Option<S>,
+                                                            msg: &str,
+                                                            diagnostic: BuiltinLintDiagnostics) {
+        let mut db = self.lookup(lint, span, msg);
+        diagnostic.run(self.sess(), &mut db);
+        db.emit();
+    }
+
     fn lookup<S: Into<MultiSpan>>(&self,
                                   lint: &'static Lint,
                                   span: Option<S>,
@@ -499,9 +528,10 @@ impl<'a> EarlyContext<'a> {
 
     fn check_id(&mut self, id: ast::NodeId) {
         for early_lint in self.buffered.take(id) {
-            self.lookup_and_emit(early_lint.lint_id.lint,
-                                 Some(early_lint.span.clone()),
-                                 &early_lint.msg);
+            self.lookup_and_emit_with_diagnostics(early_lint.lint_id.lint,
+                                                  Some(early_lint.span.clone()),
+                                                  &early_lint.msg,
+                                                  early_lint.diagnostic);
         }
     }
 }
@@ -1054,7 +1084,7 @@ pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {
     if !sess.opts.actually_rustdoc {
         for (_id, lints) in cx.buffered.map {
             for early_lint in lints {
-                span_bug!(early_lint.span, "failed to process buffered lint here");
+                sess.delay_span_bug(early_lint.span, "failed to process buffered lint here");
             }
         }
     }
diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs
index 4bc37747f2a..909904b4fc3 100644
--- a/src/librustc/lint/levels.rs
+++ b/src/librustc/lint/levels.rs
@@ -89,14 +89,15 @@ impl LintLevelSets {
     fn get_lint_level(&self,
                       lint: &'static Lint,
                       idx: u32,
-                      aux: Option<&FxHashMap<LintId, (Level, LintSource)>>)
+                      aux: Option<&FxHashMap<LintId, (Level, LintSource)>>,
+                      sess: &Session)
         -> (Level, LintSource)
     {
         let (level, mut src) = self.get_lint_id_level(LintId::of(lint), idx, aux);
 
         // If `level` is none then we actually assume the default level for this
         // lint.
-        let mut level = level.unwrap_or(lint.default_level);
+        let mut level = level.unwrap_or(lint.default_level(sess));
 
         // If we're about to issue a warning, check at the last minute for any
         // directives against the warnings "lint". If, for example, there's an
@@ -235,7 +236,8 @@ impl<'a> LintLevelsBuilder<'a> {
                         let lint = builtin::RENAMED_AND_REMOVED_LINTS;
                         let (level, src) = self.sets.get_lint_level(lint,
                                                                     self.cur,
-                                                                    Some(&specs));
+                                                                    Some(&specs),
+                                                                    &sess);
                         lint::struct_lint_level(self.sess,
                                                 lint,
                                                 level,
@@ -248,7 +250,8 @@ impl<'a> LintLevelsBuilder<'a> {
                         let lint = builtin::UNKNOWN_LINTS;
                         let (level, src) = self.sets.get_lint_level(lint,
                                                                     self.cur,
-                                                                    Some(&specs));
+                                                                    Some(&specs),
+                                                                    self.sess);
                         let msg = format!("unknown lint: `{}`", name);
                         let mut db = lint::struct_lint_level(self.sess,
                                                 lint,
@@ -342,7 +345,7 @@ impl<'a> LintLevelsBuilder<'a> {
                        msg: &str)
         -> DiagnosticBuilder<'a>
     {
-        let (level, src) = self.sets.get_lint_level(lint, self.cur, None);
+        let (level, src) = self.sets.get_lint_level(lint, self.cur, None, self.sess);
         lint::struct_lint_level(self.sess, lint, level, src, span, msg)
     }
 
@@ -377,11 +380,11 @@ impl LintLevelMap {
     /// If the `id` was not previously registered, returns `None`. If `None` is
     /// returned then the parent of `id` should be acquired and this function
     /// should be called again.
-    pub fn level_and_source(&self, lint: &'static Lint, id: HirId)
+    pub fn level_and_source(&self, lint: &'static Lint, id: HirId, session: &Session)
         -> Option<(Level, LintSource)>
     {
         self.id_to_set.get(&id).map(|idx| {
-            self.sets.get_lint_level(lint, *idx, None)
+            self.sets.get_lint_level(lint, *idx, None, session)
         })
     }
 
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index b2a9859f68a..a51d06c06ed 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -37,7 +37,8 @@ use errors::{DiagnosticBuilder, DiagnosticId};
 use hir::def_id::{CrateNum, LOCAL_CRATE};
 use hir::intravisit::{self, FnKind};
 use hir;
-use session::{Session, DiagnosticMessageId};
+use lint::builtin::BuiltinLintDiagnostics;
+use session::{config, Session, DiagnosticMessageId};
 use std::hash;
 use syntax::ast;
 use syntax::codemap::MultiSpan;
@@ -74,6 +75,9 @@ pub struct Lint {
     ///
     /// e.g. "imports that are never used"
     pub desc: &'static str,
+
+    /// Deny lint after this epoch
+    pub epoch_deny: Option<config::Epoch>,
 }
 
 impl Lint {
@@ -81,18 +85,36 @@ impl Lint {
     pub fn name_lower(&self) -> String {
         self.name.to_ascii_lowercase()
     }
+
+    pub fn default_level(&self, session: &Session) -> Level {
+        if let Some(epoch_deny) = self.epoch_deny {
+            if session.epoch() >= epoch_deny {
+                return Level::Deny
+            }
+        }
+        self.default_level
+    }
 }
 
 /// Declare a static item of type `&'static Lint`.
 #[macro_export]
 macro_rules! declare_lint {
+    ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $epoch: expr) => (
+        $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint {
+            name: stringify!($NAME),
+            default_level: $crate::lint::$Level,
+            desc: $desc,
+            epoch_deny: Some($epoch)
+        };
+    );
     ($vis: vis $NAME: ident, $Level: ident, $desc: expr) => (
         $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint {
             name: stringify!($NAME),
             default_level: $crate::lint::$Level,
-            desc: $desc
+            desc: $desc,
+            epoch_deny: None,
         };
-    )
+    );
 }
 
 /// Declare a static `LintArray` and return it as an expression.
@@ -304,7 +326,7 @@ impl LintId {
 /// Setting for how to handle a lint.
 #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
 pub enum Level {
-    Allow, Warn, Deny, Forbid
+    Allow, Warn, Deny, Forbid,
 }
 
 impl_stable_hash_for!(enum self::Level {
@@ -378,12 +400,14 @@ impl LintBuffer {
                     lint: &'static Lint,
                     id: ast::NodeId,
                     sp: MultiSpan,
-                    msg: &str) {
+                    msg: &str,
+                    diagnostic: BuiltinLintDiagnostics) {
         let early_lint = BufferedEarlyLint {
             lint_id: LintId::of(lint),
             ast_id: id,
             span: sp,
             msg: msg.to_string(),
+            diagnostic
         };
         let arr = self.map.entry(id).or_insert(Vec::new());
         if !arr.contains(&early_lint) {
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 919badfa4aa..b69f5d6c8bd 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -41,7 +41,7 @@ use std::collections::btree_map::Iter as BTreeMapIter;
 use std::collections::btree_map::Keys as BTreeMapKeysIter;
 use std::collections::btree_map::Values as BTreeMapValuesIter;
 
-use std::fmt;
+use std::{fmt, str};
 use std::hash::Hasher;
 use std::collections::hash_map::DefaultHasher;
 use std::collections::HashSet;
@@ -113,7 +113,7 @@ pub enum OutputType {
 }
 
 /// The epoch of the compiler (RFC 2052)
-#[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq)]
+#[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq, Debug)]
 #[non_exhaustive]
 pub enum Epoch {
     // epochs must be kept in order, newest to oldest
@@ -137,6 +137,37 @@ pub enum Epoch {
     // as well as changing the default Cargo template.
 }
 
+pub const ALL_EPOCHS: &[Epoch] = &[Epoch::Epoch2015, Epoch::Epoch2018];
+
+impl ToString for Epoch {
+    fn to_string(&self) -> String {
+        match *self {
+            Epoch::Epoch2015 => "2015".into(),
+            Epoch::Epoch2018 => "2018".into(),
+        }
+    }
+}
+
+impl Epoch {
+    pub fn lint_name(&self) -> &'static str {
+        match *self {
+            Epoch::Epoch2015 => "epoch_2015",
+            Epoch::Epoch2018 => "epoch_2018",
+        }
+    }
+}
+
+impl str::FromStr for Epoch {
+    type Err = ();
+    fn from_str(s: &str) -> Result<Self, ()> {
+        match s {
+            "2015" => Ok(Epoch::Epoch2015),
+            "2018" => Ok(Epoch::Epoch2018),
+            _ => Err(())
+        }
+    }
+}
+
 impl_stable_hash_for!(enum self::OutputType {
     Bitcode,
     Assembly,
@@ -435,6 +466,9 @@ top_level_options!(
         // if we otherwise use the defaults of rustc.
         cli_forced_codegen_units: Option<usize> [UNTRACKED],
         cli_forced_thinlto_off: bool [UNTRACKED],
+
+        // Remap source path prefixes in all output (messages, object files, debug, etc)
+        remap_path_prefix: Vec<(PathBuf, PathBuf)> [UNTRACKED],
     }
 );
 
@@ -617,6 +651,7 @@ pub fn basic_options() -> Options {
         actually_rustdoc: false,
         cli_forced_codegen_units: None,
         cli_forced_thinlto_off: false,
+        remap_path_prefix: Vec::new(),
     }
 }
 
@@ -635,11 +670,7 @@ impl Options {
     }
 
     pub fn file_path_mapping(&self) -> FilePathMapping {
-        FilePathMapping::new(
-            self.debugging_opts.remap_path_prefix_from.iter().zip(
-                self.debugging_opts.remap_path_prefix_to.iter()
-            ).map(|(src, dst)| (src.clone(), dst.clone())).collect()
-        )
+        FilePathMapping::new(self.remap_path_prefix.clone())
     }
 
     /// True if there will be an output file generated
@@ -1021,11 +1052,17 @@ macro_rules! options {
 
         fn parse_epoch(slot: &mut Epoch, v: Option<&str>) -> bool {
             match v {
-                Some("2015") => *slot = Epoch::Epoch2015,
-                Some("2018") => *slot = Epoch::Epoch2018,
-                _ => return false,
+                Some(s) => {
+                    let epoch = s.parse();
+                    if let Ok(parsed) = epoch {
+                        *slot = parsed;
+                        true
+                    } else {
+                        false
+                    }
+                }
+                _ => false,
             }
-            true
         }
     }
 ) }
@@ -1269,10 +1306,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "set the optimization fuel quota for a crate"),
     print_fuel: Option<String> = (None, parse_opt_string, [TRACKED],
         "make Rustc print the total optimization fuel used by a crate"),
-    remap_path_prefix_from: Vec<PathBuf> = (vec![], parse_pathbuf_push, [UNTRACKED],
-        "add a source pattern to the file path remapping config"),
-    remap_path_prefix_to: Vec<PathBuf> = (vec![], parse_pathbuf_push, [UNTRACKED],
-        "add a mapping target to the file path remapping config"),
     force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED],
         "force all crates to be `rustc_private` unstable"),
     pre_link_arg: Vec<String> = (vec![], parse_string_push, [UNTRACKED],
@@ -1597,6 +1630,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
                   `expanded` (crates expanded), or
                   `expanded,identified` (fully parenthesized, AST nodes with IDs).",
                  "TYPE"),
+        opt::multi_s("", "remap-path-prefix", "remap source names in output", "FROM=TO"),
     ]);
     opts
 }
@@ -1720,23 +1754,6 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
         output_types.insert(OutputType::Exe, None);
     }
 
-    let remap_path_prefix_sources = debugging_opts.remap_path_prefix_from.len();
-    let remap_path_prefix_targets = debugging_opts.remap_path_prefix_to.len();
-
-    if remap_path_prefix_targets < remap_path_prefix_sources {
-        for source in &debugging_opts.remap_path_prefix_from[remap_path_prefix_targets..] {
-            early_error(error_format,
-                &format!("option `-Zremap-path-prefix-from='{}'` does not have \
-                         a corresponding `-Zremap-path-prefix-to`", source.display()))
-        }
-    } else if remap_path_prefix_targets > remap_path_prefix_sources {
-        for target in &debugging_opts.remap_path_prefix_to[remap_path_prefix_sources..] {
-            early_error(error_format,
-                &format!("option `-Zremap-path-prefix-to='{}'` does not have \
-                          a corresponding `-Zremap-path-prefix-from`", target.display()))
-        }
-    }
-
     let mut cg = build_codegen_options(matches, error_format);
     let mut codegen_units = cg.codegen_units;
     let mut disable_thinlto = false;
@@ -1970,6 +1987,20 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
 
     let crate_name = matches.opt_str("crate-name");
 
+    let remap_path_prefix = matches.opt_strs("remap-path-prefix")
+        .into_iter()
+        .map(|remap| {
+            let mut parts = remap.rsplitn(2, '='); // reverse iterator
+            let to = parts.next();
+            let from = parts.next();
+            match (from, to) {
+                (Some(from), Some(to)) => (PathBuf::from(from), PathBuf::from(to)),
+                _ => early_error(error_format,
+                        "--remap-path-prefix must contain '=' between FROM and TO"),
+            }
+        })
+        .collect();
+
     (Options {
         crate_types,
         optimize: opt_level,
@@ -1997,6 +2028,7 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
         actually_rustdoc: false,
         cli_forced_codegen_units: codegen_units,
         cli_forced_thinlto_off: disable_thinlto,
+        remap_path_prefix,
     },
     cfg)
 }
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 939154fac7a..2437eaadc6d 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -16,6 +16,7 @@ use ich::Fingerprint;
 
 use ich;
 use lint;
+use lint::builtin::BuiltinLintDiagnostics;
 use middle::allocator::AllocatorKind;
 use middle::dependency_format;
 use session::search_paths::PathKind;
@@ -341,7 +342,18 @@ impl Session {
                                            sp: S,
                                            msg: &str) {
         match *self.buffered_lints.borrow_mut() {
-            Some(ref mut buffer) => buffer.add_lint(lint, id, sp.into(), msg),
+            Some(ref mut buffer) => buffer.add_lint(lint, id, sp.into(),
+                                                    msg, BuiltinLintDiagnostics::Normal),
+            None => bug!("can't buffer lints after HIR lowering"),
+        }
+    }
+
+    pub fn buffer_lint_with_diagnostic<S: Into<MultiSpan>>(&self,
+        lint: &'static lint::Lint, id: ast::NodeId, sp: S,
+        msg: &str, diagnostic: BuiltinLintDiagnostics) {
+        match *self.buffered_lints.borrow_mut() {
+            Some(ref mut buffer) => buffer.add_lint(lint, id, sp.into(),
+                                                    msg, diagnostic),
             None => bug!("can't buffer lints after HIR lowering"),
         }
     }
@@ -869,6 +881,10 @@ impl Session {
     pub fn rust_2018(&self) -> bool {
         self.opts.debugging_opts.epoch >= Epoch::Epoch2018
     }
+
+    pub fn epoch(&self) -> Epoch {
+        self.opts.debugging_opts.epoch
+    }
 }
 
 pub fn build_session(sopts: config::Options,
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 3613a34f66a..a39d63d05ee 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2234,7 +2234,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             let sets = self.lint_levels(LOCAL_CRATE);
             loop {
                 let hir_id = self.hir.definitions().node_to_hir_id(id);
-                if let Some(pair) = sets.level_and_source(lint, hir_id) {
+                if let Some(pair) = sets.level_and_source(lint, hir_id, self.sess) {
                     return pair
                 }
                 let next = self.hir.get_parent_node(id);
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index b03108ed807..2ae800e8cdc 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -737,7 +737,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
 
     // Lint plugins are registered; now we can process command line flags.
     if sess.opts.describe_lints {
-        super::describe_lints(&sess.lint_store.borrow(), true);
+        super::describe_lints(&sess, &sess.lint_store.borrow(), true);
         return Err(CompileIncomplete::Stopped);
     }
 
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 6af7a23f66d..22c26b06430 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -787,15 +787,15 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
                 -> Option<(Input, Option<PathBuf>)> {
         match matches.free.len() {
             0 => {
+                let mut sess = build_session(sopts.clone(),
+                    None,
+                    descriptions.clone());
                 if sopts.describe_lints {
                     let mut ls = lint::LintStore::new();
-                    rustc_lint::register_builtins(&mut ls, None);
-                    describe_lints(&ls, false);
+                    rustc_lint::register_builtins(&mut ls, Some(&sess));
+                    describe_lints(&sess, &ls, false);
                     return None;
                 }
-                let mut sess = build_session(sopts.clone(),
-                    None,
-                    descriptions.clone());
                 rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
                 let mut cfg = config::build_configuration(&sess, cfg.clone());
                 let trans = get_trans(&sess);
@@ -1134,7 +1134,7 @@ fn usage(verbose: bool, include_unstable_options: bool) {
              verbose_help);
 }
 
-fn describe_lints(lint_store: &lint::LintStore, loaded_plugins: bool) {
+fn describe_lints(sess: &Session, lint_store: &lint::LintStore, loaded_plugins: bool) {
     println!("
 Available lint options:
     -W <foo>           Warn about <foo>
@@ -1146,10 +1146,10 @@ Available lint options:
 
 ");
 
-    fn sort_lints(lints: Vec<(&'static Lint, bool)>) -> Vec<&'static Lint> {
+    fn sort_lints(sess: &Session, lints: Vec<(&'static Lint, bool)>) -> Vec<&'static Lint> {
         let mut lints: Vec<_> = lints.into_iter().map(|(x, _)| x).collect();
         lints.sort_by(|x: &&Lint, y: &&Lint| {
-            match x.default_level.cmp(&y.default_level) {
+            match x.default_level(sess).cmp(&y.default_level(sess)) {
                 // The sort doesn't case-fold but it's doubtful we care.
                 Equal => x.name.cmp(y.name),
                 r => r,
@@ -1172,8 +1172,8 @@ Available lint options:
                                                    .iter()
                                                    .cloned()
                                                    .partition(|&(_, p)| p);
-    let plugin = sort_lints(plugin);
-    let builtin = sort_lints(builtin);
+    let plugin = sort_lints(sess, plugin);
+    let builtin = sort_lints(sess, builtin);
 
     let (plugin_groups, builtin_groups): (Vec<_>, _) = lint_store.get_lint_groups()
                                                                  .iter()
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index f3c6ff2f2b3..9dc6d977851 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -191,75 +191,98 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
         FutureIncompatibleInfo {
             id: LintId::of(PRIVATE_IN_PUBLIC),
             reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
+            epoch: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(PUB_USE_OF_PRIVATE_EXTERN_CRATE),
             reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
+            epoch: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY),
             reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
+            epoch: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(SAFE_EXTERN_STATICS),
             reference: "issue #36247 <https://github.com/rust-lang/rust/issues/36247>",
+            epoch: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(INVALID_TYPE_PARAM_DEFAULT),
             reference: "issue #36887 <https://github.com/rust-lang/rust/issues/36887>",
+            epoch: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(LEGACY_DIRECTORY_OWNERSHIP),
             reference: "issue #37872 <https://github.com/rust-lang/rust/issues/37872>",
+            epoch: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(LEGACY_IMPORTS),
             reference: "issue #38260 <https://github.com/rust-lang/rust/issues/38260>",
+            epoch: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(LEGACY_CONSTRUCTOR_VISIBILITY),
             reference: "issue #39207 <https://github.com/rust-lang/rust/issues/39207>",
+            epoch: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(RESOLVE_TRAIT_ON_DEFAULTED_UNIT),
             reference: "issue #39216 <https://github.com/rust-lang/rust/issues/39216>",
+            epoch: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(MISSING_FRAGMENT_SPECIFIER),
             reference: "issue #40107 <https://github.com/rust-lang/rust/issues/40107>",
+            epoch: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN),
             reference: "issue #41620 <https://github.com/rust-lang/rust/issues/41620>",
+            epoch: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(ANONYMOUS_PARAMETERS),
             reference: "issue #41686 <https://github.com/rust-lang/rust/issues/41686>",
+            epoch: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES),
             reference: "issue #42238 <https://github.com/rust-lang/rust/issues/42238>",
+            epoch: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(LATE_BOUND_LIFETIME_ARGUMENTS),
             reference: "issue #42868 <https://github.com/rust-lang/rust/issues/42868>",
+            epoch: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(SAFE_PACKED_BORROWS),
             reference: "issue #46043 <https://github.com/rust-lang/rust/issues/46043>",
+            epoch: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(INCOHERENT_FUNDAMENTAL_IMPLS),
             reference: "issue #46205 <https://github.com/rust-lang/rust/issues/46205>",
+            epoch: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(COERCE_NEVER),
             reference: "issue #46325 <https://github.com/rust-lang/rust/issues/46325>",
+            epoch: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(TYVAR_BEHIND_RAW_POINTER),
             reference: "issue #46906 <https://github.com/rust-lang/rust/issues/46906>",
+            epoch: None,
         },
+         FutureIncompatibleInfo {
+             id: LintId::of(lint::builtin::BARE_TRAIT_OBJECT),
+             reference: "issue #48457 <https://github.com/rust-lang/rust/issues/48457>",
+             epoch: Some(session::config::Epoch::Epoch2018),
+         }
         ]);
 
     // Register renamed and removed lints
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 78578ca179c..d140b135416 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -323,7 +323,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 // paths because any relative paths are potentially relative to
                 // a wrong directory.
                 // However, if a path has been modified via
-                // `-Zremap-path-prefix` we assume the user has already set
+                // `--remap-path-prefix` we assume the user has already set
                 // things up the way they want and don't touch the path values
                 // anymore.
                 match filemap.name {
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 57059cd31a1..a325cfe3eaa 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -28,6 +28,7 @@ use std::mem;
 use std::u32;
 use syntax::abi::Abi;
 use syntax::ast;
+use syntax::attr::{self, UnwindAttr};
 use syntax::symbol::keywords;
 use syntax_pos::Span;
 use transform::MirSource;
@@ -355,10 +356,9 @@ macro_rules! unpack {
 }
 
 fn should_abort_on_panic<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                                         fn_id: ast::NodeId,
+                                         fn_def_id: DefId,
                                          abi: Abi)
                                          -> bool {
-
     // Not callable from C, so we can safely unwind through these
     if abi == Abi::Rust || abi == Abi::RustCall { return false; }
 
@@ -370,9 +370,17 @@ fn should_abort_on_panic<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
 
     // This is a special case: some functions have a C abi but are meant to
     // unwind anyway. Don't stop them.
-    if tcx.has_attr(tcx.hir.local_def_id(fn_id), "unwind") { return false; }
+    let attrs = &tcx.get_attrs(fn_def_id);
+    match attr::find_unwind_attr(Some(tcx.sess.diagnostic()), attrs) {
+        None => {
+            // FIXME(rust-lang/rust#48251) -- Had to disable
+            // abort-on-panic for backwards compatibility reasons.
+            false
+        }
 
-    return true;
+        Some(UnwindAttr::Allowed) => false,
+        Some(UnwindAttr::Aborts) => true,
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -399,13 +407,14 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
         safety,
         return_ty);
 
+    let fn_def_id = tcx.hir.local_def_id(fn_id);
     let call_site_scope = region::Scope::CallSite(body.value.hir_id.local_id);
     let arg_scope = region::Scope::Arguments(body.value.hir_id.local_id);
     let mut block = START_BLOCK;
     let source_info = builder.source_info(span);
     let call_site_s = (call_site_scope, source_info);
     unpack!(block = builder.in_scope(call_site_s, LintLevel::Inherited, block, |builder| {
-        if should_abort_on_panic(tcx, fn_id, abi) {
+        if should_abort_on_panic(tcx, fn_def_id, abi) {
             builder.schedule_abort();
         }
 
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index 8c15d1cf8b0..9887ac82a2e 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -15,6 +15,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
 */
 
 #![deny(warnings)]
+#![cfg_attr(not(stage0), allow(bare_trait_object))]
 
 #![feature(box_patterns)]
 #![feature(box_syntax)]
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index b16c1436a1c..54a7a0eafe0 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -257,6 +257,7 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
 
 
         // Optimizations begin.
+        uniform_array_move_out::RestoreSubsliceArrayMoveOut,
         inline::Inline,
 
         // Lowering generator control-flow and variables
diff --git a/src/librustc_mir/transform/uniform_array_move_out.rs b/src/librustc_mir/transform/uniform_array_move_out.rs
index 0db5ecf0eb2..e46de170479 100644
--- a/src/librustc_mir/transform/uniform_array_move_out.rs
+++ b/src/librustc_mir/transform/uniform_array_move_out.rs
@@ -34,15 +34,15 @@
 //  and mir statement _11 = move _2[-1 of 1]; replaced by:
 //  _11 = move _2[2 of 3];
 //
-// FIXME: convert to Subslice back for performance reason
 // FIXME: integrate this transformation to the mir build
 
 use rustc::ty;
 use rustc::ty::TyCtxt;
 use rustc::mir::*;
-use rustc::mir::visit::Visitor;
+use rustc::mir::visit::{Visitor, PlaceContext};
 use transform::{MirPass, MirSource};
 use util::patch::MirPatch;
+use rustc_data_structures::indexed_vec::{IndexVec};
 
 pub struct UniformArrayMoveOut;
 
@@ -67,12 +67,12 @@ struct UniformArrayMoveOutVisitor<'a, 'tcx: 'a> {
 }
 
 impl<'a, 'tcx> Visitor<'tcx> for UniformArrayMoveOutVisitor<'a, 'tcx> {
-    fn visit_statement(&mut self,
-                       block: BasicBlock,
-                       statement: &Statement<'tcx>,
-                       location: Location) {
-        if let StatementKind::Assign(ref dst_place,
-                                     Rvalue::Use(Operand::Move(ref src_place))) = statement.kind {
+    fn visit_assign(&mut self,
+                    block: BasicBlock,
+                    dst_place: &Place<'tcx>,
+                    rvalue: &Rvalue<'tcx>,
+                    location: Location) {
+        if let Rvalue::Use(Operand::Move(ref src_place)) = rvalue {
             if let Place::Projection(ref proj) = *src_place {
                 if let ProjectionElem::ConstantIndex{offset: _,
                                                      min_length: _,
@@ -92,7 +92,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UniformArrayMoveOutVisitor<'a, 'tcx> {
                 }
             }
         }
-        return self.super_statement(block, statement, location);
+        self.super_assign(block, dst_place, rvalue, location)
     }
 }
 
@@ -104,7 +104,7 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> {
                item_ty: &'tcx ty::TyS<'tcx>,
                size: u32) {
         match proj.elem {
-            // uniform _10 = move _2[:-1];
+            // uniforms statements like_10 = move _2[:-1];
             ProjectionElem::Subslice{from, to} => {
                 self.patch.make_nop(location);
                 let temps : Vec<_> = (from..(size-to)).map(|i| {
@@ -133,7 +133,7 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> {
                     self.patch.add_statement(location, StatementKind::StorageDead(temp));
                 }
             }
-            // _11 = move _2[-1 of 1];
+            // uniforms statements like _11 = move _2[-1 of 1];
             ProjectionElem::ConstantIndex{offset, min_length: _, from_end: true} => {
                 self.patch.make_nop(location);
                 self.patch.add_assign(location,
@@ -151,3 +151,179 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> {
         }
     }
 }
+
+// Restore Subslice move out after analysis
+// Example:
+//
+//  next statements:
+//   StorageLive(_12);
+//   _12 = move _2[0 of 3];
+//   StorageLive(_13);
+//   _13 = move _2[1 of 3];
+//   _10 = [move _12, move _13]
+//   StorageDead(_12);
+//   StorageDead(_13);
+//
+// replaced by _10 = move _2[:-1];
+
+pub struct RestoreSubsliceArrayMoveOut;
+
+impl MirPass for RestoreSubsliceArrayMoveOut {
+    fn run_pass<'a, 'tcx>(&self,
+                          tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                          _src: MirSource,
+                          mir: &mut Mir<'tcx>) {
+        let mut patch = MirPatch::new(mir);
+        {
+            let mut visitor = RestoreDataCollector {
+                locals_use: IndexVec::from_elem(LocalUse::new(), &mir.local_decls),
+                candidates: vec![],
+            };
+            visitor.visit_mir(mir);
+
+            for candidate in &visitor.candidates {
+                let statement = &mir[candidate.block].statements[candidate.statement_index];
+                if let StatementKind::Assign(ref dst_place, ref rval) = statement.kind {
+                    if let Rvalue::Aggregate(box AggregateKind::Array(_), ref items) = *rval {
+                        let items : Vec<_> = items.iter().map(|item| {
+                            if let Operand::Move(Place::Local(local)) = item {
+                                let local_use = &visitor.locals_use[*local];
+                                let opt_index_and_place = Self::try_get_item_source(local_use, mir);
+                                // each local should be used twice:
+                                //  in assign and in aggregate statments
+                                if local_use.use_count == 2 && opt_index_and_place.is_some() {
+                                    let (index, src_place) = opt_index_and_place.unwrap();
+                                    return Some((local_use, index, src_place));
+                                }
+                            }
+                            None
+                        }).collect();
+
+                        let opt_src_place = items.first().and_then(|x| *x).map(|x| x.2);
+                        let opt_size = opt_src_place.and_then(|src_place| {
+                            let src_ty = src_place.ty(mir, tcx).to_ty(tcx);
+                            if let ty::TyArray(_, ref size_o) = src_ty.sty {
+                                size_o.val.to_const_int().and_then(|v| v.to_u64())
+                            } else {
+                                None
+                            }
+                        });
+                        Self::check_and_patch(*candidate, &items, opt_size, &mut patch, dst_place);
+                    }
+                }
+            }
+        }
+        patch.apply(mir);
+    }
+}
+
+impl RestoreSubsliceArrayMoveOut {
+    // Checks that source has size, all locals are inited from same source place and
+    // indices is an integer interval. If all checks pass do the replacent.
+    // items are Vec<Option<LocalUse, index in source array, source place for init local>>
+    fn check_and_patch<'tcx>(candidate: Location,
+                             items: &Vec<Option<(&LocalUse, u32, &Place<'tcx>)>>,
+                             opt_size: Option<u64>,
+                             patch: &mut MirPatch<'tcx>,
+                             dst_place: &Place<'tcx>) {
+        let opt_src_place = items.first().and_then(|x| *x).map(|x| x.2);
+
+        if opt_size.is_some() && items.iter().all(
+            |l| l.is_some() && l.unwrap().2 == opt_src_place.unwrap()) {
+
+            let indicies: Vec<_> = items.iter().map(|x| x.unwrap().1).collect();
+            for i in 1..indicies.len() {
+                if indicies[i - 1] + 1 != indicies[i] {
+                    return;
+                }
+            }
+
+            let min = *indicies.first().unwrap();
+            let max = *indicies.last().unwrap();
+
+            for item in items {
+                let locals_use = item.unwrap().0;
+                patch.make_nop(locals_use.alive.unwrap());
+                patch.make_nop(locals_use.dead.unwrap());
+                patch.make_nop(locals_use.first_use.unwrap());
+            }
+            patch.make_nop(candidate);
+            let size = opt_size.unwrap() as u32;
+            patch.add_assign(candidate,
+                             dst_place.clone(),
+                             Rvalue::Use(
+                                 Operand::Move(
+                                     Place::Projection(box PlaceProjection{
+                                         base: opt_src_place.unwrap().clone(),
+                                         elem: ProjectionElem::Subslice{
+                                             from: min, to: size - max - 1}}))));
+        }
+    }
+
+    fn try_get_item_source<'a, 'tcx>(local_use: &LocalUse,
+                                     mir: &'a Mir<'tcx>) -> Option<(u32, &'a Place<'tcx>)> {
+        if let Some(location) = local_use.first_use {
+            let block = &mir[location.block];
+            if block.statements.len() > location.statement_index {
+                let statement = &block.statements[location.statement_index];
+                if let StatementKind::Assign(
+                    Place::Local(_),
+                    Rvalue::Use(Operand::Move(Place::Projection(box PlaceProjection{
+                        ref base, elem: ProjectionElem::ConstantIndex{
+                            offset, min_length: _, from_end: false}})))) = statement.kind {
+                    return Some((offset, base))
+                }
+            }
+        }
+        None
+    }
+}
+
+#[derive(Copy, Clone, Debug)]
+struct LocalUse {
+    alive: Option<Location>,
+    dead: Option<Location>,
+    use_count: u32,
+    first_use: Option<Location>,
+}
+
+impl LocalUse {
+    pub fn new() -> Self {
+        LocalUse{alive: None, dead: None, use_count: 0, first_use: None}
+    }
+}
+
+struct RestoreDataCollector {
+    locals_use: IndexVec<Local, LocalUse>,
+    candidates: Vec<Location>,
+}
+
+impl<'tcx> Visitor<'tcx> for RestoreDataCollector {
+    fn visit_assign(&mut self,
+                    block: BasicBlock,
+                    place: &Place<'tcx>,
+                    rvalue: &Rvalue<'tcx>,
+                    location: Location) {
+        if let Rvalue::Aggregate(box AggregateKind::Array(_), _) = *rvalue {
+            self.candidates.push(location);
+        }
+        self.super_assign(block, place, rvalue, location)
+    }
+
+    fn visit_local(&mut self,
+                   local: &Local,
+                   context: PlaceContext<'tcx>,
+                   location: Location) {
+        let local_use = &mut self.locals_use[*local];
+        match context {
+            PlaceContext::StorageLive => local_use.alive = Some(location),
+            PlaceContext::StorageDead => local_use.dead = Some(location),
+            _ => {
+                local_use.use_count += 1;
+                if local_use.first_use.is_none() {
+                    local_use.first_use = Some(location);
+                }
+            }
+        }
+    }
+}
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 161c3fc7113..454ac64735c 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -55,7 +55,8 @@ extern {
                                 data: *mut u8,
                                 data_ptr: *mut usize,
                                 vtable_ptr: *mut usize) -> u32;
-    #[unwind]
+    #[cfg_attr(stage0, unwind)]
+    #[cfg_attr(not(stage0), unwind(allowed))]
     fn __rust_start_panic(data: usize, vtable: usize) -> u32;
 }
 
@@ -315,7 +316,8 @@ pub fn panicking() -> bool {
 /// Entry point of panic from the libcore crate.
 #[cfg(not(test))]
 #[lang = "panic_fmt"]
-#[unwind]
+#[cfg_attr(stage0, unwind)]
+#[cfg_attr(not(stage0), unwind(allowed))]
 pub extern fn rust_begin_panic(msg: fmt::Arguments,
                                file: &'static str,
                                line: u32,
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 4bbad30a5a3..1608a752a46 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -1035,6 +1035,50 @@ impl<'a> cmp::Ord for Components<'a> {
     }
 }
 
+/// An iterator over [`Path`] and its ancestors.
+///
+/// This `struct` is created by the [`ancestors`] method on [`Path`].
+/// See its documentation for more.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(path_ancestors)]
+///
+/// use std::path::Path;
+///
+/// let path = Path::new("/foo/bar");
+///
+/// for ancestor in path.ancestors() {
+///     println!("{}", ancestor.display());
+/// }
+/// ```
+///
+/// [`ancestors`]: struct.Path.html#method.ancestors
+/// [`Path`]: struct.Path.html
+#[derive(Copy, Clone, Debug)]
+#[unstable(feature = "path_ancestors", issue = "48581")]
+pub struct Ancestors<'a> {
+    next: Option<&'a Path>,
+}
+
+#[unstable(feature = "path_ancestors", issue = "48581")]
+impl<'a> Iterator for Ancestors<'a> {
+    type Item = &'a Path;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let next = self.next;
+        self.next = match next {
+            Some(path) => path.parent(),
+            None => None,
+        };
+        next
+    }
+}
+
+#[unstable(feature = "fused", issue = "35602")]
+impl<'a> FusedIterator for Ancestors<'a> {}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Basic types and traits
 ////////////////////////////////////////////////////////////////////////////////
@@ -1820,6 +1864,37 @@ impl Path {
         })
     }
 
+    /// Produces an iterator over `Path` and its ancestors.
+    ///
+    /// The iterator will yield the `Path` that is returned if the [`parent`] method is used zero
+    /// or more times. That means, the iterator will yield `&self`, `&self.parent().unwrap()`,
+    /// `&self.parent().unwrap().parent().unwrap()` and so on. If the [`parent`] method returns
+    /// [`None`], the iterator will do likewise. The iterator will always yield at least one value,
+    /// namely `&self`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(path_ancestors)]
+    ///
+    /// use std::path::Path;
+    ///
+    /// let mut ancestors = Path::new("/foo/bar").ancestors();
+    /// assert_eq!(ancestors.next(), Some(Path::new("/foo/bar")));
+    /// assert_eq!(ancestors.next(), Some(Path::new("/foo")));
+    /// assert_eq!(ancestors.next(), Some(Path::new("/")));
+    /// assert_eq!(ancestors.next(), None);
+    /// ```
+    ///
+    /// [`None`]: ../../std/option/enum.Option.html#variant.None
+    /// [`parent`]: struct.Path.html#method.parent
+    #[unstable(feature = "path_ancestors", issue = "48581")]
+    pub fn ancestors(&self) -> Ancestors {
+        Ancestors {
+            next: Some(&self),
+        }
+    }
+
     /// Returns the final component of the `Path`, if there is one.
     ///
     /// If the path is a normal file, this is the file name. If it's the path of a directory, this
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index d18d6f5e6bd..d0822b69aa6 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -565,6 +565,51 @@ pub fn find_inline_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> In
     })
 }
 
+#[derive(Copy, Clone, PartialEq)]
+pub enum UnwindAttr {
+    Allowed,
+    Aborts,
+}
+
+/// Determine what `#[unwind]` attribute is present in `attrs`, if any.
+pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Option<UnwindAttr> {
+    let syntax_error = |attr: &Attribute| {
+        mark_used(attr);
+        diagnostic.map(|d| {
+            span_err!(d, attr.span, E0633, "malformed `#[unwind]` attribute");
+        });
+        None
+    };
+
+    attrs.iter().fold(None, |ia, attr| {
+        if attr.path != "unwind" {
+            return ia;
+        }
+        let meta = match attr.meta() {
+            Some(meta) => meta.node,
+            None => return ia,
+        };
+        match meta {
+            MetaItemKind::Word => {
+                syntax_error(attr)
+            }
+            MetaItemKind::List(ref items) => {
+                mark_used(attr);
+                if items.len() != 1 {
+                    syntax_error(attr)
+                } else if list_contains_name(&items[..], "allowed") {
+                    Some(UnwindAttr::Allowed)
+                } else if list_contains_name(&items[..], "aborts") {
+                    Some(UnwindAttr::Aborts)
+                } else {
+                    syntax_error(attr)
+                }
+            }
+            _ => ia,
+        }
+    })
+}
+
 /// True if `#[inline]` or `#[inline(always)]` is present in `attrs`.
 pub fn requests_inline(attrs: &[Attribute]) -> bool {
     match find_inline_attr(None, attrs) {
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index df5845f6c21..926548b6031 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -129,7 +129,7 @@ pub struct CodeMap {
     pub(super) files: RefCell<Vec<Rc<FileMap>>>,
     file_loader: Box<FileLoader>,
     // This is used to apply the file path remapping as specified via
-    // -Zremap-path-prefix to all FileMaps allocated within this CodeMap.
+    // --remap-path-prefix to all FileMaps allocated within this CodeMap.
     path_mapping: FilePathMapping,
     stable_id_to_filemap: RefCell<FxHashMap<StableFilemapId, Rc<FileMap>>>,
     /// In case we are in a doctest, replace all file names with the PathBuf,
diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs
index d841281e485..84ab0336f16 100644
--- a/src/libsyntax/diagnostic_list.rs
+++ b/src/libsyntax/diagnostic_list.rs
@@ -342,6 +342,33 @@ fn main() {
 ```
 "##,
 
+E0633: r##"
+The `unwind` attribute was malformed.
+
+Erroneous code example:
+
+```ignore (compile_fail not working here; see Issue #43707)
+#[unwind()] // error: expected one argument
+pub extern fn something() {}
+
+fn main() {}
+```
+
+The `#[unwind]` attribute should be used as follows:
+
+- `#[unwind(aborts)]` -- specifies that if a non-Rust ABI function
+  should abort the process if it attempts to unwind. This is the safer
+  and preferred option.
+
+- `#[unwind(allowed)]` -- specifies that a non-Rust ABI function
+  should be allowed to unwind. This can easily result in Undefined
+  Behavior (UB), so be careful.
+
+NB. The default behavior here is "allowed", but this is unspecified
+and likely to change in the future.
+
+"##,
+
 }
 
 register_diagnostics! {
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 1ebf52e9fe8..6444c846a8b 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -233,7 +233,7 @@ declare_features! (
     // allow `extern "platform-intrinsic" { ... }`
     (active, platform_intrinsics, "1.4.0", Some(27731)),
 
-    // allow `#[unwind]`
+    // allow `#[unwind(..)]`
     // rust runtime internal
     (active, unwind_attributes, "1.4.0", None),
 
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 0f6dbc39e21..e2c6b1b0c92 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -670,7 +670,7 @@ pub struct FileMap {
     /// originate from files has names between angle brackets by convention,
     /// e.g. `<anon>`
     pub name: FileName,
-    /// True if the `name` field above has been modified by -Zremap-path-prefix
+    /// True if the `name` field above has been modified by --remap-path-prefix
     pub name_was_remapped: bool,
     /// The unmapped path of the file that the source came from.
     /// Set to `None` if the FileMap was imported from an external crate.
diff --git a/src/libunwind/libunwind.rs b/src/libunwind/libunwind.rs
index e6fff7963f7..aa73b11fb38 100644
--- a/src/libunwind/libunwind.rs
+++ b/src/libunwind/libunwind.rs
@@ -83,7 +83,8 @@ pub enum _Unwind_Context {}
 pub type _Unwind_Exception_Cleanup_Fn = extern "C" fn(unwind_code: _Unwind_Reason_Code,
                                                       exception: *mut _Unwind_Exception);
 extern "C" {
-    #[unwind]
+    #[cfg_attr(stage0, unwind)]
+    #[cfg_attr(not(stage0), unwind(allowed))]
     pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
     pub fn _Unwind_DeleteException(exception: *mut _Unwind_Exception);
     pub fn _Unwind_GetLanguageSpecificData(ctx: *mut _Unwind_Context) -> *mut c_void;
@@ -220,7 +221,8 @@ if #[cfg(all(any(target_os = "ios", not(target_arch = "arm"))))] {
 if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] {
     // Not 32-bit iOS
     extern "C" {
-        #[unwind]
+        #[cfg_attr(stage0, unwind)]
+        #[cfg_attr(not(stage0), unwind(allowed))]
         pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
         pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
                                  trace_argument: *mut c_void)
@@ -229,7 +231,8 @@ if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] {
 } else {
     // 32-bit iOS uses SjLj and does not provide _Unwind_Backtrace()
     extern "C" {
-        #[unwind]
+        #[cfg_attr(stage0, unwind)]
+        #[cfg_attr(not(stage0), unwind(allowed))]
         pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
     }
 
diff --git a/src/test/codegen/extern-functions.rs b/src/test/codegen/extern-functions.rs
index 7ee31070b26..90ee0c75680 100644
--- a/src/test/codegen/extern-functions.rs
+++ b/src/test/codegen/extern-functions.rs
@@ -19,7 +19,7 @@ extern {
     fn extern_fn();
 // CHECK-NOT: Function Attrs: nounwind
 // CHECK: declare void @unwinding_extern_fn
-    #[unwind]
+    #[unwind(allowed)]
     fn unwinding_extern_fn();
 }
 
diff --git a/src/test/codegen/remap_path_prefix/auxiliary/remap_path_prefix_aux.rs b/src/test/codegen/remap_path_prefix/auxiliary/remap_path_prefix_aux.rs
index 5543a091680..3ef0ff9ef06 100644
--- a/src/test/codegen/remap_path_prefix/auxiliary/remap_path_prefix_aux.rs
+++ b/src/test/codegen/remap_path_prefix/auxiliary/remap_path_prefix_aux.rs
@@ -10,7 +10,7 @@
 
 // ignore-tidy-linelength
 
-// compile-flags: -g  -Zremap-path-prefix-from={{cwd}} -Zremap-path-prefix-to=/the/aux-cwd -Zremap-path-prefix-from={{src-base}}/remap_path_prefix/auxiliary -Zremap-path-prefix-to=/the/aux-src
+// compile-flags: -g  --remap-path-prefix={{cwd}}=/the/aux-cwd --remap-path-prefix={{src-base}}/remap_path_prefix/auxiliary=/the/aux-src
 
 #[inline]
 pub fn some_aux_function() -> i32 {
diff --git a/src/test/codegen/remap_path_prefix/main.rs b/src/test/codegen/remap_path_prefix/main.rs
index ea0c9ad2b83..2f46b6c5d48 100644
--- a/src/test/codegen/remap_path_prefix/main.rs
+++ b/src/test/codegen/remap_path_prefix/main.rs
@@ -11,7 +11,7 @@
 // ignore-windows
 // ignore-tidy-linelength
 
-// compile-flags: -g  -C no-prepopulate-passes -Zremap-path-prefix-from={{cwd}} -Zremap-path-prefix-to=/the/cwd -Zremap-path-prefix-from={{src-base}} -Zremap-path-prefix-to=/the/src
+// compile-flags: -g  -C no-prepopulate-passes --remap-path-prefix={{cwd}}=/the/cwd --remap-path-prefix={{src-base}}=/the/src
 // aux-build:remap_path_prefix_aux.rs
 
 extern crate remap_path_prefix_aux;
diff --git a/src/test/compile-fail/trait-bounds-not-on-struct.rs b/src/test/compile-fail/trait-bounds-not-on-struct.rs
index 6cd43916731..0dd1a4e7d73 100644
--- a/src/test/compile-fail/trait-bounds-not-on-struct.rs
+++ b/src/test/compile-fail/trait-bounds-not-on-struct.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 #![feature(dyn_trait)]
+#![allow(bare_trait_object)]
 
 struct Foo;
 
diff --git a/src/test/incremental/remapped_paths_cc/auxiliary/extern_crate.rs b/src/test/incremental/remapped_paths_cc/auxiliary/extern_crate.rs
index 1483bf92c97..c80b334623b 100644
--- a/src/test/incremental/remapped_paths_cc/auxiliary/extern_crate.rs
+++ b/src/test/incremental/remapped_paths_cc/auxiliary/extern_crate.rs
@@ -12,7 +12,7 @@
 
 //[rpass1] compile-flags: -g
 //[rpass2] compile-flags: -g
-//[rpass3] compile-flags: -g -Zremap-path-prefix-from={{src-base}} -Zremap-path-prefix-to=/the/src
+//[rpass3] compile-flags: -g --remap-path-prefix={{src-base}}=/the/src
 
 #![feature(rustc_attrs)]
 #![crate_type="rlib"]
diff --git a/src/test/mir-opt/uniform_array_move_out.rs b/src/test/mir-opt/uniform_array_move_out.rs
index 4a310255aac..482b69a59dd 100644
--- a/src/test/mir-opt/uniform_array_move_out.rs
+++ b/src/test/mir-opt/uniform_array_move_out.rs
@@ -57,3 +57,28 @@ fn main() {
 //     nop;
 //     _0 = ();
 // END rustc.move_out_by_subslice.UniformArrayMoveOut.after.mir
+
+// START rustc.move_out_by_subslice.RestoreSubsliceArrayMoveOut.before.mir
+//     StorageLive(_6);
+//     StorageLive(_7);
+//     _7 = move _1[0 of 2];
+//     StorageLive(_8);
+//     _8 = move _1[1 of 2];
+//     _6 = [move _7, move _8];
+//     StorageDead(_7);
+//     StorageDead(_8);
+//     _0 = ();
+// END rustc.move_out_by_subslice.RestoreSubsliceArrayMoveOut.before.mir
+
+// START rustc.move_out_by_subslice.RestoreSubsliceArrayMoveOut.after.mir
+//     StorageLive(_6);
+//     nop;
+//     nop;
+//     nop;
+//     nop;
+//     _6 = move _1[0:];
+//     nop;
+//     nop;
+//     nop;
+//     _0 = ();
+// END rustc.move_out_by_subslice.RestoreSubsliceArrayMoveOut.after.mir
diff --git a/src/test/run-pass/abort-on-c-abi.rs b/src/test/run-pass/abort-on-c-abi.rs
index 17661c0b120..ef368ed604b 100644
--- a/src/test/run-pass/abort-on-c-abi.rs
+++ b/src/test/run-pass/abort-on-c-abi.rs
@@ -14,11 +14,14 @@
 // ignore-cloudabi no env and process
 // ignore-emscripten no processes
 
+#![feature(unwind_attributes)]
+
 use std::{env, panic};
 use std::io::prelude::*;
 use std::io;
 use std::process::{Command, Stdio};
 
+#[unwind(aborts)]
 extern "C" fn panic_in_ffi() {
     panic!("Test");
 }