about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock10
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs2
-rw-r--r--compiler/rustc_data_structures/src/flat_map_in_place.rs (renamed from compiler/rustc_data_structures/src/map_in_place.rs)15
-rw-r--r--compiler/rustc_data_structures/src/lib.rs2
-rw-r--r--compiler/rustc_expand/src/config.rs2
-rw-r--r--compiler/rustc_expand/src/expand.rs2
-rw-r--r--compiler/rustc_hir_analysis/locales/en-US.ftl4
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs10
-rw-r--r--compiler/rustc_hir_typeck/locales/en-US.ftl4
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs4
-rw-r--r--compiler/rustc_monomorphize/src/partitioning/merging.rs2
-rw-r--r--compiler/rustc_monomorphize/src/partitioning/mod.rs2
-rw-r--r--compiler/rustc_parse/src/lexer/diagnostics.rs2
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs2
-rw-r--r--compiler/rustc_session/src/code_stats.rs12
-rw-r--r--compiler/rustc_smir/Cargo.toml19
-rw-r--r--compiler/rustc_smir/README.md37
-rw-r--r--compiler/rustc_smir/rust-toolchain.toml2
-rw-r--r--compiler/rustc_smir/src/lib.rs8
-rw-r--r--compiler/rustc_smir/src/mir.rs10
-rw-r--r--compiler/rustc_smir/src/rustc_internal/mod.rs15
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs48
-rw-r--r--compiler/rustc_smir/src/stable_mir/mod.rs60
-rw-r--r--compiler/rustc_smir/src/very_unstable.rs27
-rw-r--r--compiler/rustc_trait_selection/src/traits/misc.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs4
-rw-r--r--library/core/src/marker.rs2
-rw-r--r--src/librustdoc/html/render/context.rs4
-rw-r--r--src/tools/clippy/tests/ui-toml/array_size_threshold/array_size_threshold.rs (renamed from tests/ui-toml/array_size_threshold/array_size_threshold.rs)0
-rw-r--r--src/tools/clippy/tests/ui-toml/array_size_threshold/array_size_threshold.stderr (renamed from tests/ui-toml/array_size_threshold/array_size_threshold.stderr)0
-rw-r--r--src/tools/clippy/tests/ui-toml/array_size_threshold/clippy.toml (renamed from tests/ui-toml/array_size_threshold/clippy.toml)0
-rw-r--r--tests/rustdoc-gui/sidebar.goml14
-rw-r--r--tests/ui-fulldeps/stable-mir/crate-info.rs104
-rw-r--r--tests/ui/coherence/coherence-impls-copy.stderr6
-rw-r--r--tests/ui/coherence/deep-bad-copy-reason.rs2
-rw-r--r--tests/ui/coherence/deep-bad-copy-reason.stderr2
-rw-r--r--tests/ui/coherence/illegal-copy-bad-projection.rs16
-rw-r--r--tests/ui/coherence/illegal-copy-bad-projection.stderr9
-rw-r--r--tests/ui/const-generics/bad-generic-in-copy-impl.rs9
-rw-r--r--tests/ui/const-generics/bad-generic-in-copy-impl.stderr9
-rw-r--r--tests/ui/error-codes/E0184.stderr2
-rw-r--r--tests/ui/error-codes/E0206.rs2
-rw-r--r--tests/ui/error-codes/E0206.stderr2
-rw-r--r--tests/ui/exclusive-drop-and-copy.rs4
-rw-r--r--tests/ui/exclusive-drop-and-copy.stderr4
-rw-r--r--tests/ui/issues/issue-27340.rs2
-rw-r--r--tests/ui/issues/issue-27340.stderr2
-rw-r--r--tests/ui/opt-in-copy.rs4
-rw-r--r--tests/ui/opt-in-copy.stderr4
-rw-r--r--tests/ui/range/range_traits-2.stderr2
-rw-r--r--tests/ui/range/range_traits-3.stderr2
-rw-r--r--tests/ui/range/range_traits-6.stderr2
-rw-r--r--tests/ui/span/E0204.rs8
-rw-r--r--tests/ui/span/E0204.stderr8
-rw-r--r--tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed2
-rw-r--r--tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs2
-rw-r--r--tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr6
-rw-r--r--tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs2
-rw-r--r--tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr6
-rw-r--r--tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.fixed2
-rw-r--r--tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.rs2
-rw-r--r--tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.stderr2
-rw-r--r--tests/ui/suggestions/missing-bound-in-manual-copy-impl.fixed2
-rw-r--r--tests/ui/suggestions/missing-bound-in-manual-copy-impl.rs2
-rw-r--r--tests/ui/suggestions/missing-bound-in-manual-copy-impl.stderr2
-rw-r--r--tests/ui/traits/copy-is-not-modulo-regions.not_static.stderr2
-rw-r--r--tests/ui/traits/copy-is-not-modulo-regions.rs2
-rw-r--r--tests/ui/traits/issue-50480.rs4
-rw-r--r--tests/ui/traits/issue-50480.stderr4
-rw-r--r--tests/ui/traits/unsend-future.rs21
-rw-r--r--tests/ui/traits/unsend-future.stderr24
-rw-r--r--tests/ui/union/union-copy.rs2
-rw-r--r--tests/ui/union/union-copy.stderr2
74 files changed, 465 insertions, 165 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 71ec870e223..7776964adf9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5283,15 +5283,9 @@ dependencies = [
 name = "rustc_smir"
 version = "0.0.0"
 dependencies = [
- "rustc_borrowck",
- "rustc_driver",
- "rustc_hir",
- "rustc_interface",
  "rustc_middle",
- "rustc_mir_dataflow",
- "rustc_mir_transform",
- "rustc_serialize",
- "rustc_trait_selection",
+ "rustc_span",
+ "tracing",
 ]
 
 [[package]]
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 7dcb03b4c78..6fed0b660e8 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -12,7 +12,7 @@ use crate::ptr::P;
 use crate::token::{self, Token};
 use crate::tokenstream::*;
 
-use rustc_data_structures::map_in_place::MapInPlace;
+use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
 use rustc_data_structures::sync::Lrc;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::Ident;
diff --git a/compiler/rustc_data_structures/src/map_in_place.rs b/compiler/rustc_data_structures/src/flat_map_in_place.rs
index a0d4b7ade1f..f58844f2817 100644
--- a/compiler/rustc_data_structures/src/map_in_place.rs
+++ b/compiler/rustc_data_structures/src/flat_map_in_place.rs
@@ -2,14 +2,7 @@ use smallvec::{Array, SmallVec};
 use std::ptr;
 use thin_vec::ThinVec;
 
-pub trait MapInPlace<T>: Sized {
-    fn map_in_place<F>(&mut self, mut f: F)
-    where
-        F: FnMut(T) -> T,
-    {
-        self.flat_map_in_place(|e| Some(f(e)))
-    }
-
+pub trait FlatMapInPlace<T>: Sized {
     fn flat_map_in_place<F, I>(&mut self, f: F)
     where
         F: FnMut(T) -> I,
@@ -66,14 +59,14 @@ macro_rules! flat_map_in_place {
     };
 }
 
-impl<T> MapInPlace<T> for Vec<T> {
+impl<T> FlatMapInPlace<T> for Vec<T> {
     flat_map_in_place!();
 }
 
-impl<T, A: Array<Item = T>> MapInPlace<T> for SmallVec<A> {
+impl<T, A: Array<Item = T>> FlatMapInPlace<T> for SmallVec<A> {
     flat_map_in_place!();
 }
 
-impl<T> MapInPlace<T> for ThinVec<T> {
+impl<T> FlatMapInPlace<T> for ThinVec<T> {
     flat_map_in_place!();
 }
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index a94e52fdfe6..c595bf830a3 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -50,6 +50,7 @@ pub fn cold_path<F: FnOnce() -> R, R>(f: F) -> R {
 pub mod base_n;
 pub mod binary_search_util;
 pub mod captures;
+pub mod flat_map_in_place;
 pub mod flock;
 pub mod functor;
 pub mod fx;
@@ -57,7 +58,6 @@ pub mod graph;
 pub mod intern;
 pub mod jobserver;
 pub mod macros;
-pub mod map_in_place;
 pub mod obligation_forest;
 pub mod owning_ref;
 pub mod sip128;
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index 01500c2c77c..d6cb173ba9b 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -12,8 +12,8 @@ use rustc_ast::tokenstream::{LazyAttrTokenStream, TokenTree};
 use rustc_ast::NodeId;
 use rustc_ast::{self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem};
 use rustc_attr as attr;
+use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::map_in_place::MapInPlace;
 use rustc_feature::{Feature, Features, State as FeatureState};
 use rustc_feature::{
     ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES, STABLE_REMOVED_FEATURES,
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 79d058d9c97..4092a192e0c 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -20,7 +20,7 @@ use rustc_ast::{ForeignItemKind, HasAttrs, HasNodeId};
 use rustc_ast::{Inline, ItemKind, MacStmtStyle, MetaItemKind, ModKind};
 use rustc_ast::{NestedMetaItem, NodeId, PatKind, StmtKind, TyKind};
 use rustc_ast_pretty::pprust;
-use rustc_data_structures::map_in_place::MapInPlace;
+use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::PResult;
 use rustc_feature::Features;
diff --git a/compiler/rustc_hir_analysis/locales/en-US.ftl b/compiler/rustc_hir_analysis/locales/en-US.ftl
index 50e857ef60d..3c62529442c 100644
--- a/compiler/rustc_hir_analysis/locales/en-US.ftl
+++ b/compiler/rustc_hir_analysis/locales/en-US.ftl
@@ -89,14 +89,14 @@ hir_analysis_missing_type_params =
     .note = because of the default `Self` reference, type parameters must be specified on object types
 
 hir_analysis_copy_impl_on_type_with_dtor =
-    the trait `Copy` may not be implemented for this type; the type has a destructor
+    the trait `Copy` cannot be implemented for this type; the type has a destructor
     .label = `Copy` not allowed on types with destructors
 
 hir_analysis_multiple_relaxed_default_bounds =
     type parameter has more than one relaxed default bound, only one is supported
 
 hir_analysis_copy_impl_on_non_adt =
-    the trait `Copy` may not be implemented for this type
+    the trait `Copy` cannot be implemented for this type
     .label = type is not a structure or enumeration
 
 hir_analysis_const_impl_for_non_const_trait =
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index ffb68abf978..8294d92c936 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -2,6 +2,7 @@
 //! up data structures required by type-checking/codegen.
 
 use crate::errors::{CopyImplOnNonAdt, CopyImplOnTypeWithDtor, DropImplOnWrongItem};
+use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{struct_span_err, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -86,7 +87,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
                 tcx.sess,
                 span,
                 E0204,
-                "the trait `Copy` may not be implemented for this type"
+                "the trait `Copy` cannot be implemented for this type"
             );
 
             // We'll try to suggest constraining type parameters to fulfill the requirements of
@@ -94,7 +95,14 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
             let mut errors: BTreeMap<_, Vec<_>> = Default::default();
             let mut bounds = vec![];
 
+            let mut seen_tys = FxHashSet::default();
+
             for (field, ty, reason) in fields {
+                // Only report an error once per type.
+                if !seen_tys.insert(ty) {
+                    continue;
+                }
+
                 let field_span = tcx.def_span(field.did);
                 err.span_label(field_span, "this field does not implement `Copy`");
 
diff --git a/compiler/rustc_hir_typeck/locales/en-US.ftl b/compiler/rustc_hir_typeck/locales/en-US.ftl
index adfcbc36a4d..2c537bf4064 100644
--- a/compiler/rustc_hir_typeck/locales/en-US.ftl
+++ b/compiler/rustc_hir_typeck/locales/en-US.ftl
@@ -4,14 +4,14 @@ hir_typeck_field_multiply_specified_in_initializer =
     .previous_use_label = first use of `{$ident}`
 
 hir_typeck_copy_impl_on_type_with_dtor =
-    the trait `Copy` may not be implemented for this type; the type has a destructor
+    the trait `Copy` cannot be implemented for this type; the type has a destructor
     .label = `Copy` not allowed on types with destructors
 
 hir_typeck_multiple_relaxed_default_bounds =
     type parameter has more than one relaxed default bound, only one is supported
 
 hir_typeck_copy_impl_on_non_adt =
-    the trait `Copy` may not be implemented for this type
+    the trait `Copy` cannot be implemented for this type
     .label = type is not a structure or enumeration
 
 hir_typeck_trait_object_declared_with_no_traits =
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 3bef5cfcd78..57805f7c800 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -1031,7 +1031,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             .collect();
 
         // Sort them by the name so we have a stable result.
-        names.sort_by(|a, b| a.as_str().partial_cmp(b.as_str()).unwrap());
+        names.sort_by(|a, b| a.as_str().cmp(b.as_str()));
         names
     }
 
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index e6d6586d5ee..4b15e48bd27 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -42,7 +42,7 @@ use rustc_trait_selection::traits::{
 use super::probe::{AutorefOrPtrAdjustment, IsSuggestion, Mode, ProbeScope};
 use super::{CandidateSource, MethodError, NoMatchData};
 use rustc_hir::intravisit::Visitor;
-use std::cmp::Ordering;
+use std::cmp::{self, Ordering};
 use std::iter;
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -2527,7 +2527,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         if !candidates.is_empty() {
             // Sort from most relevant to least relevant.
-            candidates.sort_by(|a, b| a.cmp(b).reverse());
+            candidates.sort_by_key(|&info| cmp::Reverse(info));
             candidates.dedup();
 
             let param_type = match rcvr_ty.kind() {
diff --git a/compiler/rustc_monomorphize/src/partitioning/merging.rs b/compiler/rustc_monomorphize/src/partitioning/merging.rs
index 02bb8dea0c0..5c524a18454 100644
--- a/compiler/rustc_monomorphize/src/partitioning/merging.rs
+++ b/compiler/rustc_monomorphize/src/partitioning/merging.rs
@@ -24,7 +24,7 @@ pub fn merge_codegen_units<'tcx>(
     // smallest into each other) we're sure to start off with a deterministic
     // order (sorted by name). This'll mean that if two cgus have the same size
     // the stable sort below will keep everything nice and deterministic.
-    codegen_units.sort_by(|a, b| a.name().as_str().partial_cmp(b.name().as_str()).unwrap());
+    codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
 
     // This map keeps track of what got merged into what.
     let mut cgu_contents: FxHashMap<Symbol, Vec<Symbol>> =
diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs
index 524c51d88d7..7ac1c9e057e 100644
--- a/compiler/rustc_monomorphize/src/partitioning/mod.rs
+++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs
@@ -252,7 +252,7 @@ pub fn partition<'tcx>(
         internalization_candidates: _,
     } = post_inlining;
 
-    result.sort_by(|a, b| a.name().as_str().partial_cmp(b.name().as_str()).unwrap());
+    result.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
 
     result
 }
diff --git a/compiler/rustc_parse/src/lexer/diagnostics.rs b/compiler/rustc_parse/src/lexer/diagnostics.rs
index 27f4428d306..c4b9fdc81c5 100644
--- a/compiler/rustc_parse/src/lexer/diagnostics.rs
+++ b/compiler/rustc_parse/src/lexer/diagnostics.rs
@@ -71,7 +71,7 @@ pub fn report_suspicious_mismatch_block(
         .collect();
 
     // sort by `lo`, so the large block spans in the front
-    matched_spans.sort_by(|a, b| a.0.lo().cmp(&b.0.lo()));
+    matched_spans.sort_by_key(|(span, _)| span.lo());
 
     // We use larger block whose identation is well to cover those inner mismatched blocks
     // O(N^2) here, but we are on error reporting path, so it is fine
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 206c43f6902..6133e75a78f 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1736,7 +1736,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
 
         let name = path[path.len() - 1].ident.name;
         // Make sure error reporting is deterministic.
-        names.sort_by(|a, b| a.candidate.as_str().partial_cmp(b.candidate.as_str()).unwrap());
+        names.sort_by(|a, b| a.candidate.as_str().cmp(b.candidate.as_str()));
 
         match find_best_match_for_name(
             &names.iter().map(|suggestion| suggestion.candidate).collect::<Vec<Symbol>>(),
diff --git a/compiler/rustc_session/src/code_stats.rs b/compiler/rustc_session/src/code_stats.rs
index 55178250472..0dfee92f404 100644
--- a/compiler/rustc_session/src/code_stats.rs
+++ b/compiler/rustc_session/src/code_stats.rs
@@ -2,7 +2,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::sync::Lock;
 use rustc_span::Symbol;
 use rustc_target::abi::{Align, Size};
-use std::cmp::{self, Ordering};
+use std::cmp;
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub struct VariantInfo {
@@ -87,7 +87,7 @@ impl CodeStats {
         // Except for Generators, whose variants are already sorted according to
         // their yield points in `variant_info_for_generator`.
         if kind != DataTypeKind::Generator {
-            variants.sort_by(|info1, info2| info2.size.cmp(&info1.size));
+            variants.sort_by_key(|info| cmp::Reverse(info.size));
         }
         let info = TypeSizeInfo {
             kind,
@@ -107,13 +107,7 @@ impl CodeStats {
 
         // Primary sort: large-to-small.
         // Secondary sort: description (dictionary order)
-        sorted.sort_by(|info1, info2| {
-            // (reversing cmp order to get large-to-small ordering)
-            match info2.overall_size.cmp(&info1.overall_size) {
-                Ordering::Equal => info1.type_description.cmp(&info2.type_description),
-                other => other,
-            }
-        });
+        sorted.sort_by_key(|info| (cmp::Reverse(info.overall_size), &info.type_description));
 
         for info in sorted {
             let TypeSizeInfo { type_description, overall_size, align, kind, variants, .. } = info;
diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml
index 5e0d1f369a6..fb97ee5bebe 100644
--- a/compiler/rustc_smir/Cargo.toml
+++ b/compiler/rustc_smir/Cargo.toml
@@ -4,25 +4,12 @@ version = "0.0.0"
 edition = "2021"
 
 [dependencies]
-rustc_borrowck = { path = "../rustc_borrowck", optional = true }
-rustc_driver = { path = "../rustc_driver", optional = true }
-rustc_hir = { path = "../rustc_hir", optional = true }
-rustc_interface = { path = "../rustc_interface", optional = true }
 rustc_middle = { path = "../rustc_middle", optional = true }
-rustc_mir_dataflow = { path = "../rustc_mir_dataflow", optional = true }
-rustc_mir_transform = { path = "../rustc_mir_transform", optional = true }
-rustc_serialize = { path = "../rustc_serialize", optional = true }
-rustc_trait_selection = { path = "../rustc_trait_selection", optional = true }
+rustc_span = { path = "../rustc_span", optional = true }
+tracing = "0.1"
 
 [features]
 default = [
-    "rustc_borrowck",
-    "rustc_driver",
-    "rustc_hir",
-    "rustc_interface",
     "rustc_middle",
-    "rustc_mir_dataflow",
-    "rustc_mir_transform",
-    "rustc_serialize",
-    "rustc_trait_selection",
+    "rustc_span",
 ]
diff --git a/compiler/rustc_smir/README.md b/compiler/rustc_smir/README.md
index ae49098dd0c..31dee955f49 100644
--- a/compiler/rustc_smir/README.md
+++ b/compiler/rustc_smir/README.md
@@ -73,3 +73,40 @@ git subtree pull --prefix=compiler/rustc_smir https://github.com/rust-lang/proje
 Note: only ever sync to rustc from the project-stable-mir's `smir` branch. Do not sync with your own forks.
 
 Then open a PR against rustc just like a regular PR.
+
+## Stable MIR Design
+
+The stable-mir will follow a similar approach to proc-macro2. It’s
+implementation will eventually be broken down into two main crates:
+
+- `stable_mir`: Public crate, to be published on crates.io, which will contain
+the stable data structure as well as proxy APIs to make calls to the
+compiler.
+- `rustc_smir`: The compiler crate that will translate from internal MIR to
+SMIR. This crate will also implement APIs that will be invoked by
+stable-mir to query the compiler for more information.
+
+This will help tools to communicate with the rust compiler via stable APIs. Tools will depend on
+`stable_mir` crate, which will invoke the compiler using APIs defined in `rustc_smir`. I.e.:
+
+```
+    ┌──────────────────────────────────┐           ┌──────────────────────────────────┐
+    │   External Tool     ┌──────────┐ │           │ ┌──────────┐   Rust Compiler     │
+    │                     │          │ │           │ │          │                     │
+    │                     │stable_mir| │           │ │rustc_smir│                     │
+    │                     │          │ ├──────────►| │          │                     │
+    │                     │          │ │◄──────────┤ │          │                     │
+    │                     │          │ │           │ │          │                     │
+    │                     │          │ │           │ │          │                     │
+    │                     └──────────┘ │           │ └──────────┘                     │
+    └──────────────────────────────────┘           └──────────────────────────────────┘
+```
+
+More details can be found here:
+https://hackmd.io/XhnYHKKuR6-LChhobvlT-g?view
+
+For now, the code for these two crates are in separate modules of this crate.
+The modules have the same name for simplicity. We also have a third module,
+`rustc_internal` which will expose APIs and definitions that allow users to
+gather information from internal MIR constructs that haven't been exposed in
+the `stable_mir` module.
diff --git a/compiler/rustc_smir/rust-toolchain.toml b/compiler/rustc_smir/rust-toolchain.toml
index 7b696fc1f5c..157dfd620ee 100644
--- a/compiler/rustc_smir/rust-toolchain.toml
+++ b/compiler/rustc_smir/rust-toolchain.toml
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2022-06-01"
+channel = "nightly-2023-02-28"
 components = [ "rustfmt", "rustc-dev" ]
diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs
index 3e93c6bba97..54d474db038 100644
--- a/compiler/rustc_smir/src/lib.rs
+++ b/compiler/rustc_smir/src/lib.rs
@@ -11,9 +11,9 @@
     test(attr(allow(unused_variables), deny(warnings)))
 )]
 #![cfg_attr(not(feature = "default"), feature(rustc_private))]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
-pub mod mir;
+pub mod rustc_internal;
+pub mod stable_mir;
 
-pub mod very_unstable;
+// Make this module private for now since external users should not call these directly.
+mod rustc_smir;
diff --git a/compiler/rustc_smir/src/mir.rs b/compiler/rustc_smir/src/mir.rs
deleted file mode 100644
index 887e6572930..00000000000
--- a/compiler/rustc_smir/src/mir.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-pub use crate::very_unstable::hir::ImplicitSelfKind;
-pub use crate::very_unstable::middle::mir::{
-    visit::MutVisitor, AggregateKind, AssertKind, BasicBlock, BasicBlockData, BinOp, BindingForm,
-    BlockTailInfo, Body, BorrowKind, CastKind, ClearCrossCrate, Constant, ConstantKind,
-    CopyNonOverlapping, Coverage, FakeReadCause, Field, GeneratorInfo, InlineAsmOperand, Local,
-    LocalDecl, LocalInfo, LocalKind, Location, MirPhase, MirSource, NullOp, Operand, Place,
-    PlaceRef, ProjectionElem, ProjectionKind, Promoted, RetagKind, Rvalue, Safety, SourceInfo,
-    SourceScope, SourceScopeData, SourceScopeLocalData, Statement, StatementKind, UnOp,
-    UserTypeProjection, UserTypeProjections, VarBindingForm, VarDebugInfo, VarDebugInfoContents,
-};
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
new file mode 100644
index 00000000000..3eaff9c051f
--- /dev/null
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -0,0 +1,15 @@
+//! Module that implements the bridge between Stable MIR and internal compiler MIR.
+//!
+//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
+//! until stable MIR is complete.
+
+use crate::stable_mir;
+pub use rustc_span::def_id::{CrateNum, DefId};
+
+pub fn item_def_id(item: &stable_mir::CrateItem) -> DefId {
+    item.0
+}
+
+pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
+    item.id.into()
+}
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
new file mode 100644
index 00000000000..d956f0ac802
--- /dev/null
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -0,0 +1,48 @@
+//! Module that implements what will become the rustc side of Stable MIR.
+//!
+//! This module is responsible for building Stable MIR components from internal components.
+//!
+//! This module is not intended to be invoked directly by users. It will eventually
+//! become the public API of rustc that will be invoked by the `stable_mir` crate.
+//!
+//! For now, we are developing everything inside `rustc`, thus, we keep this module private.
+
+use crate::stable_mir::{self};
+use rustc_middle::ty::{tls::with, TyCtxt};
+use rustc_span::def_id::{CrateNum, LOCAL_CRATE};
+use tracing::debug;
+
+/// Get information about the local crate.
+pub fn local_crate() -> stable_mir::Crate {
+    with(|tcx| smir_crate(tcx, LOCAL_CRATE))
+}
+
+/// Retrieve a list of all external crates.
+pub fn external_crates() -> Vec<stable_mir::Crate> {
+    with(|tcx| tcx.crates(()).iter().map(|crate_num| smir_crate(tcx, *crate_num)).collect())
+}
+
+/// Find a crate with the given name.
+pub fn find_crate(name: &str) -> Option<stable_mir::Crate> {
+    with(|tcx| {
+        [LOCAL_CRATE].iter().chain(tcx.crates(()).iter()).find_map(|crate_num| {
+            let crate_name = tcx.crate_name(*crate_num).to_string();
+            (name == crate_name).then(|| smir_crate(tcx, *crate_num))
+        })
+    })
+}
+
+/// Retrieve all items of the local crate that have a MIR associated with them.
+pub fn all_local_items() -> stable_mir::CrateItems {
+    with(|tcx| {
+        tcx.mir_keys(()).iter().map(|item| stable_mir::CrateItem(item.to_def_id())).collect()
+    })
+}
+
+/// Build a stable mir crate from a given crate number.
+fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate {
+    let crate_name = tcx.crate_name(crate_num).to_string();
+    let is_local = crate_num == LOCAL_CRATE;
+    debug!(?crate_name, ?crate_num, "smir_crate");
+    stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local }
+}
diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs
new file mode 100644
index 00000000000..cbf52e691fb
--- /dev/null
+++ b/compiler/rustc_smir/src/stable_mir/mod.rs
@@ -0,0 +1,60 @@
+//! Module that implements the public interface to the Stable MIR.
+//!
+//! This module shall contain all type definitions and APIs that we expect 3P tools to invoke to
+//! interact with the compiler.
+//!
+//! The goal is to eventually move this module to its own crate which shall be published on
+//! [crates.io](https://crates.io).
+//!
+//! ## Note:
+//!
+//! There shouldn't be any direct references to internal compiler constructs in this module.
+//! If you need an internal construct, consider using `rustc_internal` or `rustc_smir`.
+
+use crate::rustc_internal;
+
+/// Use String for now but we should replace it.
+pub type Symbol = String;
+
+/// The number that identifies a crate.
+pub type CrateNum = usize;
+
+/// A unique identification number for each item accessible for the current compilation unit.
+pub type DefId = usize;
+
+/// A list of crate items.
+pub type CrateItems = Vec<CrateItem>;
+
+/// Holds information about a crate.
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub struct Crate {
+    pub(crate) id: CrateNum,
+    pub name: Symbol,
+    pub is_local: bool,
+}
+
+/// Holds information about an item in the crate.
+/// For now, it only stores the item DefId. Use functions inside `rustc_internal` module to
+/// use this item.
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub struct CrateItem(pub(crate) rustc_internal::DefId);
+
+/// Access to the local crate.
+pub fn local_crate() -> Crate {
+    crate::rustc_smir::local_crate()
+}
+
+/// Try to find a crate with the given name.
+pub fn find_crate(name: &str) -> Option<Crate> {
+    crate::rustc_smir::find_crate(name)
+}
+
+/// Try to find a crate with the given name.
+pub fn external_crates() -> Vec<Crate> {
+    crate::rustc_smir::external_crates()
+}
+
+/// Retrieve all items in the local crate that have a MIR associated with them.
+pub fn all_local_items() -> CrateItems {
+    crate::rustc_smir::all_local_items()
+}
diff --git a/compiler/rustc_smir/src/very_unstable.rs b/compiler/rustc_smir/src/very_unstable.rs
deleted file mode 100644
index 12ba133dbb1..00000000000
--- a/compiler/rustc_smir/src/very_unstable.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-//! This module reexports various crates and modules from unstable rustc APIs.
-//! Add anything you need here and it will get slowly transferred to a stable API.
-//! Only use rustc_smir in your dependencies and use the reexports here instead of
-//! directly referring to the unstable crates.
-
-macro_rules! crates {
-    ($($rustc_name:ident -> $name:ident,)*) => {
-        $(
-            #[cfg(not(feature = "default"))]
-            pub extern crate $rustc_name as $name;
-            #[cfg(feature = "default")]
-            pub use $rustc_name as $name;
-        )*
-    }
-}
-
-crates! {
-    rustc_borrowck -> borrowck,
-    rustc_driver -> driver,
-    rustc_hir -> hir,
-    rustc_interface -> interface,
-    rustc_middle -> middle,
-    rustc_mir_dataflow -> dataflow,
-    rustc_mir_transform -> transform,
-    rustc_serialize -> serialize,
-    rustc_trait_selection -> trait_selection,
-}
diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs
index b94346b0956..336db4fee6c 100644
--- a/compiler/rustc_trait_selection/src/traits/misc.rs
+++ b/compiler/rustc_trait_selection/src/traits/misc.rs
@@ -87,7 +87,12 @@ pub fn type_allowed_to_implement_copy<'tcx>(
             };
             let ty = ocx.normalize(&normalization_cause, param_env, unnormalized_ty);
             let normalization_errors = ocx.select_where_possible();
-            if !normalization_errors.is_empty() {
+
+            // NOTE: The post-normalization type may also reference errors,
+            // such as when we project to a missing type or we have a mismatch
+            // between expected and found const-generic types. Don't report an
+            // additional copy error here, since it's not typically useful.
+            if !normalization_errors.is_empty() || ty.references_error() {
                 tcx.sess.delay_span_bug(field_span, format!("couldn't normalize struct field `{unnormalized_ty}` when checking Copy implementation"));
                 continue;
             }
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index cd3f3c114ba..48c3b3601b4 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1083,7 +1083,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     let mut nested_result = EvaluationResult::EvaluatedToOk;
                     for obligation in nested_obligations {
                         nested_result = cmp::max(
-                            this.evaluate_predicate_recursively(stack.list(), obligation)?,
+                            this.evaluate_predicate_recursively(previous_stack, obligation)?,
                             nested_result,
                         );
                     }
@@ -1092,7 +1092,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                         let obligation = obligation.with(this.tcx(), predicate);
                         result = cmp::max(
                             nested_result,
-                            this.evaluate_trait_predicate_recursively(stack.list(), obligation)?,
+                            this.evaluate_trait_predicate_recursively(previous_stack, obligation)?,
                         );
                     }
                 }
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 520ae0edb09..427146941ad 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -324,7 +324,7 @@ pub trait StructuralEq {
 /// attempt to derive a `Copy` implementation, we'll get an error:
 ///
 /// ```text
-/// the trait `Copy` may not be implemented for this type; field `points` does not implement `Copy`
+/// the trait `Copy` cannot be implemented for this type; field `points` does not implement `Copy`
 /// ```
 ///
 /// Shared references (`&T`) are also `Copy`, so a type can be `Copy`, even when it holds
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 5e4a595627b..1030fe74747 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -600,9 +600,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
         };
         let all = shared.all.replace(AllTypes::new());
         let mut sidebar = Buffer::html();
-        if shared.cache.crate_version.is_some() {
-            write!(sidebar, "<h2 class=\"location\">Crate {}</h2>", crate_name)
-        };
+        write!(sidebar, "<h2 class=\"location\"><a href=\"#\">Crate {}</a></h2>", crate_name);
 
         let mut items = Buffer::html();
         sidebar_module_like(&mut items, all.item_sections());
diff --git a/tests/ui-toml/array_size_threshold/array_size_threshold.rs b/src/tools/clippy/tests/ui-toml/array_size_threshold/array_size_threshold.rs
index 7f623c7a9ec..7f623c7a9ec 100644
--- a/tests/ui-toml/array_size_threshold/array_size_threshold.rs
+++ b/src/tools/clippy/tests/ui-toml/array_size_threshold/array_size_threshold.rs
diff --git a/tests/ui-toml/array_size_threshold/array_size_threshold.stderr b/src/tools/clippy/tests/ui-toml/array_size_threshold/array_size_threshold.stderr
index ac017b20916..ac017b20916 100644
--- a/tests/ui-toml/array_size_threshold/array_size_threshold.stderr
+++ b/src/tools/clippy/tests/ui-toml/array_size_threshold/array_size_threshold.stderr
diff --git a/tests/ui-toml/array_size_threshold/clippy.toml b/src/tools/clippy/tests/ui-toml/array_size_threshold/clippy.toml
index 3f1fe9a1209..3f1fe9a1209 100644
--- a/tests/ui-toml/array_size_threshold/clippy.toml
+++ b/src/tools/clippy/tests/ui-toml/array_size_threshold/clippy.toml
diff --git a/tests/rustdoc-gui/sidebar.goml b/tests/rustdoc-gui/sidebar.goml
index a6d51709019..473ab8fc960 100644
--- a/tests/rustdoc-gui/sidebar.goml
+++ b/tests/rustdoc-gui/sidebar.goml
@@ -149,3 +149,17 @@ assert-property: (".sidebar", {"clientWidth": "200"})
 click: "#toggle-all-docs"
 assert-text: ("#toggle-all-docs", "[−]")
 assert-property: (".sidebar", {"clientWidth": "200"})
+
+// Checks that all.html and index.html have their sidebar link in the same place.
+goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
+store-property: (index_sidebar_width, ".sidebar .location a", "clientWidth")
+store-property: (index_sidebar_height, ".sidebar .location a", "clientHeight")
+store-property: (index_sidebar_x, ".sidebar .location a", "offsetTop")
+store-property: (index_sidebar_y, ".sidebar .location a", "offsetLeft")
+goto: "file://" + |DOC_PATH| + "/test_docs/all.html"
+assert-property: (".sidebar .location a", {
+    "clientWidth": |index_sidebar_width|,
+    "clientHeight": |index_sidebar_height|,
+    "offsetTop": |index_sidebar_x|,
+    "offsetLeft": |index_sidebar_y|,
+})
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs
new file mode 100644
index 00000000000..4458ab0162e
--- /dev/null
+++ b/tests/ui-fulldeps/stable-mir/crate-info.rs
@@ -0,0 +1,104 @@
+// run-pass
+// Test that users are able to use stable mir APIs to retrieve information of the current crate
+
+// ignore-stage-1
+// ignore-cross-compile
+// ignore-remote
+
+#![feature(rustc_private)]
+
+extern crate rustc_driver;
+extern crate rustc_hir;
+extern crate rustc_interface;
+extern crate rustc_middle;
+extern crate rustc_smir;
+
+use rustc_driver::{Callbacks, Compilation, RunCompiler};
+use rustc_hir::def::DefKind;
+use rustc_interface::{interface, Queries};
+use rustc_middle::ty::TyCtxt;
+use rustc_smir::{rustc_internal, stable_mir};
+use std::io::Write;
+
+const CRATE_NAME: &str = "input";
+
+/// This function uses the Stable MIR APIs to get information about the test crate.
+fn test_stable_mir(tcx: TyCtxt<'_>) {
+    // Get the local crate using stable_mir API.
+    let local = stable_mir::local_crate();
+    assert_eq!(&local.name, CRATE_NAME);
+
+    // Find items in the local crate.
+    let items = stable_mir::all_local_items();
+    assert!(has_item(tcx, &items, (DefKind::Fn, "foo_bar")));
+    assert!(has_item(tcx, &items, (DefKind::Fn, "foo::bar")));
+
+    // Find the `std` crate.
+    assert!(stable_mir::find_crate("std").is_some());
+}
+
+// Use internal API to find a function in a crate.
+fn has_item(tcx: TyCtxt, items: &stable_mir::CrateItems, item: (DefKind, &str)) -> bool {
+    items.iter().any(|crate_item| {
+        let def_id = rustc_internal::item_def_id(crate_item);
+        tcx.def_kind(def_id) == item.0 && tcx.def_path_str(def_id) == item.1
+    })
+}
+
+/// This test will generate and analyze a dummy crate using the stable mir.
+/// For that, it will first write the dummy crate into a file.
+/// It will invoke the compiler using a custom Callback implementation, which will
+/// invoke Stable MIR APIs after the compiler has finished its analysis.
+fn main() {
+    let path = "input.rs";
+    generate_input(&path).unwrap();
+    let args = vec![
+        "rustc".to_string(),
+        "--crate-type=lib".to_string(),
+        "--crate-name".to_string(),
+        CRATE_NAME.to_string(),
+        path.to_string(),
+    ];
+    rustc_driver::catch_fatal_errors(|| {
+        RunCompiler::new(&args, &mut SMirCalls {}).run().unwrap();
+    })
+    .unwrap();
+}
+
+struct SMirCalls {}
+
+impl Callbacks for SMirCalls {
+    /// Called after analysis. Return value instructs the compiler whether to
+    /// continue the compilation afterwards (defaults to `Compilation::Continue`)
+    fn after_analysis<'tcx>(
+        &mut self,
+        _compiler: &interface::Compiler,
+        queries: &'tcx Queries<'tcx>,
+    ) -> Compilation {
+        queries.global_ctxt().unwrap().enter(|tcx| {
+            test_stable_mir(tcx);
+        });
+        // No need to keep going.
+        Compilation::Stop
+    }
+}
+
+fn generate_input(path: &str) -> std::io::Result<()> {
+    let mut file = std::fs::File::create(path)?;
+    write!(
+        file,
+        r#"
+    mod foo {{
+        pub fn bar(i: i32) -> i64 {{
+            i as i64
+        }}
+    }}
+
+    pub fn foo_bar(x: i32, y: i32) -> i64 {{
+        let x_64 = foo::bar(x);
+        let y_64 = foo::bar(y);
+        x_64.wrapping_add(y_64)
+    }}"#
+    )?;
+    Ok(())
+}
diff --git a/tests/ui/coherence/coherence-impls-copy.stderr b/tests/ui/coherence/coherence-impls-copy.stderr
index d40ffc48a29..21dbc606321 100644
--- a/tests/ui/coherence/coherence-impls-copy.stderr
+++ b/tests/ui/coherence/coherence-impls-copy.stderr
@@ -52,19 +52,19 @@ LL | impl Copy for [MyType] {}
    |
    = note: define and implement a trait or new type instead
 
-error[E0206]: the trait `Copy` may not be implemented for this type
+error[E0206]: the trait `Copy` cannot be implemented for this type
   --> $DIR/coherence-impls-copy.rs:21:15
    |
 LL | impl Copy for &'static mut MyType {}
    |               ^^^^^^^^^^^^^^^^^^^ type is not a structure or enumeration
 
-error[E0206]: the trait `Copy` may not be implemented for this type
+error[E0206]: the trait `Copy` cannot be implemented for this type
   --> $DIR/coherence-impls-copy.rs:25:15
    |
 LL | impl Copy for (MyType, MyType) {}
    |               ^^^^^^^^^^^^^^^^ type is not a structure or enumeration
 
-error[E0206]: the trait `Copy` may not be implemented for this type
+error[E0206]: the trait `Copy` cannot be implemented for this type
   --> $DIR/coherence-impls-copy.rs:30:15
    |
 LL | impl Copy for [MyType] {}
diff --git a/tests/ui/coherence/deep-bad-copy-reason.rs b/tests/ui/coherence/deep-bad-copy-reason.rs
index 80bbe387ac7..97fd3f719bf 100644
--- a/tests/ui/coherence/deep-bad-copy-reason.rs
+++ b/tests/ui/coherence/deep-bad-copy-reason.rs
@@ -31,7 +31,7 @@ impl<'tcx, T> Clone for List<'tcx, T> {
 }
 
 impl<'tcx, T> Copy for List<'tcx, T> {}
-//~^ ERROR the trait `Copy` may not be implemented for this type
+//~^ ERROR the trait `Copy` cannot be implemented for this type
 
 fn assert_is_copy<T: Copy>() {}
 
diff --git a/tests/ui/coherence/deep-bad-copy-reason.stderr b/tests/ui/coherence/deep-bad-copy-reason.stderr
index 168ee57263d..7b6dd4b380f 100644
--- a/tests/ui/coherence/deep-bad-copy-reason.stderr
+++ b/tests/ui/coherence/deep-bad-copy-reason.stderr
@@ -1,4 +1,4 @@
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/deep-bad-copy-reason.rs:33:24
    |
 LL | pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
diff --git a/tests/ui/coherence/illegal-copy-bad-projection.rs b/tests/ui/coherence/illegal-copy-bad-projection.rs
new file mode 100644
index 00000000000..797443a0abe
--- /dev/null
+++ b/tests/ui/coherence/illegal-copy-bad-projection.rs
@@ -0,0 +1,16 @@
+trait AsPtr {
+    type Ptr;
+}
+
+impl AsPtr for () {
+    type Ptr = *const void;
+    //~^ ERROR cannot find type `void` in this scope
+}
+
+#[derive(Copy, Clone)]
+struct Foo {
+    p: <() as AsPtr>::Ptr,
+    // Do not report a "`Copy` cannot be implemented" here.
+}
+
+fn main() {}
diff --git a/tests/ui/coherence/illegal-copy-bad-projection.stderr b/tests/ui/coherence/illegal-copy-bad-projection.stderr
new file mode 100644
index 00000000000..8fed9ba23b2
--- /dev/null
+++ b/tests/ui/coherence/illegal-copy-bad-projection.stderr
@@ -0,0 +1,9 @@
+error[E0412]: cannot find type `void` in this scope
+  --> $DIR/illegal-copy-bad-projection.rs:6:23
+   |
+LL |     type Ptr = *const void;
+   |                       ^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/const-generics/bad-generic-in-copy-impl.rs b/tests/ui/const-generics/bad-generic-in-copy-impl.rs
new file mode 100644
index 00000000000..b5663464cf4
--- /dev/null
+++ b/tests/ui/const-generics/bad-generic-in-copy-impl.rs
@@ -0,0 +1,9 @@
+#[derive(Copy, Clone)]
+pub struct Foo {
+    x: [u8; SIZE],
+    //~^ ERROR mismatched types
+}
+
+const SIZE: u32 = 1;
+
+fn main() {}
diff --git a/tests/ui/const-generics/bad-generic-in-copy-impl.stderr b/tests/ui/const-generics/bad-generic-in-copy-impl.stderr
new file mode 100644
index 00000000000..25701ce68cc
--- /dev/null
+++ b/tests/ui/const-generics/bad-generic-in-copy-impl.stderr
@@ -0,0 +1,9 @@
+error[E0308]: mismatched types
+  --> $DIR/bad-generic-in-copy-impl.rs:3:13
+   |
+LL |     x: [u8; SIZE],
+   |             ^^^^ expected `usize`, found `u32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/error-codes/E0184.stderr b/tests/ui/error-codes/E0184.stderr
index bb3017b6ec2..52f1f30a408 100644
--- a/tests/ui/error-codes/E0184.stderr
+++ b/tests/ui/error-codes/E0184.stderr
@@ -1,4 +1,4 @@
-error[E0184]: the trait `Copy` may not be implemented for this type; the type has a destructor
+error[E0184]: the trait `Copy` cannot be implemented for this type; the type has a destructor
   --> $DIR/E0184.rs:1:10
    |
 LL | #[derive(Copy)]
diff --git a/tests/ui/error-codes/E0206.rs b/tests/ui/error-codes/E0206.rs
index 0f3d427ce11..74738d81015 100644
--- a/tests/ui/error-codes/E0206.rs
+++ b/tests/ui/error-codes/E0206.rs
@@ -2,7 +2,7 @@
 struct Bar;
 
 impl Copy for &'static mut Bar { }
-//~^ ERROR the trait `Copy` may not be implemented for this type
+//~^ ERROR the trait `Copy` cannot be implemented for this type
 
 fn main() {
 }
diff --git a/tests/ui/error-codes/E0206.stderr b/tests/ui/error-codes/E0206.stderr
index 57ae2647d33..60d8d7bfe98 100644
--- a/tests/ui/error-codes/E0206.stderr
+++ b/tests/ui/error-codes/E0206.stderr
@@ -1,4 +1,4 @@
-error[E0206]: the trait `Copy` may not be implemented for this type
+error[E0206]: the trait `Copy` cannot be implemented for this type
   --> $DIR/E0206.rs:4:15
    |
 LL | impl Copy for &'static mut Bar { }
diff --git a/tests/ui/exclusive-drop-and-copy.rs b/tests/ui/exclusive-drop-and-copy.rs
index 7a251671ee9..210ecaed756 100644
--- a/tests/ui/exclusive-drop-and-copy.rs
+++ b/tests/ui/exclusive-drop-and-copy.rs
@@ -1,13 +1,13 @@
 // issue #20126
 
-#[derive(Copy, Clone)] //~ ERROR the trait `Copy` may not be implemented
+#[derive(Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented
 struct Foo;
 
 impl Drop for Foo {
     fn drop(&mut self) {}
 }
 
-#[derive(Copy, Clone)] //~ ERROR the trait `Copy` may not be implemented
+#[derive(Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented
 struct Bar<T>(::std::marker::PhantomData<T>);
 
 impl<T> Drop for Bar<T> {
diff --git a/tests/ui/exclusive-drop-and-copy.stderr b/tests/ui/exclusive-drop-and-copy.stderr
index 8649c8abbfa..546079422a7 100644
--- a/tests/ui/exclusive-drop-and-copy.stderr
+++ b/tests/ui/exclusive-drop-and-copy.stderr
@@ -1,4 +1,4 @@
-error[E0184]: the trait `Copy` may not be implemented for this type; the type has a destructor
+error[E0184]: the trait `Copy` cannot be implemented for this type; the type has a destructor
   --> $DIR/exclusive-drop-and-copy.rs:3:10
    |
 LL | #[derive(Copy, Clone)]
@@ -6,7 +6,7 @@ LL | #[derive(Copy, Clone)]
    |
    = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0184]: the trait `Copy` may not be implemented for this type; the type has a destructor
+error[E0184]: the trait `Copy` cannot be implemented for this type; the type has a destructor
   --> $DIR/exclusive-drop-and-copy.rs:10:10
    |
 LL | #[derive(Copy, Clone)]
diff --git a/tests/ui/issues/issue-27340.rs b/tests/ui/issues/issue-27340.rs
index 61c77cc1ff3..aff37d95a3f 100644
--- a/tests/ui/issues/issue-27340.rs
+++ b/tests/ui/issues/issue-27340.rs
@@ -1,6 +1,6 @@
 struct Foo;
 #[derive(Copy, Clone)]
-//~^ ERROR the trait `Copy` may not be implemented for this type
+//~^ ERROR the trait `Copy` cannot be implemented for this type
 struct Bar(Foo);
 
 fn main() {}
diff --git a/tests/ui/issues/issue-27340.stderr b/tests/ui/issues/issue-27340.stderr
index 40889b86668..9caaffd9c9a 100644
--- a/tests/ui/issues/issue-27340.stderr
+++ b/tests/ui/issues/issue-27340.stderr
@@ -1,4 +1,4 @@
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/issue-27340.rs:2:10
    |
 LL | #[derive(Copy, Clone)]
diff --git a/tests/ui/opt-in-copy.rs b/tests/ui/opt-in-copy.rs
index 0b48418e464..d0257b5745d 100644
--- a/tests/ui/opt-in-copy.rs
+++ b/tests/ui/opt-in-copy.rs
@@ -5,7 +5,7 @@ struct IWantToCopyThis {
 }
 
 impl Copy for IWantToCopyThis {}
-//~^ ERROR the trait `Copy` may not be implemented for this type
+//~^ ERROR the trait `Copy` cannot be implemented for this type
 
 enum CantCopyThisEither {
     A,
@@ -17,6 +17,6 @@ enum IWantToCopyThisToo {
 }
 
 impl Copy for IWantToCopyThisToo {}
-//~^ ERROR the trait `Copy` may not be implemented for this type
+//~^ ERROR the trait `Copy` cannot be implemented for this type
 
 fn main() {}
diff --git a/tests/ui/opt-in-copy.stderr b/tests/ui/opt-in-copy.stderr
index 4461567df0a..258ff16e6e4 100644
--- a/tests/ui/opt-in-copy.stderr
+++ b/tests/ui/opt-in-copy.stderr
@@ -1,4 +1,4 @@
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/opt-in-copy.rs:7:15
    |
 LL |     but_i_cant: CantCopyThis,
@@ -7,7 +7,7 @@ LL |     but_i_cant: CantCopyThis,
 LL | impl Copy for IWantToCopyThis {}
    |               ^^^^^^^^^^^^^^^
 
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/opt-in-copy.rs:19:15
    |
 LL |     ButICant(CantCopyThisEither),
diff --git a/tests/ui/range/range_traits-2.stderr b/tests/ui/range/range_traits-2.stderr
index 61facba535b..0829fc2ce9b 100644
--- a/tests/ui/range/range_traits-2.stderr
+++ b/tests/ui/range/range_traits-2.stderr
@@ -1,4 +1,4 @@
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/range_traits-2.rs:3:10
    |
 LL | #[derive(Copy, Clone)]
diff --git a/tests/ui/range/range_traits-3.stderr b/tests/ui/range/range_traits-3.stderr
index e54d17b329e..db19d1baec9 100644
--- a/tests/ui/range/range_traits-3.stderr
+++ b/tests/ui/range/range_traits-3.stderr
@@ -1,4 +1,4 @@
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/range_traits-3.rs:3:10
    |
 LL | #[derive(Copy, Clone)]
diff --git a/tests/ui/range/range_traits-6.stderr b/tests/ui/range/range_traits-6.stderr
index addc525f1fa..dfc74f87ca7 100644
--- a/tests/ui/range/range_traits-6.stderr
+++ b/tests/ui/range/range_traits-6.stderr
@@ -1,4 +1,4 @@
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/range_traits-6.rs:3:10
    |
 LL | #[derive(Copy, Clone)]
diff --git a/tests/ui/span/E0204.rs b/tests/ui/span/E0204.rs
index 174de8cdd63..8793a05c8a8 100644
--- a/tests/ui/span/E0204.rs
+++ b/tests/ui/span/E0204.rs
@@ -2,9 +2,9 @@ struct Foo {
     foo: Vec<u32>,
 }
 
-impl Copy for Foo { } //~ ERROR may not be implemented for this type
+impl Copy for Foo { } //~ ERROR cannot be implemented for this type
 
-#[derive(Copy)] //~ ERROR may not be implemented for this type
+#[derive(Copy)] //~ ERROR cannot be implemented for this type
 struct Foo2<'a> {
     ty: &'a mut bool,
 }
@@ -14,9 +14,9 @@ enum EFoo {
     Baz,
 }
 
-impl Copy for EFoo { } //~ ERROR may not be implemented for this type
+impl Copy for EFoo { } //~ ERROR cannot be implemented for this type
 
-#[derive(Copy)] //~ ERROR may not be implemented for this type
+#[derive(Copy)] //~ ERROR cannot be implemented for this type
 enum EFoo2<'a> {
     Bar(&'a mut bool),
     Baz,
diff --git a/tests/ui/span/E0204.stderr b/tests/ui/span/E0204.stderr
index 0b2166eed7e..3a0afb541ba 100644
--- a/tests/ui/span/E0204.stderr
+++ b/tests/ui/span/E0204.stderr
@@ -1,4 +1,4 @@
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/E0204.rs:5:15
    |
 LL |     foo: Vec<u32>,
@@ -7,7 +7,7 @@ LL |     foo: Vec<u32>,
 LL | impl Copy for Foo { }
    |               ^^^
 
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/E0204.rs:7:10
    |
 LL | #[derive(Copy)]
@@ -18,7 +18,7 @@ LL |     ty: &'a mut bool,
    |
    = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/E0204.rs:17:15
    |
 LL |     Bar { x: Vec<u32> },
@@ -27,7 +27,7 @@ LL |     Bar { x: Vec<u32> },
 LL | impl Copy for EFoo { }
    |               ^^^^
 
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/E0204.rs:19:10
    |
 LL | #[derive(Copy)]
diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed
index 304360d48a2..47b35b412c0 100644
--- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed
+++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed
@@ -7,7 +7,7 @@ pub struct Vector2<T: Debug + Copy + Clone>{
     pub y: T
 }
 
-#[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` may not be implemented for this type
+#[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented for this type
 pub struct AABB<K: Copy + Debug>{
     pub loc: Vector2<K>,
     pub size: Vector2<K>
diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs
index 14e1fbb3311..771e9105c62 100644
--- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs
+++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs
@@ -7,7 +7,7 @@ pub struct Vector2<T: Debug + Copy + Clone>{
     pub y: T
 }
 
-#[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` may not be implemented for this type
+#[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented for this type
 pub struct AABB<K: Copy>{
     pub loc: Vector2<K>,
     pub size: Vector2<K>
diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr
index faf730a5ce3..09696e0613e 100644
--- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr
+++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr
@@ -1,4 +1,4 @@
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/missing-bound-in-derive-copy-impl-3.rs:10:17
    |
 LL | #[derive(Debug, Copy, Clone)]
@@ -6,16 +6,12 @@ LL | #[derive(Debug, Copy, Clone)]
 LL | pub struct AABB<K: Copy>{
 LL |     pub loc: Vector2<K>,
    |     ------------------- this field does not implement `Copy`
-LL |     pub size: Vector2<K>
-   |     -------------------- this field does not implement `Copy`
    |
 note: the `Copy` impl for `Vector2<K>` requires that `K: Debug`
   --> $DIR/missing-bound-in-derive-copy-impl-3.rs:12:14
    |
 LL |     pub loc: Vector2<K>,
    |              ^^^^^^^^^^
-LL |     pub size: Vector2<K>
-   |               ^^^^^^^^^^
    = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider further restricting this bound
    |
diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs
index 52163bddd4f..9c7b7ba099c 100644
--- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs
+++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs
@@ -6,7 +6,7 @@ pub struct Vector2<T: Debug + Copy + Clone>{
     pub y: T
 }
 
-#[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` may not be implemented for this type
+#[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented for this type
 pub struct AABB<K>{
     pub loc: Vector2<K>,
     pub size: Vector2<K>
diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr
index 11bc5409917..8585fe47bf3 100644
--- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr
+++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr
@@ -1,4 +1,4 @@
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/missing-bound-in-derive-copy-impl.rs:9:17
    |
 LL | #[derive(Debug, Copy, Clone)]
@@ -6,16 +6,12 @@ LL | #[derive(Debug, Copy, Clone)]
 LL | pub struct AABB<K>{
 LL |     pub loc: Vector2<K>,
    |     ------------------- this field does not implement `Copy`
-LL |     pub size: Vector2<K>
-   |     -------------------- this field does not implement `Copy`
    |
 note: the `Copy` impl for `Vector2<K>` requires that `K: Debug`
   --> $DIR/missing-bound-in-derive-copy-impl.rs:11:14
    |
 LL |     pub loc: Vector2<K>,
    |              ^^^^^^^^^^
-LL |     pub size: Vector2<K>
-   |               ^^^^^^^^^^
    = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider restricting type parameter `K`
    |
diff --git a/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.fixed b/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.fixed
index 691e7553a09..f32c61a99bb 100644
--- a/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.fixed
+++ b/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.fixed
@@ -14,6 +14,6 @@ impl<T: std::fmt::Display> Clone for OnlyCopyIfDisplay<T> {
 impl<T: std::fmt::Display> Copy for OnlyCopyIfDisplay<T> {}
 
 impl<S: std::fmt::Display> Copy for Wrapper<OnlyCopyIfDisplay<S>> {}
-//~^ ERROR the trait `Copy` may not be implemented for this type
+//~^ ERROR the trait `Copy` cannot be implemented for this type
 
 fn main() {}
diff --git a/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.rs b/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.rs
index e3185e7eff8..d7725f4a374 100644
--- a/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.rs
+++ b/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.rs
@@ -14,6 +14,6 @@ impl<T: std::fmt::Display> Clone for OnlyCopyIfDisplay<T> {
 impl<T: std::fmt::Display> Copy for OnlyCopyIfDisplay<T> {}
 
 impl<S> Copy for Wrapper<OnlyCopyIfDisplay<S>> {}
-//~^ ERROR the trait `Copy` may not be implemented for this type
+//~^ ERROR the trait `Copy` cannot be implemented for this type
 
 fn main() {}
diff --git a/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.stderr b/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.stderr
index 9e6f0d9ebbd..856d8db381b 100644
--- a/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.stderr
+++ b/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.stderr
@@ -1,4 +1,4 @@
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/missing-bound-in-manual-copy-impl-2.rs:16:18
    |
 LL | struct Wrapper<T>(T);
diff --git a/tests/ui/suggestions/missing-bound-in-manual-copy-impl.fixed b/tests/ui/suggestions/missing-bound-in-manual-copy-impl.fixed
index 32a7215c5bd..1139b315313 100644
--- a/tests/ui/suggestions/missing-bound-in-manual-copy-impl.fixed
+++ b/tests/ui/suggestions/missing-bound-in-manual-copy-impl.fixed
@@ -4,6 +4,6 @@
 struct Wrapper<T>(T);
 
 impl<S: Copy> Copy for Wrapper<S> {}
-//~^ ERROR the trait `Copy` may not be implemented for this type
+//~^ ERROR the trait `Copy` cannot be implemented for this type
 
 fn main() {}
diff --git a/tests/ui/suggestions/missing-bound-in-manual-copy-impl.rs b/tests/ui/suggestions/missing-bound-in-manual-copy-impl.rs
index c688f4d41ee..19549248efc 100644
--- a/tests/ui/suggestions/missing-bound-in-manual-copy-impl.rs
+++ b/tests/ui/suggestions/missing-bound-in-manual-copy-impl.rs
@@ -4,6 +4,6 @@
 struct Wrapper<T>(T);
 
 impl<S> Copy for Wrapper<S> {}
-//~^ ERROR the trait `Copy` may not be implemented for this type
+//~^ ERROR the trait `Copy` cannot be implemented for this type
 
 fn main() {}
diff --git a/tests/ui/suggestions/missing-bound-in-manual-copy-impl.stderr b/tests/ui/suggestions/missing-bound-in-manual-copy-impl.stderr
index fe2d133c8aa..ec3e4f23a64 100644
--- a/tests/ui/suggestions/missing-bound-in-manual-copy-impl.stderr
+++ b/tests/ui/suggestions/missing-bound-in-manual-copy-impl.stderr
@@ -1,4 +1,4 @@
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/missing-bound-in-manual-copy-impl.rs:6:18
    |
 LL | struct Wrapper<T>(T);
diff --git a/tests/ui/traits/copy-is-not-modulo-regions.not_static.stderr b/tests/ui/traits/copy-is-not-modulo-regions.not_static.stderr
index edd94d2010b..13042521184 100644
--- a/tests/ui/traits/copy-is-not-modulo-regions.not_static.stderr
+++ b/tests/ui/traits/copy-is-not-modulo-regions.not_static.stderr
@@ -1,4 +1,4 @@
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/copy-is-not-modulo-regions.rs:13:21
    |
 LL | struct Bar<'lt>(Foo<'lt>);
diff --git a/tests/ui/traits/copy-is-not-modulo-regions.rs b/tests/ui/traits/copy-is-not-modulo-regions.rs
index adb87023769..b899083747a 100644
--- a/tests/ui/traits/copy-is-not-modulo-regions.rs
+++ b/tests/ui/traits/copy-is-not-modulo-regions.rs
@@ -11,7 +11,7 @@ struct Bar<'lt>(Foo<'lt>);
 
 #[cfg(not_static)]
 impl<'any> Copy for Bar<'any> {}
-//[not_static]~^ the trait `Copy` may not be implemented for this type
+//[not_static]~^ the trait `Copy` cannot be implemented for this type
 
 #[cfg(yes_static)]
 impl<'any> Copy for Bar<'static> {}
diff --git a/tests/ui/traits/issue-50480.rs b/tests/ui/traits/issue-50480.rs
index 005939e0c46..683a85a32c1 100644
--- a/tests/ui/traits/issue-50480.rs
+++ b/tests/ui/traits/issue-50480.rs
@@ -1,5 +1,5 @@
 #[derive(Clone, Copy)]
-//~^ ERROR the trait `Copy` may not be implemented for this type
+//~^ ERROR the trait `Copy` cannot be implemented for this type
 struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
 //~^ ERROR cannot find type `NotDefined` in this scope
 //~| ERROR cannot find type `NotDefined` in this scope
@@ -7,7 +7,7 @@ struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
 //~| ERROR cannot find type `N` in this scope
 
 #[derive(Clone, Copy)]
-//~^ ERROR the trait `Copy` may not be implemented for this type
+//~^ ERROR the trait `Copy` cannot be implemented for this type
 struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
 //~^ ERROR cannot find type `NotDefined` in this scope
 //~| ERROR cannot find type `N` in this scope
diff --git a/tests/ui/traits/issue-50480.stderr b/tests/ui/traits/issue-50480.stderr
index 5063fdca092..4f72db60a16 100644
--- a/tests/ui/traits/issue-50480.stderr
+++ b/tests/ui/traits/issue-50480.stderr
@@ -60,7 +60,7 @@ error[E0412]: cannot find type `NotDefined` in this scope
 LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
    |                     ^^^^^^^^^^ not found in this scope
 
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/issue-50480.rs:1:17
    |
 LL | #[derive(Clone, Copy)]
@@ -73,7 +73,7 @@ LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
    |
    = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/issue-50480.rs:9:17
    |
 LL | #[derive(Clone, Copy)]
diff --git a/tests/ui/traits/unsend-future.rs b/tests/ui/traits/unsend-future.rs
new file mode 100644
index 00000000000..fbbc07b11e7
--- /dev/null
+++ b/tests/ui/traits/unsend-future.rs
@@ -0,0 +1,21 @@
+// edition:2021
+
+// issue 108897
+trait Handler {}
+impl<F, Fut> Handler for F
+where
+    Fut: Send,
+    F: FnOnce() -> Fut,
+{}
+
+fn require_handler<H: Handler>(h: H) {}
+
+async fn handler() {
+    let a = &1 as *const i32;
+    async {}.await;
+}
+
+fn main() {
+    require_handler(handler)
+     //~^ ERROR future cannot be sent between threads safely
+}
diff --git a/tests/ui/traits/unsend-future.stderr b/tests/ui/traits/unsend-future.stderr
new file mode 100644
index 00000000000..4aaa7c4a924
--- /dev/null
+++ b/tests/ui/traits/unsend-future.stderr
@@ -0,0 +1,24 @@
+error: future cannot be sent between threads safely
+  --> $DIR/unsend-future.rs:19:21
+   |
+LL |     require_handler(handler)
+   |                     ^^^^^^^ future returned by `handler` is not `Send`
+   |
+   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*const i32`
+note: future is not `Send` as this value is used across an await
+  --> $DIR/unsend-future.rs:15:13
+   |
+LL |     let a = &1 as *const i32;
+   |         - has type `*const i32` which is not `Send`
+LL |     async {}.await;
+   |             ^^^^^^ await occurs here, with `a` maybe used later
+LL | }
+   | - `a` is later dropped here
+note: required by a bound in `require_handler`
+  --> $DIR/unsend-future.rs:11:23
+   |
+LL | fn require_handler<H: Handler>(h: H) {}
+   |                       ^^^^^^^ required by this bound in `require_handler`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/union/union-copy.rs b/tests/ui/union/union-copy.rs
index 5c3f8d90898..7ad0a11c6ac 100644
--- a/tests/ui/union/union-copy.rs
+++ b/tests/ui/union/union-copy.rs
@@ -9,6 +9,6 @@ union W {
 }
 
 impl Copy for U {} // OK
-impl Copy for W {} //~ ERROR the trait `Copy` may not be implemented for this type
+impl Copy for W {} //~ ERROR the trait `Copy` cannot be implemented for this type
 
 fn main() {}
diff --git a/tests/ui/union/union-copy.stderr b/tests/ui/union/union-copy.stderr
index 53ee4dd2e5b..ff6fa48db90 100644
--- a/tests/ui/union/union-copy.stderr
+++ b/tests/ui/union/union-copy.stderr
@@ -1,4 +1,4 @@
-error[E0204]: the trait `Copy` may not be implemented for this type
+error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/union-copy.rs:12:15
    |
 LL |     a: std::mem::ManuallyDrop<String>