about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast/src/util/parser.rs45
-rw-r--r--compiler/rustc_ast_lowering/messages.ftl3
-rw-r--r--compiler/rustc_ast_lowering/src/errors.rs8
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs20
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs14
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs7
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs17
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs8
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/suggest.rs6
-rw-r--r--compiler/rustc_passes/src/dead.rs41
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/manual_utils.rs4
-rw-r--r--tests/run-make/print-native-static-libs/bar.rs6
-rw-r--r--tests/ui/async-await/suggest-missing-await.rs7
-rw-r--r--tests/ui/async-await/suggest-missing-await.stderr14
-rw-r--r--tests/ui/const-generics/cross_crate_complex.rs1
-rw-r--r--tests/ui/generic-associated-types/missing-bounds.fixed4
-rw-r--r--tests/ui/generic-associated-types/missing-bounds.rs4
-rw-r--r--tests/ui/generic-associated-types/missing-bounds.stderr18
-rw-r--r--tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs1
-rw-r--r--tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr10
-rw-r--r--tests/ui/impl-trait/precise-capturing/redundant.normal.stderr20
-rw-r--r--tests/ui/impl-trait/precise-capturing/redundant.rpitit.stderr18
-rw-r--r--tests/ui/impl-trait/precise-capturing/redundant.rs13
-rw-r--r--tests/ui/impl-trait/precise-capturing/redundant.stderr36
-rw-r--r--tests/ui/impl-trait/precise-capturing/rpitit.rs21
-rw-r--r--tests/ui/impl-trait/precise-capturing/rpitit.stderr50
-rw-r--r--tests/ui/impl-trait/precise-capturing/self-capture.rs3
-rw-r--r--tests/ui/impl-trait/precise-capturing/self-capture.stderr10
-rw-r--r--tests/ui/lint/dead-code/unused-trait-with-assoc-ty.rs11
-rw-r--r--tests/ui/lint/dead-code/unused-trait-with-assoc-ty.stderr20
-rw-r--r--tests/ui/pattern/issue-22546.rs2
-rw-r--r--tests/ui/pattern/issue-22546.stderr10
-rw-r--r--tests/ui/regions/account-for-lifetimes-in-closure-suggestion.rs19
-rw-r--r--tests/ui/regions/account-for-lifetimes-in-closure-suggestion.stderr17
-rw-r--r--tests/ui/regions/lifetime-not-long-enough-suggestion-regression-test-124563.rs (renamed from tests/crashes/124563.rs)11
-rw-r--r--tests/ui/regions/lifetime-not-long-enough-suggestion-regression-test-124563.stderr49
-rw-r--r--tests/ui/regions/regions-escape-method.fixed17
-rw-r--r--tests/ui/regions/regions-escape-method.rs1
-rw-r--r--tests/ui/regions/regions-escape-method.stderr7
-rw-r--r--tests/ui/suggestions/missing-impl-trait-block-but-not-ascii.rs13
-rw-r--r--tests/ui/suggestions/missing-impl-trait-block-but-not-ascii.stderr31
46 files changed, 495 insertions, 148 deletions
diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs
index 373c0ebcc5c..ad92bf2cd40 100644
--- a/compiler/rustc_ast/src/util/parser.rs
+++ b/compiler/rustc_ast/src/util/parser.rs
@@ -233,8 +233,7 @@ pub const PREC_JUMP: i8 = -30;
 pub const PREC_RANGE: i8 = -10;
 // The range 2..=14 is reserved for AssocOp binary operator precedences.
 pub const PREC_PREFIX: i8 = 50;
-pub const PREC_POSTFIX: i8 = 60;
-pub const PREC_PAREN: i8 = 99;
+pub const PREC_UNAMBIGUOUS: i8 = 60;
 pub const PREC_FORCE_PAREN: i8 = 100;
 
 #[derive(Debug, Clone, Copy)]
@@ -325,37 +324,35 @@ impl ExprPrecedence {
             | ExprPrecedence::Let
             | ExprPrecedence::Unary => PREC_PREFIX,
 
-            // Unary, postfix
-            ExprPrecedence::Await
+            // Never need parens
+            ExprPrecedence::Array
+            | ExprPrecedence::Await
+            | ExprPrecedence::Block
             | ExprPrecedence::Call
-            | ExprPrecedence::MethodCall
+            | ExprPrecedence::ConstBlock
             | ExprPrecedence::Field
+            | ExprPrecedence::ForLoop
+            | ExprPrecedence::FormatArgs
+            | ExprPrecedence::Gen
+            | ExprPrecedence::If
             | ExprPrecedence::Index
-            | ExprPrecedence::Try
             | ExprPrecedence::InlineAsm
+            | ExprPrecedence::Lit
+            | ExprPrecedence::Loop
             | ExprPrecedence::Mac
-            | ExprPrecedence::FormatArgs
+            | ExprPrecedence::Match
+            | ExprPrecedence::MethodCall
             | ExprPrecedence::OffsetOf
-            | ExprPrecedence::PostfixMatch => PREC_POSTFIX,
-
-            // Never need parens
-            ExprPrecedence::Array
+            | ExprPrecedence::Paren
+            | ExprPrecedence::Path
+            | ExprPrecedence::PostfixMatch
             | ExprPrecedence::Repeat
+            | ExprPrecedence::Struct
+            | ExprPrecedence::Try
+            | ExprPrecedence::TryBlock
             | ExprPrecedence::Tup
-            | ExprPrecedence::Lit
-            | ExprPrecedence::Path
-            | ExprPrecedence::Paren
-            | ExprPrecedence::If
             | ExprPrecedence::While
-            | ExprPrecedence::ForLoop
-            | ExprPrecedence::Loop
-            | ExprPrecedence::Match
-            | ExprPrecedence::ConstBlock
-            | ExprPrecedence::Block
-            | ExprPrecedence::TryBlock
-            | ExprPrecedence::Gen
-            | ExprPrecedence::Struct
-            | ExprPrecedence::Err => PREC_PAREN,
+            | ExprPrecedence::Err => PREC_UNAMBIGUOUS,
         }
     }
 }
diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl
index 52164d6ef16..58f65f1257f 100644
--- a/compiler/rustc_ast_lowering/messages.ftl
+++ b/compiler/rustc_ast_lowering/messages.ftl
@@ -130,6 +130,9 @@ ast_lowering_never_pattern_with_guard =
 
 ast_lowering_no_precise_captures_on_apit = `use<...>` precise capturing syntax not allowed in argument-position `impl Trait`
 
