about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-09-28 10:46:56 +0000
committerbors <bors@rust-lang.org>2024-09-28 10:46:56 +0000
commit612796c42077605fdd3c6f7dda05745d8f4dc4d8 (patch)
treeb10950ff038774560499adf434f798f6a1ddfc35
parent150247c338a54cb3d08614d8530d1bb491fa90db (diff)
parent5d7db936008110f9760dcf5e74912c6662d2bd4f (diff)
downloadrust-612796c42077605fdd3c6f7dda05745d8f4dc4d8.tar.gz
rust-612796c42077605fdd3c6f7dda05745d8f4dc4d8.zip
Auto merge of #130964 - matthiaskrgr:rollup-suriuub, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #125404 (Fix `read_buf` uses in `std`)
 - #130866 (Allow instantiating object trait binder when upcasting)
 - #130922 (Reference UNSPECIFIED instead of INADDR_ANY in join_multicast_v4)
 - #130924 (Make clashing_extern_declarations considering generic args for ADT field)
 - #130939 (rustdoc: update `ProcMacro` docs section on helper attributes)
 - #130940 (Revert space-saving operations)
 - #130944 (Allow instantiating trait object binder in ptr-to-ptr casts)
 - #130953 (Rename a few tests to make tidy happier)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/at.rs164
-rw-r--r--compiler/rustc_lint/src/foreign_modules.rs6
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs16
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs49
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs93
-rw-r--r--library/std/src/io/buffered/bufreader.rs2
-rw-r--r--library/std/src/io/buffered/bufreader/buffer.rs4
-rw-r--r--library/std/src/io/mod.rs35
-rw-r--r--library/std/src/io/tests.rs63
-rw-r--r--library/std/src/net/udp.rs4
-rwxr-xr-xsrc/ci/scripts/select-xcode.sh17
-rwxr-xr-xsrc/ci/scripts/upload-artifacts.sh6
-rw-r--r--src/rustdoc-json-types/lib.rs2
-rw-r--r--src/tools/tidy/src/issues.txt3
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs6
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr35
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-ok.rs29
-rw-r--r--tests/ui/coercion/sub-principals.rs27
-rw-r--r--tests/ui/consts/load-preserves-partial-init.rs (renamed from tests/ui/consts/issue-69488.rs)3
-rw-r--r--tests/ui/lint/clashing-extern-fn-issue-130851.rs42
-rw-r--r--tests/ui/lint/clashing-extern-fn-issue-130851.stderr31
-rw-r--r--tests/ui/lint/improper_ctypes/allow-phantomdata-in-ffi.rs (renamed from tests/ui/lint/issue-34798.rs)2
-rw-r--r--tests/ui/lint/improper_ctypes/repr-rust-is-undefined.rs (renamed from tests/ui/lint/issue-14309.rs)4
-rw-r--r--tests/ui/lint/improper_ctypes/repr-rust-is-undefined.stderr (renamed from tests/ui/lint/issue-14309.stderr)22
-rw-r--r--tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.current.stderr22
-rw-r--r--tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.next.stderr14
-rw-r--r--tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs10
-rw-r--r--tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr8
-rw-r--r--tests/ui/traits/trait-upcasting/sub.rs26
30 files changed, 483 insertions, 264 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 16e51e82f85..6b17879de26 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -2437,7 +2437,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
 
                                     debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj);
 
