about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-02-18 18:49:25 +0000
committerbors <bors@rust-lang.org>2022-02-18 18:49:25 +0000
commitb17226fcc11587fed612631be372a5b4cb89988a (patch)
treef254265efe6fcda78534a586983a65940f4d6f1d
parentb8c56fa8c30821129b0960180f528d4a1a4f9316 (diff)
parenta144ea1c4b39bdef608c537b25343674aa2b5bc7 (diff)
Auto merge of #94121 - matthiaskrgr:rollup-6ps95da, r=matthiaskrgr
Rollup of 6 pull requests

Successful merges:

 - #92683 (Suggest copying trait associated type bounds on lifetime error)
 - #92933 (Deny mixing bin crate type with lib crate types)
 - #92959 (Add more info and suggestions to use of #[test] on invalid items)
 - #93024 (Do not ICE when inlining a function with un-satisfiable bounds)
 - #93613 (Move `{core,std}::stream::Stream` to `{core,std}::async_iter::AsyncIterator`)
 - #93634 (compiler: clippy::complexity fixes)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_ast/src/attr/mod.rs2
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/proc_macro_harness.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/test.rs22
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs2
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note.rs52
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs17
-rw-r--r--compiler/rustc_interface/src/passes.rs12
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs2
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs6
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs2
-rw-r--r--compiler/rustc_middle/src/ty/trait_def.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coverage/query.rs3
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs13
-rw-r--r--compiler/rustc_monomorphize/src/partitioning/mod.rs22
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs8
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs2
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs7
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/codegen.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs2
-rw-r--r--compiler/rustc_typeck/src/astconv/errors.rs3
-rw-r--r--compiler/rustc_typeck/src/check/check.rs2
-rw-r--r--compiler/rustc_typeck/src/check/compare_method.rs9
-rw-r--r--compiler/rustc_typeck/src/check/demand.rs6
-rw-r--r--compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs2
-rw-r--r--compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs4
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs2
-rw-r--r--library/alloc/src/boxed.rs6
-rw-r--r--library/alloc/src/lib.rs2
-rw-r--r--library/core/src/async_iter/async_iter.rs (renamed from library/core/src/stream/stream.rs)56
-rw-r--r--library/core/src/async_iter/from_iter.rs (renamed from library/core/src/stream/from_iter.rs)18
-rw-r--r--library/core/src/async_iter/mod.rs (renamed from library/core/src/stream/mod.rs)69
-rw-r--r--library/core/src/lib.rs4
-rw-r--r--library/core/src/panic/unwind_safe.rs6
-rw-r--r--library/std/src/lib.rs6
-rw-r--r--src/test/run-make-fulldeps/libs-and-bins/Makefile6
-rw-r--r--src/test/run-make-fulldeps/libs-and-bins/foo.rs4
-rw-r--r--src/test/run-make-fulldeps/output-with-hyphens/Makefile3
-rw-r--r--src/test/run-make-fulldeps/output-with-hyphens/foo-bar.rs3
-rw-r--r--src/test/ui/generic-associated-types/impl_bounds.stderr7
-rw-r--r--src/test/ui/generic-associated-types/issue-88595.rs5
-rw-r--r--src/test/ui/generic-associated-types/issue-88595.stderr22
-rw-r--r--src/test/ui/generic-associated-types/issue-90014.stderr7
-rw-r--r--src/test/ui/generic-associated-types/issue-92033.rs39
-rw-r--r--src/test/ui/generic-associated-types/issue-92033.stderr22
-rw-r--r--src/test/ui/issues/issue-14772.rs6
-rw-r--r--src/test/ui/issues/issue-14772.stderr8
-rw-r--r--src/test/ui/test-attrs/test-on-macro.rs13
-rw-r--r--src/test/ui/test-attrs/test-on-macro.stderr8
-rw-r--r--src/test/ui/test-attrs/test-on-not-fn.rs80
-rw-r--r--src/test/ui/test-attrs/test-on-not-fn.stderr185
-rw-r--r--src/test/ui/trait-bounds/issue-93008.rs10
-rw-r--r--src/test/ui/trait-bounds/issue-93008.stderr12
59 files changed, 613 insertions, 221 deletions
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index 6a0ace04d4b..b94b8c87216 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -230,7 +230,7 @@ impl AttrItem {
     }
 
     pub fn meta_kind(&self) -> Option<MetaItemKind> {
-        Some(MetaItemKind::from_mac_args(&self.args)?)
+        MetaItemKind::from_mac_args(&self.args)
     }
 }
 
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 0a96e60d4d3..6c44fb0df23 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -823,7 +823,7 @@ fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
             );
             let mut all_stable = true;
             for ident in
-                attr.meta_item_list().into_iter().flatten().map(|nested| nested.ident()).flatten()
+                attr.meta_item_list().into_iter().flatten().flat_map(|nested| nested.ident())
             {
                 let name = ident.name;
                 let stable_since = lang_features
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index 6f61e4cba07..c9dd114047b 100644
--- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
@@ -56,7 +56,6 @@ pub fn inject(
     is_proc_macro_crate: bool,
     has_proc_macro_decls: bool,
     is_test_crate: bool,
-    num_crate_types: usize,
     handler: &rustc_errors::Handler,
 ) -> ast::Crate {
     let ecfg = ExpansionConfig::default("proc_macro".to_string());
@@ -81,10 +80,6 @@ pub fn inject(
         return krate;
     }
 
-    if num_crate_types > 1 {
-        handler.err("cannot mix `proc-macro` crate type with others");
-    }
-
     if is_test_crate {
         return krate;
     }
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index 9459bb7047f..69087962405 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -6,6 +6,7 @@ use rustc_ast as ast;
 use rustc_ast::attr;
 use rustc_ast::ptr::P;
 use rustc_ast_pretty::pprust;
+use rustc_errors::Applicability;
 use rustc_expand::base::*;
 use rustc_session::Session;
 use rustc_span::symbol::{sym, Ident, Symbol};
@@ -102,11 +103,20 @@ pub fn expand_test_or_bench(
         }
     };
 
-    if let ast::ItemKind::MacCall(_) = item.kind {
-        cx.sess.parse_sess.span_diagnostic.span_warn(
-            item.span,
-            "`#[test]` attribute should not be used on macros. Use `#[cfg(test)]` instead.",
-        );
+    // Note: non-associated fn items are already handled by `expand_test_or_bench`
+    if !matches!(item.kind, ast::ItemKind::Fn(_)) {
+        cx.sess
+            .parse_sess
+            .span_diagnostic
+            .struct_span_err(
+                attr_sp,
+                "the `#[test]` attribute may only be used on a non-associated function",
+            )
+            .note("the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions")
+            .span_label(item.span, format!("expected a non-associated function, found {} {}", item.kind.article(), item.kind.descr()))
+            .span_suggestion(attr_sp, "replace with conditional compilation to make the item only exist when tests are being run", String::from("#[cfg(test)]"), Applicability::MaybeIncorrect)
+            .emit();
+
         return vec![Annotatable::Item(item)];
     }
 
@@ -466,7 +476,7 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
             (false, _) => true,
         }
     } else {
-        sd.span_err(i.span, "only functions may be used as tests");
+        // should be unreachable because `is_test_fn_item` should catch all non-fn items
         false
     }
 }
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index ec68f6eb0f8..90ddf791450 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -292,7 +292,7 @@ pub unsafe fn create_module<'ll>(
             "sign-return-address-all\0".as_ptr().cast(),
             pac_opts.leaf.into(),
         );