+ast_lowering_no_precise_captures_on_rpitit = `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
+    .note = currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
+
 ast_lowering_previously_used_here = previously used here
 
 ast_lowering_register1 = register `{$reg1_name}`
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index 02744d16b42..3d4b6a1f033 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -425,6 +425,14 @@ pub(crate) struct NoPreciseCapturesOnApit {
 }
 
 #[derive(Diagnostic)]
+#[diag(ast_lowering_no_precise_captures_on_rpitit)]
+#[note]
+pub(crate) struct NoPreciseCapturesOnRpitit {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(ast_lowering_yield_in_closure)]
 pub(crate) struct YieldInClosure {
     #[primary_span]
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index da8682d3d09..0a06304fcec 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1594,6 +1594,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         };
         debug!(?captured_lifetimes_to_duplicate);
 
+        match fn_kind {
+            // Deny `use<>` on RPITIT in trait/trait-impl for now.
+            Some(FnDeclKind::Trait | FnDeclKind::Impl) => {
+                if let Some(span) = bounds.iter().find_map(|bound| match *bound {
+                    ast::GenericBound::Use(_, span) => Some(span),
+                    _ => None,
+                }) {
+                    self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnRpitit { span });
+                }
+            }
+            None
+            | Some(
+                FnDeclKind::Fn
+                | FnDeclKind::Inherent
+                | FnDeclKind::ExternFn
+                | FnDeclKind::Closure
+                | FnDeclKind::Pointer,
+            ) => {}
+        }
+
         self.lower_opaque_inner(
             opaque_ty_node_id,
             origin,
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index 1e117c46b6e..f2f6594e686 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -217,7 +217,7 @@ impl<'a> State<'a> {
     fn print_expr_call(&mut self, func: &ast::Expr, args: &[P<ast::Expr>], fixup: FixupContext) {
         let prec = match func.kind {
             ast::ExprKind::Field(..) => parser::PREC_FORCE_PAREN,
-            _ => parser::PREC_POSTFIX,
+            _ => parser::PREC_UNAMBIGUOUS,
         };
 
         // Independent of parenthesization related to precedence, we must
@@ -257,7 +257,7 @@ impl<'a> State<'a> {
         // boundaries, `$receiver.method()` can be parsed back as a statement
         // containing an expression if and only if `$receiver` can be parsed as
         // a statement containing an expression.
-        self.print_expr_maybe_paren(receiver, parser::PREC_POSTFIX, fixup);
+        self.print_expr_maybe_paren(receiver, parser::PREC_UNAMBIGUOUS, fixup);
 
         self.word(".");
         self.print_ident(segment.ident);
@@ -489,7 +489,7 @@ impl<'a> State<'a> {
                         self.space();
                     }
                     MatchKind::Postfix => {
-                        self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX, fixup);
+                        self.print_expr_maybe_paren(expr, parser::PREC_UNAMBIGUOUS, fixup);
                         self.word_nbsp(".match");
                     }
                 }
@@ -549,7 +549,7 @@ impl<'a> State<'a> {
                 self.print_block_with_attrs(blk, attrs);
             }
             ast::ExprKind::Await(expr, _) => {
-                self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX, fixup);
+                self.print_expr_maybe_paren(expr, parser::PREC_UNAMBIGUOUS, fixup);
                 self.word(".await");
             }
             ast::ExprKind::Assign(lhs, rhs, _) => {
@@ -568,14 +568,14 @@ impl<'a> State<'a> {
                 self.print_expr_maybe_paren(rhs, prec, fixup.subsequent_subexpression());
             }
             ast::ExprKind::Field(expr, ident) => {
-                self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX, fixup);
+                self.print_expr_maybe_paren(expr, parser::PREC_UNAMBIGUOUS, fixup);
                 self.word(".");
                 self.print_ident(*ident);
             }
             ast::ExprKind::Index(expr, index, _) => {
                 self.print_expr_maybe_paren(
                     expr,
-                    parser::PREC_POSTFIX,
+                    parser::PREC_UNAMBIGUOUS,
                     fixup.leftmost_subexpression(),
                 );
                 self.word("[");
@@ -713,7 +713,7 @@ impl<'a> State<'a> {
                 }
             }
             ast::ExprKind::Try(e) => {
-                self.print_expr_maybe_paren(e, parser::PREC_POSTFIX, fixup);
+                self.print_expr_maybe_paren(e, parser::PREC_UNAMBIGUOUS, fixup);
                 self.word("?")
             }
             ast::ExprKind::TryBlock(blk) => {
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 245ce790e49..db78edc45b9 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -1151,7 +1151,9 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
         // Get the arguments for the found method, only specifying that `Self` is the receiver type.
         let Some(possible_rcvr_ty) = typeck_results.node_type_opt(rcvr.hir_id) else { return };
         let args = GenericArgs::for_item(tcx, method_def_id, |param, _| {
-            if param.index == 0 {
+            if let ty::GenericParamDefKind::Lifetime = param.kind {
+                tcx.lifetimes.re_erased.into()
+            } else if param.index == 0 && param.name == kw::SelfUpper {
                 possible_rcvr_ty.into()
             } else if param.index == closure_param.index {
                 closure_ty.into()
@@ -1168,7 +1170,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
             Obligation::misc(tcx, span, self.mir_def_id(), self.param_env, pred)
         }));
 
-        if ocx.select_all_or_error().is_empty() {
+        if ocx.select_all_or_error().is_empty() && count > 0 {
             diag.span_suggestion_verbose(
                 tcx.hir().body(*body).value.peel_blocks().span.shrink_to_lo(),
                 "dereference the return value",
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index c352100b01b..d509e4ce56d 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1490,11 +1490,6 @@ fn print_native_static_libs(
     let mut lib_args: Vec<_> = all_native_libs
         .iter()
         .filter(|l| relevant_lib(sess, l))
-        // Deduplication of successive repeated libraries, see rust-lang/rust#113209
-        //
-        // note: we don't use PartialEq/Eq because NativeLib transitively depends on local
-        // elements like spans, which we don't care about and would make the deduplication impossible
-        .dedup_by(|l1, l2| l1.name == l2.name && l1.kind == l2.kind && l1.verbatim == l2.verbatim)
         .filter_map(|lib| {
             let name = lib.name;
             match lib.kind {
@@ -1521,6 +1516,8 @@ fn print_native_static_libs(
                 | NativeLibKind::RawDylib => None,
             }
         })
+        // deduplication of consecutive repeated libraries, see rust-lang/rust#113209
+        .dedup()
         .collect();
     for path in all_rust_dylibs {
         // FIXME deduplicate with add_dynamic_crate
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 4d1b96d9c1b..8469cbbbc7d 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -211,11 +211,18 @@ fn missing_items_err(
         .collect::<Vec<_>>()
         .join("`, `");
 
-    // `Span` before impl block closing brace.
-    let hi = full_impl_span.hi() - BytePos(1);
-    // Point at the place right before the closing brace of the relevant `impl` to suggest
-    // adding the associated item at the end of its body.
-    let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
+    let sugg_sp = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(full_impl_span)
+        && snippet.ends_with("}")
+    {
+        // `Span` before impl block closing brace.
+        let hi = full_impl_span.hi() - BytePos(1);
+        // Point at the place right before the closing brace of the relevant `impl` to suggest
+        // adding the associated item at the end of its body.
+        full_impl_span.with_lo(hi).with_hi(hi)
+    } else {
+        full_impl_span.shrink_to_hi()
+    };
+
     // Obtain the level of indentation ending in `sugg_sp`.
     let padding =
         tcx.sess.source_map().indentation_before(sugg_sp).unwrap_or_else(|| String::new());
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index b21f1eadfb7..25b0cbdc026 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1120,7 +1120,7 @@ impl<'a> State<'a> {
     fn print_expr_call(&mut self, func: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
         let prec = match func.kind {
             hir::ExprKind::Field(..) => parser::PREC_FORCE_PAREN,
-            _ => parser::PREC_POSTFIX,
+            _ => parser::PREC_UNAMBIGUOUS,
         };
 
         self.print_expr_maybe_paren(func, prec);
@@ -1134,7 +1134,7 @@ impl<'a> State<'a> {
         args: &[hir::Expr<'_>],
     ) {
         let base_args = args;
-        self.print_expr_maybe_paren(receiver, parser::PREC_POSTFIX);
+        self.print_expr_maybe_paren(receiver, parser::PREC_UNAMBIGUOUS);
         self.word(".");
         self.print_ident(segment.ident);
 
@@ -1478,12 +1478,12 @@ impl<'a> State<'a> {
                 self.print_expr_maybe_paren(rhs, prec);
             }
             hir::ExprKind::Field(expr, ident) => {
-                self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
+                self.print_expr_maybe_paren(expr, parser::PREC_UNAMBIGUOUS);
                 self.word(".");
                 self.print_ident(ident);
             }
             hir::ExprKind::Index(expr, index, _) => {
-                self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
+                self.print_expr_maybe_paren(expr, parser::PREC_UNAMBIGUOUS);
                 self.word("[");
                 self.print_expr(index);
                 self.word("]");
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 46c85515575..3b199b7e3c2 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -3,7 +3,7 @@ use super::method::MethodCallee;
 use super::{Expectation, FnCtxt, TupleArgumentsFlag};
 
 use crate::errors;
-use rustc_ast::util::parser::PREC_POSTFIX;
+use rustc_ast::util::parser::PREC_UNAMBIGUOUS;
 use rustc_errors::{Applicability, Diag, ErrorGuaranteed, StashKey};
 use rustc_hir::def::{self, CtorKind, Namespace, Res};
 use rustc_hir::def_id::DefId;
@@ -656,7 +656,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             };
 
             if let Ok(rest_snippet) = rest_snippet {
-                let sugg = if callee_expr.precedence().order() >= PREC_POSTFIX {
+                let sugg = if callee_expr.precedence().order() >= PREC_UNAMBIGUOUS {
                     vec![
                         (up_to_rcvr_span, "".to_string()),
                         (rest_span, format!(".{}({rest_snippet}", segment.ident)),
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 58708510282..92f2d3254bb 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -946,7 +946,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
 
     fn lossy_provenance_ptr2int_lint(&self, fcx: &FnCtxt<'a, 'tcx>, t_c: ty::cast::IntTy) {
         let expr_prec = self.expr.precedence().order();
-        let needs_parens = expr_prec < rustc_ast::util::parser::PREC_POSTFIX;
+        let needs_parens = expr_prec < rustc_ast::util::parser::PREC_UNAMBIGUOUS;
 
         let needs_cast = !matches!(t_c, ty::cast::IntTy::U(ty::UintTy::Usize));
         let cast_span = self.expr_span.shrink_to_hi().to(self.cast_span);
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index b3ebc0621cb..8d380caf916 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -9,7 +9,7 @@ use crate::method::probe::{IsSuggestion, Mode, ProbeScope};
 use core::cmp::min;
 use core::iter;
 use hir::def_id::LocalDefId;
-use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
+use rustc_ast::util::parser::{ExprPrecedence, PREC_UNAMBIGUOUS};
 use rustc_data_structures::packed::Pu128;
 use rustc_errors::{Applicability, Diag, MultiSpan};
 use rustc_hir as hir;
@@ -1329,7 +1329,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         {
             let span = expr.span.find_oldest_ancestor_in_same_ctxt();
 
-            let mut sugg = if expr.precedence().order() >= PREC_POSTFIX {
+            let mut sugg = if expr.precedence().order() >= PREC_UNAMBIGUOUS {
                 vec![(span.shrink_to_hi(), ".into()".to_owned())]
             } else {
                 vec![
@@ -2868,7 +2868,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             "change the type of the numeric literal from `{checked_ty}` to `{expected_ty}`",
         );
 
-        let close_paren = if expr.precedence().order() < PREC_POSTFIX {
+        let close_paren = if expr.precedence().order() < PREC_UNAMBIGUOUS {
             sugg.push((expr.span.shrink_to_lo(), "(".to_string()));
             ")"
         } else {
@@ -2893,7 +2893,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let len = src.trim_end_matches(&checked_ty.to_string()).len();
                 expr.span.with_lo(expr.span.lo() + BytePos(len as u32))
             },
-            if expr.precedence().order() < PREC_POSTFIX {
+            if expr.precedence().order() < PREC_UNAMBIGUOUS {
                 // Readd `)`
                 format!("{expected_ty})")
             } else {
diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
index 74c65e93616..13b145296a7 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
@@ -209,8 +209,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             }
             (Some(ty), _) if self.same_type_modulo_infer(ty, exp_found.found) => match cause.code()
             {
-                ObligationCauseCode::Pattern { span: Some(then_span), .. } => {
-                    Some(ConsiderAddingAwait::FutureSugg { span: then_span.shrink_to_hi() })
+                ObligationCauseCode::Pattern { span: Some(then_span), origin_expr, .. } => {
+                    origin_expr.then_some(ConsiderAddingAwait::FutureSugg {
+                        span: then_span.shrink_to_hi(),
+                    })
                 }
                 ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => {
                     let then_span = self.find_block_span_from_hir_id(*then_id);
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 2c86949685b..bbd586386dd 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -155,7 +155,10 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
 
     fn handle_res(&mut self, res: Res) {
         match res {
-            Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::TyAlias, def_id) => {
+            Res::Def(
+                DefKind::Const | DefKind::AssocConst | DefKind::AssocTy | DefKind::TyAlias,
+                def_id,
+            ) => {
                 self.check_def_id(def_id);
             }
             _ if self.in_pat => {}
@@ -466,7 +469,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
                     intravisit::walk_item(self, item)
                 }
                 hir::ItemKind::ForeignMod { .. } => {}
-                hir::ItemKind::Trait(..) => {
+                hir::ItemKind::Trait(_, _, _, _, trait_item_refs) => {
                     for impl_def_id in self.tcx.all_impls(item.owner_id.to_def_id()) {
                         if let Some(local_def_id) = impl_def_id.as_local()
                             && let ItemKind::Impl(impl_ref) =
@@ -479,7 +482,12 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
                             intravisit::walk_path(self, impl_ref.of_trait.unwrap().path);
                         }
                     }
-
+                    // mark assoc ty live if the trait is live
+                    for trait_item in trait_item_refs {
+                        if let hir::AssocItemKind::Type = trait_item.kind {
+                            self.check_def_id(trait_item.id.owner_id.to_def_id());
+                        }
+                    }
                     intravisit::walk_item(self, item)
                 }
                 _ => intravisit::walk_item(self, item),
@@ -496,9 +504,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
                             && let ItemKind::Impl(impl_ref) =
                                 self.tcx.hir().expect_item(local_impl_id).kind
                         {
-                            if !matches!(trait_item.kind, hir::TraitItemKind::Type(..))
-                                && !ty_ref_to_pub_struct(self.tcx, impl_ref.self_ty)
-                                    .ty_and_all_fields_are_public
+                            if !ty_ref_to_pub_struct(self.tcx, impl_ref.self_ty)
+                                .ty_and_all_fields_are_public
                             {
                                 // skip impl-items of non pure pub ty,
                                 // cause we don't know the ty is constructed or not,
@@ -837,9 +844,8 @@ fn check_item<'tcx>(
                 // for trait impl blocks,
                 // mark the method live if the self_ty is public,
                 // or the method is public and may construct self
-                if of_trait && matches!(tcx.def_kind(local_def_id), DefKind::AssocTy)
-                    || tcx.visibility(local_def_id).is_public()
-                        && (ty_and_all_fields_are_public || may_construct_self)
+                if tcx.visibility(local_def_id).is_public()
+                    && (ty_and_all_fields_are_public || may_construct_self)
                 {
                     // if the impl item is public,
                     // and the ty may be constructed or can be constructed in foreign crates,
@@ -876,10 +882,13 @@ fn check_trait_item(
     worklist: &mut Vec<(LocalDefId, ComesFromAllowExpect)>,
     id: hir::TraitItemId,
 ) {
-    use hir::TraitItemKind::{Const, Fn};
-    if matches!(tcx.def_kind(id.owner_id), DefKind::AssocConst | DefKind::AssocFn) {
+    use hir::TraitItemKind::{Const, Fn, Type};
+    if matches!(
+        tcx.def_kind(id.owner_id),
+        DefKind::AssocConst | DefKind::AssocTy | DefKind::AssocFn
+    ) {
         let trait_item = tcx.hir().trait_item(id);
-        if matches!(trait_item.kind, Const(_, Some(_)) | Fn(..))
+        if matches!(trait_item.kind, Const(_, Some(_)) | Type(_, Some(_)) | Fn(..))
             && let Some(comes_from_allow) =
                 has_allow_dead_code_or_lang_attr(tcx, trait_item.owner_id.def_id)
         {
@@ -921,7 +930,7 @@ fn create_and_seed_worklist(
                     // checks impls, impl-items and pub structs with all public fields later
                     match tcx.def_kind(id) {
                         DefKind::Impl { .. } => false,
-                        DefKind::AssocConst | DefKind::AssocFn => !matches!(tcx.associated_item(id).container, AssocItemContainer::ImplContainer),
+                        DefKind::AssocConst | DefKind::AssocTy | DefKind::AssocFn => !matches!(tcx.associated_item(id).container, AssocItemContainer::ImplContainer),
                         DefKind::Struct => struct_all_fields_are_public(tcx, id.to_def_id()) || has_allow_dead_code_or_lang_attr(tcx, id).is_some(),
                         _ => true
                     })
@@ -1208,6 +1217,7 @@ impl<'tcx> DeadVisitor<'tcx> {
         }
         match self.tcx.def_kind(def_id) {
             DefKind::AssocConst
+            | DefKind::AssocTy
             | DefKind::AssocFn
             | DefKind::Fn
             | DefKind::Static { .. }
@@ -1249,15 +1259,14 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
             || (def_kind == DefKind::Trait && live_symbols.contains(&item.owner_id.def_id))
         {
             for &def_id in tcx.associated_item_def_ids(item.owner_id.def_id) {
-                // We have diagnosed unused assoc consts and fns in traits
+                // We have diagnosed unused assocs in traits
                 if matches!(def_kind, DefKind::Impl { of_trait: true })
-                    && matches!(tcx.def_kind(def_id), DefKind::AssocConst | DefKind::AssocFn)
+                    && matches!(tcx.def_kind(def_id), DefKind::AssocConst | DefKind::AssocTy | DefKind::AssocFn)
                     // skip unused public inherent methods,
                     // cause we have diagnosed unconstructed struct
                     || matches!(def_kind, DefKind::Impl { of_trait: false })
                         && tcx.visibility(def_id).is_public()
                         && ty_ref_to_pub_struct(tcx, tcx.hir().item(item).expect_impl().self_ty).ty_is_public
-                    || def_kind == DefKind::Trait && tcx.def_kind(def_id) == DefKind::AssocTy
                 {
                     continue;
                 }
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index d60320d8282..f451758c335 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -6,7 +6,7 @@ use clippy_utils::{
     expr_use_ctxt, get_parent_expr, is_block_like, is_lint_allowed, path_to_local, DefinedTy, ExprUseNode,
 };
 use core::mem;
-use rustc_ast::util::parser::{PREC_POSTFIX, PREC_PREFIX};
+use rustc_ast::util::parser::{PREC_UNAMBIGUOUS, PREC_PREFIX};
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_ty, Visitor};
@@ -1013,7 +1013,7 @@ fn report<'tcx>(
                     let (precedence, calls_field) = match cx.tcx.parent_hir_node(data.first_expr.hir_id) {
                         Node::Expr(e) => match e.kind {
                             ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => (0, false),
-                            ExprKind::Call(..) => (PREC_POSTFIX, matches!(expr.kind, ExprKind::Field(..))),
+                            ExprKind::Call(..) => (PREC_UNAMBIGUOUS, matches!(expr.kind, ExprKind::Field(..))),
                             _ => (e.precedence().order(), false),
                         },
                         _ => (0, false),
@@ -1160,7 +1160,7 @@ impl<'tcx> Dereferencing<'tcx> {
                         },
                         Some(parent) if !parent.span.from_expansion() => {
                             // Double reference might be needed at this point.
-                            if parent.precedence().order() == PREC_POSTFIX {
+                            if parent.precedence().order() == PREC_UNAMBIGUOUS {
                                 // Parentheses would be needed here, don't lint.
                                 *outer_pat = None;
                             } else {
diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs
index 183caab56c5..be80aebed6d 100644
--- a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs
@@ -7,7 +7,7 @@ use clippy_utils::{
     can_move_expr_to_closure, is_else_clause, is_lint_allowed, is_res_lang_ctor, path_res, path_to_local_id,
     peel_blocks, peel_hir_expr_refs, peel_hir_expr_while, CaptureKind,
 };
-use rustc_ast::util::parser::PREC_POSTFIX;
+use rustc_ast::util::parser::PREC_UNAMBIGUOUS;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::LangItem::{OptionNone, OptionSome};
@@ -117,7 +117,7 @@ where
     // it's being passed by value.
     let scrutinee = peel_hir_expr_refs(scrutinee).0;
     let (scrutinee_str, _) = snippet_with_context(cx, scrutinee.span, expr_ctxt, "..", &mut app);
-    let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence().order() < PREC_POSTFIX {
+    let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence().order() < PREC_UNAMBIGUOUS {
         format!("({scrutinee_str})")
     } else {
         scrutinee_str.into()
diff --git a/tests/run-make/print-native-static-libs/bar.rs b/tests/run-make/print-native-static-libs/bar.rs
index cd9c1c453e5..74c76da6938 100644
--- a/tests/run-make/print-native-static-libs/bar.rs
+++ b/tests/run-make/print-native-static-libs/bar.rs
@@ -17,3 +17,9 @@ extern "C" {
 extern "C" {
     fn g_free2(p: *mut ());
 }
+
+#[cfg(windows)]
+#[link(name = "glib-2.0", kind = "raw-dylib")]
+extern "C" {
+    fn g_free3(p: *mut ());
+}
diff --git a/tests/ui/async-await/suggest-missing-await.rs b/tests/ui/async-await/suggest-missing-await.rs
index 96996af0bd2..0bd67cec335 100644
--- a/tests/ui/async-await/suggest-missing-await.rs
+++ b/tests/ui/async-await/suggest-missing-await.rs
@@ -71,4 +71,11 @@ async fn suggest_await_in_generic_pattern() {
     }
 }
 
+// Issue #126903
+async fn do_async() {}
+fn dont_suggest_awaiting_closure_patterns() {
+    Some(do_async()).map(|()| {});
+    //~^ ERROR mismatched types [E0308]
+}
+
 fn main() {}
diff --git a/tests/ui/async-await/suggest-missing-await.stderr b/tests/ui/async-await/suggest-missing-await.stderr
index f0ec34a6a55..f9db86ea40a 100644
--- a/tests/ui/async-await/suggest-missing-await.stderr
+++ b/tests/ui/async-await/suggest-missing-await.stderr
@@ -133,6 +133,18 @@ help: consider `await`ing on the `Future`
 LL |     match dummy_result().await {
    |                         ++++++
 
-error: aborting due to 7 previous errors
+error[E0308]: mismatched types
+  --> $DIR/suggest-missing-await.rs:77:27
+   |
+LL |     Some(do_async()).map(|()| {});
+   |                           ^^
+   |                           |
+   |                           expected future, found `()`
+   |                           expected due to this
+   |
+   = note: expected opaque type `impl Future<Output = ()>`
+                found unit type `()`
+
+error: aborting due to 8 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/cross_crate_complex.rs b/tests/ui/const-generics/cross_crate_complex.rs
index d13b69aa0cf..b44d889f5e9 100644
--- a/tests/ui/const-generics/cross_crate_complex.rs
+++ b/tests/ui/const-generics/cross_crate_complex.rs
@@ -11,6 +11,7 @@ async fn foo() {
     async_in_foo(async_out_foo::<4>().await).await;
 }
 
+#[allow(dead_code)]
 struct Faz<const N: usize>;
 
 impl<const N: usize> Foo<N> for Faz<N> {}
diff --git a/tests/ui/generic-associated-types/missing-bounds.fixed b/tests/ui/generic-associated-types/missing-bounds.fixed
index 703d3c1e0fb..ff69016d862 100644
--- a/tests/ui/generic-associated-types/missing-bounds.fixed
+++ b/tests/ui/generic-associated-types/missing-bounds.fixed
@@ -2,6 +2,7 @@
 
 use std::ops::Add;
 
+#[allow(dead_code)]
 struct A<B>(B);
 
 impl<B> Add for A<B> where B: Add<Output = B> {
@@ -12,6 +13,7 @@ impl<B> Add for A<B> where B: Add<Output = B> {
     }
 }
 
+#[allow(dead_code)]
 struct C<B>(B);
 
 impl<B: Add<Output = B>> Add for C<B> {
@@ -22,6 +24,7 @@ impl<B: Add<Output = B>> Add for C<B> {
     }
 }
 
+#[allow(dead_code)]
 struct D<B>(B);
 
 impl<B: std::ops::Add<Output = B>> Add for D<B> {
@@ -32,6 +35,7 @@ impl<B: std::ops::Add<Output = B>> Add for D<B> {
     }
 }
 
+#[allow(dead_code)]
 struct E<B>(B);
 
 impl<B: Add<Output = B>> Add for E<B> where B: Add<Output = B> {
diff --git a/tests/ui/generic-associated-types/missing-bounds.rs b/tests/ui/generic-associated-types/missing-bounds.rs
index f40b4228873..1f83356c2fa 100644
--- a/tests/ui/generic-associated-types/missing-bounds.rs
+++ b/tests/ui/generic-associated-types/missing-bounds.rs
@@ -2,6 +2,7 @@
 
 use std::ops::Add;
 
+#[allow(dead_code)]
 struct A<B>(B);
 
 impl<B> Add for A<B> where B: Add {
@@ -12,6 +13,7 @@ impl<B> Add for A<B> where B: Add {
     }
 }
 
+#[allow(dead_code)]
 struct C<B>(B);
 
 impl<B: Add> Add for C<B> {
@@ -22,6 +24,7 @@ impl<B: Add> Add for C<B> {
     }
 }
 
+#[allow(dead_code)]
 struct D<B>(B);
 
 impl<B> Add for D<B> {
@@ -32,6 +35,7 @@ impl<B> Add for D<B> {
     }
 }
 
+#[allow(dead_code)]
 struct E<B>(B);
 
 impl<B: Add> Add for E<B> where <B as Add>::Output = B {
diff --git a/tests/ui/generic-associated-types/missing-bounds.stderr b/tests/ui/generic-associated-types/missing-bounds.stderr
index 1d7d80d1b07..0f0dc24c06c 100644
--- a/tests/ui/generic-associated-types/missing-bounds.stderr
+++ b/tests/ui/generic-associated-types/missing-bounds.stderr
@@ -1,5 +1,5 @@
 error: equality constraints are not yet supported in `where` clauses
-  --> $DIR/missing-bounds.rs:37:33
+  --> $DIR/missing-bounds.rs:41:33
    |
 LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B {
    |                                 ^^^^^^^^^^^^^^^^^^^^^^ not supported
@@ -11,7 +11,7 @@ LL | impl<B: Add> Add for E<B> where B: Add<Output = B> {
    |                                 ~~~~~~~~~~~~~~~~~~
 
 error[E0308]: mismatched types
-  --> $DIR/missing-bounds.rs:11:11
+  --> $DIR/missing-bounds.rs:12:11
    |
 LL | impl<B> Add for A<B> where B: Add {
    |      - expected this type parameter
@@ -24,14 +24,14 @@ LL |         A(self.0 + rhs.0)
    = note: expected type parameter `B`
              found associated type `<B as Add>::Output`
 help: the type constructed contains `<B as Add>::Output` due to the type of the argument passed
-  --> $DIR/missing-bounds.rs:11:9
+  --> $DIR/missing-bounds.rs:12:9
    |
 LL |         A(self.0 + rhs.0)
    |         ^^--------------^
    |           |
    |           this argument influences the type of `A`
 note: tuple struct defined here
-  --> $DIR/missing-bounds.rs:5:8
+  --> $DIR/missing-bounds.rs:6:8
    |
 LL | struct A<B>(B);
    |        ^
@@ -41,7 +41,7 @@ LL | impl<B> Add for A<B> where B: Add<Output = B> {
    |                                  ++++++++++++
 
 error[E0308]: mismatched types
-  --> $DIR/missing-bounds.rs:21:14
+  --> $DIR/missing-bounds.rs:23:14
    |
 LL | impl<B: Add> Add for C<B> {
    |      - expected this type parameter
@@ -54,7 +54,7 @@ LL |         Self(self.0 + rhs.0)
    = note: expected type parameter `B`
              found associated type `<B as Add>::Output`
 note: tuple struct defined here
-  --> $DIR/missing-bounds.rs:15:8
+  --> $DIR/missing-bounds.rs:17:8
    |
 LL | struct C<B>(B);
    |        ^
@@ -64,7 +64,7 @@ LL | impl<B: Add<Output = B>> Add for C<B> {
    |            ++++++++++++
 
 error[E0369]: cannot add `B` to `B`
-  --> $DIR/missing-bounds.rs:31:21
+  --> $DIR/missing-bounds.rs:34:21
    |
 LL |         Self(self.0 + rhs.0)
    |              ------ ^ ----- B
@@ -77,7 +77,7 @@ LL | impl<B: std::ops::Add<Output = B>> Add for D<B> {
    |       +++++++++++++++++++++++++++
 
 error[E0308]: mismatched types
-  --> $DIR/missing-bounds.rs:42:14
+  --> $DIR/missing-bounds.rs:46:14
    |
 LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B {
    |      - expected this type parameter
@@ -90,7 +90,7 @@ LL |         Self(self.0 + rhs.0)
    = note: expected type parameter `B`
              found associated type `<B as Add>::Output`
 note: tuple struct defined here
-  --> $DIR/missing-bounds.rs:35:8
+  --> $DIR/missing-bounds.rs:39:8
    |
 LL | struct E<B>(B);
    |        ^
diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs
index 08014985783..0028a45cbf3 100644
--- a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs
+++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs
@@ -6,6 +6,7 @@ fn type_param<T>() -> impl Sized + use<> {}
 trait Foo {
     fn bar() -> impl Sized + use<>;
     //~^ ERROR `impl Trait` must mention the `Self` type of the trait
+    //~| ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr
index 93b44a0c18c..89bd4df4431 100644
--- a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr
+++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr
@@ -1,3 +1,11 @@
+error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
+  --> $DIR/forgot-to-capture-type.rs:7:30
+   |
+LL |     fn bar() -> impl Sized + use<>;
+   |                              ^^^^^
+   |
+   = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
+
 error: `impl Trait` must mention all type parameters in scope in `use<...>`
   --> $DIR/forgot-to-capture-type.rs:3:23
    |
@@ -18,5 +26,5 @@ LL |     fn bar() -> impl Sized + use<>;
    |
    = note: currently, all type parameters are required to be mentioned in the precise captures list
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/impl-trait/precise-capturing/redundant.normal.stderr b/tests/ui/impl-trait/precise-capturing/redundant.normal.stderr
new file mode 100644
index 00000000000..44bc9f7daad
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/redundant.normal.stderr
@@ -0,0 +1,20 @@
+warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
+  --> $DIR/redundant.rs:7:19
+   |
+LL | fn hello<'a>() -> impl Sized + use<'a> {}
+   |                   ^^^^^^^^^^^^^-------
+   |                                |
+   |                                help: remove the `use<...>` syntax
+   |
+   = note: `#[warn(impl_trait_redundant_captures)]` on by default
+
+warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
+  --> $DIR/redundant.rs:12:27
+   |
+LL |     fn inherent(&self) -> impl Sized + use<'_> {}
+   |                           ^^^^^^^^^^^^^-------
+   |                                        |
+   |                                        help: remove the `use<...>` syntax
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/impl-trait/precise-capturing/redundant.rpitit.stderr b/tests/ui/impl-trait/precise-capturing/redundant.rpitit.stderr
new file mode 100644
index 00000000000..9aa73353126
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/redundant.rpitit.stderr
@@ -0,0 +1,18 @@
+error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
+  --> $DIR/redundant.rs:18:35
+   |
+LL |     fn in_trait() -> impl Sized + use<'a, Self>;
+   |                                   ^^^^^^^^^^^^^
+   |
+   = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
+
+error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
+  --> $DIR/redundant.rs:23:35
+   |
+LL |     fn in_trait() -> impl Sized + use<'a> {}
+   |                                   ^^^^^^^
+   |
+   = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/impl-trait/precise-capturing/redundant.rs b/tests/ui/impl-trait/precise-capturing/redundant.rs
index 99c128fdc48..ef4f05bd7e4 100644
--- a/tests/ui/impl-trait/precise-capturing/redundant.rs
+++ b/tests/ui/impl-trait/precise-capturing/redundant.rs
@@ -1,24 +1,27 @@
 //@ compile-flags: -Zunstable-options --edition=2024