-                                    self.eq_types(
+                                    self.sub_types(
                                         src_obj,
                                         dst_obj,
                                         location.to_locations(),
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 9f6a1763866..6ce47db8b9b 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -92,12 +92,7 @@ impl<'tcx> InferCtxt<'tcx> {
 }
 
 pub trait ToTrace<'tcx>: Relate<TyCtxt<'tcx>> + Copy {
-    fn to_trace(
-        cause: &ObligationCause<'tcx>,
-        a_is_expected: bool,
-        a: Self,
-        b: Self,
-    ) -> TypeTrace<'tcx>;
+    fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx>;
 }
 
 impl<'a, 'tcx> At<'a, 'tcx> {
@@ -116,7 +111,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     {
         let mut fields = CombineFields::new(
             self.infcx,
-            ToTrace::to_trace(self.cause, true, expected, actual),
+            ToTrace::to_trace(self.cause, expected, actual),
             self.param_env,
             define_opaque_types,
         );
@@ -136,7 +131,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     {
         let mut fields = CombineFields::new(
             self.infcx,
-            ToTrace::to_trace(self.cause, true, expected, actual),
+            ToTrace::to_trace(self.cause, expected, actual),
             self.param_env,
             define_opaque_types,
         );
@@ -154,12 +149,26 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     where
         T: ToTrace<'tcx>,
     {
-        let mut fields = CombineFields::new(
-            self.infcx,
-            ToTrace::to_trace(self.cause, true, expected, actual),
-            self.param_env,
+        self.eq_trace(
             define_opaque_types,
-        );
+            ToTrace::to_trace(self.cause, expected, actual),
+            expected,
+            actual,
+        )
+    }
+
+    /// Makes `expected == actual`.
+    pub fn eq_trace<T>(
+        self,
+        define_opaque_types: DefineOpaqueTypes,
+        trace: TypeTrace<'tcx>,
+        expected: T,
+        actual: T,
+    ) -> InferResult<'tcx, ()>
+    where
+        T: Relate<TyCtxt<'tcx>>,
+    {
+        let mut fields = CombineFields::new(self.infcx, trace, self.param_env, define_opaque_types);
         fields.equate(StructurallyRelateAliases::No).relate(expected, actual)?;
         Ok(InferOk {
             value: (),
@@ -192,7 +201,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
         assert!(self.infcx.next_trait_solver());
         let mut fields = CombineFields::new(
             self.infcx,
-            ToTrace::to_trace(self.cause, true, expected, actual),
+            ToTrace::to_trace(self.cause, expected, actual),
             self.param_env,
             DefineOpaqueTypes::Yes,
         );
@@ -284,7 +293,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     {
         let mut fields = CombineFields::new(
             self.infcx,
-            ToTrace::to_trace(self.cause, true, expected, actual),
+            ToTrace::to_trace(self.cause, expected, actual),
             self.param_env,
             define_opaque_types,
         );
@@ -306,7 +315,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     {
         let mut fields = CombineFields::new(
             self.infcx,
-            ToTrace::to_trace(self.cause, true, expected, actual),
+            ToTrace::to_trace(self.cause, expected, actual),
             self.param_env,
             define_opaque_types,
         );
@@ -316,18 +325,13 @@ impl<'a, 'tcx> At<'a, 'tcx> {
 }
 
 impl<'tcx> ToTrace<'tcx> for ImplSubject<'tcx> {
-    fn to_trace(
-        cause: &ObligationCause<'tcx>,
-        a_is_expected: bool,
-        a: Self,
-        b: Self,
-    ) -> TypeTrace<'tcx> {
+    fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         match (a, b) {
             (ImplSubject::Trait(trait_ref_a), ImplSubject::Trait(trait_ref_b)) => {
-                ToTrace::to_trace(cause, a_is_expected, trait_ref_a, trait_ref_b)
+                ToTrace::to_trace(cause, trait_ref_a, trait_ref_b)
             }
             (ImplSubject::Inherent(ty_a), ImplSubject::Inherent(ty_b)) => {
-                ToTrace::to_trace(cause, a_is_expected, ty_a, ty_b)
+                ToTrace::to_trace(cause, ty_a, ty_b)
             }
             (ImplSubject::Trait(_), ImplSubject::Inherent(_))
             | (ImplSubject::Inherent(_), ImplSubject::Trait(_)) => {
@@ -338,65 +342,45 @@ impl<'tcx> ToTrace<'tcx> for ImplSubject<'tcx> {
 }
 
 impl<'tcx> ToTrace<'tcx> for Ty<'tcx> {
-    fn to_trace(
-        cause: &ObligationCause<'tcx>,
-        a_is_expected: bool,
-        a: Self,
-        b: Self,
-    ) -> TypeTrace<'tcx> {
+    fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
-            values: ValuePairs::Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())),
+            values: ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into())),
         }
     }
 }
 
 impl<'tcx> ToTrace<'tcx> for ty::Region<'tcx> {
-    fn to_trace(
-        cause: &ObligationCause<'tcx>,
-        a_is_expected: bool,
-        a: Self,
-        b: Self,
-    ) -> TypeTrace<'tcx> {
+    fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
-            values: ValuePairs::Regions(ExpectedFound::new(a_is_expected, a, b)),
+            values: ValuePairs::Regions(ExpectedFound::new(true, a, b)),
         }
     }
 }
 
 impl<'tcx> ToTrace<'tcx> for Const<'tcx> {
-    fn to_trace(
-        cause: &ObligationCause<'tcx>,
-        a_is_expected: bool,
-        a: Self,
-        b: Self,
-    ) -> TypeTrace<'tcx> {
+    fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
-            values: ValuePairs::Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())),
+            values: ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into())),
         }
     }
 }
 
 impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> {
-    fn to_trace(
-        cause: &ObligationCause<'tcx>,
-        a_is_expected: bool,
-        a: Self,
-        b: Self,
-    ) -> TypeTrace<'tcx> {
+    fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
             values: match (a.unpack(), b.unpack()) {
                 (GenericArgKind::Lifetime(a), GenericArgKind::Lifetime(b)) => {
-                    ValuePairs::Regions(ExpectedFound::new(a_is_expected, a, b))
+                    ValuePairs::Regions(ExpectedFound::new(true, a, b))
                 }
                 (GenericArgKind::Type(a), GenericArgKind::Type(b)) => {
-                    ValuePairs::Terms(ExpectedFound::new(a_is_expected, a.into(), b.into()))
+                    ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into()))
                 }
                 (GenericArgKind::Const(a), GenericArgKind::Const(b)) => {
-                    ValuePairs::Terms(ExpectedFound::new(a_is_expected, a.into(), b.into()))
+                    ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into()))
                 }
 
                 (
@@ -419,72 +403,47 @@ impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> {
 }
 
 impl<'tcx> ToTrace<'tcx> for ty::Term<'tcx> {
-    fn to_trace(
-        cause: &ObligationCause<'tcx>,
-        a_is_expected: bool,
-        a: Self,
-        b: Self,
-    ) -> TypeTrace<'tcx> {
+    fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
-            values: ValuePairs::Terms(ExpectedFound::new(a_is_expected, a, b)),
+            values: ValuePairs::Terms(ExpectedFound::new(true, a, b)),
         }
     }
 }
 
 impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> {
-    fn to_trace(
-        cause: &ObligationCause<'tcx>,
-        a_is_expected: bool,
-        a: Self,
-        b: Self,
-    ) -> TypeTrace<'tcx> {
+    fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
-            values: ValuePairs::TraitRefs(ExpectedFound::new(a_is_expected, a, b)),
+            values: ValuePairs::TraitRefs(ExpectedFound::new(true, a, b)),
         }
     }
 }
 
 impl<'tcx> ToTrace<'tcx> for ty::AliasTy<'tcx> {
-    fn to_trace(
-        cause: &ObligationCause<'tcx>,
-        a_is_expected: bool,
-        a: Self,
-        b: Self,
-    ) -> TypeTrace<'tcx> {
+    fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
-            values: ValuePairs::Aliases(ExpectedFound::new(a_is_expected, a.into(), b.into())),
+            values: ValuePairs::Aliases(ExpectedFound::new(true, a.into(), b.into())),
         }
     }
 }
 
 impl<'tcx> ToTrace<'tcx> for ty::AliasTerm<'tcx> {
-    fn to_trace(
-        cause: &ObligationCause<'tcx>,
-        a_is_expected: bool,
-        a: Self,
-        b: Self,
-    ) -> TypeTrace<'tcx> {
+    fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
-            values: ValuePairs::Aliases(ExpectedFound::new(a_is_expected, a, b)),
+            values: ValuePairs::Aliases(ExpectedFound::new(true, a, b)),
         }
     }
 }
 
 impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> {
-    fn to_trace(
-        cause: &ObligationCause<'tcx>,
-        a_is_expected: bool,
-        a: Self,
-        b: Self,
-    ) -> TypeTrace<'tcx> {
+    fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
             values: ValuePairs::PolySigs(ExpectedFound::new(
-                a_is_expected,
+                true,
                 ty::Binder::dummy(a),
                 ty::Binder::dummy(b),
             )),
@@ -493,43 +452,28 @@ impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> {
 }
 
 impl<'tcx> ToTrace<'tcx> for ty::PolyFnSig<'tcx> {
-    fn to_trace(
-        cause: &ObligationCause<'tcx>,
-        a_is_expected: bool,
-        a: Self,
-        b: Self,
-    ) -> TypeTrace<'tcx> {
+    fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
-            values: ValuePairs::PolySigs(ExpectedFound::new(a_is_expected, a, b)),
+            values: ValuePairs::PolySigs(ExpectedFound::new(true, a, b)),
         }
     }
 }
 
 impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialTraitRef<'tcx> {
-    fn to_trace(
-        cause: &ObligationCause<'tcx>,
-        a_is_expected: bool,
-        a: Self,
-        b: Self,
-    ) -> TypeTrace<'tcx> {
+    fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
-            values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(a_is_expected, a, b)),
+            values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(true, a, b)),
         }
     }
 }
 
 impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialProjection<'tcx> {
-    fn to_trace(
-        cause: &ObligationCause<'tcx>,
-        a_is_expected: bool,
-        a: Self,
-        b: Self,
-    ) -> TypeTrace<'tcx> {
+    fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
-            values: ValuePairs::ExistentialProjection(ExpectedFound::new(a_is_expected, a, b)),
+            values: ValuePairs::ExistentialProjection(ExpectedFound::new(true, a, b)),
         }
     }
 }
diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs
index 1ead377607f..816882962be 100644
--- a/compiler/rustc_lint/src/foreign_modules.rs
+++ b/compiler/rustc_lint/src/foreign_modules.rs
@@ -280,7 +280,7 @@ fn structurally_same_type_impl<'tcx>(
 
         ensure_sufficient_stack(|| {
             match (a.kind(), b.kind()) {
-                (&Adt(a_def, _), &Adt(b_def, _)) => {
+                (&Adt(a_def, a_gen_args), &Adt(b_def, b_gen_args)) => {
                     // Only `repr(C)` types can be compared structurally.
                     if !(a_def.repr().c() && b_def.repr().c()) {
                         return false;
@@ -304,8 +304,8 @@ fn structurally_same_type_impl<'tcx>(
                                 seen_types,
                                 tcx,
                                 param_env,
-                                tcx.type_of(a_did).instantiate_identity(),
-                                tcx.type_of(b_did).instantiate_identity(),
+                                tcx.type_of(a_did).instantiate(tcx, a_gen_args),
+                                tcx.type_of(b_did).instantiate(tcx, b_gen_args),
                                 ckind,
                             )
                         },
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index 270d50b5af4..ced1ca23e9b 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -448,10 +448,10 @@ where
                 }
             }
         } else {
-            self.delegate.enter_forall(kind, |kind| {
-                let goal = goal.with(self.cx(), ty::Binder::dummy(kind));
-                self.add_goal(GoalSource::InstantiateHigherRanked, goal);
-                self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+            self.enter_forall(kind, |ecx, kind| {
+                let goal = goal.with(ecx.cx(), ty::Binder::dummy(kind));
+                ecx.add_goal(GoalSource::InstantiateHigherRanked, goal);
+                ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
             })
         }
     }
@@ -840,12 +840,14 @@ where
         self.delegate.instantiate_binder_with_infer(value)
     }
 
+    /// `enter_forall`, but takes `&mut self` and passes it back through the
+    /// callback since it can't be aliased during the call.
     pub(super) fn enter_forall<T: TypeFoldable<I> + Copy, U>(
-        &self,
+        &mut self,
         value: ty::Binder<I, T>,
-        f: impl FnOnce(T) -> U,
+        f: impl FnOnce(&mut Self, T) -> U,
     ) -> U {
-        self.delegate.enter_forall(value, f)
+        self.delegate.enter_forall(value, |value| f(self, value))
     }
 
     pub(super) fn resolve_vars_if_possible<T>(&self, value: T) -> T
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 703e88d1339..2074bdec485 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -895,10 +895,13 @@ where
                 source_projection.item_def_id() == target_projection.item_def_id()
                     && ecx
                         .probe(|_| ProbeKind::UpcastProjectionCompatibility)
-                        .enter(|ecx| -> Result<(), NoSolution> {
-                            ecx.eq(param_env, source_projection, target_projection)?;
-                            let _ = ecx.try_evaluate_added_goals()?;
-                            Ok(())
+                        .enter(|ecx| -> Result<_, NoSolution> {
+                            ecx.enter_forall(target_projection, |ecx, target_projection| {
+                                let source_projection =
+                                    ecx.instantiate_binder_with_infer(source_projection);
+                                ecx.eq(param_env, source_projection, target_projection)?;
+                                ecx.try_evaluate_added_goals()
+                            })
                         })
                         .is_ok()
             };
@@ -909,11 +912,14 @@ where
                     // Check that a's supertrait (upcast_principal) is compatible
                     // with the target (b_ty).
                     ty::ExistentialPredicate::Trait(target_principal) => {
-                        ecx.eq(
-                            param_env,
-                            upcast_principal.unwrap(),
-                            bound.rebind(target_principal),
-                        )?;
+                        let source_principal = upcast_principal.unwrap();
+                        let target_principal = bound.rebind(target_principal);
+                        ecx.enter_forall(target_principal, |ecx, target_principal| {
+                            let source_principal =
+                                ecx.instantiate_binder_with_infer(source_principal);
+                            ecx.eq(param_env, source_principal, target_principal)?;
+                            ecx.try_evaluate_added_goals()
+                        })?;
                     }
                     // Check that b_ty's projection is satisfied by exactly one of
                     // a_ty's projections. First, we look through the list to see if
@@ -934,7 +940,12 @@ where
                                 Certainty::AMBIGUOUS,
                             );
                         }
-                        ecx.eq(param_env, source_projection, target_projection)?;
+                        ecx.enter_forall(target_projection, |ecx, target_projection| {
+                            let source_projection =
+                                ecx.instantiate_binder_with_infer(source_projection);
+                            ecx.eq(param_env, source_projection, target_projection)?;
+                            ecx.try_evaluate_added_goals()
+                        })?;
                     }
                     // Check that b_ty's auto traits are present in a_ty's bounds.
                     ty::ExistentialPredicate::AutoTrait(def_id) => {
@@ -1187,17 +1198,15 @@ where
         ) -> Result<Vec<ty::Binder<I, I::Ty>>, NoSolution>,
     ) -> Result<Candidate<I>, NoSolution> {
         self.probe_trait_candidate(source).enter(|ecx| {
-            ecx.add_goals(
-                GoalSource::ImplWhereBound,
-                constituent_tys(ecx, goal.predicate.self_ty())?
-                    .into_iter()
-                    .map(|ty| {
-                        ecx.enter_forall(ty, |ty| {
-                            goal.with(ecx.cx(), goal.predicate.with_self_ty(ecx.cx(), ty))
-                        })
+            let goals = constituent_tys(ecx, goal.predicate.self_ty())?
+                .into_iter()
+                .map(|ty| {
+                    ecx.enter_forall(ty, |ecx, ty| {
+                        goal.with(ecx.cx(), goal.predicate.with_self_ty(ecx.cx(), ty))
                     })
-                    .collect::<Vec<_>>(),
-            );
+                })
+                .collect::<Vec<_>>();
+            ecx.add_goals(GoalSource::ImplWhereBound, goals);
             ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
         })
     }
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 20b540831aa..fba1d1025ca 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -16,6 +16,7 @@ use rustc_hir::LangItem;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType};
 use rustc_infer::infer::DefineOpaqueTypes;
+use rustc_infer::infer::at::ToTrace;
 use rustc_infer::infer::relate::TypeRelation;
 use rustc_infer::traits::TraitObligation;
 use rustc_middle::bug;
@@ -44,7 +45,7 @@ use super::{
     TraitQueryMode, const_evaluatable, project, util, wf,
 };
 use crate::error_reporting::InferCtxtErrorExt;
-use crate::infer::{InferCtxt, InferCtxtExt, InferOk, TypeFreshener};
+use crate::infer::{InferCtxt, InferOk, TypeFreshener};
 use crate::solve::InferCtxtSelectExt as _;
 use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to};
 use crate::traits::project::{ProjectAndUnifyResult, ProjectionCacheKeyExt};
