about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs20
-rw-r--r--compiler/rustc_middle/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs36
-rw-r--r--compiler/rustc_trait_selection/src/traits/misc.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs4
-rw-r--r--compiler/rustc_typeck/src/check/pat.rs6
-rw-r--r--compiler/rustc_typeck/src/coherence/builtin.rs36
-rw-r--r--src/test/rustdoc/auto-trait-not-send.rs8
-rw-r--r--src/test/ui/async-await/async-block-control-flow-static-semantics.rs2
-rw-r--r--src/test/ui/async-await/async-block-control-flow-static-semantics.stderr4
-rw-r--r--src/test/ui/async-await/generator-desc.stderr4
-rw-r--r--src/test/ui/async-await/issue-67252-unnamed-future.stderr2
-rw-r--r--src/test/ui/async-await/issue-68112.stderr4
-rw-r--r--src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr2
-rw-r--r--src/test/ui/async-await/partial-drop-partial-reinit.stderr2
-rw-r--r--src/test/ui/chalkify/bugs/async.stderr2
-rw-r--r--src/test/ui/coherence/deep-bad-copy-reason.rs40
-rw-r--r--src/test/ui/coherence/deep-bad-copy-reason.stderr18
-rw-r--r--src/test/ui/consts/const-deref-ptr.stderr2
-rw-r--r--src/test/ui/consts/const-eval/const_raw_ptr_ops2.stderr4
-rw-r--r--src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr2
-rw-r--r--src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr2
-rw-r--r--src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr2
-rw-r--r--src/test/ui/consts/offset_ub.stderr4
-rw-r--r--src/test/ui/error-codes/E0396-fixed.stderr2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-89008.stderr2
-rw-r--r--src/test/ui/impl-trait/issue-55872-2.rs2
-rw-r--r--src/test/ui/impl-trait/issue-55872-2.stderr4
-rw-r--r--src/test/ui/impl-trait/issues/issue-78722.stderr2
-rw-r--r--src/test/ui/pattern/non-structural-match-types.stderr2
-rw-r--r--src/test/ui/structs-enums/struct-enum-ignoring-field-with-underscore.rs12
-rw-r--r--src/test/ui/structs-enums/struct-enum-ignoring-field-with-underscore.stderr24
-rw-r--r--src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr2
-rw-r--r--src/test/ui/union/union-copy.stderr6
34 files changed, 203 insertions, 66 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index 6397fcaaf8d..871b7578abd 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -427,22 +427,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
             }
         }
 