-//@ check-pass
+//@ revisions: normal rpitit
+//@[normal] check-pass
 
 #![feature(precise_capturing)]
 
 fn hello<'a>() -> impl Sized + use<'a> {}
-//~^ WARN all possible in-scope parameters are already captured
+//[normal]~^ WARN all possible in-scope parameters are already captured
 
 struct Inherent;
 impl Inherent {
     fn inherent(&self) -> impl Sized + use<'_> {}
-    //~^ WARN all possible in-scope parameters are already captured
+    //[normal]~^ WARN all possible in-scope parameters are already captured
 }
 
+#[cfg(rpitit)]
 trait Test<'a> {
     fn in_trait() -> impl Sized + use<'a, Self>;
-    //~^ WARN all possible in-scope parameters are already captured
+    //[rpitit]~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
 }
+#[cfg(rpitit)]
 impl<'a> Test<'a> for () {
     fn in_trait() -> impl Sized + use<'a> {}
-    //~^ WARN all possible in-scope parameters are already captured
+    //[rpitit]~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/redundant.stderr b/tests/ui/impl-trait/precise-capturing/redundant.stderr
deleted file mode 100644
index 274d9d2375f..00000000000
--- a/tests/ui/impl-trait/precise-capturing/redundant.stderr
+++ /dev/null
@@ -1,36 +0,0 @@
-warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
-  --> $DIR/redundant.rs:6:19
-   |
-LL | fn hello<'a>() -> impl Sized + use<'a> {}
-   |                   ^^^^^^^^^^^^^-------
-   |                                |
-   |                                help: remove the `use<...>` syntax
-   |
-   = note: `#[warn(impl_trait_redundant_captures)]` on by default
-
-warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
-  --> $DIR/redundant.rs:11:27
-   |
-LL |     fn inherent(&self) -> impl Sized + use<'_> {}
-   |                           ^^^^^^^^^^^^^-------
-   |                                        |
-   |                                        help: remove the `use<...>` syntax
-
-warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
-  --> $DIR/redundant.rs:16:22
-   |
-LL |     fn in_trait() -> impl Sized + use<'a, Self>;
-   |                      ^^^^^^^^^^^^^-------------
-   |                                   |
-   |                                   help: remove the `use<...>` syntax
-
-warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
-  --> $DIR/redundant.rs:20:22
-   |
-LL |     fn in_trait() -> impl Sized + use<'a> {}
-   |                      ^^^^^^^^^^^^^-------
-   |                                   |
-   |                                   help: remove the `use<...>` syntax
-
-warning: 4 warnings emitted
-
diff --git a/tests/ui/impl-trait/precise-capturing/rpitit.rs b/tests/ui/impl-trait/precise-capturing/rpitit.rs
new file mode 100644
index 00000000000..4eb053573e1
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/rpitit.rs
@@ -0,0 +1,21 @@
+//@ known-bug: unknown
+
+// RPITITs don't have variances in their GATs, so they always relate invariantly
+// and act as if they capture all their args.
+// To fix this soundly, we need to make sure that all the trait header args
+// remain captured, since they affect trait selection.
+
+#![feature(precise_capturing)]
+
+trait Foo<'a> {
+    fn hello() -> impl PartialEq + use<Self>;
+}
+
+fn test<'a, 'b, T: for<'r> Foo<'r>>() {
+    PartialEq::eq(
+        &<T as Foo<'a>>::hello(),
+        &<T as Foo<'b>>::hello(),
+    );
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/rpitit.stderr b/tests/ui/impl-trait/precise-capturing/rpitit.stderr
new file mode 100644
index 00000000000..45eceef2f49
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/rpitit.stderr
@@ -0,0 +1,50 @@
+error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
+  --> $DIR/rpitit.rs:11:36
+   |
+LL |     fn hello() -> impl PartialEq + use<Self>;
+   |                                    ^^^^^^^^^
+   |
+   = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
+
+error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
+  --> $DIR/rpitit.rs:11:19
+   |
+LL | trait Foo<'a> {
+   |           -- this lifetime parameter is captured
+LL |     fn hello() -> impl PartialEq + use<Self>;
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime captured due to being mentioned in the bounds of the `impl Trait`
+
+error: lifetime may not live long enough
+  --> $DIR/rpitit.rs:15:5
+   |
+LL |   fn test<'a, 'b, T: for<'r> Foo<'r>>() {
+   |           --  -- lifetime `'b` defined here
+   |           |
+   |           lifetime `'a` defined here
+LL | /     PartialEq::eq(
+LL | |         &<T as Foo<'a>>::hello(),
+LL | |         &<T as Foo<'b>>::hello(),
+LL | |     );
+   | |_____^ argument requires that `'a` must outlive `'b`
+   |
+   = help: consider adding the following bound: `'a: 'b`
+
+error: lifetime may not live long enough
+  --> $DIR/rpitit.rs:15:5
+   |
+LL |   fn test<'a, 'b, T: for<'r> Foo<'r>>() {
+   |           --  -- lifetime `'b` defined here
+   |           |
+   |           lifetime `'a` defined here
+LL | /     PartialEq::eq(
+LL | |         &<T as Foo<'a>>::hello(),
+LL | |         &<T as Foo<'b>>::hello(),
+LL | |     );
+   | |_____^ argument requires that `'b` must outlive `'a`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+
+help: `'a` and `'b` must be the same: replace one with the other
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/impl-trait/precise-capturing/self-capture.rs b/tests/ui/impl-trait/precise-capturing/self-capture.rs
index e0a4a8b658c..07bb417f9f7 100644
--- a/tests/ui/impl-trait/precise-capturing/self-capture.rs
+++ b/tests/ui/impl-trait/precise-capturing/self-capture.rs
@@ -1,9 +1,8 @@
-//@ check-pass
-
 #![feature(precise_capturing)]
 
 trait Foo {
     fn bar<'a>() -> impl Sized + use<Self>;
+    //~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/self-capture.stderr b/tests/ui/impl-trait/precise-capturing/self-capture.stderr
new file mode 100644
index 00000000000..351de86dd5f
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/self-capture.stderr
@@ -0,0 +1,10 @@
+error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
+  --> $DIR/self-capture.rs:4:34
+   |
+LL |     fn bar<'a>() -> impl Sized + use<Self>;
+   |                                  ^^^^^^^^^
+   |
+   = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/lint/dead-code/unused-trait-with-assoc-ty.rs b/tests/ui/lint/dead-code/unused-trait-with-assoc-ty.rs
new file mode 100644
index 00000000000..e8116d83ebf
--- /dev/null
+++ b/tests/ui/lint/dead-code/unused-trait-with-assoc-ty.rs
@@ -0,0 +1,11 @@
+#![deny(dead_code)]
+
+struct T1; //~ ERROR struct `T1` is never constructed
+
+trait Foo { type Unused; } //~ ERROR trait `Foo` is never used
+impl Foo for T1 { type Unused = Self; }
+
+pub trait Bar { type Used; }
+impl Bar for T1 { type Used = Self; }
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/unused-trait-with-assoc-ty.stderr b/tests/ui/lint/dead-code/unused-trait-with-assoc-ty.stderr
new file mode 100644
index 00000000000..ab73c640634
--- /dev/null
+++ b/tests/ui/lint/dead-code/unused-trait-with-assoc-ty.stderr
@@ -0,0 +1,20 @@
+error: struct `T1` is never constructed
+  --> $DIR/unused-trait-with-assoc-ty.rs:3:8
+   |
+LL | struct T1;
+   |        ^^
+   |
+note: the lint level is defined here
+  --> $DIR/unused-trait-with-assoc-ty.rs:1:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: trait `Foo` is never used
+  --> $DIR/unused-trait-with-assoc-ty.rs:5:7
+   |
+LL | trait Foo { type Unused; }
+   |       ^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/pattern/issue-22546.rs b/tests/ui/pattern/issue-22546.rs
index fd1d5fb6c47..d5c5b68be78 100644
--- a/tests/ui/pattern/issue-22546.rs
+++ b/tests/ui/pattern/issue-22546.rs
@@ -15,7 +15,7 @@ impl<T: ::std::fmt::Display> Foo<T> {
     }
 }
 
-trait Tr { //~ WARN trait `Tr` is never used
+trait Tr {
     type U;
 }
 
diff --git a/tests/ui/pattern/issue-22546.stderr b/tests/ui/pattern/issue-22546.stderr
deleted file mode 100644
index e067a95e422..00000000000
--- a/tests/ui/pattern/issue-22546.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-warning: trait `Tr` is never used
-  --> $DIR/issue-22546.rs:18:7
-   |
-LL | trait Tr {
-   |       ^^
-   |
-   = note: `#[warn(dead_code)]` on by default
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/regions/account-for-lifetimes-in-closure-suggestion.rs b/tests/ui/regions/account-for-lifetimes-in-closure-suggestion.rs
new file mode 100644
index 00000000000..2de92cf62da
--- /dev/null
+++ b/tests/ui/regions/account-for-lifetimes-in-closure-suggestion.rs
@@ -0,0 +1,19 @@
+// #125634
+struct Thing;
+
+// Invariant in 'a, Covariant in 'b
+struct TwoThings<'a, 'b>(*mut &'a (), &'b mut ());
+
+impl Thing {
+    fn enter_scope<'a>(self, _scope: impl for<'b> FnOnce(TwoThings<'a, 'b>)) {}
+}
+
+fn foo() {
+    Thing.enter_scope(|ctx| {
+        SameLifetime(ctx); //~ ERROR lifetime may not live long enough
+    });
+}
+
+struct SameLifetime<'a>(TwoThings<'a, 'a>);
+
+fn main() {}
diff --git a/tests/ui/regions/account-for-lifetimes-in-closure-suggestion.stderr b/tests/ui/regions/account-for-lifetimes-in-closure-suggestion.stderr
new file mode 100644
index 00000000000..5e158f59cdc
--- /dev/null
+++ b/tests/ui/regions/account-for-lifetimes-in-closure-suggestion.stderr
@@ -0,0 +1,17 @@
+error: lifetime may not live long enough
+  --> $DIR/account-for-lifetimes-in-closure-suggestion.rs:13:22
+   |
+LL |     Thing.enter_scope(|ctx| {
+   |                        ---
+   |                        |
+   |                        has type `TwoThings<'_, '1>`
+   |                        has type `TwoThings<'2, '_>`
+LL |         SameLifetime(ctx);
+   |                      ^^^ this usage requires that `'1` must outlive `'2`
+   |
+   = note: requirement occurs because of the type `TwoThings<'_, '_>`, which makes the generic argument `'_` invariant
+   = note: the struct `TwoThings<'a, 'b>` is invariant over the parameter `'a`
+   = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+error: aborting due to 1 previous error
+
diff --git a/tests/crashes/124563.rs b/tests/ui/regions/lifetime-not-long-enough-suggestion-regression-test-124563.rs
index b082739af53..23427838ceb 100644
--- a/tests/crashes/124563.rs
+++ b/tests/ui/regions/lifetime-not-long-enough-suggestion-regression-test-124563.rs
@@ -1,5 +1,4 @@
-//@ known-bug: rust-lang/rust#124563
-
+// #124563
 use std::marker::PhantomData;
 
 pub trait Trait {}
@@ -17,11 +16,11 @@ where
     T: Trait,
 {
     type Trait = T;
-    type Bar = BarImpl<'a, 'b, T>;
+    type Bar = BarImpl<'a, 'b, T>; //~ ERROR lifetime bound not satisfied
 
     fn foo(&mut self) {
-        self.enter_scope(|ctx| {
-            BarImpl(ctx);
+        self.enter_scope(|ctx| { //~ ERROR lifetime may not live long enough
+            BarImpl(ctx); //~ ERROR lifetime may not live long enough
         });
     }
 }
@@ -44,3 +43,5 @@ where
 {
     type Foo = FooImpl<'a, 'b, T>;
 }
+
+fn main() {}
diff --git a/tests/ui/regions/lifetime-not-long-enough-suggestion-regression-test-124563.stderr b/tests/ui/regions/lifetime-not-long-enough-suggestion-regression-test-124563.stderr
new file mode 100644
index 00000000000..fcd0a232a7b
--- /dev/null
+++ b/tests/ui/regions/lifetime-not-long-enough-suggestion-regression-test-124563.stderr
@@ -0,0 +1,49 @@
+error[E0478]: lifetime bound not satisfied
+  --> $DIR/lifetime-not-long-enough-suggestion-regression-test-124563.rs:19:16
+   |
+LL |     type Bar = BarImpl<'a, 'b, T>;
+   |                ^^^^^^^^^^^^^^^^^^
+   |
+note: lifetime parameter instantiated with the lifetime `'a` as defined here
+  --> $DIR/lifetime-not-long-enough-suggestion-regression-test-124563.rs:14:6
+   |
+LL | impl<'a, 'b, T> Foo for FooImpl<'a, 'b, T>
+   |      ^^
+note: but lifetime parameter must outlive the lifetime `'b` as defined here
+  --> $DIR/lifetime-not-long-enough-suggestion-regression-test-124563.rs:14:10
+   |
+LL | impl<'a, 'b, T> Foo for FooImpl<'a, 'b, T>
+   |          ^^
+
+error: lifetime may not live long enough
+  --> $DIR/lifetime-not-long-enough-suggestion-regression-test-124563.rs:23:21
+   |
+LL |         self.enter_scope(|ctx| {
+   |                           ---
+   |                           |
+   |                           has type `&'1 mut FooImpl<'_, '_, T>`
+   |                           has type `&mut FooImpl<'2, '_, T>`
+LL |             BarImpl(ctx);
+   |                     ^^^ this usage requires that `'1` must outlive `'2`
+
+error: lifetime may not live long enough
+  --> $DIR/lifetime-not-long-enough-suggestion-regression-test-124563.rs:22:9
+   |
+LL |   impl<'a, 'b, T> Foo for FooImpl<'a, 'b, T>
+   |        --  -- lifetime `'b` defined here
+   |        |
+   |        lifetime `'a` defined here
+...
+LL | /         self.enter_scope(|ctx| {
+LL | |             BarImpl(ctx);
+LL | |         });
+   | |__________^ argument requires that `'a` must outlive `'b`
+   |
+   = help: consider adding the following bound: `'a: 'b`
+   = note: requirement occurs because of a mutable reference to `FooImpl<'_, '_, T>`
+   = note: mutable references are invariant over their type parameter
+   = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0478`.
diff --git a/tests/ui/regions/regions-escape-method.fixed b/tests/ui/regions/regions-escape-method.fixed
new file mode 100644
index 00000000000..f192dca1e25
--- /dev/null
+++ b/tests/ui/regions/regions-escape-method.fixed
@@ -0,0 +1,17 @@
+// Test a method call where the parameter `B` would (illegally) be
+// inferred to a region bound in the method argument. If this program
+// were accepted, then the closure passed to `s.f` could escape its
+// argument.
+//@ run-rustfix
+
+struct S;
+
+impl S {
+    fn f<B, F>(&self, _: F) where F: FnOnce(&i32) -> B {
+    }
+}
+
+fn main() {
+    let s = S;
+    s.f(|p| *p) //~ ERROR lifetime may not live long enough
+}
diff --git a/tests/ui/regions/regions-escape-method.rs b/tests/ui/regions/regions-escape-method.rs
index 69c01ae6906..82bf86c79b2 100644
--- a/tests/ui/regions/regions-escape-method.rs
+++ b/tests/ui/regions/regions-escape-method.rs
@@ -2,6 +2,7 @@
 // inferred to a region bound in the method argument. If this program
 // were accepted, then the closure passed to `s.f` could escape its
 // argument.
+//@ run-rustfix
 
 struct S;
 
diff --git a/tests/ui/regions/regions-escape-method.stderr b/tests/ui/regions/regions-escape-method.stderr
index aeda923b0ba..687b91bb7b4 100644
--- a/tests/ui/regions/regions-escape-method.stderr
+++ b/tests/ui/regions/regions-escape-method.stderr
@@ -1,11 +1,16 @@
 error: lifetime may not live long enough
-  --> $DIR/regions-escape-method.rs:15:13
+  --> $DIR/regions-escape-method.rs:16:13
    |
 LL |     s.f(|p| p)
    |          -- ^ returning this value requires that `'1` must outlive `'2`
    |          ||
    |          |return type of closure is &'2 i32
    |          has type `&'1 i32`
+   |
+help: dereference the return value
+   |
+LL |     s.f(|p| *p)
+   |             +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/suggestions/missing-impl-trait-block-but-not-ascii.rs b/tests/ui/suggestions/missing-impl-trait-block-but-not-ascii.rs
new file mode 100644
index 00000000000..ddb6bd1e902
--- /dev/null
+++ b/tests/ui/suggestions/missing-impl-trait-block-but-not-ascii.rs
@@ -0,0 +1,13 @@
+// issue#126764
+
+struct S;
+
+trait T {
+    fn f();
+}
+impl T for S;
+//~^ ERROR: unknown start of token
+//~| ERROR: expected `{}`
+//~| ERROR: not all trait items implemented, missing: `f`
+
+fn main() {}
diff --git a/tests/ui/suggestions/missing-impl-trait-block-but-not-ascii.stderr b/tests/ui/suggestions/missing-impl-trait-block-but-not-ascii.stderr
new file mode 100644
index 00000000000..56cdc11b62e
--- /dev/null
+++ b/tests/ui/suggestions/missing-impl-trait-block-but-not-ascii.stderr
@@ -0,0 +1,31 @@
+error: unknown start of token: \u{ff1b}
+  --> $DIR/missing-impl-trait-block-but-not-ascii.rs:8:13
+   |
+LL | impl T for S;
+   |             ^^
+   |
+help: Unicode character ';' (Fullwidth Semicolon) looks like ';' (Semicolon), but it is not
+   |
+LL | impl T for S;
+   |             ~
+
+error: expected `{}`, found `;`
+  --> $DIR/missing-impl-trait-block-but-not-ascii.rs:8:13
+   |
+LL | impl T for S;
+   |             ^^
+   |
+   = help: try using `{}` instead
+
+error[E0046]: not all trait items implemented, missing: `f`
+  --> $DIR/missing-impl-trait-block-but-not-ascii.rs:8:1
+   |
+LL |     fn f();
+   |     ------- `f` from trait
+LL | }
+LL | impl T for S;
+   | ^^^^^^^^^^^^ missing `f` in implementation
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0046`.