@@ -2579,16 +2580,31 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 // Check that a_ty's supertrait (upcast_principal) is compatible
                 // with the target (b_ty).
                 ty::ExistentialPredicate::Trait(target_principal) => {
+                    let hr_source_principal = upcast_principal.map_bound(|trait_ref| {
+                        ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
+                    });
+                    let hr_target_principal = bound.rebind(target_principal);
+
                     nested.extend(
                         self.infcx
-                            .at(&obligation.cause, obligation.param_env)
-                            .eq(
-                                DefineOpaqueTypes::Yes,
-                                upcast_principal.map_bound(|trait_ref| {
-                                    ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
-                                }),
-                                bound.rebind(target_principal),
-                            )
+                            .enter_forall(hr_target_principal, |target_principal| {
+                                let source_principal =
+                                    self.infcx.instantiate_binder_with_fresh_vars(
+                                        obligation.cause.span,
+                                        HigherRankedType,
+                                        hr_source_principal,
+                                    );
+                                self.infcx.at(&obligation.cause, obligation.param_env).eq_trace(
+                                    DefineOpaqueTypes::Yes,
+                                    ToTrace::to_trace(
+                                        &obligation.cause,
+                                        hr_target_principal,
+                                        hr_source_principal,
+                                    ),
+                                    target_principal,
+                                    source_principal,
+                                )
+                            })
                             .map_err(|_| SelectionError::Unimplemented)?
                             .into_obligations(),
                     );
@@ -2599,19 +2615,40 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 // return ambiguity. Otherwise, if exactly one matches, equate
                 // it with b_ty's projection.
                 ty::ExistentialPredicate::Projection(target_projection) => {
-                    let target_projection = bound.rebind(target_projection);
+                    let hr_target_projection = bound.rebind(target_projection);
+
                     let mut matching_projections =
-                        a_data.projection_bounds().filter(|source_projection| {
+                        a_data.projection_bounds().filter(|&hr_source_projection| {
                             // Eager normalization means that we can just use can_eq
                             // here instead of equating and processing obligations.
-                            source_projection.item_def_id() == target_projection.item_def_id()
-                                && self.infcx.can_eq(
-                                    obligation.param_env,
-                                    *source_projection,
-                                    target_projection,
-                                )
+                            hr_source_projection.item_def_id() == hr_target_projection.item_def_id()
+                                && self.infcx.probe(|_| {
+                                    self.infcx
+                                        .enter_forall(hr_target_projection, |target_projection| {
+                                            let source_projection =
+                                                self.infcx.instantiate_binder_with_fresh_vars(
+                                                    obligation.cause.span,
+                                                    HigherRankedType,
+                                                    hr_source_projection,
+                                                );
+                                            self.infcx
+                                                .at(&obligation.cause, obligation.param_env)
+                                                .eq_trace(
+                                                    DefineOpaqueTypes::Yes,
+                                                    ToTrace::to_trace(
+                                                        &obligation.cause,
+                                                        hr_target_projection,
+                                                        hr_source_projection,
+                                                    ),
+                                                    target_projection,
+                                                    source_projection,
+                                                )
+                                        })
+                                        .is_ok()
+                                })
                         });
-                    let Some(source_projection) = matching_projections.next() else {
+
+                    let Some(hr_source_projection) = matching_projections.next() else {
                         return Err(SelectionError::Unimplemented);
                     };
                     if matching_projections.next().is_some() {
@@ -2619,8 +2656,24 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                     }
                     nested.extend(
                         self.infcx
-                            .at(&obligation.cause, obligation.param_env)
-                            .eq(DefineOpaqueTypes::Yes, source_projection, target_projection)
+                            .enter_forall(hr_target_projection, |target_projection| {
+                                let source_projection =
+                                    self.infcx.instantiate_binder_with_fresh_vars(
+                                        obligation.cause.span,
+                                        HigherRankedType,
+                                        hr_source_projection,
+                                    );
+                                self.infcx.at(&obligation.cause, obligation.param_env).eq_trace(
+                                    DefineOpaqueTypes::Yes,
+                                    ToTrace::to_trace(
+                                        &obligation.cause,
+                                        hr_target_projection,
+                                        hr_source_projection,
+                                    ),
+                                    target_projection,
+                                    source_projection,
+                                )
+                            })
                             .map_err(|_| SelectionError::Unimplemented)?
                             .into_obligations(),
                     );
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs
index fcb3e36027b..8b46738ab8a 100644
--- a/library/std/src/io/buffered/bufreader.rs
+++ b/library/std/src/io/buffered/bufreader.rs
@@ -357,7 +357,7 @@ impl<R: ?Sized + Read> Read for BufReader<R> {
         let prev = cursor.written();
 
         let mut rem = self.fill_buf()?;
-        rem.read_buf(cursor.reborrow())?;
+        rem.read_buf(cursor.reborrow())?; // actually never fails
 
         self.consume(cursor.written() - prev); //slice impl of read_buf known to never unfill buf
 
diff --git a/library/std/src/io/buffered/bufreader/buffer.rs b/library/std/src/io/buffered/bufreader/buffer.rs
index 3df7e3971da..52fe49985c6 100644
--- a/library/std/src/io/buffered/bufreader/buffer.rs
+++ b/library/std/src/io/buffered/bufreader/buffer.rs
@@ -143,11 +143,13 @@ impl Buffer {
                 buf.set_init(self.initialized);
             }
 
-            reader.read_buf(buf.unfilled())?;
+            let result = reader.read_buf(buf.unfilled());
 
             self.pos = 0;
             self.filled = buf.len();
             self.initialized = buf.init_len();
+
+            result?;
         }
         Ok(self.buffer())
     }
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 0b57d01f273..dd6458c38c6 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -474,18 +474,28 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
         }
 
         let mut cursor = read_buf.unfilled();
-        loop {
+        let result = loop {
             match r.read_buf(cursor.reborrow()) {
-                Ok(()) => break,
                 Err(e) if e.is_interrupted() => continue,
-                Err(e) => return Err(e),
+                // Do not stop now in case of error: we might have received both data
+                // and an error
+                res => break res,
             }
-        }
+        };
 
         let unfilled_but_initialized = cursor.init_ref().len();
         let bytes_read = cursor.written();
         let was_fully_initialized = read_buf.init_len() == buf_len;
 
+        // SAFETY: BorrowedBuf's invariants mean this much memory is initialized.
+        unsafe {
+            let new_len = bytes_read + buf.len();
+            buf.set_len(new_len);
+        }
+
+        // Now that all data is pushed to the vector, we can fail without data loss
+        result?;
+
         if bytes_read == 0 {
             return Ok(buf.len() - start_len);
         }
@@ -499,12 +509,6 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
         // store how much was initialized but not filled
         initialized = unfilled_but_initialized;
 
-        // SAFETY: BorrowedBuf's invariants mean this much memory is initialized.
-        unsafe {
-            let new_len = bytes_read + buf.len();
-            buf.set_len(new_len);
-        }
-
         // Use heuristics to determine the max read size if no initial size hint was provided
         if size_hint.is_none() {
             // The reader is returning short reads but it doesn't call ensure_init().
@@ -974,6 +978,8 @@ pub trait Read {
     /// with uninitialized buffers. The new data will be appended to any existing contents of `buf`.
     ///
     /// The default implementation delegates to `read`.
+    ///
+    /// This method makes it possible to return both data and an error but it is advised against.
     #[unstable(feature = "read_buf", issue = "78485")]
     fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<()> {
         default_read_buf(|b| self.read(b), buf)
@@ -2941,7 +2947,7 @@ impl<T: Read> Read for Take<T> {
             }
 
             let mut cursor = sliced_buf.unfilled();
-            self.inner.read_buf(cursor.reborrow())?;
+            let result = self.inner.read_buf(cursor.reborrow());
 
             let new_init = cursor.init_ref().len();
             let filled = sliced_buf.len();
@@ -2956,13 +2962,14 @@ impl<T: Read> Read for Take<T> {
             }
 
             self.limit -= filled as u64;
+
+            result
         } else {
             let written = buf.written();
-            self.inner.read_buf(buf.reborrow())?;
+            let result = self.inner.read_buf(buf.reborrow());
             self.limit -= (buf.written() - written) as u64;
+            result
         }
-
-        Ok(())
     }
 }
 
diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs
index f551dcd401e..56b71c47dc7 100644
--- a/library/std/src/io/tests.rs
+++ b/library/std/src/io/tests.rs
@@ -735,6 +735,69 @@ fn read_buf_full_read() {
     assert_eq!(BufReader::new(FullRead).fill_buf().unwrap().len(), DEFAULT_BUF_SIZE);
 }
 
+struct DataAndErrorReader(&'static [u8]);
+
+impl Read for DataAndErrorReader {
+    fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
+        panic!("We want tests to use `read_buf`")
+    }
+
+    fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> {
+        self.0.read_buf(buf).unwrap();
+        Err(io::Error::other("error"))
+    }
+}
+
+#[test]
+fn read_buf_data_and_error_take() {
+    let mut buf = [0; 64];
+    let mut buf = io::BorrowedBuf::from(buf.as_mut_slice());
+
+    let mut r = DataAndErrorReader(&[4, 5, 6]).take(1);
+    assert!(r.read_buf(buf.unfilled()).is_err());
+    assert_eq!(buf.filled(), &[4]);
+
+    assert!(r.read_buf(buf.unfilled()).is_ok());
+    assert_eq!(buf.filled(), &[4]);
+    assert_eq!(r.get_ref().0, &[5, 6]);
+}
+
+#[test]
+fn read_buf_data_and_error_buf() {
+    let mut r = BufReader::new(DataAndErrorReader(&[4, 5, 6]));
+
+    assert!(r.fill_buf().is_err());
+    assert_eq!(r.fill_buf().unwrap(), &[4, 5, 6]);
+}
+
+#[test]
+fn read_buf_data_and_error_read_to_end() {
+    let mut r = DataAndErrorReader(&[4, 5, 6]);
+
+    let mut v = Vec::with_capacity(200);
+    assert!(r.read_to_end(&mut v).is_err());
+
+    assert_eq!(v, &[4, 5, 6]);
+}
+
+#[test]
+fn read_to_end_error() {
+    struct ErrorReader;
+
+    impl Read for ErrorReader {
+        fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
+            Err(io::Error::other("error"))
+        }
+    }
+
+    let mut r = [4, 5, 6].chain(ErrorReader);
+
+    let mut v = Vec::with_capacity(200);
+    assert!(r.read_to_end(&mut v).is_err());
+
+    assert_eq!(v, &[4, 5, 6]);
+}
+
 #[test]
 // Miri does not support signalling OOM
 #[cfg_attr(miri, ignore)]
diff --git a/library/std/src/net/udp.rs b/library/std/src/net/udp.rs
index d4252cb87ac..8c9e31f9c15 100644
--- a/library/std/src/net/udp.rs
+++ b/library/std/src/net/udp.rs
@@ -579,8 +579,8 @@ impl UdpSocket {
     /// This function specifies a new multicast group for this socket to join.
     /// The address must be a valid multicast address, and `interface` is the
     /// address of the local interface with which the system should join the
-    /// multicast group. If it's equal to `INADDR_ANY` then an appropriate
-    /// interface is chosen by the system.
+    /// multicast group. If it's equal to [`UNSPECIFIED`](Ipv4Addr::UNSPECIFIED)
+    /// then an appropriate interface is chosen by the system.
     #[stable(feature = "net2_mutators", since = "1.9.0")]
     pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
         self.0.join_multicast_v4(multiaddr, interface)
diff --git a/src/ci/scripts/select-xcode.sh b/src/ci/scripts/select-xcode.sh
index d635d438472..569c4a4136d 100755
--- a/src/ci/scripts/select-xcode.sh
+++ b/src/ci/scripts/select-xcode.sh
@@ -1,6 +1,5 @@
 #!/bin/bash
 # This script selects the Xcode instance to use.
-# It also tries to do some cleanup in CI jobs of unused Xcodes.
 
 set -euo pipefail
 IFS=$'\n\t'
@@ -8,21 +7,5 @@ IFS=$'\n\t'
 source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
 
 if isMacOS; then
-    # This additional step is to try to remove an Xcode we aren't using because each one is HUGE
-    old_xcode="$(xcode-select --print-path)"
-    old_xcode="${old_xcode%/*}" # pop a dir
-    old_xcode="${old_xcode%/*}" # twice
-    if [[ $old_xcode =~ $SELECT_XCODE ]]; then
-        echo "xcode-select.sh's brutal hack may not be necessary?"
-        exit 1
-    elif [[ $SELECT_XCODE =~ "16" ]]; then
-        echo "Using Xcode 16? Please fix xcode-select.sh"
-        exit 1
-    fi
-    if [ $CI ]; then # just in case someone sources this on their real computer
-        sudo rm -rf "${old_xcode}"
-        xcode_16="${old_xcode%/*}/Xcode-16.0.0.app"
-        sudo rm -rf "${xcode_16}"
-    fi
     sudo xcode-select -s "${SELECT_XCODE}"
 fi
diff --git a/src/ci/scripts/upload-artifacts.sh b/src/ci/scripts/upload-artifacts.sh
index 61c187fa77c..0bc91f6ba71 100755
--- a/src/ci/scripts/upload-artifacts.sh
+++ b/src/ci/scripts/upload-artifacts.sh
@@ -23,14 +23,14 @@ if [[ "${DEPLOY-0}" -eq "1" ]] || [[ "${DEPLOY_ALT-0}" -eq "1" ]]; then
 fi
 
 # CPU usage statistics.
-mv build/cpu-usage.csv "${upload_dir}/cpu-${CI_JOB_NAME}.csv"
+cp build/cpu-usage.csv "${upload_dir}/cpu-${CI_JOB_NAME}.csv"
 
 # Build metrics generated by x.py.
-mv "${build_dir}/metrics.json" "${upload_dir}/metrics-${CI_JOB_NAME}.json"
+cp "${build_dir}/metrics.json" "${upload_dir}/metrics-${CI_JOB_NAME}.json"
 
 # Toolstate data.
 if [[ -n "${DEPLOY_TOOLSTATES_JSON+x}" ]]; then
-    mv /tmp/toolstate/toolstates.json "${upload_dir}/${DEPLOY_TOOLSTATES_JSON}"
+    cp /tmp/toolstate/toolstates.json "${upload_dir}/${DEPLOY_TOOLSTATES_JSON}"
 fi
 
 echo "Files that will be uploaded:"
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index ef21779b099..b3707cf6157 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -1168,7 +1168,7 @@ pub struct ProcMacro {
     pub kind: MacroKind,
     /// Helper attributes defined by a macro to be used inside it.
     ///
-    /// Defined only for attribute & derive macros.
+    /// Defined only for derive macros.
     ///
     /// E.g. the [`Default`] derive macro defines a `#[default]` helper attribute so that one can
     /// do:
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index 2071abefbe1..86cae849b97 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -795,7 +795,6 @@ ui/consts/issue-68684.rs
 ui/consts/issue-69191-ice-on-uninhabited-enum-field.rs
 ui/consts/issue-69310-array-size-lit-wrong-ty.rs
 ui/consts/issue-69312.rs
-ui/consts/issue-69488.rs
 ui/consts/issue-69532.rs
 ui/consts/issue-6991.rs
 ui/consts/issue-70773-mir-typeck-lt-norm.rs
@@ -2745,14 +2744,12 @@ ui/lint/issue-111359.rs
 ui/lint/issue-112489.rs
 ui/lint/issue-117949.rs
 ui/lint/issue-121070-let-range.rs
-ui/lint/issue-14309.rs
 ui/lint/issue-14837.rs
 ui/lint/issue-17718-const-naming.rs
 ui/lint/issue-1866.rs
 ui/lint/issue-19102.rs
 ui/lint/issue-20343.rs
 ui/lint/issue-30302.rs
-ui/lint/issue-34798.rs
 ui/lint/issue-35075.rs
 ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs
 ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs
diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs
index d7c6c50d8be..18566acc07f 100644
--- a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs
+++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs
@@ -15,6 +15,12 @@ fn change_lt_ba<'a, 'b: 'a>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> {
     x as _ //~ error: lifetime may not live long enough
 }
 
+fn change_lt_hr<'a>(x: *mut dyn Trait<'a>) -> *mut dyn for<'b> Trait<'b> {
+    x as _ //~ error: lifetime may not live long enough
+    //~^ error: mismatched types
+    //~| one type is more general than the other
+}
+
 trait Assocked {
     type Assoc: ?Sized;
 }
diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr
index 6069f4f3b55..6f590585c4a 100644
--- a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr
+++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr
@@ -61,7 +61,29 @@ LL |     x as _
    = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
 
 error: lifetime may not live long enough
-  --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:25:5
+  --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:19:5
+   |
+LL | fn change_lt_hr<'a>(x: *mut dyn Trait<'a>) -> *mut dyn for<'b> Trait<'b> {
+   |                 -- lifetime `'a` defined here
+LL |     x as _
+   |     ^^^^^^ cast requires that `'a` must outlive `'static`
+   |
+help: to declare that the trait object captures data from argument `x`, you can add an explicit `'a` lifetime bound
+   |
+LL | fn change_lt_hr<'a>(x: *mut dyn Trait<'a>) -> *mut dyn for<'b> Trait<'b> + 'a {
+   |                                                                          ++++
+
+error[E0308]: mismatched types
+  --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:19:5
+   |
+LL |     x as _
+   |     ^^^^^^ one type is more general than the other
+   |
+   = note: expected trait object `dyn for<'b> Trait<'b>`
+              found trait object `dyn Trait<'_>`
+
+error: lifetime may not live long enough
+  --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:31:5
    |
 LL | fn change_assoc_0<'a, 'b>(
    |                   --  -- lifetime `'b` defined here
@@ -77,7 +99,7 @@ LL |     x as _
    = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
 
 error: lifetime may not live long enough
-  --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:25:5
+  --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:31:5
    |
 LL | fn change_assoc_0<'a, 'b>(
    |                   --  -- lifetime `'b` defined here
@@ -97,7 +119,7 @@ help: `'b` and `'a` must be the same: replace one with the other
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: lifetime may not live long enough
-  --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5
+  --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:38:5
    |
 LL | fn change_assoc_1<'a, 'b>(
    |                   --  -- lifetime `'b` defined here
@@ -113,7 +135,7 @@ LL |     x as _
    = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
 
 error: lifetime may not live long enough
-  --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5
+  --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:38:5
    |
 LL | fn change_assoc_1<'a, 'b>(
    |                   --  -- lifetime `'b` defined here
@@ -133,12 +155,13 @@ help: `'b` and `'a` must be the same: replace one with the other
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: lifetime may not live long enough
-  --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:39:20
+  --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:45:20
    |
 LL | fn extend_to_static<'a>(ptr: *const dyn Trait<'a>) {
    |                     -- lifetime `'a` defined here
 LL |     require_static(ptr as _)
    |                    ^^^^^^^^ cast requires that `'a` must outlive `'static`
 
-error: aborting due to 9 previous errors
+error: aborting due to 11 previous errors
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/cast/ptr-to-trait-obj-ok.rs b/tests/ui/cast/ptr-to-trait-obj-ok.rs
index 656c99c58dc..dbeee9d2944 100644
--- a/tests/ui/cast/ptr-to-trait-obj-ok.rs
+++ b/tests/ui/cast/ptr-to-trait-obj-ok.rs
@@ -10,8 +10,37 @@ fn cast_inherent_lt<'a, 'b>(x: *mut (dyn Trait<'static> + 'a)) -> *mut (dyn Trai
     x as _
 }
 
+fn cast_away_higher_ranked<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut dyn Trait<'a> {
+    x as _
+}
+
 fn unprincipled<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) {
     x as _
 }
 
+// If it is possible to coerce from the source to the target type modulo
+// regions, then we skip the HIR checks for ptr-to-ptr casts and possibly
+// insert an unsizing coercion into the MIR before the ptr-to-ptr cast.
+// By wrapping the target type, we ensure that no coercion happens
+// and also test the non-coercion cast behavior.
+struct Wrapper<T: ?Sized>(T);
+
+fn remove_auto_wrap<'a>(x: *mut (dyn Trait<'a> + Send)) -> *mut Wrapper<dyn Trait<'a>> {
+    x as _
+}
+
+fn cast_inherent_lt_wrap<'a, 'b>(
+    x: *mut (dyn Trait<'static> + 'a),
+) -> *mut Wrapper<dyn Trait<'static> + 'b> {
+    x as _
+}
+
+fn cast_away_higher_ranked_wrap<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut Wrapper<dyn Trait<'a>> {
+    x as _
+}
+
+fn unprincipled_wrap<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Sync + 'b> {
+    x as _
+}
+
 fn main() {}