-        let is_bkey = if pac_opts.key == PAuthKey::A { false } else { true };
+        let is_bkey: bool = pac_opts.key != PAuthKey::A;
         llvm::LLVMRustAddModuleFlag(
             llmod,
             llvm::LLVMModFlagBehavior::Error,
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index c21d19a6227..6976999c0e4 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -476,7 +476,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 mir::ProjectionElem::Subslice { from, to, from_end } => {
                     let mut subslice = cg_base.project_index(bx, bx.cx().const_usize(from as u64));
                     let projected_ty =
-                        PlaceTy::from_ty(cg_base.layout.ty).projection_ty(tcx, elem.clone()).ty;
+                        PlaceTy::from_ty(cg_base.layout.ty).projection_ty(tcx, *elem).ty;
                     subslice.layout = bx.cx().layout_of(self.monomorphize(projected_ty));
 
                     if subslice.layout.is_unsized() {
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 8065911afb9..f71fb58cf6b 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -1039,7 +1039,7 @@ fn check_matcher_core(
                                 ));
                                 err.span_suggestion(
                                     span,
-                                    &format!("try a `pat_param` fragment specifier instead"),
+                                    "try a `pat_param` fragment specifier instead",
                                     suggestion,
                                     Applicability::MaybeIncorrect,
                                 );
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs
index 8512597cb91..f44e6e04346 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs
@@ -64,7 +64,7 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
             .or_else(|| self.try_report_mismatched_static_lifetime())
     }
 
-    pub fn regions(&self) -> Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)> {
+    pub(super) fn regions(&self) -> Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)> {
         match (&self.error, self.regions) {
             (Some(ConcreteFailure(origin, sub, sup)), None) => Some((origin.span(), *sub, *sup)),
             (Some(SubSupConflict(_, _, origin, sub, _, sup, _)), None) => {
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs
index 8e5efa12ac6..8671ecba6e9 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs
@@ -102,6 +102,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     "...so that the definition in impl matches the definition from the trait",
                 );
             }
+            infer::CheckAssociatedTypeBounds { ref parent, .. } => {
+                self.note_region_origin(err, &parent);
+            }
         }
     }
 
@@ -345,6 +348,55 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     trait_item_def_id,
                     &format!("`{}: {}`", sup, sub),
                 ),
+            infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => {
+                let mut err = self.report_concrete_failure(*parent, sub, sup);
+
+                let trait_item_span = self.tcx.def_span(trait_item_def_id);
+                let item_name = self.tcx.item_name(impl_item_def_id);
+                err.span_label(
+                    trait_item_span,
+                    format!("definition of `{}` from trait", item_name),
+                );
+
+                let trait_predicates = self.tcx.explicit_predicates_of(trait_item_def_id);
+                let impl_predicates = self.tcx.explicit_predicates_of(impl_item_def_id);
+
+                let impl_predicates: rustc_data_structures::stable_set::FxHashSet<_> =
+                    impl_predicates.predicates.into_iter().map(|(pred, _)| pred).collect();
+                let clauses: Vec<_> = trait_predicates
+                    .predicates
+                    .into_iter()
+                    .filter(|&(pred, _)| !impl_predicates.contains(pred))
+                    .map(|(pred, _)| format!("{}", pred))
+                    .collect();
+
+                if !clauses.is_empty() {
+                    let where_clause_span = self
+                        .tcx
+                        .hir()
+                        .get_generics(impl_item_def_id.expect_local())
+                        .unwrap()
+                        .where_clause
+                        .tail_span_for_suggestion();
+
+                    let suggestion = format!(
+                        "{} {}",
+                        if !impl_predicates.is_empty() { "," } else { " where" },
+                        clauses.join(", "),
+                    );
+                    err.span_suggestion(
+                        where_clause_span,
+                        &format!(
+                            "try copying {} from the trait",
+                            if clauses.len() > 1 { "these clauses" } else { "this clause" }
+                        ),
+                        suggestion,
+                        rustc_errors::Applicability::MaybeIncorrect,
+                    );
+                }
+
+                err
+            }
         }
     }
 
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index f0a4ec81313..57ac98ca897 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -438,6 +438,13 @@ pub enum SubregionOrigin<'tcx> {
     /// Comparing the signature and requirements of an impl associated type
     /// against the containing trait
     CompareImplTypeObligation { span: Span, impl_item_def_id: DefId, trait_item_def_id: DefId },
+
+    /// Checking that the bounds of a trait's associated type hold for a given impl
+    CheckAssociatedTypeBounds {
+        parent: Box<SubregionOrigin<'tcx>>,
+        impl_item_def_id: DefId,
+        trait_item_def_id: DefId,
+    },
 }
 
 // `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger.
@@ -1832,6 +1839,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
             ReferenceOutlivesReferent(_, a) => a,
             CompareImplMethodObligation { span, .. } => span,
             CompareImplTypeObligation { span, .. } => span,
+            CheckAssociatedTypeBounds { ref parent, .. } => parent.span(),
         }
     }
 
@@ -1862,6 +1870,15 @@ impl<'tcx> SubregionOrigin<'tcx> {
                 trait_item_def_id,
             },
 
+            traits::ObligationCauseCode::CheckAssociatedTypeBounds {
+                impl_item_def_id,
+                trait_item_def_id,
+            } => SubregionOrigin::CheckAssociatedTypeBounds {
+                impl_item_def_id,
+                trait_item_def_id,
+                parent: Box::new(default()),
+            },
+
             _ => default(),
         }
     }
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 66e1e78b285..c0552fd200b 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -393,8 +393,18 @@ pub fn configure_and_expand(
     });
 
     let crate_types = sess.crate_types();
+    let is_executable_crate = crate_types.contains(&CrateType::Executable);
     let is_proc_macro_crate = crate_types.contains(&CrateType::ProcMacro);
 
+    if crate_types.len() > 1 {
+        if is_executable_crate {
+            sess.err("cannot mix `bin` crate type with others");
+        }
+        if is_proc_macro_crate {
+            sess.err("cannot mix `proc-macro` crate type with others");
+        }
+    }
+
     // For backwards compatibility, we don't try to run proc macro injection
     // if rustdoc is run on a proc macro crate without '--crate-type proc-macro' being
     // specified. This should only affect users who manually invoke 'rustdoc', as
