about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_attr_parsing/messages.ftl2
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/must_use.rs20
-rw-r--r--compiler/rustc_attr_parsing/src/lints.rs1
-rw-r--r--compiler/rustc_attr_parsing/src/session_diagnostics.rs3
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs28
-rw-r--r--compiler/rustc_lint/src/foreign_modules.rs2
-rw-r--r--compiler/rustc_macros/src/print_attribute.rs60
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs2
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs17
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs5
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs9
-rw-r--r--compiler/rustc_middle/src/query/on_disk_cache.rs51
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs40
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs24
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs17
-rw-r--r--compiler/rustc_parse/messages.ftl3
-rw-r--r--compiler/rustc_parse/src/errors.rs21
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs4
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs11
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs147
-rw-r--r--compiler/rustc_passes/messages.ftl4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs41
-rw-r--r--compiler/rustc_passes/src/errors.rs8
-rw-r--r--compiler/rustc_resolve/src/lib.rs5
-rw-r--r--compiler/rustc_span/src/caching_source_map_view.rs30
-rw-r--r--compiler/rustc_symbol_mangling/src/lib.rs50
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs61
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs8
-rw-r--r--compiler/rustc_type_ir/src/inherent.rs6
32 files changed, 316 insertions, 369 deletions
diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl
index 4fb66a81652..067d95a0f48 100644
--- a/compiler/rustc_attr_parsing/messages.ftl
+++ b/compiler/rustc_attr_parsing/messages.ftl
@@ -12,9 +12,11 @@ attr_parsing_empty_attribute =
 
 attr_parsing_invalid_target = `#[{$name}]` attribute cannot be used on {$target}
     .help = `#[{$name}]` can {$only}be applied to {$applied}
+    .suggestion = remove the attribute
 attr_parsing_invalid_target_lint = `#[{$name}]` attribute cannot be used on {$target}
     .warn = {-attr_parsing_previously_accepted}
     .help = `#[{$name}]` can {$only}be applied to {$applied}
+    .suggestion = remove the attribute
 
 attr_parsing_empty_confusables =
     expected at least one confusable name
diff --git a/compiler/rustc_attr_parsing/src/attributes/must_use.rs b/compiler/rustc_attr_parsing/src/attributes/must_use.rs
index b0ee3d1ba6e..eb2b39298bc 100644
--- a/compiler/rustc_attr_parsing/src/attributes/must_use.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/must_use.rs
@@ -1,10 +1,12 @@
 use rustc_errors::DiagArgValue;
 use rustc_feature::{AttributeTemplate, template};
 use rustc_hir::attrs::AttributeKind;
+use rustc_hir::{MethodKind, Target};
 use rustc_span::{Symbol, sym};
 
 use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
-use crate::context::{ALL_TARGETS, AcceptContext, AllowedTargets, Stage};
+use crate::context::MaybeWarn::{Allow, Error};
+use crate::context::{AcceptContext, AllowedTargets, Stage};
 use crate::parser::ArgParser;
 use crate::session_diagnostics;
 pub(crate) struct MustUseParser;
@@ -13,7 +15,21 @@ impl<S: Stage> SingleAttributeParser<S> for MustUseParser {
     const PATH: &[Symbol] = &[sym::must_use];
     const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
-    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs`
+    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
+        Allow(Target::Fn),
+        Allow(Target::Enum),
+        Allow(Target::Struct),
+        Allow(Target::Union),
+        Allow(Target::Method(MethodKind::Trait { body: false })),
+        Allow(Target::Method(MethodKind::Trait { body: true })),
+        Allow(Target::Method(MethodKind::Inherent)),
+        Allow(Target::ForeignFn),
+        // `impl Trait` in return position can trip
+        // `unused_must_use` if `Trait` is marked as
+        // `#[must_use]`
+        Allow(Target::Trait),
+        Error(Target::WherePredicate),
+    ]);
     const TEMPLATE: AttributeTemplate = template!(
         Word, NameValueStr: "reason",
         "https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"
diff --git a/compiler/rustc_attr_parsing/src/lints.rs b/compiler/rustc_attr_parsing/src/lints.rs
index 733225bab59..2813fef3148 100644
--- a/compiler/rustc_attr_parsing/src/lints.rs
+++ b/compiler/rustc_attr_parsing/src/lints.rs
@@ -53,6 +53,7 @@ pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<HirId>, lint_emi
                     target: target.plural_name(),
                     applied: applied.clone(),
                     only,
+                    attr_span: *span,
                 },
             ),
     }
diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs
index c65937b35b3..aec970a3ce9 100644
--- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs
+++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs
@@ -489,6 +489,8 @@ pub(crate) struct InvalidTargetLint {
     pub target: &'static str,
     pub applied: String,
     pub only: &'static str,
+    #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
+    pub attr_span: Span,
 }
 
 #[derive(Diagnostic)]
