about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-05-02 10:13:57 +0000
committerbors <bors@rust-lang.org>2020-05-02 10:13:57 +0000
commit7184d137f65bb8d143ce8b5b664e50d33c4b5fbd (patch)
tree1439159b957c88e57d5773c16bc82fca38be08cb
parent08dfbfb61871a83f720c6e97a3b737076e89fe3e (diff)
parent2ee49eb7382856f25c3a4f5c708d0725d3494392 (diff)
downloadrust-7184d137f65bb8d143ce8b5b664e50d33c4b5fbd.tar.gz
rust-7184d137f65bb8d143ce8b5b664e50d33c4b5fbd.zip
Auto merge of #71795 - RalfJung:rollup-yqxfi5a, r=RalfJung
Rollup of 6 pull requests

Successful merges:

 - #71712 (Miri: port error backtraces to std::backtrace)
 - #71736 (bootstrap: also apply unused-attributes hack without deny_warnings)
 - #71738 (remove AllocId generalization of Pointer)
 - #71739 (remove obsolete comment)
 - #71781 (Uncomment test code for failure to use `Box::pin`)
 - #71782 (Use a non-existent test path instead of clobbering /dev/null)

Failed merges:

r? @ghost
-rw-r--r--Cargo.lock1
-rw-r--r--src/bootstrap/builder.rs12
-rw-r--r--src/librustc_middle/Cargo.toml1
-rw-r--r--src/librustc_middle/lib.rs1
-rw-r--r--src/librustc_middle/mir/interpret/error.rs20
-rw-r--r--src/librustc_middle/mir/interpret/pointer.rs16
-rw-r--r--src/librustc_middle/mir/interpret/value.rs12
-rw-r--r--src/librustc_mir/const_eval/error.rs2
-rw-r--r--src/librustc_mir/interpret/eval_context.rs10
-rw-r--r--src/librustc_mir/interpret/operand.rs16
-rw-r--r--src/librustc_mir/interpret/place.rs20
-rw-r--r--src/librustc_trait_selection/traits/util.rs1
-rw-r--r--src/test/ui/non-ice-error-on-worker-io-fail.rs10
-rw-r--r--src/test/ui/non-ice-error-on-worker-io-fail.stderr2
-rw-r--r--src/test/ui/suggestions/expected-boxed-future-isnt-pinned.rs35
-rw-r--r--src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr76
16 files changed, 154 insertions, 81 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 13a130a1b49..8bd1e5f3308 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3978,7 +3978,6 @@ name = "rustc_middle"
 version = "0.0.0"
 dependencies = [
  "arena",
- "backtrace",
  "bitflags",
  "byteorder",
  "log",
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 4a664205bff..c0018c613ba 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -1088,13 +1088,13 @@ impl<'a> Builder<'a> {
 
             if self.config.deny_warnings {
                 rustflags.arg("-Dwarnings");
+            }
 
-                // FIXME(#58633) hide "unused attribute" errors in incremental
-                // builds of the standard library, as the underlying checks are
-                // not yet properly integrated with incremental recompilation.
-                if mode == Mode::Std && compiler.stage == 0 && self.config.incremental {
-                    rustflags.arg("-Aunused-attributes");
-                }
+            // FIXME(#58633) hide "unused attribute" errors in incremental
+            // builds of the standard library, as the underlying checks are
+            // not yet properly integrated with incremental recompilation.
+            if mode == Mode::Std && compiler.stage == 0 && self.config.incremental {
+                rustflags.arg("-Aunused-attributes");
             }
         }
 
diff --git a/src/librustc_middle/Cargo.toml b/src/librustc_middle/Cargo.toml
index 8e27e03ea4f..398ba4d72d4 100644
--- a/src/librustc_middle/Cargo.toml
+++ b/src/librustc_middle/Cargo.toml
@@ -30,7 +30,6 @@ rustc_index = { path = "../librustc_index" }
 rustc_serialize = { path = "../libserialize", package = "serialize" }
 rustc_ast = { path = "../librustc_ast" }
 rustc_span = { path = "../librustc_span" }
-backtrace = "0.3.40"
 byteorder = { version = "1.3" }
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 measureme = "0.7.1"
diff --git a/src/librustc_middle/lib.rs b/src/librustc_middle/lib.rs
index 4ed03fd21ad..9b38b43c93a 100644
--- a/src/librustc_middle/lib.rs
+++ b/src/librustc_middle/lib.rs
@@ -23,6 +23,7 @@
 //! This API is completely unstable and subject to change.
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
+#![feature(backtrace)]
 #![feature(bool_to_option)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
diff --git a/src/librustc_middle/mir/interpret/error.rs b/src/librustc_middle/mir/interpret/error.rs
index 0ab14b53e1b..4b88467ac11 100644
--- a/src/librustc_middle/mir/interpret/error.rs
+++ b/src/librustc_middle/mir/interpret/error.rs
@@ -6,7 +6,6 @@ use crate::ty::query::TyCtxtAt;
 use crate::ty::tls;
 use crate::ty::{self, layout, Ty};
 
-use backtrace::Backtrace;
 use rustc_data_structures::sync::Lock;
 use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorReported};
 use rustc_hir as hir;