@@ -411,7 +421,6 @@ pub fn configure_and_expand(
         msg.emit()
     } else {
         krate = sess.time("maybe_create_a_macro_crate", || {
-            let num_crate_types = crate_types.len();
             let is_test_crate = sess.opts.test;
             rustc_builtin_macros::proc_macro_harness::inject(
                 sess,
@@ -420,7 +429,6 @@ pub fn configure_and_expand(
                 is_proc_macro_crate,
                 has_proc_macro_decls,
                 is_test_crate,
-                num_crate_types,
                 sess.diagnostic(),
             )
         });
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index 03cca51dc0b..fedf456ccc8 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -198,7 +198,7 @@ fn deprecation_message(
     } else {
         let since = since.as_ref().map(Symbol::as_str);
 
-        if since.as_deref() == Some("TBD") {
+        if since == Some("TBD") {
             format!("use of {} `{}` that will be deprecated in a future Rust version", kind, path)
         } else {
             format!(
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 1123cab8076..b54418e5201 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -285,6 +285,12 @@ pub enum ObligationCauseCode<'tcx> {
         trait_item_def_id: DefId,
     },
 
+    /// Checking that the bounds of a trait's associated type hold for a given impl
+    CheckAssociatedTypeBounds {
+        impl_item_def_id: DefId,
+        trait_item_def_id: DefId,
+    },
+
     /// Checking that this expression can be assigned where it needs to be
     // FIXME(eddyb) #11161 is the original Expr required?
     ExprAssignable,
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index b59fb6afe6f..7c57d42631a 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -855,7 +855,7 @@ impl<'tcx> Relate<'tcx> for ty::ProjectionPredicate<'tcx> {
     ) -> RelateResult<'tcx, ty::ProjectionPredicate<'tcx>> {
         Ok(ty::ProjectionPredicate {
             projection_ty: relation.relate(a.projection_ty, b.projection_ty)?,
-            term: relation.relate(a.term, b.term)?.into(),
+            term: relation.relate(a.term, b.term)?,
         })
     }
 }
diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs
index 597f7dd95a2..8f4cc182e7f 100644
--- a/compiler/rustc_middle/src/ty/trait_def.rs
+++ b/compiler/rustc_middle/src/ty/trait_def.rs
@@ -210,7 +210,7 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn all_impls(self, def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
         let TraitImpls { blanket_impls, non_blanket_impls } = self.trait_impls_of(def_id);
 
-        blanket_impls.iter().chain(non_blanket_impls.iter().map(|(_, v)| v).flatten()).cloned()
+        blanket_impls.iter().chain(non_blanket_impls.iter().flat_map(|(_, v)| v)).cloned()
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs
index 46de6d939a1..da921904523 100644
--- a/compiler/rustc_mir_transform/src/coverage/query.rs
+++ b/compiler/rustc_mir_transform/src/coverage/query.rs
@@ -140,7 +140,7 @@ fn covered_code_regions<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Vec<&'tcx Cod
     let body = mir_body(tcx, def_id);
     body.basic_blocks()
         .iter()
-        .map(|data| {
+        .flat_map(|data| {
             data.statements.iter().filter_map(|statement| match statement.kind {
                 StatementKind::Coverage(box ref coverage) => {
                     if is_inlined(body, statement) {
@@ -152,7 +152,6 @@ fn covered_code_regions<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Vec<&'tcx Cod
                 _ => None,
             })
         })
-        .flatten()
         .collect()
 }
 
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index f0e4129b002..55ce5910c81 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -7,6 +7,7 @@ use rustc_index::vec::Idx;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
 use rustc_middle::mir::visit::*;
 use rustc_middle::mir::*;
+use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::subst::Subst;
 use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
 use rustc_span::{hygiene::ExpnKind, ExpnData, Span};
@@ -75,10 +76,18 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool {
         return false;
     }
 
+    let param_env = tcx.param_env_reveal_all_normalized(def_id);
+    let param_env = rustc_trait_selection::traits::normalize_param_env_or_error(
+        tcx,
+        def_id,
+        param_env,
+        ObligationCause::misc(body.span, hir_id),
+    );
+
     let mut this = Inliner {
         tcx,
-        param_env: tcx.param_env_reveal_all_normalized(body.source.def_id()),
-        codegen_fn_attrs: tcx.codegen_fn_attrs(body.source.def_id()),
+        param_env,
+        codegen_fn_attrs: tcx.codegen_fn_attrs(def_id),
         hir_id,
         history: Vec::new(),
         changed: false,
diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs
index 67597a0d7b4..b8684a09fd7 100644
--- a/compiler/rustc_monomorphize/src/partitioning/mod.rs
+++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs
@@ -220,18 +220,16 @@ pub fn partition<'tcx>(
         let mut cgus: Vec<_> = post_inlining.codegen_units.iter_mut().collect();
         cgus.sort_by_key(|cgu| cgu.size_estimate());
 
-        let dead_code_cgu = if let Some(cgu) = cgus
-            .into_iter()
-            .rev()
-            .filter(|cgu| cgu.items().iter().any(|(_, (linkage, _))| *linkage == Linkage::External))
-            .next()
-        {
-            cgu
-        } else {
-            // If there are no CGUs that have externally linked items,
-            // then we just pick the first CGU as a fallback.
-            &mut post_inlining.codegen_units[0]
-        };
+        let dead_code_cgu =
+            if let Some(cgu) = cgus.into_iter().rev().find(|cgu| {
+                cgu.items().iter().any(|(_, (linkage, _))| *linkage == Linkage::External)
+            }) {
+                cgu
+            } else {
+                // If there are no CGUs that have externally linked items,
+                // then we just pick the first CGU as a fallback.
+                &mut post_inlining.codegen_units[0]
+            };
         dead_code_cgu.make_code_coverage_dead_code_cgu();
     }
 
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 7b74b137d21..def23005fbe 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -2156,7 +2156,7 @@ impl<'a> Parser<'a> {
                             | PatKind::TupleStruct(qself @ None, path, _)
                             | PatKind::Path(qself @ None, path) => match &first_pat.kind {
                                 PatKind::Ident(_, ident, _) => {
-                                    path.segments.insert(0, PathSegment::from_ident(ident.clone()));
+                                    path.segments.insert(0, PathSegment::from_ident(*ident));
                                     path.span = new_span;
                                     show_sugg = true;
                                     first_pat = pat;
@@ -2183,8 +2183,8 @@ impl<'a> Parser<'a> {
                                             Path {
                                                 span: new_span,
                                                 segments: vec![
-                                                    PathSegment::from_ident(old_ident.clone()),
-                                                    PathSegment::from_ident(ident.clone()),
+                                                    PathSegment::from_ident(*old_ident),
+                                                    PathSegment::from_ident(*ident),
                                                 ],
                                                 tokens: None,
                                             },
@@ -2194,7 +2194,7 @@ impl<'a> Parser<'a> {
                                     }
                                     PatKind::Path(old_qself, old_path) => {
                                         let mut segments = old_path.segments.clone();
-                                        segments.push(PathSegment::from_ident(ident.clone()));
+                                        segments.push(PathSegment::from_ident(*ident));
                                         let path = PatKind::Path(
                                             old_qself.clone(),
                                             Path { span: new_span, segments, tokens: None },
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index 62ed104aef3..4b57aa1f24a 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -260,7 +260,7 @@ impl<'a> Parser<'a> {
             let ate_comma = self.eat(&token::Comma);
 
             if self.eat_keyword_noexpect(kw::Where) {
-                let msg = &format!("cannot define duplicate `where` clauses on an item");
+                let msg = "cannot define duplicate `where` clauses on an item";
                 let mut err = self.struct_span_err(self.token.span, msg);
                 err.span_label(lo, "previous `where` clause starts here");
                 err.span_suggestion_verbose(
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 4b85531557c..9a2fb3b86e2 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1362,8 +1362,7 @@ impl<'a> Resolver<'a> {
                     .filter(|(_, module)| {
                         current_module.is_ancestor_of(module) && !ptr::eq(current_module, *module)
                     })
-                    .map(|(_, module)| module.kind.name())
-                    .flatten(),
+                    .flat_map(|(_, module)| module.kind.name()),
             )
             .filter(|c| !c.to_string().is_empty())
             .collect::<Vec<_>>();
@@ -1859,7 +1858,7 @@ crate fn show_candidates(
         let instead = if instead { " instead" } else { "" };
         let mut msg = format!("consider importing {} {}{}", determiner, kind, instead);
 
-        for note in accessible_path_strings.iter().map(|cand| cand.3.as_ref()).flatten() {
+        for note in accessible_path_strings.iter().flat_map(|cand| cand.3.as_ref()) {
             err.note(note);
         }
 
@@ -1942,7 +1941,7 @@ crate fn show_candidates(
                 multi_span.push_span_label(span, format!("`{}`: not accessible", name));
             }
 
-            for note in inaccessible_path_strings.iter().map(|cand| cand.3.as_ref()).flatten() {
+            for note in inaccessible_path_strings.iter().flat_map(|cand| cand.3.as_ref()) {
                 err.note(note);
             }
 
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index f9926a71c30..129db038f4a 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1163,7 +1163,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                         err.span_suggestion(
                             span,
                             &"use this syntax instead",
-                            format!("{path_str}"),
+                            path_str.to_string(),
                             Applicability::MaybeIncorrect,
                         );
                     }
diff --git a/compiler/rustc_trait_selection/src/traits/codegen.rs b/compiler/rustc_trait_selection/src/traits/codegen.rs
index 603ab0622f0..bf6e6a4fcbb 100644
--- a/compiler/rustc_trait_selection/src/traits/codegen.rs
+++ b/compiler/rustc_trait_selection/src/traits/codegen.rs
@@ -64,6 +64,8 @@ pub fn codegen_fulfill_obligation<'tcx>(
             Err(Unimplemented) => {
                 // This can trigger when we probe for the source of a `'static` lifetime requirement
                 // on a trait object: `impl Foo for dyn Trait {}` has an implicit `'static` bound.
+                // This can also trigger when we have a global bound that is not actually satisfied,
+                // but was included during typeck due to the trivial_bounds feature.
                 infcx.tcx.sess.delay_span_bug(
                     rustc_span::DUMMY_SP,
                     &format!(
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index f22b4e8d072..c3df17c83bb 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1437,8 +1437,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                                     self.tcx
                                         .associated_items(did)
                                         .in_definition_order()
-                                        .filter(|assoc| assoc.ident(self.tcx) == trait_assoc_ident)
-                                        .next()
+                                        .find(|assoc| assoc.ident(self.tcx) == trait_assoc_ident)
                                 },
                             )
                         })
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 6d1b6e5ac84..7df880a7cc0 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1928,7 +1928,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             | ObligationCauseCode::AwaitableExpr(_)
             | ObligationCauseCode::ForLoopIterator
             | ObligationCauseCode::QuestionMark
-            | ObligationCauseCode::LetElse => {}
+            | ObligationCauseCode::LetElse
+            | ObligationCauseCode::CheckAssociatedTypeBounds { .. } => {}
             ObligationCauseCode::SliceOrArrayElem => {
                 err.note("slice and array elements must have `Sized` type");
             }
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 5f338664c9a..f5d531e631e 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -959,7 +959,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
                 infcx.inner.borrow_mut().projection_cache().insert_term(cache_key, result.clone());
             }
             obligations.extend(result.obligations);
-            Ok(Some(result.value.into()))
+            Ok(Some(result.value))
         }
         Ok(Projected::NoProgress(projected_ty)) => {
             let result = Normalized { value: projected_ty, obligations: vec![] };
diff --git a/compiler/rustc_typeck/src/astconv/errors.rs b/compiler/rustc_typeck/src/astconv/errors.rs
index a49d6e24f26..7e9abe3a250 100644
--- a/compiler/rustc_typeck/src/astconv/errors.rs
+++ b/compiler/rustc_typeck/src/astconv/errors.rs
@@ -211,8 +211,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         );
 
         let all_candidate_names: Vec<_> = all_candidates()
-            .map(|r| self.tcx().associated_items(r.def_id()).in_definition_order())
-            .flatten()
+            .flat_map(|r| self.tcx().associated_items(r.def_id()).in_definition_order())
             .filter_map(
                 |item| if item.kind == ty::AssocKind::Type { Some(item.name) } else { None },
             )
diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs
index fba8292b467..1650a62f79f 100644
--- a/compiler/rustc_typeck/src/check/check.rs
+++ b/compiler/rustc_typeck/src/check/check.rs
@@ -392,7 +392,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
                     "when the type does not implement `Copy`, \
                     wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped",
                     vec![
-                        (ty_span.shrink_to_lo(), format!("std::mem::ManuallyDrop<")),
+                        (ty_span.shrink_to_lo(), "std::mem::ManuallyDrop<".into()),
                         (ty_span.shrink_to_hi(), ">".into()),
                     ],
                     Applicability::MaybeIncorrect,
diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs
index 457e9cf1ea5..38449c2a76a 100644
--- a/compiler/rustc_typeck/src/check/compare_method.rs
+++ b/compiler/rustc_typeck/src/check/compare_method.rs
@@ -1378,7 +1378,14 @@ pub fn check_type_bounds<'tcx>(
         let mut selcx = traits::SelectionContext::new(&infcx);
 
         let impl_ty_hir_id = tcx.hir().local_def_id_to_hir_id(impl_ty.def_id.expect_local());
-        let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_hir_id);
+        let normalize_cause = ObligationCause::new(
+            impl_ty_span,
+            impl_ty_hir_id,
+            ObligationCauseCode::CheckAssociatedTypeBounds {
+                impl_item_def_id: impl_ty.def_id,
+                trait_item_def_id: trait_ty.def_id,
+            },
+        );
         let mk_cause = |span: Span| {
             let code = if span.is_dummy() {
                 traits::MiscObligation
diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs
index d0e96e7538c..e7eadb760c7 100644
--- a/compiler/rustc_typeck/src/check/demand.rs
+++ b/compiler/rustc_typeck/src/check/demand.rs
@@ -340,7 +340,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
                 Some(ident) => format!("{}: ", ident),
-                None => format!(""),
+                None => String::new(),
             };
 
             match &compatible_variants[..] {
@@ -683,7 +683,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                         let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
                             Some(ident) => format!("{}: ", ident),
-                            None => format!(""),
+                            None => String::new(),
                         };
 
                         if let Some(hir::Node::Expr(hir::Expr {
@@ -875,7 +875,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             };
                             let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
                                 Some(ident) => format!("{}: ", ident),
-                                None => format!(""),
+                                None => String::new(),
                             };
                             let (span, suggestion) = if self.is_else_if_block(expr) {
                                 // Don't suggest nonsense like `else *if`
diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs
index c4e7d6a199e..972dd622d6e 100644
--- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs
@@ -246,7 +246,7 @@ impl DropRangesBuilder {
 
     fn add_control_edge(&mut self, from: PostOrderId, to: PostOrderId) {
         trace!("adding control edge from {:?} to {:?}", from, to);
-        self.node_mut(from.into()).successors.push(to.into());
+        self.node_mut(from).successors.push(to);
     }
 }
 
diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs
index e2a4d9c1b3a..cfed784ea72 100644
--- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs
@@ -527,7 +527,7 @@ impl DropRangesBuilder {
 
     fn drop_at(&mut self, value: TrackedValue, location: PostOrderId) {
         let value = self.tracked_value_index(value);
-        self.node_mut(location.into()).drops.push(value);
+        self.node_mut(location).drops.push(value);
     }
 
     fn reinit_at(&mut self, value: TrackedValue, location: PostOrderId) {
@@ -537,7 +537,7 @@ impl DropRangesBuilder {
             // ignore this.
             None => return,
         };
-        self.node_mut(location.into()).reinits.push(value);
+        self.node_mut(location).reinits.push(value);
     }
 
     /// Looks up PostOrderId for any control edges added by HirId and adds a proper edge for them.
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 90555b213c1..cd7343a3211 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -527,7 +527,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                       // FIXME(associated_const_equality): add a useful error message here.
                       tcx.ty_error_with_message(
                         DUMMY_SP,
-                        &format!("Could not find associated const on trait"),
+                        "Could not find associated const on trait",
                     )
                   }
                 }
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index aa7344ba405..68bf59a01b3 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -133,6 +133,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use core::any::Any;
+use core::async_iter::AsyncIterator;
 use core::borrow;
 use core::cmp::Ordering;
 use core::convert::{From, TryFrom};
@@ -149,7 +150,6 @@ use core::ops::{
 };
 use core::pin::Pin;
 use core::ptr::{self, Unique};
-use core::stream::Stream;
 use core::task::{Context, Poll};
 
 #[cfg(not(no_global_oom_handling))]
@@ -1992,8 +1992,8 @@ where
     }
 }
 
-#[unstable(feature = "async_stream", issue = "79024")]
-impl<S: ?Sized + Stream + Unpin> Stream for Box<S> {
+#[unstable(feature = "async_iterator", issue = "79024")]
+impl<S: ?Sized + AsyncIterator + Unpin> AsyncIterator for Box<S> {
     type Item = S::Item;
 
     fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index ce75859f963..6da32df57ef 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -91,7 +91,7 @@
 #![feature(array_chunks)]
 #![feature(array_methods)]
 #![feature(array_windows)]
-#![feature(async_stream)]
+#![feature(async_iterator)]
 #![feature(coerce_unsized)]
 #![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))]
 #![feature(const_box)]
diff --git a/library/core/src/stream/stream.rs b/library/core/src/async_iter/async_iter.rs
index 2cfddf9ad01..f29de31171a 100644
--- a/library/core/src/stream/stream.rs
+++ b/library/core/src/async_iter/async_iter.rs
@@ -4,50 +4,50 @@ use crate::task::{Context, Poll};
 
 /// An interface for dealing with asynchronous iterators.
 ///
-/// This is the main stream trait. For more about the concept of streams
+/// This is the main async iterator trait. For more about the concept of async iterators
 /// generally, please see the [module-level documentation]. In particular, you
-/// may want to know how to [implement `Stream`][impl].
+/// may want to know how to [implement `AsyncIterator`][impl].
 ///
 /// [module-level documentation]: index.html
-/// [impl]: index.html#implementing-stream
-#[unstable(feature = "async_stream", issue = "79024")]
-#[must_use = "streams do nothing unless polled"]
-pub trait Stream {
-    /// The type of items yielded by the stream.
+/// [impl]: index.html#implementing-async-iterator
+#[unstable(feature = "async_iterator", issue = "79024")]
+#[must_use = "async iterators do nothing unless polled"]
+pub trait AsyncIterator {
+    /// The type of items yielded by the async iterator.
     type Item;
 
-    /// Attempt to pull out the next value of this stream, registering the
+    /// Attempt to pull out the next value of this async iterator, registering the
     /// current task for wakeup if the value is not yet available, and returning
-    /// `None` if the stream is exhausted.
+    /// `None` if the async iterator is exhausted.
     ///
     /// # Return value
     ///
     /// There are several possible return values, each indicating a distinct
-    /// stream state:
+    /// async iterator state:
     ///
-    /// - `Poll::Pending` means that this stream's next value is not ready
+    /// - `Poll::Pending` means that this async iterator's next value is not ready
     /// yet. Implementations will ensure that the current task will be notified
     /// when the next value may be ready.
     ///
-    /// - `Poll::Ready(Some(val))` means that the stream has successfully
+    /// - `Poll::Ready(Some(val))` means that the async iterator has successfully
     /// produced a value, `val`, and may produce further values on subsequent
     /// `poll_next` calls.
     ///
-    /// - `Poll::Ready(None)` means that the stream has terminated, and
+    /// - `Poll::Ready(None)` means that the async iterator has terminated, and
     /// `poll_next` should not be invoked again.
     ///
     /// # Panics
     ///
-    /// Once a stream has finished (returned `Ready(None)` from `poll_next`), calling its
+    /// Once an async iterator has finished (returned `Ready(None)` from `poll_next`), calling its
     /// `poll_next` method again may panic, block forever, or cause other kinds of
-    /// problems; the `Stream` trait places no requirements on the effects of
+    /// problems; the `AsyncIterator` trait places no requirements on the effects of
     /// such a call. However, as the `poll_next` method is not marked `unsafe`,
     /// Rust's usual rules apply: calls must never cause undefined behavior
     /// (memory corruption, incorrect use of `unsafe` functions, or the like),
-    /// regardless of the stream's state.
+    /// regardless of the async iterator's state.
     fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>;
 
-    /// Returns the bounds on the remaining length of the stream.
+    /// Returns the bounds on the remaining length of the async iterator.
     ///
     /// Specifically, `size_hint()` returns a tuple where the first element
     /// is the lower bound, and the second element is the upper bound.
@@ -58,12 +58,12 @@ pub trait Stream {
     ///
     /// # Implementation notes
     ///
-    /// It is not enforced that a stream implementation yields the declared
-    /// number of elements. A buggy stream may yield less than the lower bound
+    /// It is not enforced that an async iterator implementation yields the declared
+    /// number of elements. A buggy async iterator may yield less than the lower bound
     /// or more than the upper bound of elements.
     ///
     /// `size_hint()` is primarily intended to be used for optimizations such as
-    /// reserving space for the elements of the stream, but must not be
+    /// reserving space for the elements of the async iterator, but must not be
     /// trusted to e.g., omit bounds checks in unsafe code. An incorrect
     /// implementation of `size_hint()` should not lead to memory safety
     /// violations.
@@ -72,15 +72,15 @@ pub trait Stream {
     /// because otherwise it would be a violation of the trait's protocol.
     ///
     /// The default implementation returns <code>(0, [None])</code> which is correct for any
-    /// stream.
+    /// async iterator.
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         (0, None)
     }
 }
 
-#[unstable(feature = "async_stream", issue = "79024")]
-impl<S: ?Sized + Stream + Unpin> Stream for &mut S {
+#[unstable(feature = "async_iterator", issue = "79024")]
+impl<S: ?Sized + AsyncIterator + Unpin> AsyncIterator for &mut S {
     type Item = S::Item;
 
     fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
@@ -92,16 +92,16 @@ impl<S: ?Sized + Stream + Unpin> Stream for &mut S {
     }
 }
 
-#[unstable(feature = "async_stream", issue = "79024")]
-impl<P> Stream for Pin<P>
+#[unstable(feature = "async_iterator", issue = "79024")]
+impl<P> AsyncIterator for Pin<P>
 where
     P: DerefMut,
-    P::Target: Stream,
+    P::Target: AsyncIterator,
 {
-    type Item = <P::Target as Stream>::Item;
+    type Item = <P::Target as AsyncIterator>::Item;
 
     fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
-        <P::Target as Stream>::poll_next(self.as_deref_mut(), cx)
+        <P::Target as AsyncIterator>::poll_next(self.as_deref_mut(), cx)
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
diff --git a/library/core/src/stream/from_iter.rs b/library/core/src/async_iter/from_iter.rs
index eb9a0fd2842..3180187afc8 100644
--- a/library/core/src/stream/from_iter.rs
+++ b/library/core/src/async_iter/from_iter.rs
@@ -1,31 +1,31 @@
 use crate::pin::Pin;
 
-use crate::stream::Stream;
+use crate::async_iter::AsyncIterator;
 use crate::task::{Context, Poll};
 
-/// A stream that was created from iterator.
+/// An async iterator that was created from iterator.
 ///
-/// This stream is created by the [`from_iter`] function.
+/// This async iterator is created by the [`from_iter`] function.
 /// See it documentation for more.
 ///
 /// [`from_iter`]: fn.from_iter.html
-#[unstable(feature = "stream_from_iter", issue = "81798")]
+#[unstable(feature = "async_iter_from_iter", issue = "81798")]
 #[derive(Clone, Debug)]
 pub struct FromIter<I> {
     iter: I,
 }
 
-#[unstable(feature = "stream_from_iter", issue = "81798")]
+#[unstable(feature = "async_iter_from_iter", issue = "81798")]
 impl<I> Unpin for FromIter<I> {}
 
-/// Converts an iterator into a stream.
-#[unstable(feature = "stream_from_iter", issue = "81798")]
+/// Converts an iterator into an async iterator.
+#[unstable(feature = "async_iter_from_iter", issue = "81798")]
 pub fn from_iter<I: IntoIterator>(iter: I) -> FromIter<I::IntoIter> {
     FromIter { iter: iter.into_iter() }
 }
 
-#[unstable(feature = "stream_from_iter", issue = "81798")]
-impl<I: Iterator> Stream for FromIter<I> {
+#[unstable(feature = "async_iter_from_iter", issue = "81798")]
+impl<I: Iterator> AsyncIterator for FromIter<I> {
     type Item = I::Item;
 
     fn poll_next(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
diff --git a/library/core/src/stream/mod.rs b/library/core/src/async_iter/mod.rs
index b59a46d5f3a..0c6f637711b 100644
--- a/library/core/src/stream/mod.rs
+++ b/library/core/src/async_iter/mod.rs
@@ -1,10 +1,9 @@
 //! Composable asynchronous iteration.
 //!
-//! If futures are asynchronous values, then streams are asynchronous
-//! iterators. If you've found yourself with an asynchronous collection of some kind,
+//! If you've found yourself with an asynchronous collection of some kind,
 //! and needed to perform an operation on the elements of said collection,
-//! you'll quickly run into 'streams'. Streams are heavily used in idiomatic
-//! asynchronous Rust code, so it's worth becoming familiar with them.
+//! you'll quickly run into 'async iterators'. Async Iterators are heavily used in
+//! idiomatic asynchronous Rust code, so it's worth becoming familiar with them.
 //!
 //! Before explaining more, let's talk about how this module is structured:
 //!
@@ -12,71 +11,71 @@
 //!
 //! This module is largely organized by type:
 //!
-//! * [Traits] are the core portion: these traits define what kind of streams
+//! * [Traits] are the core portion: these traits define what kind of async iterators
 //!   exist and what you can do with them. The methods of these traits are worth
 //!   putting some extra study time into.
-//! * Functions provide some helpful ways to create some basic streams.
+//! * Functions provide some helpful ways to create some basic async iterators.
 //! * Structs are often the return types of the various methods on this
 //!   module's traits. You'll usually want to look at the method that creates
 //!   the `struct`, rather than the `struct` itself. For more detail about why,
-//!   see '[Implementing Stream](#implementing-stream)'.
+//!   see '[Implementing Async Iterator](#implementing-async-iterator)'.
 //!
 //! [Traits]: #traits
 //!
-//! That's it! Let's dig into streams.
+//! That's it! Let's dig into async iterators.
 //!
-//! # Stream
+//! # Async Iterators
 //!
-//! The heart and soul of this module is the [`Stream`] trait. The core of
-//! [`Stream`] looks like this:
+//! The heart and soul of this module is the [`AsyncIterator`] trait. The core of
+//! [`AsyncIterator`] looks like this:
 //!
 //! ```
 //! # use core::task::{Context, Poll};
 //! # use core::pin::Pin;
-//! trait Stream {
+//! trait AsyncIterator {
 //!     type Item;
 //!     fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>;
 //! }
 //! ```
 //!
-//! Unlike `Iterator`, `Stream` makes a distinction between the [`poll_next`]
-//! method which is used when implementing a `Stream`, and a (to-be-implemented)
-//! `next` method which is used when consuming a stream. Consumers of `Stream`
+//! Unlike `Iterator`, `AsyncIterator` makes a distinction between the [`poll_next`]
+//! method which is used when implementing an `AsyncIterator`, and a (to-be-implemented)
+//! `next` method which is used when consuming an async iterator. Consumers of `AsyncIterator`
 //! only need to consider `next`, which when called, returns a future which
-//! yields `Option<Stream::Item>`.
+//! yields `Option<AsyncIterator::Item>`.
 //!
 //! The future returned by `next` will yield `Some(Item)` as long as there are
 //! elements, and once they've all been exhausted, will yield `None` to indicate
 //! that iteration is finished. If we're waiting on something asynchronous to
-//! resolve, the future will wait until the stream is ready to yield again.
+//! resolve, the future will wait until the async iterator is ready to yield again.
 //!
-//! Individual streams may choose to resume iteration, and so calling `next`
+//! Individual async iterators may choose to resume iteration, and so calling `next`
 //! again may or may not eventually yield `Some(Item)` again at some point.
 //!
-//! [`Stream`]'s full definition includes a number of other methods as well,
+//! [`AsyncIterator`]'s full definition includes a number of other methods as well,
 //! but they are default methods, built on top of [`poll_next`], and so you get
 //! them for free.
 //!
 //! [`Poll`]: super::task::Poll
-//! [`poll_next`]: Stream::poll_next
+//! [`poll_next`]: AsyncIterator::poll_next
 //!
-//! # Implementing Stream
+//! # Implementing Async Iterator
 //!
-//! Creating a stream of your own involves two steps: creating a `struct` to
-//! hold the stream's state, and then implementing [`Stream`] for that
+//! Creating an async iterator of your own involves two steps: creating a `struct` to
+//! hold the async iterator's state, and then implementing [`AsyncIterator`] for that
 //! `struct`.
 //!
-//! Let's make a stream named `Counter` which counts from `1` to `5`:
+//! Let's make an async iterator named `Counter` which counts from `1` to `5`:
 //!
 //! ```no_run
-//! #![feature(async_stream)]
-//! # use core::stream::Stream;
+//! #![feature(async_iterator)]
+//! # use core::async_iter::AsyncIterator;
 //! # use core::task::{Context, Poll};
 //! # use core::pin::Pin;
 //!
 //! // First, the struct:
 //!
-//! /// A stream which counts from one to five
+//! /// An async iterator which counts from one to five
 //! struct Counter {
 //!     count: usize,
 //! }
@@ -90,9 +89,9 @@
 //!     }
 //! }
 //!
-//! // Then, we implement `Stream` for our `Counter`:
+//! // Then, we implement `AsyncIterator` for our `Counter`:
 //!
-//! impl Stream for Counter {
+//! impl AsyncIterator for Counter {
 //!     // we will be counting with usize
 //!     type Item = usize;
 //!
@@ -113,17 +112,17 @@
 //!
 //! # Laziness
 //!
-//! Streams are *lazy*. This means that just creating a stream doesn't _do_ a
-//! whole lot. Nothing really happens until you call `poll_next`. This is
-//! sometimes a source of confusion when creating a stream solely for its side
+//! Async iterators are *lazy*. This means that just creating an async iterator doesn't
+//! _do_ a whole lot. Nothing really happens until you call `poll_next`. This is
+//! sometimes a source of confusion when creating an async iterator solely for its side
 //! effects. The compiler will warn us about this kind of behavior:
 //!
 //! ```text
-//! warning: unused result that must be used: streams do nothing unless polled
+//! warning: unused result that must be used: async iterators do nothing unless polled
 //! ```
 
+mod async_iter;
 mod from_iter;
-mod stream;
 
+pub use async_iter::AsyncIterator;
 pub use from_iter::{from_iter, FromIter};
-pub use stream::Stream;
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index afef129303e..aa1ad9362a9 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -305,6 +305,8 @@ pub mod ops;
 pub mod any;
 pub mod array;
 pub mod ascii;
+#[unstable(feature = "async_iterator", issue = "79024")]
+pub mod async_iter;
 pub mod cell;
 pub mod char;
 pub mod ffi;
@@ -316,8 +318,6 @@ pub mod panic;
 pub mod panicking;
 pub mod pin;
 pub mod result;
-#[unstable(feature = "async_stream", issue = "79024")]
-pub mod stream;
 pub mod sync;
 
 pub mod fmt;
diff --git a/library/core/src/panic/unwind_safe.rs b/library/core/src/panic/unwind_safe.rs
index 092b7cf0f2c..95be879e319 100644
--- a/library/core/src/panic/unwind_safe.rs
+++ b/library/core/src/panic/unwind_safe.rs
@@ -1,10 +1,10 @@
+use crate::async_iter::AsyncIterator;
 use crate::cell::UnsafeCell;
 use crate::fmt;
 use crate::future::Future;
 use crate::ops::{Deref, DerefMut};
 use crate::pin::Pin;
 use crate::ptr::{NonNull, Unique};
-use crate::stream::Stream;
 use crate::task::{Context, Poll};
 
 /// A marker trait which represents "panic safe" types in Rust.
@@ -290,8 +290,8 @@ impl<F: Future> Future for AssertUnwindSafe<F> {
     }
 }
 
-#[unstable(feature = "async_stream", issue = "79024")]
-impl<S: Stream> Stream for AssertUnwindSafe<S> {
+#[unstable(feature = "async_iterator", issue = "79024")]
+impl<S: AsyncIterator> AsyncIterator for AssertUnwindSafe<S> {
     type Item = S::Item;
 
     fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<S::Item>> {
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index a03da0682a5..8c38db9b62c 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -233,7 +233,7 @@
 #![feature(array_error_internals)]
 #![feature(assert_matches)]
 #![feature(associated_type_bounds)]
-#![feature(async_stream)]
+#![feature(async_iterator)]
 #![feature(atomic_mut_ptr)]
 #![feature(auto_traits)]
 #![feature(bench_black_box)]
@@ -404,6 +404,8 @@ pub use alloc_crate::vec;
 pub use core::any;
 #[stable(feature = "core_array", since = "1.36.0")]
 pub use core::array;
+#[unstable(feature = "async_iterator", issue = "79024")]
+pub use core::async_iter;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::cell;
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -458,8 +460,6 @@ pub use core::pin;
 pub use core::ptr;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::result;
-#[unstable(feature = "async_stream", issue = "79024")]
-pub use core::stream;
 #[stable(feature = "i128", since = "1.26.0")]
 #[allow(deprecated, deprecated_in_future)]
 pub use core::u128;
diff --git a/src/test/run-make-fulldeps/libs-and-bins/Makefile b/src/test/run-make-fulldeps/libs-and-bins/Makefile
deleted file mode 100644
index cc3b257a5c5..00000000000
--- a/src/test/run-make-fulldeps/libs-and-bins/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
--include ../tools.mk
-
-all:
-	$(RUSTC) foo.rs
-	$(call RUN,foo)
-	rm $(TMPDIR)/$(call DYLIB_GLOB,foo)
diff --git a/src/test/run-make-fulldeps/libs-and-bins/foo.rs b/src/test/run-make-fulldeps/libs-and-bins/foo.rs
deleted file mode 100644
index ae166b17840..00000000000
--- a/src/test/run-make-fulldeps/libs-and-bins/foo.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-#![crate_type = "dylib"]
-#![crate_type = "bin"]
-
-fn main() {}
diff --git a/src/test/run-make-fulldeps/output-with-hyphens/Makefile b/src/test/run-make-fulldeps/output-with-hyphens/Makefile
index 783d826a53d..69a286f0b74 100644
--- a/src/test/run-make-fulldeps/output-with-hyphens/Makefile
+++ b/src/test/run-make-fulldeps/output-with-hyphens/Makefile
@@ -1,6 +1,7 @@
 -include ../tools.mk
 
 all:
-	$(RUSTC) foo-bar.rs
+	$(RUSTC) foo-bar.rs --crate-type bin
 	[ -f $(TMPDIR)/$(call BIN,foo-bar) ]
+	$(RUSTC) foo-bar.rs --crate-type lib
 	[ -f $(TMPDIR)/libfoo_bar.rlib ]
diff --git a/src/test/run-make-fulldeps/output-with-hyphens/foo-bar.rs b/src/test/run-make-fulldeps/output-with-hyphens/foo-bar.rs
index 3f1a70458e3..f328e4d9d04 100644
--- a/src/test/run-make-fulldeps/output-with-hyphens/foo-bar.rs
+++ b/src/test/run-make-fulldeps/output-with-hyphens/foo-bar.rs
@@ -1,4 +1 @@
-#![crate_type = "lib"]
-#![crate_type = "bin"]
-
 fn main() {}
diff --git a/src/test/ui/generic-associated-types/impl_bounds.stderr b/src/test/ui/generic-associated-types/impl_bounds.stderr
index 5be431f2933..bd0dea37219 100644
--- a/src/test/ui/generic-associated-types/impl_bounds.stderr
+++ b/src/test/ui/generic-associated-types/impl_bounds.stderr
@@ -19,8 +19,13 @@ LL |     type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
 error[E0478]: lifetime bound not satisfied
   --> $DIR/impl_bounds.rs:17:35
    |
+LL |     type B<'a, 'b> where 'a: 'b;
+   |     ---------------------------- definition of `B` from trait
+...
 LL |     type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
-   |                                   ^^^^^^^^^^^^^^^
+   |                                -  ^^^^^^^^^^^^^^^
+   |                                |
+   |                                help: try copying this clause from the trait: `, 'a: 'b`
    |
 note: lifetime parameter instantiated with the lifetime `'a` as defined here
   --> $DIR/impl_bounds.rs:17:12
diff --git a/src/test/ui/generic-associated-types/issue-88595.rs b/src/test/ui/generic-associated-types/issue-88595.rs
index e397390783f..c97d17811ba 100644
--- a/src/test/ui/generic-associated-types/issue-88595.rs
+++ b/src/test/ui/generic-associated-types/issue-88595.rs
@@ -8,7 +8,7 @@ trait A<'a> {
     // FIXME(generic_associated_types): Remove one of the below bounds
     // https://github.com/rust-lang/rust/pull/90678#discussion_r744976085
     where
-        'a: 'b, Self: 'a, Self: 'b;
+        Self: 'a, Self: 'b;
 
     fn a(&'a self) -> Self::B<'a>;
 }
@@ -17,8 +17,7 @@ struct C;
 
 impl<'a> A<'a> for C {
     type B<'b> = impl Clone;
-    //~^ ERROR: lifetime bound not satisfied
-    //~| ERROR: could not find defining uses
+    //~^ ERROR: could not find defining uses
 
     fn a(&'a self) -> Self::B<'a> {} //~ ERROR: non-defining opaque type use in defining scope
 }
diff --git a/src/test/ui/generic-associated-types/issue-88595.stderr b/src/test/ui/generic-associated-types/issue-88595.stderr
index cb462871ccd..4e4f86bbac8 100644
--- a/src/test/ui/generic-associated-types/issue-88595.stderr
+++ b/src/test/ui/generic-associated-types/issue-88595.stderr
@@ -1,22 +1,5 @@
-error[E0478]: lifetime bound not satisfied
-  --> $DIR/issue-88595.rs:19:18
-   |
-LL |     type B<'b> = impl Clone;
-   |                  ^^^^^^^^^^
-   |
-note: lifetime parameter instantiated with the lifetime `'a` as defined here
-  --> $DIR/issue-88595.rs:18:6
-   |
-LL | impl<'a> A<'a> for C {
-   |      ^^
-note: but lifetime parameter must outlive the lifetime `'b` as defined here
-  --> $DIR/issue-88595.rs:19:12
-   |
-LL |     type B<'b> = impl Clone;
-   |            ^^
-
 error: non-defining opaque type use in defining scope
-  --> $DIR/issue-88595.rs:23:23
+  --> $DIR/issue-88595.rs:22:23
    |
 LL |     fn a(&'a self) -> Self::B<'a> {}
    |                       ^^^^^^^^^^^
@@ -35,6 +18,5 @@ error: could not find defining uses
 LL |     type B<'b> = impl Clone;
    |                  ^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0478`.
diff --git a/src/test/ui/generic-associated-types/issue-90014.stderr b/src/test/ui/generic-associated-types/issue-90014.stderr
index 23e8d08af34..f8fb71bbddb 100644
--- a/src/test/ui/generic-associated-types/issue-90014.stderr
+++ b/src/test/ui/generic-associated-types/issue-90014.stderr
@@ -1,8 +1,13 @@
 error[E0477]: the type `&mut ()` does not fulfill the required lifetime
   --> $DIR/issue-90014.rs:14:20
    |
+LL |     type Fut<'a> where Self: 'a;
+   |     ---------------------------- definition of `Fut` from trait
+...
 LL |     type Fut<'a> = impl Future<Output = ()>;
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                 -  ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                 |
+   |                 help: try copying this clause from the trait: `where Self: 'a`
    |
 note: type must outlive the lifetime `'a` as defined here
   --> $DIR/issue-90014.rs:14:14
diff --git a/src/test/ui/generic-associated-types/issue-92033.rs b/src/test/ui/generic-associated-types/issue-92033.rs
new file mode 100644
index 00000000000..1d5f7d5c009
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-92033.rs
@@ -0,0 +1,39 @@
+#![feature(generic_associated_types)]
+
+struct Texture;
+
+trait Surface {
+    type TextureIter<'a>: Iterator<Item = &'a Texture>
+    where
+        Self: 'a;
+
+    fn get_texture(&self) -> Self::TextureIter<'_>;
+}
+
+trait Swapchain {
+    type Surface<'a>: Surface
+    where
+        Self: 'a;
+
+    fn get_surface(&self) -> Self::Surface<'_>;
+}
+
+impl<'s> Surface for &'s Texture {
+    type TextureIter<'a> = std::option::IntoIter<&'a Texture>;
+    //~^ ERROR the type
+
+    fn get_texture(&self) -> Self::TextureIter<'_> {
+        let option: Option<&Texture> = Some(self);
+        option.into_iter()
+    }
+}
+
+impl Swapchain for Texture {
+    type Surface<'a> = &'a Texture;
+
+    fn get_surface(&self) -> Self::Surface<'_> {
+        self
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-92033.stderr b/src/test/ui/generic-associated-types/issue-92033.stderr
new file mode 100644
index 00000000000..caa6618f398
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-92033.stderr
@@ -0,0 +1,22 @@
+error[E0477]: the type `&'s Texture` does not fulfill the required lifetime
+  --> $DIR/issue-92033.rs:22:28
+   |
+LL | /     type TextureIter<'a>: Iterator<Item = &'a Texture>
+LL | |     where
+LL | |         Self: 'a;
+   | |_________________- definition of `TextureIter` from trait
+...
+LL |       type TextureIter<'a> = std::option::IntoIter<&'a Texture>;
+   |                           -  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                           |
+   |                           help: try copying this clause from the trait: `where Self: 'a`
+   |
+note: type must outlive the lifetime `'a` as defined here
+  --> $DIR/issue-92033.rs:22:22
+   |
+LL |     type TextureIter<'a> = std::option::IntoIter<&'a Texture>;
+   |                      ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0477`.
diff --git a/src/test/ui/issues/issue-14772.rs b/src/test/ui/issues/issue-14772.rs
deleted file mode 100644
index 8f6745246fd..00000000000
--- a/src/test/ui/issues/issue-14772.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-// compile-flags: --test
-
-#[test]
-mod foo {} //~ ERROR only functions may be used as tests
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-14772.stderr b/src/test/ui/issues/issue-14772.stderr
deleted file mode 100644
index 253fec5e578..00000000000
--- a/src/test/ui/issues/issue-14772.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: only functions may be used as tests
-  --> $DIR/issue-14772.rs:4:1
-   |
-LL | mod foo {}
-   | ^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/test-attrs/test-on-macro.rs b/src/test/ui/test-attrs/test-on-macro.rs
deleted file mode 100644
index 0667364d13c..00000000000
--- a/src/test/ui/test-attrs/test-on-macro.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-// check-pass
-// compile-flags:--test
-
-#![deny(warnings)]
-
-macro_rules! foo {
-    () => (fn foo(){})
-}
-
-#[test]
-foo!(); //~ WARNING `#[test]` attribute should not be used on macros
-
-fn main(){}
diff --git a/src/test/ui/test-attrs/test-on-macro.stderr b/src/test/ui/test-attrs/test-on-macro.stderr
deleted file mode 100644
index 98190b060ce..00000000000
--- a/src/test/ui/test-attrs/test-on-macro.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-warning: `#[test]` attribute should not be used on macros. Use `#[cfg(test)]` instead.
-  --> $DIR/test-on-macro.rs:11:1
-   |
-LL | foo!();
-   | ^^^^^^^
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/test-attrs/test-on-not-fn.rs b/src/test/ui/test-attrs/test-on-not-fn.rs
new file mode 100644
index 00000000000..b2f681c01d1
--- /dev/null
+++ b/src/test/ui/test-attrs/test-on-not-fn.rs
@@ -0,0 +1,80 @@
+// compile-flags: --test
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+mod test {}
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+mod loooooooooooooong_teeeeeeeeeest {
+    /*
+    this is a comment
+    this comment goes on for a very long time
+    this is to pad out the span for this module for a long time
+    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
+    labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
+    laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
+    voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
+    non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+    */
+}
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+extern "C" {}
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+trait Foo {}
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+impl Foo for i32 {}
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+const FOO: i32 = -1_i32;
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+static BAR: u64 = 10_000_u64;
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+enum MyUnit {
+    Unit,
+}
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+struct NewI32(i32);
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+union Spooky {
+    x: i32,
+    y: u32,
+}
+
+#[repr(C, align(64))]
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+#[derive(Copy, Clone, Debug)]
+struct MoreAttrs {
+    a: i32,
+    b: u64,
+}
+
+macro_rules! foo {
+    () => {};
+}
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+foo!();
+
+// make sure it doesn't erroneously trigger on a real test
+#[test]
+fn real_test() {
+    assert_eq!(42_i32, 42_i32);
+}
+
+// make sure it works with cfg test
+#[cfg(test)]
+mod real_tests {
+    #[cfg(test)]
+    fn foo() {}
+
+    #[test]
+    fn bar() {
+        foo();
+    }
+}
diff --git a/src/test/ui/test-attrs/test-on-not-fn.stderr b/src/test/ui/test-attrs/test-on-not-fn.stderr
new file mode 100644
index 00000000000..dd693cf316d
--- /dev/null
+++ b/src/test/ui/test-attrs/test-on-not-fn.stderr
@@ -0,0 +1,185 @@
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:3:1
+   |
+LL | #[test]
+   | ^^^^^^^
+LL | mod test {}
+   | ----------- expected a non-associated function, found a module
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:6:1
+   |
+LL |   #[test]
+   |   ^^^^^^^
+LL | / mod loooooooooooooong_teeeeeeeeeest {
+LL | |     /*
+LL | |     this is a comment
+LL | |     this comment goes on for a very long time
+...  |
+LL | |     */
+LL | | }
+   | |_- expected a non-associated function, found a module
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:20:1
+   |
+LL | #[test]
+   | ^^^^^^^
+LL | extern "C" {}
+   | ------------- expected a non-associated function, found an extern block
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:23:1
+   |
+LL | #[test]
+   | ^^^^^^^
+LL | trait Foo {}
+   | ------------ expected a non-associated function, found a trait
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:26:1
+   |
+LL | #[test]
+   | ^^^^^^^
+LL | impl Foo for i32 {}
+   | ------------------- expected a non-associated function, found an implementation
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:29:1
+   |
+LL | #[test]
+   | ^^^^^^^
+LL | const FOO: i32 = -1_i32;
+   | ------------------------ expected a non-associated function, found a constant item
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:32:1
+   |
+LL | #[test]
+   | ^^^^^^^
+LL | static BAR: u64 = 10_000_u64;
+   | ----------------------------- expected a non-associated function, found a static item
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:35:1
+   |
+LL |   #[test]
+   |   ^^^^^^^
+LL | / enum MyUnit {
+LL | |     Unit,
+LL | | }
+   | |_- expected a non-associated function, found an enum
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:40:1
+   |
+LL | #[test]
+   | ^^^^^^^
+LL | struct NewI32(i32);
+   | ------------------- expected a non-associated function, found a struct
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:43:1
+   |
+LL |   #[test]
+   |   ^^^^^^^
+LL | / union Spooky {
+LL | |     x: i32,
+LL | |     y: u32,
+LL | | }
+   | |_- expected a non-associated function, found a union
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:50:1
+   |
+LL |   #[test]
+   |   ^^^^^^^
+LL |   #[derive(Copy, Clone, Debug)]
+LL | / struct MoreAttrs {
+LL | |     a: i32,
+LL | |     b: u64,
+LL | | }
+   | |_- expected a non-associated function, found a struct
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:61:1
+   |
+LL | #[test]
+   | ^^^^^^^
+LL | foo!();
+   | ------- expected a non-associated function, found an item macro invocation
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: aborting due to 12 previous errors
+
diff --git a/src/test/ui/trait-bounds/issue-93008.rs b/src/test/ui/trait-bounds/issue-93008.rs
new file mode 100644
index 00000000000..1b010566cbc
--- /dev/null
+++ b/src/test/ui/trait-bounds/issue-93008.rs
@@ -0,0 +1,10 @@
+// compile-flags: -Zmir-opt-level=4
+
+pub fn bar<T>(s: &'static mut ())
+where
+    &'static mut (): Clone, //~ ERROR the trait bound
+{
+    <&'static mut () as Clone>::clone(&s);
+}
+
+fn main() {}
diff --git a/src/test/ui/trait-bounds/issue-93008.stderr b/src/test/ui/trait-bounds/issue-93008.stderr
new file mode 100644
index 00000000000..10f80f8de0c
--- /dev/null
+++ b/src/test/ui/trait-bounds/issue-93008.stderr
@@ -0,0 +1,12 @@
+error[E0277]: the trait bound `&'static mut (): Clone` is not satisfied
+  --> $DIR/issue-93008.rs:5:5
+   |
+LL |     &'static mut (): Clone,
+   |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `&'static mut ()`
+   |
+   = help: see issue #48214
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.