@@ -496,6 +498,7 @@ pub(crate) struct InvalidTargetLint {
 #[diag(attr_parsing_invalid_target)]
 pub(crate) struct InvalidTarget {
     #[primary_span]
+    #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
     pub span: Span,
     pub name: Symbol,
     pub target: &'static str,
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 86a4927f390..1bcea95fbb7 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -8,7 +8,6 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(assert_matches)]
-#![feature(autodiff)]
 #![feature(box_patterns)]
 #![feature(decl_macro)]
 #![feature(if_let_guard)]
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index a6daacd95ef..8f1218bb505 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -497,7 +497,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
             to_add.push(llvm::CreateAttrStringValue(cx.llcx, "wasm-import-module", module));
 
             let name =
-                codegen_fn_attrs.link_name.unwrap_or_else(|| cx.tcx.item_name(instance.def_id()));
+                codegen_fn_attrs.symbol_name.unwrap_or_else(|| cx.tcx.item_name(instance.def_id()));
             let name = name.as_str();
             to_add.push(llvm::CreateAttrStringValue(cx.llcx, "wasm-import-name", name));
         }
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 67cd1f4cd41..8abaf201aba 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -858,7 +858,7 @@ pub fn is_call_from_compiler_builtins_to_upstream_monomorphization<'tcx>(
     instance: Instance<'tcx>,
 ) -> bool {
     fn is_llvm_intrinsic(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
-        if let Some(name) = tcx.codegen_fn_attrs(def_id).link_name {
+        if let Some(name) = tcx.codegen_fn_attrs(def_id).symbol_name {
             name.as_str().starts_with("llvm.")
         } else {
             false
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index bf14c02a09c..c8690251bd0 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -6,7 +6,6 @@ use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr};
 use rustc_hir::attrs::{AttributeKind, InlineAttr, InstructionSetAttr, UsedBy};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
-use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
 use rustc_hir::{self as hir, Attribute, LangItem, find_attr, lang_items};
 use rustc_middle::middle::codegen_fn_attrs::{
     CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry,
@@ -156,7 +155,7 @@ fn process_builtin_attrs(
             match p {
                 AttributeKind::Cold(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD,
                 AttributeKind::ExportName { name, .. } => {
-                    codegen_fn_attrs.export_name = Some(*name)
+                    codegen_fn_attrs.symbol_name = Some(*name)
                 }
                 AttributeKind::Inline(inline, span) => {
                     codegen_fn_attrs.inline = *inline;
@@ -164,7 +163,13 @@ fn process_builtin_attrs(
                 }
                 AttributeKind::Naked(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
                 AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align),
-                AttributeKind::LinkName { name, .. } => codegen_fn_attrs.link_name = Some(*name),
+                AttributeKind::LinkName { name, .. } => {
+                    // FIXME Remove check for foreign functions once #[link_name] on non-foreign
+                    // functions is a hard error
+                    if tcx.is_foreign_item(did) {
+                        codegen_fn_attrs.symbol_name = Some(*name);
+                    }
+                }
                 AttributeKind::LinkOrdinal { ordinal, span } => {
                     codegen_fn_attrs.link_ordinal = Some(*ordinal);
                     interesting_spans.link_ordinal = Some(*span);
@@ -382,7 +387,7 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code
             // * `#[rustc_std_internal_symbol]` mangles the symbol name in a special way
             //   both for exports and imports through foreign items. This is handled further,
             //   during symbol mangling logic.
-        } else if codegen_fn_attrs.link_name.is_some() {
+        } else if codegen_fn_attrs.symbol_name.is_some() {
             // * This can be overridden with the `#[link_name]` attribute
         } else {
             // NOTE: there's one more exception that we cannot apply here. On wasm,
@@ -437,7 +442,7 @@ fn check_result(
     }
 
     // error when specifying link_name together with link_ordinal
-    if let Some(_) = codegen_fn_attrs.link_name
+    if let Some(_) = codegen_fn_attrs.symbol_name
         && let Some(_) = codegen_fn_attrs.link_ordinal
     {
         let msg = "cannot use `#[link_name]` with `#[link_ordinal]`";
@@ -484,14 +489,11 @@ fn handle_lang_items(
     // strippable by the linker.
     //
     // Additionally weak lang items have predetermined symbol names.
-    if let Some(lang_item) = lang_item {
-        if WEAK_LANG_ITEMS.contains(&lang_item) {
-            codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
-        }
-        if let Some(link_name) = lang_item.link_name() {
-            codegen_fn_attrs.export_name = Some(link_name);
-            codegen_fn_attrs.link_name = Some(link_name);
-        }
+    if let Some(lang_item) = lang_item
+        && let Some(link_name) = lang_item.link_name()
+    {
+        codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
+        codegen_fn_attrs.symbol_name = Some(link_name);
     }
 
     // error when using no_mangle on a lang item item
diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs
index 759e6c927b8..3267e70f1de 100644
--- a/compiler/rustc_lint/src/foreign_modules.rs
+++ b/compiler/rustc_lint/src/foreign_modules.rs
@@ -179,7 +179,7 @@ impl ClashingExternDeclarations {
 /// symbol's name.
 fn name_of_extern_decl(tcx: TyCtxt<'_>, fi: hir::OwnerId) -> SymbolName {
     if let Some((overridden_link_name, overridden_link_name_span)) =
-        tcx.codegen_fn_attrs(fi).link_name.map(|overridden_link_name| {
+        tcx.codegen_fn_attrs(fi).symbol_name.map(|overridden_link_name| {
             // FIXME: Instead of searching through the attributes again to get span
             // information, we could have codegen_fn_attrs also give span information back for
             // where the attribute was defined. However, until this is found to be a
diff --git a/compiler/rustc_macros/src/print_attribute.rs b/compiler/rustc_macros/src/print_attribute.rs
index 9023520c750..0114e0dfde0 100644
--- a/compiler/rustc_macros/src/print_attribute.rs
+++ b/compiler/rustc_macros/src/print_attribute.rs
@@ -4,7 +4,7 @@ use syn::spanned::Spanned;
 use syn::{Data, Fields, Ident};
 use synstructure::Structure;
 
-fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, TokenStream) {
+fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream) {
     let string_name = name.to_string();
     let mut disps = vec![quote! {let mut __printed_anything = false;}];
 
@@ -43,7 +43,6 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok
                     #(#disps)*
                     __p.word("}");
                 },
-                quote! { true },
             )
         }
         Fields::Unnamed(fields_unnamed) => {
@@ -76,10 +75,9 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok
                     #(#disps)*
                     __p.pclose();
                 },
-                quote! { true },
             )
         }
-        Fields::Unit => (quote! {}, quote! { __p.word(#string_name) }, quote! { true }),
+        Fields::Unit => (quote! {}, quote! { __p.word(#string_name) }),
     }
 }
 
@@ -89,51 +87,33 @@ pub(crate) fn print_attribute(input: Structure<'_>) -> TokenStream {
     };
 
     // Must be applied to an enum type.
-    let (code, printed) = match &input.ast().data {
+    let code = match &input.ast().data {
         Data::Enum(e) => {
-            let (arms, printed) = e
+            let arms = e
                 .variants
                 .iter()
                 .map(|x| {
                     let ident = &x.ident;
-                    let (pat, code, printed) = print_fields(ident, &x.fields);
+                    let (pat, code) = print_fields(ident, &x.fields);
 
-                    (
-                        quote! {
-                            Self::#ident #pat => {#code}
-                        },
-                        quote! {
-                            Self::#ident #pat => {#printed}
-                        },
-                    )
+                    quote! {
+                        Self::#ident #pat => {#code}
+                    }
                 })
-                .unzip::<_, _, Vec<_>, Vec<_>>();
+                .collect::<Vec<_>>();
 
-            (
-                quote! {
-                    match self {
-                        #(#arms)*
-                    }
-                },
-                quote! {
-                    match self {
-                        #(#printed)*
-                    }
-                },
-            )
+            quote! {
+                match self {
+                    #(#arms)*
+                }
+            }
         }
         Data::Struct(s) => {
-            let (pat, code, printed) = print_fields(&input.ast().ident, &s.fields);
-            (
-                quote! {
-                    let Self #pat = self;
-                    #code
-                },
-                quote! {
-                    let Self #pat = self;
-                    #printed
-                },
-            )
+            let (pat, code) = print_fields(&input.ast().ident, &s.fields);
+            quote! {
+                let Self #pat = self;
+                #code
+            }
         }
         Data::Union(u) => {
             return span_error(u.union_token.span(), "can't derive PrintAttribute on unions");
@@ -144,7 +124,7 @@ pub(crate) fn print_attribute(input: Structure<'_>) -> TokenStream {
     input.gen_impl(quote! {
         #[allow(unused)]
         gen impl PrintAttribute for @Self {
-            fn should_render(&self) -> bool { #printed }
+            fn should_render(&self) -> bool { true }
             fn print_attribute(&self, __p: &mut rustc_ast_pretty::pp::Printer) { #code }
         }
     })
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 958e314efab..63f1b51df1c 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -701,7 +701,7 @@ impl<'tcx> Collector<'tcx> {
             .link_ordinal
             .map_or(import_name_type, |ord| Some(PeImportNameType::Ordinal(ord)));
 
-        let name = codegen_fn_attrs.link_name.unwrap_or_else(|| self.tcx.item_name(item));
+        let name = codegen_fn_attrs.symbol_name.unwrap_or_else(|| self.tcx.item_name(item));
 
         if self.tcx.sess.target.binary_format == BinaryFormat::Elf {
             let name = name.as_str();
diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
index da17ac04c76..347319b07c9 100644
--- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
+++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
@@ -35,14 +35,10 @@ pub struct CodegenFnAttrs {
     pub inline: InlineAttr,
     /// Parsed representation of the `#[optimize]` attribute
     pub optimize: OptimizeAttr,
-    /// The `#[export_name = "..."]` attribute, indicating a custom symbol a
-    /// function should be exported under
-    pub export_name: Option<Symbol>,
-    /// The `#[link_name = "..."]` attribute, indicating a custom symbol an
-    /// imported function should be imported as. Note that `export_name`
-    /// probably isn't set when this is set, this is for foreign items while
-    /// `#[export_name]` is for Rust-defined functions.
-    pub link_name: Option<Symbol>,
+    /// The name this function will be imported/exported under. This can be set
+    /// using the `#[export_name = "..."]` or `#[link_name = "..."]` attribute
+    /// depending on if this is a function definition or foreign function.
+    pub symbol_name: Option<Symbol>,
     /// The `#[link_ordinal = "..."]` attribute, indicating an ordinal an
     /// imported function has in the dynamic library. Note that this must not
     /// be set when `link_name` is set. This is for foreign items with the
@@ -167,8 +163,7 @@ impl CodegenFnAttrs {
             flags: CodegenFnAttrFlags::empty(),
             inline: InlineAttr::None,
             optimize: OptimizeAttr::Default,
-            export_name: None,
-            link_name: None,
+            symbol_name: None,
             link_ordinal: None,
             target_features: vec![],
             safe_target_features: false,
@@ -196,7 +191,7 @@ impl CodegenFnAttrs {
 
         self.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
             || self.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
-            || self.export_name.is_some()
+            || self.symbol_name.is_some()
             || match self.linkage {
                 // These are private, so make sure we don't try to consider
                 // them external.
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index f2d5b13cbc8..128ae8549f7 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -929,7 +929,10 @@ impl<'tcx> TerminatorKind<'tcx> {
             }
             Yield { value, resume_arg, .. } => write!(fmt, "{resume_arg:?} = yield({value:?})"),
             Unreachable => write!(fmt, "unreachable"),
-            Drop { place, .. } => write!(fmt, "drop({place:?})"),
+            Drop { place, async_fut: None, .. } => write!(fmt, "drop({place:?})"),
+            Drop { place, async_fut: Some(async_fut), .. } => {
+                write!(fmt, "async drop({place:?}; poll={async_fut:?})")
+            }
             Call { func, args, destination, .. } => {
                 write!(fmt, "{destination:?} = ")?;
                 write!(fmt, "{func:?}(")?;
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 42a68b29ec7..904d78d69b6 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -531,13 +531,20 @@ macro_rules! make_mir_visitor {
                         unwind: _,
                         replace: _,
                         drop: _,
-                        async_fut: _,
+                        async_fut,
                     } => {
                         self.visit_place(
                             place,
                             PlaceContext::MutatingUse(MutatingUseContext::Drop),
                             location
                         );
+                        if let Some(async_fut) = async_fut {
+                            self.visit_local(
+                                $(&$mutability)? *async_fut,
+                                PlaceContext::MutatingUse(MutatingUseContext::Borrow),
+                                location
+                            );
+                        }
                     }
 
                     TerminatorKind::Call {
diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs
index a7ac3442898..546791135ba 100644
--- a/compiler/rustc_middle/src/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/query/on_disk_cache.rs
@@ -645,34 +645,29 @@ impl<'a, 'tcx> SpanDecoder for CacheDecoder<'a, 'tcx> {
         let parent = Option::<LocalDefId>::decode(self);
         let tag: u8 = Decodable::decode(self);
 
-        if tag == TAG_PARTIAL_SPAN {
-            return Span::new(BytePos(0), BytePos(0), ctxt, parent);
-        } else if tag == TAG_RELATIVE_SPAN {
-            let dlo = u32::decode(self);
-            let dto = u32::decode(self);
-
-            let enclosing = self.tcx.source_span_untracked(parent.unwrap()).data_untracked();
-            let span = Span::new(
-                enclosing.lo + BytePos::from_u32(dlo),
-                enclosing.lo + BytePos::from_u32(dto),
-                ctxt,
-                parent,
-            );
-
-            return span;
-        } else {
-            debug_assert_eq!(tag, TAG_FULL_SPAN);
-        }
-
-        let file_lo_index = SourceFileIndex::decode(self);
-        let line_lo = usize::decode(self);
-        let col_lo = RelativeBytePos::decode(self);
-        let len = BytePos::decode(self);
-
-        let file_lo = self.file_index_to_file(file_lo_index);
-        let lo = file_lo.lines()[line_lo - 1] + col_lo;
-        let lo = file_lo.absolute_position(lo);
-        let hi = lo + len;
+        let (lo, hi) = match tag {
+            TAG_PARTIAL_SPAN => (BytePos(0), BytePos(0)),
+            TAG_RELATIVE_SPAN => {
+                let dlo = u32::decode(self);
+                let dto = u32::decode(self);
+
+                let enclosing = self.tcx.source_span_untracked(parent.unwrap()).data_untracked();
+                (enclosing.lo + BytePos::from_u32(dlo), enclosing.lo + BytePos::from_u32(dto))
+            }
+            TAG_FULL_SPAN => {
+                let file_lo_index = SourceFileIndex::decode(self);
+                let line_lo = usize::decode(self);
+                let col_lo = RelativeBytePos::decode(self);
+                let len = BytePos::decode(self);
+
+                let file_lo = self.file_index_to_file(file_lo_index);
+                let lo = file_lo.lines()[line_lo - 1] + col_lo;
+                let lo = file_lo.absolute_position(lo);
+                let hi = lo + len;
+                (lo, hi)
+            }
+            _ => unreachable!(),
+        };
 
         Span::new(lo, hi, ctxt, parent)
     }
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 72474a60566..755fc68d86f 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -821,10 +821,38 @@ impl<'tcx> Ty<'tcx> {
     #[inline]
     pub fn new_coroutine_witness(
         tcx: TyCtxt<'tcx>,
-        id: DefId,
+        def_id: DefId,
         args: GenericArgsRef<'tcx>,
     ) -> Ty<'tcx> {
-        Ty::new(tcx, CoroutineWitness(id, args))
+        if cfg!(debug_assertions) {
+            tcx.debug_assert_args_compatible(tcx.typeck_root_def_id(def_id), args);
+        }
+        Ty::new(tcx, CoroutineWitness(def_id, args))
+    }
+
+    pub fn new_coroutine_witness_for_coroutine(
+        tcx: TyCtxt<'tcx>,
+        def_id: DefId,
+        coroutine_args: GenericArgsRef<'tcx>,
+    ) -> Ty<'tcx> {
+        tcx.debug_assert_args_compatible(def_id, coroutine_args);
+        // HACK: Coroutine witness types are lifetime erased, so they
+        // never reference any lifetime args from the coroutine. We erase
+        // the regions here since we may get into situations where a
+        // coroutine is recursively contained within itself, leading to
+        // witness types that differ by region args. This means that
+        // cycle detection in fulfillment will not kick in, which leads
+        // to unnecessary overflows in async code. See the issue:
+        // <https://github.com/rust-lang/rust/issues/145151>.
+        let args =
+            ty::GenericArgs::for_item(tcx, tcx.typeck_root_def_id(def_id), |def, _| {
+                match def.kind {
+                    ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
+                    ty::GenericParamDefKind::Type { .. }
+                    | ty::GenericParamDefKind::Const { .. } => coroutine_args[def.index as usize],
+                }
+            });
+        Ty::new_coroutine_witness(tcx, def_id, args)
     }
 
     // misc
@@ -985,6 +1013,14 @@ impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> {
         Ty::new_coroutine_witness(interner, def_id, args)
     }
 
+    fn new_coroutine_witness_for_coroutine(
+        interner: TyCtxt<'tcx>,
+        def_id: DefId,
+        coroutine_args: ty::GenericArgsRef<'tcx>,
+    ) -> Self {
+        Ty::new_coroutine_witness_for_coroutine(interner, def_id, coroutine_args)
+    }
+
     fn new_ptr(interner: TyCtxt<'tcx>, ty: Self, mutbl: hir::Mutability) -> Self {
         Ty::new_ptr(interner, ty, mutbl)
     }
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
index faa86734d08..d25e74e7335 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
@@ -75,17 +75,10 @@ where
             Ok(ty::Binder::dummy(vec![args.as_coroutine_closure().tupled_upvars_ty()]))
         }
 
-        ty::Coroutine(def_id, args) => {
-            let coroutine_args = args.as_coroutine();
-            Ok(ty::Binder::dummy(vec![
-                coroutine_args.tupled_upvars_ty(),
-                Ty::new_coroutine_witness(
-                    ecx.cx(),
-                    def_id,
-                    ecx.cx().mk_args(coroutine_args.parent_args().as_slice()),
-                ),
-            ]))
-        }
+        ty::Coroutine(def_id, args) => Ok(ty::Binder::dummy(vec![
+            args.as_coroutine().tupled_upvars_ty(),
+            Ty::new_coroutine_witness_for_coroutine(ecx.cx(), def_id, args),
+        ])),
 
         ty::CoroutineWitness(def_id, args) => Ok(ecx
             .cx()
@@ -251,14 +244,9 @@ where
             Movability::Static => Err(NoSolution),
             Movability::Movable => {
                 if ecx.cx().features().coroutine_clone() {
-                    let coroutine = args.as_coroutine();
                     Ok(ty::Binder::dummy(vec![
-                        coroutine.tupled_upvars_ty(),
-                        Ty::new_coroutine_witness(
-                            ecx.cx(),
-                            def_id,
-                            ecx.cx().mk_args(coroutine.parent_args().as_slice()),
-                        ),
+                        args.as_coroutine().tupled_upvars_ty(),
+                        Ty::new_coroutine_witness_for_coroutine(ecx.cx(), def_id, args),
                     ]))
                 } else {
                     Err(NoSolution)
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index 04ede365a21..891ecab041a 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -6,8 +6,8 @@ use rustc_type_ir::inherent::*;
 use rustc_type_ir::lang_items::TraitSolverLangItem;
 use rustc_type_ir::solve::{CanonicalResponse, SizedTraitKind};
 use rustc_type_ir::{
-    self as ty, Interner, Movability, TraitPredicate, TraitRef, TypeVisitableExt as _, TypingMode,
-    Upcast as _, elaborate,
+    self as ty, Interner, Movability, PredicatePolarity, TraitPredicate, TraitRef,
+    TypeVisitableExt as _, TypingMode, Upcast as _, elaborate,
 };
 use tracing::{debug, instrument, trace};
 
@@ -133,19 +133,26 @@ where
             cx: I,
             clause_def_id: I::DefId,
             goal_def_id: I::DefId,
+            polarity: PredicatePolarity,
         ) -> bool {
             clause_def_id == goal_def_id
             // PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so
             // check for a `MetaSized` supertrait being matched against a `Sized` assumption.
             //
             // `PointeeSized` bounds are syntactic sugar for a lack of bounds so don't need this.
-                || (cx.is_lang_item(clause_def_id, TraitSolverLangItem::Sized)
+                || (polarity == PredicatePolarity::Positive
+                    && cx.is_lang_item(clause_def_id, TraitSolverLangItem::Sized)
                     && cx.is_lang_item(goal_def_id, TraitSolverLangItem::MetaSized))
         }
 
         if let Some(trait_clause) = assumption.as_trait_clause()
             && trait_clause.polarity() == goal.predicate.polarity
-            && trait_def_id_matches(ecx.cx(), trait_clause.def_id(), goal.predicate.def_id())
+            && trait_def_id_matches(
+                ecx.cx(),
+                trait_clause.def_id(),
+                goal.predicate.def_id(),
+                goal.predicate.polarity,
+            )
             && DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
                 goal.predicate.trait_ref.args,
                 trait_clause.skip_binder().trait_ref.args,
@@ -168,6 +175,8 @@ where
         // PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so
         // check for a `Sized` subtrait when looking for `MetaSized`. `PointeeSized` bounds
         // are syntactic sugar for a lack of bounds so don't need this.
+        // We don't need to check polarity, `fast_reject_assumption` already rejected non-`Positive`
+        // polarity `Sized` assumptions as matching non-`Positive` `MetaSized` goals.
         if ecx.cx().is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::MetaSized)
             && ecx.cx().is_lang_item(trait_clause.def_id(), TraitSolverLangItem::Sized)
         {
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index 9e0075c21b9..a107a682184 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -748,9 +748,6 @@ parse_parentheses_with_struct_fields = invalid `struct` delimiters or `fn` call
     .suggestion_braces_for_struct = if `{$type}` is a struct, use braces as delimiters
     .suggestion_no_fields_for_fn = if `{$type}` is a function, use the arguments directly
 
-parse_parenthesized_lifetime = parenthesized lifetime bounds are not supported
-parse_parenthesized_lifetime_suggestion = remove the parentheses
-
 parse_path_double_colon = path separator must be a double colon
     .suggestion = use a double colon instead
 
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index a105dd1909e..2c046329e33 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -3163,27 +3163,6 @@ pub(crate) struct ModifierLifetime {
     pub modifier: &'static str,
 }
 
-#[derive(Subdiagnostic)]
-#[multipart_suggestion(
-    parse_parenthesized_lifetime_suggestion,
-    applicability = "machine-applicable"
-)]
-pub(crate) struct RemoveParens {
-    #[suggestion_part(code = "")]
-    pub lo: Span,
-    #[suggestion_part(code = "")]
-    pub hi: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parse_parenthesized_lifetime)]
-pub(crate) struct ParenthesizedLifetime {
-    #[primary_span]
-    pub span: Span,
-    #[subdiagnostic]
-    pub sugg: RemoveParens,
-}
-
 #[derive(Diagnostic)]
 #[diag(parse_underscore_literal_suffix)]
 pub(crate) struct UnderscoreLiteralSuffix {
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index d0604f76317..ea8cd3754a0 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2397,12 +2397,12 @@ impl<'a> Parser<'a> {
         let before = self.prev_token;
         let binder = if self.check_keyword(exp!(For)) {
             let lo = self.token.span;
-            let (lifetime_defs, _) = self.parse_late_bound_lifetime_defs()?;
+            let (bound_vars, _) = self.parse_higher_ranked_binder()?;
             let span = lo.to(self.prev_token.span);
 
             self.psess.gated_spans.gate(sym::closure_lifetime_binder, span);
 
-            ClosureBinder::For { span, generic_params: lifetime_defs }
+            ClosureBinder::For { span, generic_params: bound_vars }
         } else {
             ClosureBinder::NotPresent
         };
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index 4a8530a2b38..eb684c3a62f 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -172,8 +172,11 @@ impl<'a> Parser<'a> {
         })
     }
 
-    /// Parses a (possibly empty) list of lifetime and type parameters, possibly including
-    /// a trailing comma and erroneous trailing attributes.
+    /// Parse a (possibly empty) list of generic (lifetime, type, const) parameters.
+    ///
+    /// ```ebnf
+    /// GenericParams = (GenericParam ("," GenericParam)* ","?)?
+    /// ```
     pub(super) fn parse_generic_params(&mut self) -> PResult<'a, ThinVec<ast::GenericParam>> {
         let mut params = ThinVec::new();
         let mut done = false;
@@ -520,7 +523,7 @@ impl<'a> Parser<'a> {
         // * `for<'a> Trait1<'a>: Trait2<'a /* ok */>`
         // * `(for<'a> Trait1<'a>): Trait2<'a /* not ok */>`
         // * `for<'a> for<'b> Trait1<'a, 'b>: Trait2<'a /* ok */, 'b /* not ok */>`
-        let (lifetime_defs, _) = self.parse_late_bound_lifetime_defs()?;
+        let (bound_vars, _) = self.parse_higher_ranked_binder()?;
 
         // Parse type with mandatory colon and (possibly empty) bounds,
         // or with mandatory equality sign and the second type.
@@ -528,7 +531,7 @@ impl<'a> Parser<'a> {
         if self.eat(exp!(Colon)) {
             let bounds = self.parse_generic_bounds()?;
             Ok(ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate {
-                bound_generic_params: lifetime_defs,
+                bound_generic_params: bound_vars,
                 bounded_ty: ty,
                 bounds,
             }))
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 290f0a440af..899a43955ab 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -308,11 +308,11 @@ impl<'a> Parser<'a> {
             // Function pointer type or bound list (trait object type) starting with a poly-trait.
             //   `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
             //   `for<'lt> Trait1<'lt> + Trait2 + 'a`
-            let (lifetime_defs, _) = self.parse_late_bound_lifetime_defs()?;
+            let (bound_vars, _) = self.parse_higher_ranked_binder()?;
             if self.check_fn_front_matter(false, Case::Sensitive) {
                 self.parse_ty_fn_ptr(
                     lo,
-                    lifetime_defs,
+                    bound_vars,
                     Some(self.prev_token.span.shrink_to_lo()),
                     recover_return_sign,
                 )?
@@ -326,7 +326,7 @@ impl<'a> Parser<'a> {
                     let path = self.parse_path(PathStyle::Type)?;
                     let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
                     let kind = self.parse_remaining_bounds_path(
-                        lifetime_defs,
+                        bound_vars,
                         path,
                         lo,
                         parse_plus,
@@ -359,7 +359,7 @@ impl<'a> Parser<'a> {
                     let path = self.parse_path(PathStyle::Type)?;
                     let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
                     self.parse_remaining_bounds_path(
-                        lifetime_defs,
+                        bound_vars,
                         path,
                         lo,
                         parse_plus,
@@ -443,7 +443,7 @@ impl<'a> Parser<'a> {
             let ty = ts.into_iter().next().unwrap();
             let maybe_bounds = allow_plus == AllowPlus::Yes && self.token.is_like_plus();
             match ty.kind {
-                // `(TY_BOUND_NOPAREN) + BOUND + ...`.
+                // `"(" BareTraitBound ")" "+" Bound "+" ...`.
                 TyKind::Path(None, path) if maybe_bounds => self.parse_remaining_bounds_path(
                     ThinVec::new(),
                     path,
@@ -853,10 +853,13 @@ impl<'a> Parser<'a> {
         Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds))
     }
 
-    fn parse_precise_capturing_args(
-        &mut self,
-    ) -> PResult<'a, (ThinVec<PreciseCapturingArg>, Span)> {
-        let lo = self.token.span;
+    /// Parse a use-bound aka precise capturing list.
+    ///
+    /// ```ebnf
+    /// UseBound = "use" "<" (PreciseCapture ("," PreciseCapture)* ","?)? ">"
+    /// PreciseCapture = "Self" | Ident | Lifetime
+    /// ```
+    fn parse_use_bound(&mut self, lo: Span, parens: ast::Parens) -> PResult<'a, GenericBound> {
         self.expect_lt()?;
         let (args, _, _) = self.parse_seq_to_before_tokens(
             &[exp!(Gt)],
@@ -882,7 +885,13 @@ impl<'a> Parser<'a> {
             },
         )?;
         self.expect_gt()?;
-        Ok((args, lo.to(self.prev_token.span)))
+
+        if let ast::Parens::Yes = parens {
+            self.expect(exp!(CloseParen))?;
+            self.report_parenthesized_bound(lo, self.prev_token.span, "precise capturing lists");
+        }
+
+        Ok(GenericBound::Use(args, lo.to(self.prev_token.span)))
     }
 
     /// Is a `dyn B0 + ... + Bn` type allowed here?
@@ -940,9 +949,10 @@ impl<'a> Parser<'a> {
         self.parse_generic_bounds_common(AllowPlus::Yes)
     }
 
-    /// Parses bounds of a type parameter `BOUND + BOUND + ...`, possibly with trailing `+`.
+    /// Parse generic bounds.
     ///
-    /// See `parse_generic_bound` for the `BOUND` grammar.
+    /// Only if `allow_plus` this parses a `+`-separated list of bounds (trailing `+` is admitted).
+    /// Otherwise, this only parses a single bound or none.
     fn parse_generic_bounds_common(&mut self, allow_plus: AllowPlus) -> PResult<'a, GenericBounds> {
         let mut bounds = Vec::new();
 
@@ -988,48 +998,56 @@ impl<'a> Parser<'a> {
             || self.check_keyword(exp!(Use))
     }
 
-    /// Parses a bound according to the grammar:
+    /// Parse a bound.
+    ///
     /// ```ebnf
-    /// BOUND = TY_BOUND | LT_BOUND
+    /// Bound = LifetimeBound | UseBound | TraitBound
     /// ```
     fn parse_generic_bound(&mut self) -> PResult<'a, GenericBound> {
-        let lo = self.token.span;
         let leading_token = self.prev_token;
+        let lo = self.token.span;
+
+        // We only admit parenthesized *trait* bounds. However, we want to gracefully recover from
+        // other kinds of parenthesized bounds, so parse the opening parenthesis *here*.
+        //
+        // In the future we might want to lift this syntactic restriction and
+        // introduce "`GenericBound::Paren(Box<GenericBound>)`".
         let parens = if self.eat(exp!(OpenParen)) { ast::Parens::Yes } else { ast::Parens::No };
 
-        let bound = if self.token.is_lifetime() {
-            self.parse_generic_lt_bound(lo, parens)?
+        if self.token.is_lifetime() {
+            self.parse_lifetime_bound(lo, parens)
         } else if self.eat_keyword(exp!(Use)) {
-            // parse precise captures, if any. This is `use<'lt, 'lt, P, P>`; a list of
-            // lifetimes and ident params (including SelfUpper). These are validated later
-            // for order, duplication, and whether they actually reference params.
-            let use_span = self.prev_token.span;
-            let (args, args_span) = self.parse_precise_capturing_args()?;
-            GenericBound::Use(args, use_span.to(args_span))
+            self.parse_use_bound(lo, parens)
         } else {
-            self.parse_generic_ty_bound(lo, parens, &leading_token)?
-        };
-
-        Ok(bound)
+            self.parse_trait_bound(lo, parens, &leading_token)
+        }
     }
 
-    /// Parses a lifetime ("outlives") bound, e.g. `'a`, according to:
+    /// Parse a lifetime-bound aka outlives-bound.
+    ///
     /// ```ebnf
-    /// LT_BOUND = LIFETIME
+    /// LifetimeBound = Lifetime
     /// ```
-    fn parse_generic_lt_bound(
-        &mut self,
-        lo: Span,
-        parens: ast::Parens,
-    ) -> PResult<'a, GenericBound> {
+    fn parse_lifetime_bound(&mut self, lo: Span, parens: ast::Parens) -> PResult<'a, GenericBound> {
         let lt = self.expect_lifetime();
-        let bound = GenericBound::Outlives(lt);
+
         if let ast::Parens::Yes = parens {
-            // FIXME(Centril): Consider not erroring here and accepting `('lt)` instead,
-            // possibly introducing `GenericBound::Paren(Box<GenericBound>)`?
-            self.recover_paren_lifetime(lo)?;
+            self.expect(exp!(CloseParen))?;
+            self.report_parenthesized_bound(lo, self.prev_token.span, "lifetime bounds");
         }
-        Ok(bound)
+
+        Ok(GenericBound::Outlives(lt))
+    }
+
+    fn report_parenthesized_bound(&self, lo: Span, hi: Span, kind: &str) -> ErrorGuaranteed {
+        let mut diag =
+            self.dcx().struct_span_err(lo.to(hi), format!("{kind} may not be parenthesized"));
+        diag.multipart_suggestion(
+            "remove the parentheses",
+            vec![(lo, String::new()), (hi, String::new())],
+            Applicability::MachineApplicable,
+        );
+        diag.emit()
     }
 
     /// Emits an error if any trait bound modifiers were present.
@@ -1074,27 +1092,17 @@ impl<'a> Parser<'a> {
         unreachable!("lifetime bound intercepted in `parse_generic_ty_bound` but no modifiers?")
     }
 
-    /// Recover on `('lifetime)` with `(` already eaten.
-    fn recover_paren_lifetime(&mut self, lo: Span) -> PResult<'a, ()> {
-        self.expect(exp!(CloseParen))?;
-        let span = lo.to(self.prev_token.span);
-        let sugg = errors::RemoveParens { lo, hi: self.prev_token.span };
-
-        self.dcx().emit_err(errors::ParenthesizedLifetime { span, sugg });
-        Ok(())
-    }
-
     /// Parses the modifiers that may precede a trait in a bound, e.g. `?Trait` or `[const] Trait`.
     ///
     /// If no modifiers are present, this does not consume any tokens.
     ///
     /// ```ebnf
-    /// CONSTNESS = [["["] "const" ["]"]]
-    /// ASYNCNESS = ["async"]
-    /// POLARITY = ["?" | "!"]
+    /// Constness = ("const" | "[" "const" "]")?
+    /// Asyncness = "async"?
+    /// Polarity = ("?" | "!")?
     /// ```
     ///
-    /// See `parse_generic_ty_bound` for the complete grammar of trait bound modifiers.
+    /// See `parse_trait_bound` for more context.
     fn parse_trait_bound_modifiers(&mut self) -> PResult<'a, TraitBoundModifiers> {
         let modifier_lo = self.token.span;
         let constness = self.parse_bound_constness()?;
@@ -1187,20 +1195,21 @@ impl<'a> Parser<'a> {
         })
     }
 
-    /// Parses a type bound according to:
+    /// Parse a trait bound.
+    ///
     /// ```ebnf
-    /// TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
-    /// TY_BOUND_NOPAREN = [for<GENERIC_PARAMS> CONSTNESS ASYNCNESS | POLARITY] SIMPLE_PATH
+    /// TraitBound = BareTraitBound | "(" BareTraitBound ")"
+    /// BareTraitBound =
+    ///     (HigherRankedBinder Constness Asyncness | Polarity)
+    ///     TypePath
     /// ```
-    ///
-    /// For example, this grammar accepts `for<'a: 'b> [const] ?m::Trait<'a>`.
-    fn parse_generic_ty_bound(
+    fn parse_trait_bound(
         &mut self,
         lo: Span,
         parens: ast::Parens,
         leading_token: &Token,
     ) -> PResult<'a, GenericBound> {
-        let (mut lifetime_defs, binder_span) = self.parse_late_bound_lifetime_defs()?;
+        let (mut bound_vars, binder_span) = self.parse_higher_ranked_binder()?;
 
         let modifiers_lo = self.token.span;
         let modifiers = self.parse_trait_bound_modifiers()?;
@@ -1223,11 +1232,11 @@ impl<'a> Parser<'a> {
         // e.g. `T: for<'a> 'a` or `T: [const] 'a`.
         if self.token.is_lifetime() {
             let _: ErrorGuaranteed = self.error_lt_bound_with_modifiers(modifiers, binder_span);
-            return self.parse_generic_lt_bound(lo, parens);
+            return self.parse_lifetime_bound(lo, parens);
         }
 
-        if let (more_lifetime_defs, Some(binder_span)) = self.parse_late_bound_lifetime_defs()? {
-            lifetime_defs.extend(more_lifetime_defs);
+        if let (more_bound_vars, Some(binder_span)) = self.parse_higher_ranked_binder()? {
+            bound_vars.extend(more_bound_vars);
             self.dcx().emit_err(errors::BinderBeforeModifiers { binder_span, modifiers_span });
         }
 
@@ -1287,7 +1296,7 @@ impl<'a> Parser<'a> {
         };
 
         if self.may_recover() && self.token == TokenKind::OpenParen {
-            self.recover_fn_trait_with_lifetime_params(&mut path, &mut lifetime_defs)?;
+            self.recover_fn_trait_with_lifetime_params(&mut path, &mut bound_vars)?;
         }
 
         if let ast::Parens::Yes = parens {
@@ -1310,7 +1319,7 @@ impl<'a> Parser<'a> {
         }
 
         let poly_trait =
-            PolyTraitRef::new(lifetime_defs, path, modifiers, lo.to(self.prev_token.span), parens);
+            PolyTraitRef::new(bound_vars, path, modifiers, lo.to(self.prev_token.span), parens);
         Ok(GenericBound::Trait(poly_trait))
     }
 
@@ -1349,8 +1358,12 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Optionally parses `for<$generic_params>`.
-    pub(super) fn parse_late_bound_lifetime_defs(
+    /// Parse an optional higher-ranked binder.
+    ///
+    /// ```ebnf
+    /// HigherRankedBinder = ("for" "<" GenericParams ">")?
+    /// ```
+    pub(super) fn parse_higher_ranked_binder(
         &mut self,
     ) -> PResult<'a, (ThinVec<GenericParam>, Option<Span>)> {
         if self.eat_keyword(exp!(For)) {
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 03096f205c6..00a41e31a02 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -432,10 +432,6 @@ passes_must_not_suspend =
     `must_not_suspend` attribute should be applied to a struct, enum, union, or trait
     .label = is not a struct, enum, union, or trait
 
-passes_must_use_no_effect =
-    `#[must_use]` has no effect when applied to {$target}
-    .suggestion = remove the attribute
-
 passes_no_link =
     attribute should be applied to an `extern crate` item
     .label = not an `extern crate` item
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index c1a212d7ab5..70eae82392c 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -194,9 +194,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => {
                     self.check_may_dangle(hir_id, *attr_span)
                 }
-                Attribute::Parsed(AttributeKind::MustUse { span, .. }) => {
-                    self.check_must_use(hir_id, *span, target)
-                }
                 &Attribute::Parsed(AttributeKind::CustomMir(dialect, phase, attr_span)) => {
                     self.check_custom_mir(dialect, phase, attr_span)
                 }
@@ -249,7 +246,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     | AttributeKind::Coverage (..)
                     | AttributeKind::ShouldPanic { .. }
                     | AttributeKind::Coroutine(..)
-                    | AttributeKind::Linkage(..),
+                    | AttributeKind::Linkage(..)
+                    | AttributeKind::MustUse { .. },
                 ) => { /* do nothing  */ }
                 Attribute::Unparsed(attr_item) => {
                     style = Some(attr_item.style);
@@ -1263,41 +1261,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    /// Warns against some misuses of `#[must_use]`
-    fn check_must_use(&self, hir_id: HirId, attr_span: Span, target: Target) {
-        if matches!(
-            target,
-            Target::Fn
-                | Target::Enum
-                | Target::Struct
-                | Target::Union
-                | Target::Method(MethodKind::Trait { body: false } | MethodKind::Inherent)
-                | Target::ForeignFn
-                // `impl Trait` in return position can trip
-                // `unused_must_use` if `Trait` is marked as
-                // `#[must_use]`
-                | Target::Trait
-        ) {
-            return;
-        }
-
-        // `#[must_use]` can be applied to a trait method definition with a default body
-        if let Target::Method(MethodKind::Trait { body: true }) = target
-            && let parent_def_id = self.tcx.hir_get_parent_item(hir_id).def_id
-            && let containing_item = self.tcx.hir_expect_item(parent_def_id)
-            && let hir::ItemKind::Trait(..) = containing_item.kind
-        {
-            return;
-        }
-
-        self.tcx.emit_node_span_lint(
-            UNUSED_ATTRIBUTES,
-            hir_id,
-            attr_span,
-            errors::MustUseNoEffect { target: target.plural_name(), attr_span },
-        );
-    }
-
     /// Checks if `#[must_not_suspend]` is applied to a struct, enum, union, or trait.
     fn check_must_not_suspend(&self, attr: &Attribute, span: Span, target: Target) {
         match target {
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index ab46ac2dd8b..4fec6b0798a 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -358,14 +358,6 @@ pub(crate) struct BothFfiConstAndPure {
     pub attr_span: Span,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(passes_must_use_no_effect)]
-pub(crate) struct MustUseNoEffect {
-    pub target: &'static str,
-    #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
-    pub attr_span: Span,
-}
-
 #[derive(Diagnostic)]
 #[diag(passes_must_not_suspend)]
 pub(crate) struct MustNotSuspend {
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index c0a46e3b16b..2063c46124c 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -781,7 +781,10 @@ impl<'ra> std::ops::Deref for Module<'ra> {
 
 impl<'ra> fmt::Debug for Module<'ra> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{:?}", self.res())
+        match self.kind {
+            ModuleKind::Block => write!(f, "block"),
+            ModuleKind::Def(..) => write!(f, "{:?}", self.res()),
+        }
     }
 }
 
diff --git a/compiler/rustc_span/src/caching_source_map_view.rs b/compiler/rustc_span/src/caching_source_map_view.rs
index a887b50ec1e..41cfaa3ee34 100644
--- a/compiler/rustc_span/src/caching_source_map_view.rs
+++ b/compiler/rustc_span/src/caching_source_map_view.rs
@@ -123,27 +123,25 @@ impl<'sm> CachingSourceMapView<'sm> {
 
         if lo_cache_idx != -1 && hi_cache_idx != -1 {
             // Cache hit for span lo and hi. Check if they belong to the same file.
-            let result = {
-                let lo = &self.line_cache[lo_cache_idx as usize];
-                let hi = &self.line_cache[hi_cache_idx as usize];
+            let lo_file_index = self.line_cache[lo_cache_idx as usize].file_index;
+            let hi_file_index = self.line_cache[hi_cache_idx as usize].file_index;
 
-                if lo.file_index != hi.file_index {
-                    return None;
-                }
-
-                (
-                    lo.file.stable_id,
-                    lo.line_number,
-                    span_data.lo - lo.line.start,
-                    hi.line_number,
-                    span_data.hi - hi.line.start,
-                )
-            };
+            if lo_file_index != hi_file_index {
+                return None;
+            }
 
             self.line_cache[lo_cache_idx as usize].touch(self.time_stamp);
             self.line_cache[hi_cache_idx as usize].touch(self.time_stamp);
 
-            return Some(result);
+            let lo = &self.line_cache[lo_cache_idx as usize];
+            let hi = &self.line_cache[hi_cache_idx as usize];
+            return Some((
+                lo.file.stable_id,
+                lo.line_number,
+                span_data.lo - lo.line.start,
+                hi.line_number,
+                span_data.hi - hi.line.start,
+            ));
         }
 
         // No cache hit or cache hit for only one of span lo and hi.
diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs
index f3c96f64190..d97ee956525 100644
--- a/compiler/rustc_symbol_mangling/src/lib.rs
+++ b/compiler/rustc_symbol_mangling/src/lib.rs
@@ -193,29 +193,20 @@ fn compute_symbol_name<'tcx>(
         // defining crate.
         // Weak lang items automatically get #[rustc_std_internal_symbol]
         // applied by the code computing the CodegenFnAttrs.
-        // We are mangling all #[rustc_std_internal_symbol] items that don't
-        // also have #[no_mangle] as a combination of the rustc version and the
-        // unmangled linkage name. This is to ensure that if we link against a
-        // staticlib compiled by a different rustc version, we don't get symbol
-        // conflicts or even UB due to a different implementation/ABI. Rust
-        // staticlibs currently export all symbols, including those that are
-        // hidden in cdylibs.
+        // We are mangling all #[rustc_std_internal_symbol] items as a
+        // combination of the rustc version and the unmangled linkage name.
+        // This is to ensure that if we link against a staticlib compiled by a
+        // different rustc version, we don't get symbol conflicts or even UB
+        // due to a different implementation/ABI. Rust staticlibs currently
+        // export all symbols, including those that are hidden in cdylibs.
         // We are using the v0 symbol mangling scheme here as we need to be
         // consistent across all crates and in some contexts the legacy symbol
         // mangling scheme can't be used. For example both the GCC backend and
         // Rust-for-Linux don't support some of the characters used by the
         // legacy symbol mangling scheme.
-        let name = if tcx.is_foreign_item(def_id) {
-            if let Some(name) = attrs.link_name { name } else { tcx.item_name(def_id) }
-        } else {
-            if let Some(name) = attrs.export_name { name } else { tcx.item_name(def_id) }
-        };
+        let name = if let Some(name) = attrs.symbol_name { name } else { tcx.item_name(def_id) };
 
-        if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
-            return name.to_string();
-        } else {
-            return v0::mangle_internal_symbol(tcx, name.as_str());
-        }
+        return v0::mangle_internal_symbol(tcx, name.as_str());
     }
 
     let wasm_import_module_exception_force_mangling = {
@@ -240,23 +231,16 @@ fn compute_symbol_name<'tcx>(
             && tcx.wasm_import_module_map(LOCAL_CRATE).contains_key(&def_id.into())
     };
 
-    if let Some(name) = attrs.link_name
-        && !wasm_import_module_exception_force_mangling
-    {
-        // Use provided name
-        return name.to_string();
-    }
-
-    if let Some(name) = attrs.export_name {
-        // Use provided name
-        return name.to_string();
-    }
+    if !wasm_import_module_exception_force_mangling {
+        if let Some(name) = attrs.symbol_name {
+            // Use provided name
+            return name.to_string();
+        }
 
-    if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
-        && !wasm_import_module_exception_force_mangling
-    {
-        // Don't mangle
-        return tcx.item_name(def_id).to_string();
+        if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
+            // Don't mangle
+            return tcx.item_name(def_id).to_string();
+        }
     }
 
     // If we're dealing with an instance of a function that's inlined from
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 468c42abf48..1dd31990ab7 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -4,9 +4,9 @@
 
 use std::assert_matches::assert_matches;
 use std::cell::{Cell, RefCell};
+use std::cmp;
 use std::fmt::{self, Display};
 use std::ops::ControlFlow;
-use std::{cmp, iter};
 
 use hir::def::DefKind;
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
@@ -2185,32 +2185,23 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 ty::Binder::dummy(vec![ty])
             }
 
-            ty::Coroutine(coroutine_def_id, args) => {
-                match self.tcx().coroutine_movability(coroutine_def_id) {
-                    hir::Movability::Static => {
-                        unreachable!("tried to assemble `Sized` for static coroutine")
-                    }
-                    hir::Movability::Movable => {
-                        if self.tcx().features().coroutine_clone() {
-                            ty::Binder::dummy(
-                                args.as_coroutine()
-                                    .upvar_tys()
-                                    .iter()
-                                    .chain([Ty::new_coroutine_witness(
-                                        self.tcx(),
-                                        coroutine_def_id,
-                                        self.tcx().mk_args(args.as_coroutine().parent_args()),
-                                    )])
-                                    .collect::<Vec<_>>(),
-                            )
-                        } else {
-                            unreachable!(
-                                "tried to assemble `Sized` for coroutine without enabled feature"
-                            )
-                        }
+            ty::Coroutine(def_id, args) => match self.tcx().coroutine_movability(def_id) {
+                hir::Movability::Static => {
+                    unreachable!("tried to assemble `Clone` for static coroutine")
+                }
+                hir::Movability::Movable => {
+                    if self.tcx().features().coroutine_clone() {
+                        ty::Binder::dummy(vec![
+                            args.as_coroutine().tupled_upvars_ty(),
+                            Ty::new_coroutine_witness_for_coroutine(self.tcx(), def_id, args),
+                        ])
+                    } else {
+                        unreachable!(
+                            "tried to assemble `Clone` for coroutine without enabled feature"
+                        )
                     }
                 }
-            }
+            },
 
             ty::CoroutineWitness(def_id, args) => self
                 .infcx
@@ -2334,25 +2325,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
             ty::Coroutine(def_id, args) => {
                 let ty = self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty());
                 let tcx = self.tcx();
-                let witness = Ty::new_coroutine_witness(
-                    tcx,
-                    def_id,
-                    ty::GenericArgs::for_item(tcx, def_id, |def, _| match def.kind {
-                        // HACK: Coroutine witnesse types are lifetime erased, so they
-                        // never reference any lifetime args from the coroutine. We erase
-                        // the regions here since we may get into situations where a
-                        // coroutine is recursively contained within itself, leading to
-                        // witness types that differ by region args. This means that
-                        // cycle detection in fulfillment will not kick in, which leads
-                        // to unnecessary overflows in async code. See the issue:
-                        // <https://github.com/rust-lang/rust/issues/145151>.
-                        ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
-                        ty::GenericParamDefKind::Type { .. }
-                        | ty::GenericParamDefKind::Const { .. } => args[def.index as usize],
-                    }),
-                );
+                let witness = Ty::new_coroutine_witness_for_coroutine(tcx, def_id, args);
                 ty::Binder::dummy(AutoImplConstituents {
-                    types: [ty].into_iter().chain(iter::once(witness)).collect(),
+                    types: vec![ty, witness],
                     assumptions: vec![],
                 })
             }
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index 83c0969762f..335942d5bcc 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -9,8 +9,8 @@ pub use rustc_infer::traits::util::*;
 use rustc_middle::bug;
 use rustc_middle::ty::fast_reject::DeepRejectCtxt;
 use rustc_middle::ty::{
-    self, PolyTraitPredicate, SizedTraitKind, TraitPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
-    TypeFolder, TypeSuperFoldable, TypeVisitableExt,
+    self, PolyTraitPredicate, PredicatePolarity, SizedTraitKind, TraitPredicate, TraitRef, Ty,
+    TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
 };
 pub use rustc_next_trait_solver::placeholder::BoundVarReplacer;
 use rustc_span::Span;
@@ -427,7 +427,9 @@ pub(crate) fn lazily_elaborate_sizedness_candidate<'tcx>(
         return candidate;
     }
 
-    if obligation.predicate.polarity() != candidate.polarity() {
+    if obligation.predicate.polarity() != PredicatePolarity::Positive
+        || candidate.polarity() != PredicatePolarity::Positive
+    {
         return candidate;
     }
 
diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs
index 1a6c99ce7de..569570b5783 100644
--- a/compiler/rustc_type_ir/src/inherent.rs
+++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -91,6 +91,12 @@ pub trait Ty<I: Interner<Ty = Self>>:
 
     fn new_coroutine_witness(interner: I, def_id: I::DefId, args: I::GenericArgs) -> Self;
 
+    fn new_coroutine_witness_for_coroutine(
+        interner: I,
+        def_id: I::DefId,
+        coroutine_args: I::GenericArgs,
+    ) -> Self;
+
     fn new_ptr(interner: I, ty: Self, mutbl: Mutability) -> Self;
 
     fn new_ref(interner: I, region: I::Region, ty: Self, mutbl: Mutability) -> Self;