@@ -15,7 +14,7 @@ use rustc_macros::HashStable;
 use rustc_session::CtfeBacktrace;
 use rustc_span::{def_id::DefId, Pos, Span};
 use rustc_target::abi::{Align, Size};
-use std::{any::Any, fmt, mem};
+use std::{any::Any, backtrace::Backtrace, fmt, mem};
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, RustcEncodable, RustcDecodable)]
 pub enum ErrorHandled {
@@ -219,16 +218,15 @@ impl fmt::Display for InterpErrorInfo<'_> {
 }
 
 impl InterpErrorInfo<'_> {
-    pub fn print_backtrace(&mut self) {
-        if let Some(ref mut backtrace) = self.backtrace {
-            print_backtrace(&mut *backtrace);
+    pub fn print_backtrace(&self) {
+        if let Some(backtrace) = self.backtrace.as_ref() {
+            print_backtrace(backtrace);
         }
     }
 }
 
-fn print_backtrace(backtrace: &mut Backtrace) {
-    backtrace.resolve();
-    eprintln!("\n\nAn error occurred in miri:\n{:?}", backtrace);
+fn print_backtrace(backtrace: &Backtrace) {
+    eprintln!("\n\nAn error occurred in miri:\n{}", backtrace);
 }
 
 impl From<ErrorHandled> for InterpErrorInfo<'_> {
@@ -255,11 +253,11 @@ impl<'tcx> From<InterpError<'tcx>> for InterpErrorInfo<'tcx> {
 
         let backtrace = match capture_backtrace {
             CtfeBacktrace::Disabled => None,
-            CtfeBacktrace::Capture => Some(Box::new(Backtrace::new_unresolved())),
+            CtfeBacktrace::Capture => Some(Box::new(Backtrace::force_capture())),
             CtfeBacktrace::Immediate => {
                 // Print it now.
-                let mut backtrace = Backtrace::new_unresolved();
-                print_backtrace(&mut backtrace);
+                let backtrace = Backtrace::force_capture();
+                print_backtrace(&backtrace);
                 None
             }
         };
diff --git a/src/librustc_middle/mir/interpret/pointer.rs b/src/librustc_middle/mir/interpret/pointer.rs
index 19642278b44..0b060056499 100644
--- a/src/librustc_middle/mir/interpret/pointer.rs
+++ b/src/librustc_middle/mir/interpret/pointer.rs
@@ -75,18 +75,14 @@ pub trait PointerArithmetic: HasDataLayout {
 
 impl<T: HasDataLayout> PointerArithmetic for T {}
 
-/// `Pointer` is generic over the type that represents a reference to `Allocation`s,
-/// thus making it possible for the most convenient representation to be used in
-/// each context.
+/// Represents a pointer in the Miri engine.
 ///
-/// Defaults to the index based and loosely coupled `AllocId`.
-///
-/// `Pointer` is also generic over the `Tag` associated with each pointer,
+/// `Pointer` is generic over the `Tag` associated with each pointer,
 /// which is used to do provenance tracking during execution.
 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
 #[derive(HashStable)]
-pub struct Pointer<Tag = (), Id = AllocId> {
-    pub alloc_id: Id,
+pub struct Pointer<Tag = ()> {
+    pub alloc_id: AllocId,
     pub offset: Size,
     pub tag: Tag,
 }
@@ -97,7 +93,7 @@ static_assert_size!(Pointer, 16);
 // all the Miri types.
 // We have to use `Debug` output for the tag, because `()` does not implement
 // `Display` so we cannot specialize that.
-impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for Pointer<Tag, Id> {
+impl<Tag: fmt::Debug> fmt::Debug for Pointer<Tag> {
     default fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         if f.alternate() {
             write!(f, "{:#?}+0x{:x}[{:?}]", self.alloc_id, self.offset.bytes(), self.tag)
@@ -107,7 +103,7 @@ impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for Pointer<Tag, Id> {
     }
 }
 // Specialization for no tag
-impl<Id: fmt::Debug> fmt::Debug for Pointer<(), Id> {
+impl fmt::Debug for Pointer<()> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         if f.alternate() {
             write!(f, "{:#?}+0x{:x}", self.alloc_id, self.offset.bytes())
diff --git a/src/librustc_middle/mir/interpret/value.rs b/src/librustc_middle/mir/interpret/value.rs
index 0df8a9aa9b0..ed779d52fb5 100644
--- a/src/librustc_middle/mir/interpret/value.rs
+++ b/src/librustc_middle/mir/interpret/value.rs
@@ -89,7 +89,7 @@ impl<'tcx> ConstValue<'tcx> {
 /// of a simple value or a pointer into another `Allocation`
 #[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
 #[derive(HashStable)]
-pub enum Scalar<Tag = (), Id = AllocId> {
+pub enum Scalar<Tag = ()> {
     /// The raw bytes of a simple value.
     Raw {
         /// The first `size` bytes of `data` are the value.
@@ -101,7 +101,7 @@ pub enum Scalar<Tag = (), Id = AllocId> {
     /// A pointer into an `Allocation`. An `Allocation` in the `memory` module has a list of
     /// relocations, but a `Scalar` is only large enough to contain one, so we just represent the
     /// relocation and its associated offset together as a `Pointer` here.
-    Ptr(Pointer<Tag, Id>),
+    Ptr(Pointer<Tag>),
 }
 
 #[cfg(target_arch = "x86_64")]
@@ -109,7 +109,7 @@ static_assert_size!(Scalar, 24);
 
 // We want the `Debug` output to be readable as it is used by `derive(Debug)` for
 // all the Miri types.
-impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for Scalar<Tag, Id> {
+impl<Tag: fmt::Debug> fmt::Debug for Scalar<Tag> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
             Scalar::Ptr(ptr) => write!(f, "{:?}", ptr),
@@ -542,8 +542,8 @@ impl<Tag> From<Pointer<Tag>> for Scalar<Tag> {
 }
 
 #[derive(Clone, Copy, Eq, PartialEq, RustcEncodable, RustcDecodable, HashStable, Hash)]
-pub enum ScalarMaybeUndef<Tag = (), Id = AllocId> {
-    Scalar(Scalar<Tag, Id>),
+pub enum ScalarMaybeUndef<Tag = ()> {
+    Scalar(Scalar<Tag>),
     Undef,
 }
 
@@ -563,7 +563,7 @@ impl<Tag> From<Pointer<Tag>> for ScalarMaybeUndef<Tag> {
 
 // We want the `Debug` output to be readable as it is used by `derive(Debug)` for
 // all the Miri types.
-impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for ScalarMaybeUndef<Tag, Id> {
+impl<Tag: fmt::Debug> fmt::Debug for ScalarMaybeUndef<Tag> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
             ScalarMaybeUndef::Undef => write!(f, "<uninitialized>"),
diff --git a/src/librustc_mir/const_eval/error.rs b/src/librustc_mir/const_eval/error.rs
index 3c3618f390c..b165a69433d 100644
--- a/src/librustc_mir/const_eval/error.rs
+++ b/src/librustc_mir/const_eval/error.rs
@@ -52,7 +52,7 @@ impl Error for ConstEvalErrKind {}
 /// Should be called only if the error is actually going to to be reported!
 pub fn error_to_const_error<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>(
     ecx: &InterpCx<'mir, 'tcx, M>,
-    mut error: InterpErrorInfo<'tcx>,
+    error: InterpErrorInfo<'tcx>,
 ) -> ConstEvalErr<'tcx> {
     error.print_backtrace();
     let stacktrace = ecx.generate_stacktrace();
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 82e1984e462..f668bafe080 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -11,7 +11,7 @@ use rustc_macros::HashStable;
 use rustc_middle::ich::StableHashingContext;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{
-    sign_extend, truncate, AllocId, FrameInfo, GlobalId, InterpResult, Pointer, Scalar,
+    sign_extend, truncate, FrameInfo, GlobalId, InterpResult, Pointer, Scalar,
 };
 use rustc_middle::ty::layout::{self, TyAndLayout};
 use rustc_middle::ty::{
@@ -103,8 +103,8 @@ pub enum StackPopCleanup {
 
 /// State of a local variable including a memoized layout
 #[derive(Clone, PartialEq, Eq, HashStable)]
-pub struct LocalState<'tcx, Tag = (), Id = AllocId> {
-    pub value: LocalValue<Tag, Id>,
+pub struct LocalState<'tcx, Tag = ()> {
+    pub value: LocalValue<Tag>,
     /// Don't modify if `Some`, this is only used to prevent computing the layout twice
     #[stable_hasher(ignore)]
     pub layout: Cell<Option<TyAndLayout<'tcx>>>,
@@ -112,7 +112,7 @@ pub struct LocalState<'tcx, Tag = (), Id = AllocId> {
 
 /// Current value of a local variable
 #[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable)] // Miri debug-prints these
-pub enum LocalValue<Tag = (), Id = AllocId> {
+pub enum LocalValue<Tag = ()> {
     /// This local is not currently alive, and cannot be used at all.
     Dead,
     /// This local is alive but not yet initialized. It can be written to
@@ -125,7 +125,7 @@ pub enum LocalValue<Tag = (), Id = AllocId> {
     /// This is an optimization over just always having a pointer here;
     /// we can thus avoid doing an allocation when the local just stores
     /// immediate values *and* never has its address taken.
-    Live(Operand<Tag, Id>),
+    Live(Operand<Tag>),
 }
 
 impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> {
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index b924f20ce7c..e2fb9de486f 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -15,8 +15,8 @@ use rustc_target::abi::{Abi, DiscriminantKind, HasDataLayout, Integer, LayoutOf,
 use rustc_target::abi::{VariantIdx, Variants};
 
 use super::{
-    from_known_layout, sign_extend, truncate, AllocId, ConstValue, GlobalId, InterpCx,
-    InterpResult, MPlaceTy, Machine, MemPlace, Place, PlaceTy, Pointer, Scalar, ScalarMaybeUndef,
+    from_known_layout, sign_extend, truncate, ConstValue, GlobalId, InterpCx, InterpResult,
+    MPlaceTy, Machine, MemPlace, Place, PlaceTy, Pointer, Scalar, ScalarMaybeUndef,
 };
 
 /// An `Immediate` represents a single immediate self-contained Rust value.
@@ -27,9 +27,9 @@ use super::{
 /// In particular, thanks to `ScalarPair`, arithmetic operations and casts can be entirely
 /// defined on `Immediate`, and do not have to work with a `Place`.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable, Hash)]
-pub enum Immediate<Tag = (), Id = AllocId> {
-    Scalar(ScalarMaybeUndef<Tag, Id>),
-    ScalarPair(ScalarMaybeUndef<Tag, Id>, ScalarMaybeUndef<Tag, Id>),
+pub enum Immediate<Tag = ()> {
+    Scalar(ScalarMaybeUndef<Tag>),
+    ScalarPair(ScalarMaybeUndef<Tag>, ScalarMaybeUndef<Tag>),
 }
 
 impl<Tag> From<ScalarMaybeUndef<Tag>> for Immediate<Tag> {
@@ -145,9 +145,9 @@ impl<'tcx, Tag> ::std::ops::Deref for ImmTy<'tcx, Tag> {
 /// or still in memory. The latter is an optimization, to delay reading that chunk of
 /// memory and to avoid having to store arbitrary-sized data here.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable, Hash)]
-pub enum Operand<Tag = (), Id = AllocId> {
-    Immediate(Immediate<Tag, Id>),
-    Indirect(MemPlace<Tag, Id>),
+pub enum Operand<Tag = ()> {
+    Immediate(Immediate<Tag>),
+    Indirect(MemPlace<Tag>),
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index ba17a0b482a..fee9ca0c02e 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -20,9 +20,9 @@ use super::{
 
 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)]
 /// Information required for the sound usage of a `MemPlace`.
-pub enum MemPlaceMeta<Tag = (), Id = AllocId> {
+pub enum MemPlaceMeta<Tag = ()> {
     /// The unsized payload (e.g. length for slices or vtable pointer for trait objects).
-    Meta(Scalar<Tag, Id>),
+    Meta(Scalar<Tag>),
     /// `Sized` types or unsized `extern type`
     None,
     /// The address of this place may not be taken. This protects the `MemPlace` from coming from
@@ -32,8 +32,8 @@ pub enum MemPlaceMeta<Tag = (), Id = AllocId> {
     Poison,
 }
 
-impl<Tag, Id> MemPlaceMeta<Tag, Id> {
-    pub fn unwrap_meta(self) -> Scalar<Tag, Id> {
+impl<Tag> MemPlaceMeta<Tag> {
+    pub fn unwrap_meta(self) -> Scalar<Tag> {
         match self {
             Self::Meta(s) => s,
             Self::None | Self::Poison => {
@@ -47,9 +47,7 @@ impl<Tag, Id> MemPlaceMeta<Tag, Id> {
             Self::None | Self::Poison => false,
         }
     }
-}
 
-impl<Tag> MemPlaceMeta<Tag> {
     pub fn erase_tag(self) -> MemPlaceMeta<()> {
         match self {
             Self::Meta(s) => MemPlaceMeta::Meta(s.erase_tag()),
@@ -60,22 +58,22 @@ impl<Tag> MemPlaceMeta<Tag> {
 }
 
 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)]
-pub struct MemPlace<Tag = (), Id = AllocId> {
+pub struct MemPlace<Tag = ()> {
     /// A place may have an integral pointer for ZSTs, and since it might
     /// be turned back into a reference before ever being dereferenced.
     /// However, it may never be undef.
-    pub ptr: Scalar<Tag, Id>,
+    pub ptr: Scalar<Tag>,
     pub align: Align,
     /// Metadata for unsized places. Interpretation is up to the type.
     /// Must not be present for sized types, but can be missing for unsized types
     /// (e.g., `extern type`).
-    pub meta: MemPlaceMeta<Tag, Id>,
+    pub meta: MemPlaceMeta<Tag>,
 }
 
 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)]
-pub enum Place<Tag = (), Id = AllocId> {
+pub enum Place<Tag = ()> {
     /// A place referring to a value allocated in the `Memory` system.
-    Ptr(MemPlace<Tag, Id>),
+    Ptr(MemPlace<Tag>),
 
     /// To support alloc-free locals, we are able to write directly to a local.
     /// (Without that optimization, we'd just always be a `MemPlace`.)
diff --git a/src/librustc_trait_selection/traits/util.rs b/src/librustc_trait_selection/traits/util.rs
index 4aceccf64ce..eff73cf4a2d 100644
--- a/src/librustc_trait_selection/traits/util.rs
+++ b/src/librustc_trait_selection/traits/util.rs
@@ -217,7 +217,6 @@ pub fn impl_trait_ref_and_oblig<'a, 'tcx>(
     (impl_trait_ref, impl_obligations)
 }
 
-/// See [`super::obligations_for_generics`].
 pub fn predicates_for_generics<'tcx>(
     cause: ObligationCause<'tcx>,
     recursion_depth: usize,
diff --git a/src/test/ui/non-ice-error-on-worker-io-fail.rs b/src/test/ui/non-ice-error-on-worker-io-fail.rs
index 8af17742850..30779fc65c0 100644
--- a/src/test/ui/non-ice-error-on-worker-io-fail.rs
+++ b/src/test/ui/non-ice-error-on-worker-io-fail.rs
@@ -4,8 +4,12 @@
 //
 // An attempt to `-o` into a directory we cannot write into should indeed
 // be an error; but not an ICE.
+//
+// However, some folks run tests as root, which can write `/dev/` and end
+// up clobbering `/dev/null`. Instead we'll use a non-existent path, which
+// also used to ICE, but even root can't magically write there.
 
-// compile-flags: -o /dev/null
+// compile-flags: -o /does-not-exist/output
 
 // The error-pattern check occurs *before* normalization, and the error patterns
 // are wildly different between build environments. So this is a cop-out (and we
@@ -15,10 +19,10 @@
 // error-pattern: error
 
 // On Mac OS X, we get an error like the below
-// normalize-stderr-test "failed to write bytecode to /dev/null.non_ice_error_on_worker_io_fail.*" -> "io error modifying /dev/"
+// normalize-stderr-test "failed to write bytecode to /does-not-exist/output.non_ice_error_on_worker_io_fail.*" -> "io error modifying /does-not-exist/"
 
 // On Linux, we get an error like the below
-// normalize-stderr-test "couldn't create a temp dir.*" -> "io error modifying /dev/"
+// normalize-stderr-test "couldn't create a temp dir.*" -> "io error modifying /does-not-exist/"
 
 // ignore-tidy-linelength
 // ignore-windows - this is a unix-specific test
diff --git a/src/test/ui/non-ice-error-on-worker-io-fail.stderr b/src/test/ui/non-ice-error-on-worker-io-fail.stderr
index f732abc52b7..edadecf273a 100644
--- a/src/test/ui/non-ice-error-on-worker-io-fail.stderr
+++ b/src/test/ui/non-ice-error-on-worker-io-fail.stderr
@@ -1,6 +1,6 @@
 warning: ignoring --out-dir flag due to -o flag
 
-error: io error modifying /dev/
+error: io error modifying /does-not-exist/
 
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.rs b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.rs
index 0a1686eac9d..5dee0f5dae0 100644
--- a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.rs
+++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.rs
@@ -11,19 +11,26 @@ fn foo<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32>
     x //~ ERROR mismatched types
 }
 
-// FIXME: uncomment these once this commit is in Beta and we can rely on `rustc_on_unimplemented`
-//        having filtering for `Self` being a trait.
-//
-// fn bar<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
-//     Box::new(x)
-// }
-//
-// fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
-//     Pin::new(x)
-// }
-//
-// fn qux<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
-//     Pin::new(Box::new(x))
-// }
+// This case is still subpar:
+// `Pin::new(x)`: store this in the heap by calling `Box::new`: `Box::new(x)`
+// Should suggest changing the code from `Pin::new` to `Box::pin`.
+fn bar<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
+    Box::new(x) //~ ERROR mismatched types
+}
+
+fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
+    Pin::new(x) //~ ERROR mismatched types
+    //~^ ERROR E0277
+}
+
+fn qux<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
+    Pin::new(Box::new(x)) //~ ERROR E0277
+}
+
+fn zap() -> BoxFuture<'static, i32> {
+    async { //~ ERROR mismatched types
+        42
+    }
+}
 
 fn main() {}
diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
index 48d941283b6..ff256eb3094 100644
--- a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
+++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
@@ -15,6 +15,78 @@ LL |     x
    = help: type parameters must be constrained to match other types
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
-error: aborting due to previous error
+error[E0308]: mismatched types
+  --> $DIR/expected-boxed-future-isnt-pinned.rs:18:5
+   |
+LL | fn bar<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
+   |                                                         ----------------------- expected `std::pin::Pin<std::boxed::Box<(dyn std::future::Future<Output = i32> + std::marker::Send + 'static)>>` because of return type
+LL |     Box::new(x)
+   |     ^^^^^^^^^^^ expected struct `std::pin::Pin`, found struct `std::boxed::Box`
+   |
+   = note: expected struct `std::pin::Pin<std::boxed::Box<(dyn std::future::Future<Output = i32> + std::marker::Send + 'static)>>`
+              found struct `std::boxed::Box<F>`
+   = help: use `Box::pin`
+
+error[E0308]: mismatched types
+  --> $DIR/expected-boxed-future-isnt-pinned.rs:22:14
+   |
+LL | fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
+   |        - this type parameter
+LL |     Pin::new(x)
+   |              ^
+   |              |
+   |              expected struct `std::boxed::Box`, found type parameter `F`
+   |              help: store this in the heap by calling `Box::new`: `Box::new(x)`
+   |
+   = note:      expected struct `std::boxed::Box<dyn std::future::Future<Output = i32> + std::marker::Send>`
+           found type parameter `F`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+   = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+
+error[E0277]: `dyn std::future::Future<Output = i32> + std::marker::Send` cannot be unpinned
+  --> $DIR/expected-boxed-future-isnt-pinned.rs:22:5
+   |
+LL |     Pin::new(x)
+   |     ^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `dyn std::future::Future<Output = i32> + std::marker::Send`
+   |
+   = note: consider using `Box::pin`
+   = note: required by `std::pin::Pin::<P>::new`
+
+error[E0277]: `dyn std::future::Future<Output = i32> + std::marker::Send` cannot be unpinned
+  --> $DIR/expected-boxed-future-isnt-pinned.rs:27:5
+   |
+LL |     Pin::new(Box::new(x))
+   |     ^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `dyn std::future::Future<Output = i32> + std::marker::Send`
+   |
+   = note: consider using `Box::pin`
+   = note: required by `std::pin::Pin::<P>::new`
+
+error[E0308]: mismatched types
+  --> $DIR/expected-boxed-future-isnt-pinned.rs:31:5
+   |
+LL |   fn zap() -> BoxFuture<'static, i32> {
+   |               ----------------------- expected `std::pin::Pin<std::boxed::Box<(dyn std::future::Future<Output = i32> + std::marker::Send + 'static)>>` because of return type
+LL | /     async {
+LL | |         42
+LL | |     }
+   | |_____^ expected struct `std::pin::Pin`, found opaque type
+   | 
+  ::: $SRC_DIR/libcore/future/mod.rs:LL:COL
+   |
+LL |   pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
+   |                                             ------------------------------- the found opaque type
+   |
+   = note:   expected struct `std::pin::Pin<std::boxed::Box<(dyn std::future::Future<Output = i32> + std::marker::Send + 'static)>>`
+           found opaque type `impl std::future::Future`
+help: you need to pin and box this expression
+   |
+LL |     Box::pin(async {
+LL |         42
+LL |     })
+   |
+
+error: aborting due to 6 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.