-        // Extract from the pointer an `Option<AllocId>` and an offset, which is relative to the
-        // allocation or (if that is `None`) an absolute address.
-        let ptr_or_addr = if size.bytes() == 0 {
-            // Let's see what we can do, but don't throw errors if there's nothing there.
-            self.ptr_try_get_alloc(ptr)
-        } else {
-            // A "real" access, we insist on getting an `AllocId`.
-            Ok(self.ptr_get_alloc(ptr)?)
-        };
-        Ok(match ptr_or_addr {
+        Ok(match self.ptr_try_get_alloc(ptr) {
             Err(addr) => {
-                // No memory is actually being accessed.
-                debug_assert!(size.bytes() == 0);
-                // Must be non-null.
-                if addr == 0 {
-                    throw_ub!(DanglingIntPointer(0, msg))
+                // We couldn't get a proper allocation. This is only okay if the access size is 0,
+                // and the address is not null.
+                if size.bytes() > 0 || addr == 0 {
+                    throw_ub!(DanglingIntPointer(addr, msg));
                 }
                 // Must be aligned.
                 if let Some(align) = align {
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index a575f27ad38..fa2dad5ce25 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -41,6 +41,7 @@
 #![feature(new_uninit)]
 #![feature(nll)]
 #![feature(once_cell)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(min_specialization)]
 #![feature(trusted_len)]
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 00cb9907d95..5cfd9a5edfb 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -896,44 +896,48 @@ pub trait PrettyPrinter<'tcx>:
             );
 
             if !generics.is_empty() || !assoc_items.is_empty() {
-                p!("<");
                 let mut first = true;
 
                 for ty in generics {
-                    if !first {
+                    if first {
+                        p!("<");
+                        first = false;
+                    } else {
                         p!(", ");
                     }
                     p!(print(trait_ref.rebind(*ty)));
-                    first = false;
                 }
 
                 for (assoc_item_def_id, term) in assoc_items {
-                    if !first {
+                    // Skip printing `<[generator@] as Generator<_>>::Return` from async blocks
+                    if let Some(ty) = term.skip_binder().ty() &&
+                       let ty::Projection(ty::ProjectionTy { item_def_id, .. }) = ty.kind() &&
+                       Some(*item_def_id) == self.tcx().lang_items().generator_return() {
+                        continue;
+                    }
+
+                    if first {
+                        p!("<");
+                        first = false;
+                    } else {
                         p!(", ");
                     }
+
                     p!(write("{} = ", self.tcx().associated_item(assoc_item_def_id).name));
 
                     match term.skip_binder() {
                         Term::Ty(ty) => {
-                            // Skip printing `<[generator@] as Generator<_>>::Return` from async blocks
-                            if matches!(
-                              ty.kind(), ty::Projection(ty::ProjectionTy { item_def_id, .. })
-                              if Some(*item_def_id) == self.tcx().lang_items().generator_return()
-                            ) {
-                                p!("[async output]")
-                            } else {
-                                p!(print(ty))
-                            }
+                            p!(print(ty))
                         }
                         Term::Const(c) => {
                             p!(print(c));
                         }
                     };
-
-                    first = false;
                 }
 
-                p!(">");
+                if !first {
+                    p!(">");
+                }
             }
 
             first = false;
diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs
index 08308253ced..b83b0bf1ca5 100644
--- a/compiler/rustc_trait_selection/src/traits/misc.rs
+++ b/compiler/rustc_trait_selection/src/traits/misc.rs
@@ -11,7 +11,7 @@ use crate::traits::error_reporting::InferCtxtExt;
 
 #[derive(Clone)]
 pub enum CopyImplementationError<'tcx> {
-    InfrigingFields(Vec<&'tcx ty::FieldDef>),
+    InfrigingFields(Vec<(&'tcx ty::FieldDef, Ty<'tcx>)>),
     NotAnAdt,
     HasDestructor,
 }
@@ -67,7 +67,7 @@ pub fn can_type_implement_copy<'tcx>(
                 match traits::fully_normalize(&infcx, ctx, cause, param_env, ty) {
                     Ok(ty) => {
                         if !infcx.type_is_copy_modulo_regions(param_env, ty, span) {
-                            infringing.push(field);
+                            infringing.push((field, ty));
                         }
                     }
                     Err(errors) => {
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 5d07139e87b..4135fbca060 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1270,7 +1270,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // the master cache. Since coherence executes pretty quickly,
         // it's not worth going to more trouble to increase the
         // hit-rate, I don't think.
-        if self.intercrate {
+        if self.intercrate || self.allow_negative_impls {
             return false;
         }
 
@@ -1287,7 +1287,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // mode, so don't do any caching. In particular, we might
         // re-use the same `InferCtxt` with both an intercrate
         // and non-intercrate `SelectionContext`
-        if self.intercrate {
+        if self.intercrate || self.allow_negative_impls {
             return None;
         }
         let tcx = self.tcx();
diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index c16be38d5fc..1c4fbbbb9bf 100644
--- a/compiler/rustc_typeck/src/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
@@ -17,7 +17,7 @@ use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
 use rustc_span::hygiene::DesugaringKind;
 use rustc_span::lev_distance::find_best_match_for_name;
 use rustc_span::source_map::{Span, Spanned};
-use rustc_span::symbol::{sym, Ident};
+use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::{BytePos, MultiSpan, DUMMY_SP};
 use rustc_trait_selection::autoderef::Autoderef;
 use rustc_trait_selection::traits::{ObligationCause, Pattern};
@@ -1275,7 +1275,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .filter(|(_, ident)| !used_fields.contains_key(ident))
             .collect::<Vec<_>>();
 
-        let inexistent_fields_err = if !(inexistent_fields.is_empty() || variant.is_recovered()) {
+        let inexistent_fields_err = if !(inexistent_fields.is_empty() || variant.is_recovered())
+            && !inexistent_fields.iter().any(|field| field.name == kw::Underscore)
+        {
             Some(self.error_inexistent_fields(
                 adt.variant_descr(),
                 &inexistent_fields,
diff --git a/compiler/rustc_typeck/src/coherence/builtin.rs b/compiler/rustc_typeck/src/coherence/builtin.rs
index ef59df0dc88..3135e9996ab 100644
--- a/compiler/rustc_typeck/src/coherence/builtin.rs
+++ b/compiler/rustc_typeck/src/coherence/builtin.rs
@@ -91,8 +91,40 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
                 E0204,
                 "the trait `Copy` may not be implemented for this type"
             );
-            for span in fields.iter().map(|f| tcx.def_span(f.did)) {
-                err.span_label(span, "this field does not implement `Copy`");
+            for (field, ty) in fields {
+                let field_span = tcx.def_span(field.did);
+                err.span_label(field_span, "this field does not implement `Copy`");
+                // Spin up a new FulfillmentContext, so we can get the _precise_ reason
+                // why this field does not implement Copy. This is useful because sometimes
+                // it is not immediately clear why Copy is not implemented for a field, since
+                // all we point at is the field itself.
+                tcx.infer_ctxt().enter(|infcx| {
+                    let mut fulfill_cx = traits::FulfillmentContext::new_ignoring_regions();
+                    fulfill_cx.register_bound(
+                        &infcx,
+                        param_env,
+                        ty,
+                        tcx.lang_items().copy_trait().unwrap(),
+                        traits::ObligationCause::dummy_with_span(field_span),
+                    );
+                    for error in fulfill_cx.select_all_or_error(&infcx) {
+                        let error_predicate = error.obligation.predicate;
+                        // Only note if it's not the root obligation, otherwise it's trivial and
+                        // should be self-explanatory (i.e. a field literally doesn't implement Copy).
+
+                        // FIXME: This error could be more descriptive, especially if the error_predicate
+                        // contains a foreign type or if it's a deeply nested type...
+                        if error_predicate != error.root_obligation.predicate {
+                            err.span_note(
+                                error.obligation.cause.span,
+                                &format!(
+                                    "the `Copy` impl for `{}` requires that `{}`",
+                                    ty, error_predicate
+                                ),
+                            );
+                        }
+                    }
+                });
             }
             err.emit();
         }
diff --git a/src/test/rustdoc/auto-trait-not-send.rs b/src/test/rustdoc/auto-trait-not-send.rs
new file mode 100644
index 00000000000..7bd4f6dbd8c
--- /dev/null
+++ b/src/test/rustdoc/auto-trait-not-send.rs
@@ -0,0 +1,8 @@
+#![crate_name = "foo"]
+
+// @has 'foo/struct.Foo.html'
+// @has - '//*[@id="impl-Send"]' 'impl !Send for Foo'
+// @has - '//*[@id="impl-Sync"]' 'impl !Sync for Foo'
+pub struct Foo(*const i8);
+pub trait Whatever: Send {}
+impl<T: Send + ?Sized> Whatever for T {}
diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.rs b/src/test/ui/async-await/async-block-control-flow-static-semantics.rs
index e3832767203..f6c6f90a393 100644
--- a/src/test/ui/async-await/async-block-control-flow-static-semantics.rs
+++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.rs
@@ -24,7 +24,7 @@ async fn return_targets_async_block_not_async_fn() -> u8 {
         return 0u8;
     };
     let _: &dyn Future<Output = ()> = &block;
-    //~^ ERROR type mismatch resolving `<impl Future<Output = [async output]> as Future>::Output == ()`
+    //~^ ERROR type mismatch resolving `<impl Future as Future>::Output == ()`
 }
 
 fn no_break_in_async_block() {
diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
index fe864c65b7c..919904ce3b6 100644
--- a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
+++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
@@ -31,7 +31,7 @@ LL | |
 LL | | }
    | |_^ expected `u8`, found `()`
 
-error[E0271]: type mismatch resolving `<impl Future<Output = [async output]> as Future>::Output == ()`
+error[E0271]: type mismatch resolving `<impl Future as Future>::Output == ()`
   --> $DIR/async-block-control-flow-static-semantics.rs:26:39
    |
 LL |     let _: &dyn Future<Output = ()> = &block;
@@ -47,7 +47,7 @@ LL | fn return_targets_async_block_not_fn() -> u8 {
    |    |
    |    implicitly returns `()` as its body has no tail or `return` expression
 
-error[E0271]: type mismatch resolving `<impl Future<Output = [async output]> as Future>::Output == ()`
+error[E0271]: type mismatch resolving `<impl Future as Future>::Output == ()`
   --> $DIR/async-block-control-flow-static-semantics.rs:17:39
    |
 LL |     let _: &dyn Future<Output = ()> = &block;
diff --git a/src/test/ui/async-await/generator-desc.stderr b/src/test/ui/async-await/generator-desc.stderr
index 4a45d8d2a94..79834ed7ec1 100644
--- a/src/test/ui/async-await/generator-desc.stderr
+++ b/src/test/ui/async-await/generator-desc.stderr
@@ -46,8 +46,8 @@ LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
    |                                           the expected opaque type
    |                                           the found opaque type
    |
-   = note: expected opaque type `impl Future<Output = [async output]>` (`async` closure body)
-              found opaque type `impl Future<Output = [async output]>` (`async` closure body)
+   = note: expected opaque type `impl Future` (`async` closure body)
+              found opaque type `impl Future` (`async` closure body)
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/async-await/issue-67252-unnamed-future.stderr b/src/test/ui/async-await/issue-67252-unnamed-future.stderr
index f32e074d75d..19b90f1d878 100644
--- a/src/test/ui/async-await/issue-67252-unnamed-future.stderr
+++ b/src/test/ui/async-await/issue-67252-unnamed-future.stderr
@@ -4,7 +4,7 @@ error: future cannot be sent between threads safely
 LL |     spawn(async {
    |     ^^^^^ future created by async block is not `Send`
    |
-   = help: within `impl Future<Output = [async output]>`, the trait `Send` is not implemented for `*mut ()`
+   = help: within `impl Future`, the trait `Send` is not implemented for `*mut ()`
 note: future is not `Send` as this value is used across an await
   --> $DIR/issue-67252-unnamed-future.rs:20:16
    |
diff --git a/src/test/ui/async-await/issue-68112.stderr b/src/test/ui/async-await/issue-68112.stderr
index a8c2ebe12fa..9682a7055e9 100644
--- a/src/test/ui/async-await/issue-68112.stderr
+++ b/src/test/ui/async-await/issue-68112.stderr
@@ -44,13 +44,13 @@ LL |     require_send(send_fut);
    = note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
    = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:47:31: 47:36]`
    = note: required because it appears within the type `from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:47:31: 47:36]>`
-   = note: required because it appears within the type `impl Future<Output = [async output]>`
+   = note: required because it appears within the type `impl Future`
    = note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>`
    = note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>`
    = note: required because it appears within the type `{ResumeTy, impl Future<Output = Arc<RefCell<i32>>>, (), i32, Ready<i32>}`
    = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:55:26: 59:6]`
    = note: required because it appears within the type `from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:55:26: 59:6]>`
-   = note: required because it appears within the type `impl Future<Output = [async output]>`
+   = note: required because it appears within the type `impl Future`
 note: required by a bound in `require_send`
   --> $DIR/issue-68112.rs:11:25
    |
diff --git a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr
index b4d20064803..cf023bd0f97 100644
--- a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr
+++ b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr
@@ -4,7 +4,7 @@ error: future cannot be sent between threads safely
 LL |     assert_send(async {
    |     ^^^^^^^^^^^ future created by async block is not `Send`
    |
-   = help: within `impl Future<Output = [async output]>`, the trait `Send` is not implemented for `*const u8`
+   = help: within `impl Future`, the trait `Send` is not implemented for `*const u8`
 note: future is not `Send` as this value is used across an await
   --> $DIR/issue-65436-raw-ptr-not-send.rs:14:35
    |
diff --git a/src/test/ui/async-await/partial-drop-partial-reinit.stderr b/src/test/ui/async-await/partial-drop-partial-reinit.stderr
index 2097642eb24..a83b1d660c3 100644
--- a/src/test/ui/async-await/partial-drop-partial-reinit.stderr
+++ b/src/test/ui/async-await/partial-drop-partial-reinit.stderr
@@ -14,7 +14,7 @@ LL | async fn foo() {
    = note: required because it appears within the type `{ResumeTy, (NotSend,), impl Future<Output = ()>, ()}`
    = note: required because it appears within the type `[static generator@$DIR/partial-drop-partial-reinit.rs:22:16: 27:2]`
    = note: required because it appears within the type `from_generator::GenFuture<[static generator@$DIR/partial-drop-partial-reinit.rs:22:16: 27:2]>`
-   = note: required because it appears within the type `impl Future<Output = [async output]>`
+   = note: required because it appears within the type `impl Future`
    = note: required because it appears within the type `impl Future<Output = ()>`
 note: required by a bound in `gimme_send`
   --> $DIR/partial-drop-partial-reinit.rs:10:18
diff --git a/src/test/ui/chalkify/bugs/async.stderr b/src/test/ui/chalkify/bugs/async.stderr
index 7a86561bcb9..3d62f059f37 100644
--- a/src/test/ui/chalkify/bugs/async.stderr
+++ b/src/test/ui/chalkify/bugs/async.stderr
@@ -28,7 +28,7 @@ note: required by a bound in `from_generator`
 LL |     T: Generator<ResumeTy, Yield = ()>,
    |                            ^^^^^^^^^^ required by this bound in `from_generator`
 
-error[E0280]: the requirement `<impl Future<Output = [async output]> as Future>::Output == u32` is not satisfied
+error[E0280]: the requirement `<impl Future as Future>::Output == u32` is not satisfied
   --> $DIR/async.rs:7:25
    |
 LL | async fn foo(x: u32) -> u32 {
diff --git a/src/test/ui/coherence/deep-bad-copy-reason.rs b/src/test/ui/coherence/deep-bad-copy-reason.rs
new file mode 100644
index 00000000000..80bbe387ac7
--- /dev/null
+++ b/src/test/ui/coherence/deep-bad-copy-reason.rs
@@ -0,0 +1,40 @@
+#![feature(extern_types)]
+
+extern "Rust" {
+    type OpaqueListContents;
+}
+
+pub struct ListS<T> {
+    len: usize,
+    data: [T; 0],
+    opaque: OpaqueListContents,
+}
+
+pub struct Interned<'a, T>(&'a T);
+
+impl<'a, T> Clone for Interned<'a, T> {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+
+impl<'a, T> Copy for Interned<'a, T> {}
+
+pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
+//~^ NOTE this field does not implement `Copy`
+//~| NOTE the `Copy` impl for `Interned<'tcx, ListS<T>>` requires that `OpaqueListContents: Sized`
+
+impl<'tcx, T> Clone for List<'tcx, T> {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+
+impl<'tcx, T> Copy for List<'tcx, T> {}
+//~^ ERROR the trait `Copy` may not be implemented for this type
+
+fn assert_is_copy<T: Copy>() {}
+
+fn main() {
+    assert_is_copy::<List<'static, ()>>();
+}
diff --git a/src/test/ui/coherence/deep-bad-copy-reason.stderr b/src/test/ui/coherence/deep-bad-copy-reason.stderr
new file mode 100644
index 00000000000..295538cee60
--- /dev/null
+++ b/src/test/ui/coherence/deep-bad-copy-reason.stderr
@@ -0,0 +1,18 @@
+error[E0204]: the trait `Copy` may not be implemented for this type
+  --> $DIR/deep-bad-copy-reason.rs:33:15
+   |
+LL | pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
+   |                          ------------------------ this field does not implement `Copy`
+...
+LL | impl<'tcx, T> Copy for List<'tcx, T> {}
+   |               ^^^^
+   |
+note: the `Copy` impl for `Interned<'tcx, ListS<T>>` requires that `OpaqueListContents: Sized`
+  --> $DIR/deep-bad-copy-reason.rs:23:26
+   |
+LL | pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0204`.
diff --git a/src/test/ui/consts/const-deref-ptr.stderr b/src/test/ui/consts/const-deref-ptr.stderr
index 316843889c6..7606afdc4ff 100644
--- a/src/test/ui/consts/const-deref-ptr.stderr
+++ b/src/test/ui/consts/const-deref-ptr.stderr
@@ -2,7 +2,7 @@ error[E0080]: could not evaluate static initializer
   --> $DIR/const-deref-ptr.rs:4:29
    |
 LL |     static C: u64 = unsafe {*(0xdeadbeef as *const u64)};
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 0xdeadbeef is not a valid pointer
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: 0xdeadbeef is not a valid pointer
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-eval/const_raw_ptr_ops2.stderr b/src/test/ui/consts/const-eval/const_raw_ptr_ops2.stderr
index 44fa437806b..df8a80be72c 100644
--- a/src/test/ui/consts/const-eval/const_raw_ptr_ops2.stderr
+++ b/src/test/ui/consts/const-eval/const_raw_ptr_ops2.stderr
@@ -2,13 +2,13 @@ error[E0080]: evaluation of constant value failed
   --> $DIR/const_raw_ptr_ops2.rs:7:26
    |
 LL | const Z2: i32 = unsafe { *(42 as *const i32) };
-   |                          ^^^^^^^^^^^^^^^^^^^ 0x2a is not a valid pointer
+   |                          ^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: 0x2a is not a valid pointer
 
 error[E0080]: evaluation of constant value failed
   --> $DIR/const_raw_ptr_ops2.rs:9:26
    |
 LL | const Z3: i32 = unsafe { *(44 as *const i32) };
-   |                          ^^^^^^^^^^^^^^^^^^^ 0x2c is not a valid pointer
+   |                          ^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: 0x2c is not a valid pointer
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
index 2a489e8b69c..f8c9dca566b 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
@@ -296,7 +296,7 @@ error[E0080]: could not evaluate static initializer
   --> $DIR/ub-wide-ptr.rs:135:5
    |
 LL |     mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ null pointer is not a valid pointer for this operation
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is not a valid pointer
 
 error[E0080]: could not evaluate static initializer
   --> $DIR/ub-wide-ptr.rs:139:5
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
index ff850d2dbe9..ded007ce281 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
@@ -296,7 +296,7 @@ error[E0080]: could not evaluate static initializer
   --> $DIR/ub-wide-ptr.rs:135:5
    |
 LL |     mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ null pointer is not a valid pointer for this operation
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is not a valid pointer
 
 error[E0080]: could not evaluate static initializer
   --> $DIR/ub-wide-ptr.rs:139:5
diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr
index 7d6716787aa..9c1733e827d 100644
--- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr
+++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr
@@ -4,7 +4,7 @@ error[E0080]: evaluation of constant value failed
 LL |     Some(&mut *(42 as *mut i32))
    |          ^^^^^^^^^^^^^^^^^^^^^^
    |          |
-   |          0x2a is not a valid pointer
+   |          dereferencing pointer failed: 0x2a is not a valid pointer
    |          inside `helper` at $DIR/mut_ref_in_final_dynamic_check.rs:13:10
 ...
 LL | const A: Option<&mut i32> = helper();
diff --git a/src/test/ui/consts/offset_ub.stderr b/src/test/ui/consts/offset_ub.stderr
index 237950a30e8..e774e389313 100644
--- a/src/test/ui/consts/offset_ub.stderr
+++ b/src/test/ui/consts/offset_ub.stderr
@@ -130,7 +130,7 @@ error[E0080]: evaluation of constant value failed
 LL |         unsafe { intrinsics::offset(self, count) as *mut T }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                  |
-   |                  0x1 is not a valid pointer
+   |                  pointer arithmetic failed: 0x1 is not a valid pointer
    |                  inside `ptr::mut_ptr::<impl *mut u8>::offset` at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
    |
   ::: $DIR/offset_ub.rs:19:42
@@ -158,7 +158,7 @@ error[E0080]: evaluation of constant value failed
 LL |         unsafe { intrinsics::offset(self, count) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                  |
-   |                  0x7f..f is not a valid pointer
+   |                  pointer arithmetic failed: 0x7f..f is not a valid pointer
    |                  inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
    |
   ::: $DIR/offset_ub.rs:25:47
diff --git a/src/test/ui/error-codes/E0396-fixed.stderr b/src/test/ui/error-codes/E0396-fixed.stderr
index 91997fcf0f9..3eb291f0f70 100644
--- a/src/test/ui/error-codes/E0396-fixed.stderr
+++ b/src/test/ui/error-codes/E0396-fixed.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed
   --> $DIR/E0396-fixed.rs:5:28
    |
 LL | const VALUE: u8 = unsafe { *REG_ADDR };
-   |                            ^^^^^^^^^ 0x5f3759df is not a valid pointer
+   |                            ^^^^^^^^^ dereferencing pointer failed: 0x5f3759df is not a valid pointer
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/generic-associated-types/bugs/issue-89008.stderr b/src/test/ui/generic-associated-types/bugs/issue-89008.stderr
index c2687ca5401..3e607d4004e 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-89008.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-89008.stderr
@@ -1,4 +1,4 @@
-error[E0271]: type mismatch resolving `<impl Future<Output = [async output]> as Future>::Output == impl Stream<Item = Repr>`
+error[E0271]: type mismatch resolving `<impl Future as Future>::Output == impl Stream<Item = Repr>`
   --> $DIR/issue-89008.rs:39:43
    |
 LL |     type LineStream<'a, Repr> = impl Stream<Item = Repr>;
diff --git a/src/test/ui/impl-trait/issue-55872-2.rs b/src/test/ui/impl-trait/issue-55872-2.rs
index 17a6a857874..1841d7b3d37 100644
--- a/src/test/ui/impl-trait/issue-55872-2.rs
+++ b/src/test/ui/impl-trait/issue-55872-2.rs
@@ -12,7 +12,7 @@ impl<S> Bar for S {
     type E = impl std::marker::Copy;
     fn foo<T>() -> Self::E {
         //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-        //~| ERROR the trait bound `impl Future<Output = [async output]>: Copy` is not satisfied
+        //~| ERROR the trait bound `impl Future: Copy` is not satisfied
         async {}
     }
 }
diff --git a/src/test/ui/impl-trait/issue-55872-2.stderr b/src/test/ui/impl-trait/issue-55872-2.stderr
index b76b564dfb1..76122e60c4c 100644
--- a/src/test/ui/impl-trait/issue-55872-2.stderr
+++ b/src/test/ui/impl-trait/issue-55872-2.stderr
@@ -1,8 +1,8 @@
-error[E0277]: the trait bound `impl Future<Output = [async output]>: Copy` is not satisfied
+error[E0277]: the trait bound `impl Future: Copy` is not satisfied
   --> $DIR/issue-55872-2.rs:13:20
    |
 LL |     fn foo<T>() -> Self::E {
-   |                    ^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = [async output]>`
+   |                    ^^^^^^^ the trait `Copy` is not implemented for `impl Future`
 
 error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
   --> $DIR/issue-55872-2.rs:13:28
diff --git a/src/test/ui/impl-trait/issues/issue-78722.stderr b/src/test/ui/impl-trait/issues/issue-78722.stderr
index 130678de237..86bde9a0cdd 100644
--- a/src/test/ui/impl-trait/issues/issue-78722.stderr
+++ b/src/test/ui/impl-trait/issues/issue-78722.stderr
@@ -15,7 +15,7 @@ LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
    |                                           ------------------------------- the found opaque type
    |
    = note: expected opaque type `impl Future<Output = u8>`
-              found opaque type `impl Future<Output = [async output]>`
+              found opaque type `impl Future`
    = note: distinct uses of `impl Trait` result in different opaque types
 
 error: aborting due to previous error
diff --git a/src/test/ui/pattern/non-structural-match-types.stderr b/src/test/ui/pattern/non-structural-match-types.stderr
index 31168e29eb8..91fed81eaef 100644
--- a/src/test/ui/pattern/non-structural-match-types.stderr
+++ b/src/test/ui/pattern/non-structural-match-types.stderr
@@ -4,7 +4,7 @@ error: `[closure@$DIR/non-structural-match-types.rs:9:17: 9:22]` cannot be used
 LL |         const { || {} } => {},
    |         ^^^^^^^^^^^^^^^
 
-error: `impl Future<Output = [async output]>` cannot be used in patterns
+error: `impl Future` cannot be used in patterns
   --> $DIR/non-structural-match-types.rs:12:9
    |
 LL |         const { async {} } => {},
diff --git a/src/test/ui/structs-enums/struct-enum-ignoring-field-with-underscore.rs b/src/test/ui/structs-enums/struct-enum-ignoring-field-with-underscore.rs
new file mode 100644
index 00000000000..c30b8a1e1f1
--- /dev/null
+++ b/src/test/ui/structs-enums/struct-enum-ignoring-field-with-underscore.rs
@@ -0,0 +1,12 @@
+enum Foo {
+    Bar { bar: bool },
+    Other,
+}
+
+fn main() {
+    let foo = Some(Foo::Other);
+
+    if let Some(Foo::Bar {_}) = foo {}
+    //~^ ERROR expected identifier, found reserved identifier `_`
+    //~| ERROR pattern does not mention field `bar` [E0027]
+}
diff --git a/src/test/ui/structs-enums/struct-enum-ignoring-field-with-underscore.stderr b/src/test/ui/structs-enums/struct-enum-ignoring-field-with-underscore.stderr
new file mode 100644
index 00000000000..16f751444a5
--- /dev/null
+++ b/src/test/ui/structs-enums/struct-enum-ignoring-field-with-underscore.stderr
@@ -0,0 +1,24 @@
+error: expected identifier, found reserved identifier `_`
+  --> $DIR/struct-enum-ignoring-field-with-underscore.rs:9:27
+   |
+LL |     if let Some(Foo::Bar {_}) = foo {}
+   |                           ^ expected identifier, found reserved identifier
+
+error[E0027]: pattern does not mention field `bar`
+  --> $DIR/struct-enum-ignoring-field-with-underscore.rs:9:17
+   |
+LL |     if let Some(Foo::Bar {_}) = foo {}
+   |                 ^^^^^^^^^^^^ missing field `bar`
+   |
+help: include the missing field in the pattern
+   |
+LL |     if let Some(Foo::Bar {_, bar }) = foo {}
+   |                            ~~~~~~~
+help: if you don't care about this missing field, you can explicitly ignore it
+   |
+LL |     if let Some(Foo::Bar {_, .. }) = foo {}
+   |                            ~~~~~~
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0027`.
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 550ed4b03b0..7ef4895249c 100644
--- a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
+++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
@@ -81,7 +81,7 @@ LL |   pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
    |                                             ------------------------------- the found opaque type
    |
    = note:   expected struct `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>`
-           found opaque type `impl Future<Output = [async output]>`
+           found opaque type `impl Future`
 help: you need to pin and box this expression
    |
 LL ~     Box::pin(async {
diff --git a/src/test/ui/union/union-copy.stderr b/src/test/ui/union/union-copy.stderr
index 0f47bae7f0f..279808dd55b 100644
--- a/src/test/ui/union/union-copy.stderr
+++ b/src/test/ui/union/union-copy.stderr
@@ -6,6 +6,12 @@ LL |     a: std::mem::ManuallyDrop<String>
 ...
 LL | impl Copy for W {}
    |      ^^^^
+   |
+note: the `Copy` impl for `ManuallyDrop<String>` requires that `String: Copy`
+  --> $DIR/union-copy.rs:8:5
+   |
+LL |     a: std::mem::ManuallyDrop<String>
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error