diff --git a/tests/ui/coercion/sub-principals.rs b/tests/ui/coercion/sub-principals.rs
new file mode 100644
index 00000000000..c38769f0d09
--- /dev/null
+++ b/tests/ui/coercion/sub-principals.rs
@@ -0,0 +1,27 @@
+//@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+// Verify that the unsize goal can cast a higher-ranked trait goal to
+// a non-higer-ranked instantiation.
+
+#![feature(unsize)]
+
+use std::marker::Unsize;
+
+fn test<T: ?Sized, U: ?Sized>()
+where
+    T: Unsize<U>,
+{
+}
+
+fn main() {
+    test::<dyn for<'a> Fn(&'a ()) -> &'a (), dyn Fn(&'static ()) -> &'static ()>();
+
+    trait Foo<'a, 'b> {}
+    test::<dyn for<'a, 'b> Foo<'a, 'b>, dyn for<'a> Foo<'a, 'a>>();
+
+    trait Bar<'a> {}
+    test::<dyn for<'a> Bar<'a>, dyn Bar<'_>>();
+}
diff --git a/tests/ui/consts/issue-69488.rs b/tests/ui/consts/load-preserves-partial-init.rs
index d528d6a88de..d97e9cb3d9d 100644
--- a/tests/ui/consts/issue-69488.rs
+++ b/tests/ui/consts/load-preserves-partial-init.rs
@@ -1,6 +1,9 @@
 //@ run-pass
 
 #![feature(const_ptr_write)]
+// issue: https://github.com/rust-lang/rust/issues/69488
+// Loads of partially-initialized data could produce completely-uninitialized results.
+// Test to make sure that we no longer do such a "deinitializing" load.
 
 // Or, equivalently: `MaybeUninit`.
 pub union BagOfBits<T: Copy> {
diff --git a/tests/ui/lint/clashing-extern-fn-issue-130851.rs b/tests/ui/lint/clashing-extern-fn-issue-130851.rs
new file mode 100644
index 00000000000..1b2fdf1d3fc
--- /dev/null
+++ b/tests/ui/lint/clashing-extern-fn-issue-130851.rs
@@ -0,0 +1,42 @@
+//@ build-pass
+#![warn(clashing_extern_declarations)]
+
+#[repr(C)]
+pub struct A {
+    a: [u16; 4],
+}
+#[repr(C)]
+pub struct B {
+    b: [u32; 4],
+}
+
+pub mod a {
+    extern "C" {
+        pub fn foo(_: super::A);
+    }
+}
+pub mod b {
+    extern "C" {
+        pub fn foo(_: super::B);
+        //~^ WARN `foo` redeclared with a different signature
+    }
+}
+
+#[repr(C)]
+pub struct G<T> {
+    g: [T; 4],
+}
+
+pub mod x {
+    extern "C" {
+        pub fn bar(_: super::G<u16>);
+    }
+}
+pub mod y {
+    extern "C" {
+        pub fn bar(_: super::G<u32>);
+        //~^ WARN `bar` redeclared with a different signature
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/clashing-extern-fn-issue-130851.stderr b/tests/ui/lint/clashing-extern-fn-issue-130851.stderr
new file mode 100644
index 00000000000..c38ec404047
--- /dev/null
+++ b/tests/ui/lint/clashing-extern-fn-issue-130851.stderr
@@ -0,0 +1,31 @@
+warning: `foo` redeclared with a different signature
+  --> $DIR/clashing-extern-fn-issue-130851.rs:20:9
+   |
+LL |         pub fn foo(_: super::A);
+   |         ------------------------ `foo` previously declared here
+...
+LL |         pub fn foo(_: super::B);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+   |
+   = note: expected `unsafe extern "C" fn(A)`
+              found `unsafe extern "C" fn(B)`
+note: the lint level is defined here
+  --> $DIR/clashing-extern-fn-issue-130851.rs:2:9
+   |
+LL | #![warn(clashing_extern_declarations)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: `bar` redeclared with a different signature
+  --> $DIR/clashing-extern-fn-issue-130851.rs:37:9
+   |
+LL |         pub fn bar(_: super::G<u16>);
+   |         ----------------------------- `bar` previously declared here
+...
+LL |         pub fn bar(_: super::G<u32>);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+   |
+   = note: expected `unsafe extern "C" fn(G<u16>)`
+              found `unsafe extern "C" fn(G<u32>)`
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/lint/issue-34798.rs b/tests/ui/lint/improper_ctypes/allow-phantomdata-in-ffi.rs
index 064fc7c4ad6..a90159d2b58 100644
--- a/tests/ui/lint/issue-34798.rs
+++ b/tests/ui/lint/improper_ctypes/allow-phantomdata-in-ffi.rs
@@ -1,6 +1,8 @@
 //@ run-pass
 #![forbid(improper_ctypes)]
 #![allow(dead_code)]
+// issue https://github.com/rust-lang/rust/issues/34798
+// We allow PhantomData in FFI so bindgen can bind templated C++ structs with "unused generic args"
 
 #[repr(C)]
 pub struct Foo {
diff --git a/tests/ui/lint/issue-14309.rs b/tests/ui/lint/improper_ctypes/repr-rust-is-undefined.rs
index 328a4c982b8..379c4132404 100644
--- a/tests/ui/lint/issue-14309.rs
+++ b/tests/ui/lint/improper_ctypes/repr-rust-is-undefined.rs
@@ -1,6 +1,10 @@
 #![deny(improper_ctypes)]
 #![allow(dead_code)]
 
+// issue https://github.com/rust-lang/rust/issues/14309
+// Validates we lint on repr(Rust) structs and not repr(C) structs in FFI, to implement RFC 79:
+// https://rust-lang.github.io/rfcs/0079-undefined-struct-layout.html
+
 struct A {
     x: i32
 }
diff --git a/tests/ui/lint/issue-14309.stderr b/tests/ui/lint/improper_ctypes/repr-rust-is-undefined.stderr
index 9ce62a6b804..5f0465bcf00 100644
--- a/tests/ui/lint/issue-14309.stderr
+++ b/tests/ui/lint/improper_ctypes/repr-rust-is-undefined.stderr
@@ -1,5 +1,5 @@
 error: `extern` block uses type `A`, which is not FFI-safe
-  --> $DIR/issue-14309.rs:30:15
+  --> $DIR/repr-rust-is-undefined.rs:34:15
    |
 LL |     fn foo(x: A);
    |               ^ not FFI-safe
@@ -7,18 +7,18 @@ LL |     fn foo(x: A);
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
    = note: this struct has unspecified layout
 note: the type is defined here
-  --> $DIR/issue-14309.rs:4:1
+  --> $DIR/repr-rust-is-undefined.rs:8:1
    |
 LL | struct A {
    | ^^^^^^^^
 note: the lint level is defined here
-  --> $DIR/issue-14309.rs:1:9
+  --> $DIR/repr-rust-is-undefined.rs:1:9
    |
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
 
 error: `extern` block uses type `A`, which is not FFI-safe
-  --> $DIR/issue-14309.rs:31:15
+  --> $DIR/repr-rust-is-undefined.rs:35:15
    |
 LL |     fn bar(x: B);
    |               ^ not FFI-safe
@@ -26,13 +26,13 @@ LL |     fn bar(x: B);
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
    = note: this struct has unspecified layout
 note: the type is defined here
-  --> $DIR/issue-14309.rs:4:1
+  --> $DIR/repr-rust-is-undefined.rs:8:1
    |
 LL | struct A {
    | ^^^^^^^^
 
 error: `extern` block uses type `A`, which is not FFI-safe
-  --> $DIR/issue-14309.rs:33:15
+  --> $DIR/repr-rust-is-undefined.rs:37:15
    |
 LL |     fn qux(x: A2);
    |               ^^ not FFI-safe
@@ -40,13 +40,13 @@ LL |     fn qux(x: A2);
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
    = note: this struct has unspecified layout
 note: the type is defined here
-  --> $DIR/issue-14309.rs:4:1
+  --> $DIR/repr-rust-is-undefined.rs:8:1
    |
 LL | struct A {
    | ^^^^^^^^
 
 error: `extern` block uses type `A`, which is not FFI-safe
-  --> $DIR/issue-14309.rs:34:16
+  --> $DIR/repr-rust-is-undefined.rs:38:16
    |
 LL |     fn quux(x: B2);
    |                ^^ not FFI-safe
@@ -54,13 +54,13 @@ LL |     fn quux(x: B2);
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
    = note: this struct has unspecified layout
 note: the type is defined here
-  --> $DIR/issue-14309.rs:4:1
+  --> $DIR/repr-rust-is-undefined.rs:8:1
    |
 LL | struct A {
    | ^^^^^^^^
 
 error: `extern` block uses type `A`, which is not FFI-safe
-  --> $DIR/issue-14309.rs:36:16
+  --> $DIR/repr-rust-is-undefined.rs:40:16
    |
 LL |     fn fred(x: D);
    |                ^ not FFI-safe
@@ -68,7 +68,7 @@ LL |     fn fred(x: D);
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
    = note: this struct has unspecified layout
 note: the type is defined here
-  --> $DIR/issue-14309.rs:4:1
+  --> $DIR/repr-rust-is-undefined.rs:8:1
    |
 LL | struct A {
    | ^^^^^^^^
diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.current.stderr b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.current.stderr
deleted file mode 100644
index 098ab71e946..00000000000
--- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.current.stderr
+++ /dev/null
@@ -1,22 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/higher-ranked-upcasting-ok.rs:17:5
-   |
-LL |     x
-   |     ^ one type is more general than the other
-   |
-   = note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
-              found existential trait ref `for<'a> Supertrait<'a, 'a>`
-
-error[E0308]: mismatched types
-  --> $DIR/higher-ranked-upcasting-ok.rs:17:5
-   |
-LL |     x
-   |     ^ one type is more general than the other
-   |
-   = note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
-              found existential trait ref `for<'a> Supertrait<'a, 'a>`
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.next.stderr b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.next.stderr
deleted file mode 100644
index ac516fd6975..00000000000
--- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.next.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/higher-ranked-upcasting-ok.rs:17:5
-   |
-LL | fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> {
-   |                                                ------------------------------- expected `&dyn for<'a> Supertrait<'a, 'a>` because of return type
-LL |     x
-   |     ^ expected trait `Supertrait`, found trait `Subtrait`
-   |
-   = note: expected reference `&dyn for<'a> Supertrait<'a, 'a>`
-              found reference `&dyn for<'a, 'b> Subtrait<'a, 'b>`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs
index 00743203179..7f793e1269f 100644
--- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs
+++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs
@@ -1,19 +1,21 @@
 //@ revisions: current next
 //@ ignore-compare-mode-next-solver (explicit revisions)
 //@[next] compile-flags: -Znext-solver
+//@ check-pass
 
 // We should be able to instantiate a binder during trait upcasting.
 // This test could be `check-pass`, but we should make sure that we
 // do so in both trait solvers.
+
 #![feature(trait_upcasting)]
-#![crate_type = "rlib"]
-trait Supertrait<'a, 'b> {}
 
+trait Supertrait<'a, 'b> {}
 trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {}
 
 impl<'a> Supertrait<'a, 'a> for () {}
 impl<'a> Subtrait<'a, 'a> for () {}
 fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> {
-    x //~ ERROR mismatched types
-    //[current]~^ ERROR mismatched types
+    x
 }
+
+fn main() {}
diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr
index bac82983268..e5885ea35a7 100644
--- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr
+++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     x
    |     ^ one type is more general than the other
    |
-   = note: expected existential trait ref `for<'a> Supertrait<'a, 'a>`
-              found existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
+   = note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
+              found existential trait ref `for<'a> Supertrait<'a, 'a>`
 
 error[E0308]: mismatched types
   --> $DIR/higher-ranked-upcasting-ub.rs:22:5
@@ -13,8 +13,8 @@ error[E0308]: mismatched types
 LL |     x
    |     ^ one type is more general than the other
    |
-   = note: expected existential trait ref `for<'a> Supertrait<'a, 'a>`
-              found existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
+   = note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
+              found existential trait ref `for<'a> Supertrait<'a, 'a>`
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/traits/trait-upcasting/sub.rs b/tests/ui/traits/trait-upcasting/sub.rs
new file mode 100644
index 00000000000..255c4895b7f
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/sub.rs
@@ -0,0 +1,26 @@
+//@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+// Verify that the unsize goal can cast a higher-ranked trait goal to
+// a non-higer-ranked instantiation.
+
+#![feature(unsize)]
+
+use std::marker::Unsize;
+
+fn test<T: ?Sized, U: ?Sized>()
+where
+    T: Unsize<U>,
+{
+}
+
+fn main() {
+    test::<dyn for<'a> Fn(&'a ()) -> &'a (), dyn FnOnce(&'static ()) -> &'static ()>();
+
+    trait Foo: for<'a> Bar<'a> {}
+    trait Bar<'a> {}
+    test::<dyn Foo, dyn Bar<'static>>();
+    test::<dyn Foo, dyn Bar<'_>>();
+}