about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-06-05 20:53:32 +0000
committerbors <bors@rust-lang.org>2024-06-05 20:53:32 +0000
commit72fdf913c53dd0e75313ba83e4aa80df3f6e2871 (patch)
tree5829faefbcc8109308bf1c33fe5f0031e3f878c2
parent7ebd2bdbf6d798e6e711a0100981b0ff029abf5f (diff)
parentfa58891f992b09dddd42cb90099d54ea04282a9a (diff)
downloadrust-72fdf913c53dd0e75313ba83e4aa80df3f6e2871.tar.gz
rust-72fdf913c53dd0e75313ba83e4aa80df3f6e2871.zip
Auto merge of #126038 - matthiaskrgr:rollup-h4rm3x2, r=matthiaskrgr
Rollup of 9 pull requests

Successful merges:

 - #124840 (resolve: mark it undetermined if single import is not has any bindings)
 - #125622 (Winnow private method candidates instead of assuming any candidate of the right name will apply)
 - #125648 (Remove unused(?) `~/rustsrc` folder from docker script)
 - #125672 (Add more ABI test cases to miri (RFC 3391))
 - #125800 (Fix `mut` static task queue in SGX target)
 - #125871 (Orphanck[old solver]: Consider opaque types to never cover type parameters)
 - #125893 (Handle all GVN binops in a single place.)
 - #126008 (Port `tests/run-make-fulldeps/issue-19371` to ui-fulldeps)
 - #126032 (Update description of the `IsTerminal` example)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs31
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs28
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs70
-rw-r--r--compiler/rustc_resolve/src/ident.rs29
-rw-r--r--compiler/rustc_resolve/src/imports.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs59
-rw-r--r--library/std/src/io/stdio.rs5
-rw-r--r--library/std/src/sys/pal/sgx/thread.rs18
-rw-r--r--library/std/src/thread/mod.rs5
-rwxr-xr-xsrc/ci/docker/run.sh1
-rw-r--r--src/ci/github-actions/jobs.yml6
-rw-r--r--src/tools/compiletest/src/header.rs10
-rw-r--r--src/tools/miri/tests/pass/function_calls/abi_compat.rs16
-rw-r--r--src/tools/tidy/src/issues.txt1
-rw-r--r--src/tools/tidy/src/ui_tests.rs2
-rw-r--r--tests/crashes/124490.rs16
-rw-r--r--tests/crashes/125013-1.rs5
-rw-r--r--tests/crashes/125013-2.rs16
-rw-r--r--tests/run-make-fulldeps/issue-19371/Makefile9
-rw-r--r--tests/ui-fulldeps/run-compiler-twice.rs (renamed from tests/run-make-fulldeps/issue-19371/foo.rs)38
-rw-r--r--tests/ui/coherence/orphan-check-opaque-types-not-covering.classic.stderr21
-rw-r--r--tests/ui/coherence/orphan-check-opaque-types-not-covering.next.stderr21
-rw-r--r--tests/ui/coherence/orphan-check-opaque-types-not-covering.rs31
-rw-r--r--tests/ui/imports/cycle-import-in-diff-module-0.rs14
-rw-r--r--tests/ui/imports/cycle-import-in-diff-module-1.rs14
-rw-r--r--tests/ui/imports/shadow-glob-module-resolution-1.rs17
-rw-r--r--tests/ui/imports/shadow-glob-module-resolution-1.stderr23
-rw-r--r--tests/ui/imports/shadow-glob-module-resolution-2.rs19
-rw-r--r--tests/ui/imports/shadow-glob-module-resolution-2.stderr26
-rw-r--r--tests/ui/issues/issue-53498.rs17
-rw-r--r--tests/ui/privacy/ufc-method-call.different_name.stderr15
-rw-r--r--tests/ui/privacy/ufc-method-call.rs30
-rw-r--r--tests/ui/privacy/ufc-method-call.same_name.stderr (renamed from tests/ui/issues/issue-53498.stderr)2
-rw-r--r--tests/ui/type-alias-impl-trait/coherence.classic.stderr (renamed from tests/ui/type-alias-impl-trait/coherence.stderr)2
-rw-r--r--tests/ui/type-alias-impl-trait/coherence.next.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/coherence.rs2
37 files changed, 455 insertions, 190 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index 0649bb5617c..cbfe25ca8df 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -294,17 +294,30 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
 
     /// Unwrap types that are guaranteed a null-pointer-optimization
     fn unfold_npo(&self, layout: TyAndLayout<'tcx>) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
-        // Check if this is `Option` wrapping some type.
-        let inner = match layout.ty.kind() {
-            ty::Adt(def, args) if self.tcx.is_diagnostic_item(sym::Option, def.did()) => {
-                args[0].as_type().unwrap()
-            }
-            _ => {
-                // Not an `Option`.
-                return Ok(layout);
+        // Check if this is `Option` wrapping some type or if this is `Result` wrapping a 1-ZST and
+        // another type.
+        let ty::Adt(def, args) = layout.ty.kind() else {
+            // Not an ADT, so definitely no NPO.
+            return Ok(layout);
+        };
+        let inner = if self.tcx.is_diagnostic_item(sym::Option, def.did()) {
+            // The wrapped type is the only arg.
+            self.layout_of(args[0].as_type().unwrap())?
+        } else if self.tcx.is_diagnostic_item(sym::Result, def.did()) {
+            // We want to extract which (if any) of the args is not a 1-ZST.
+            let lhs = self.layout_of(args[0].as_type().unwrap())?;
+            let rhs = self.layout_of(args[1].as_type().unwrap())?;
+            if lhs.is_1zst() {
+                rhs
+            } else if rhs.is_1zst() {
+                lhs
+            } else {
+                return Ok(layout); // no NPO
             }
+        } else {
+            return Ok(layout); // no NPO
         };
-        let inner = self.layout_of(inner)?;
+
         // Check if the inner type is one of the NPO-guaranteed ones.
         // For that we first unpeel transparent *structs* (but not unions).
         let is_npo = |def: AdtDef<'tcx>| {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 084639ad40c..157b0be6164 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -1066,7 +1066,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     ty::ImplContainer => {
                         if segments.len() == 1 {
                             // `<T>::assoc` will end up here, and so
-                            // can `T::assoc`. It this came from an
+                            // can `T::assoc`. If this came from an
                             // inherent impl, we need to record the
                             // `T` for posterity (see `UserSelfTy` for
                             // details).
@@ -1416,11 +1416,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ) {
                 Ok(ok) => self.register_infer_ok_obligations(ok),
                 Err(_) => {
-                    self.dcx().span_delayed_bug(
+                    self.dcx().span_bug(
                         span,
                         format!(
-                        "instantiate_value_path: (UFCS) {self_ty:?} was a subtype of {impl_ty:?} but now is not?",
-                    ),
+                            "instantiate_value_path: (UFCS) {self_ty:?} was a subtype of {impl_ty:?} but now is not?",
+                        ),
                     );
                 }
             }
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 12ced49f92f..ab0f16bd87d 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -41,6 +41,7 @@ use rustc_trait_selection::traits::query::method_autoderef::{
 use rustc_trait_selection::traits::query::CanonicalTyGoal;
 use rustc_trait_selection::traits::ObligationCtxt;
 use rustc_trait_selection::traits::{self, ObligationCause};
+use std::cell::Cell;
 use std::cell::RefCell;
 use std::cmp::max;
 use std::iter;
@@ -76,8 +77,12 @@ pub(crate) struct ProbeContext<'a, 'tcx> {
     /// requested name (by edit distance)
     allow_similar_names: bool,
 
+    /// List of potential private candidates. Will be trimmed to ones that
+    /// actually apply and then the result inserted into `private_candidate`
+    private_candidates: Vec<Candidate<'tcx>>,
+
     /// Some(candidate) if there is a private candidate
-    private_candidate: Option<(DefKind, DefId)>,
+    private_candidate: Cell<Option<(DefKind, DefId)>>,
 
     /// Collects near misses when the candidate functions are missing a `self` keyword and is only
     /// used for error reporting
@@ -581,7 +586,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             orig_steps_var_values,
             steps,
             allow_similar_names: false,
-            private_candidate: None,
+            private_candidates: Vec::new(),
+            private_candidate: Cell::new(None),
             static_candidates: RefCell::new(Vec::new()),
             unsatisfied_predicates: RefCell::new(Vec::new()),
             scope_expr_id,
@@ -593,7 +599,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         self.inherent_candidates.clear();
         self.extension_candidates.clear();
         self.impl_dups.clear();
-        self.private_candidate = None;
+        self.private_candidates.clear();
+        self.private_candidate.set(None);
         self.static_candidates.borrow_mut().clear();
         self.unsatisfied_predicates.borrow_mut().clear();
     }
@@ -617,9 +624,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             } else {
                 self.extension_candidates.push(candidate);
             }
-        } else if self.private_candidate.is_none() {
-            self.private_candidate =
-                Some((candidate.item.kind.as_def_kind(), candidate.item.def_id));
+        } else {
+            self.private_candidates.push(candidate);
         }
     }
 
@@ -1171,7 +1177,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         let mut possibly_unsatisfied_predicates = Vec::new();
 
         for (kind, candidates) in
-            &[("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)]
+            [("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)]
         {
             debug!("searching {} candidates", kind);
             let res = self.consider_candidates(
@@ -1185,6 +1191,14 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             }
         }
 
+        if self.private_candidate.get().is_none() {
+            if let Some(Ok(pick)) =
+                self.consider_candidates(self_ty, &self.private_candidates, &mut vec![], None)
+            {
+                self.private_candidate.set(Some((pick.item.kind.as_def_kind(), pick.item.def_id)));
+            }
+        }
+
         // `pick_method` may be called twice for the same self_ty if no stable methods
         // match. Only extend once.
         if unstable_candidates.is_some() {
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index fadb5edefdf..548e4e30936 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -223,7 +223,6 @@ enum Value<'tcx> {
     NullaryOp(NullOp<'tcx>, Ty<'tcx>),
     UnaryOp(UnOp, VnIndex),
     BinaryOp(BinOp, VnIndex, VnIndex),
-    CheckedBinaryOp(BinOp, VnIndex, VnIndex), // FIXME get rid of this, work like MIR instead
     Cast {
         kind: CastKind,
         value: VnIndex,
@@ -508,17 +507,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                 let val = self.ecx.binary_op(bin_op, &lhs, &rhs).ok()?;
                 val.into()
             }
-            CheckedBinaryOp(bin_op, lhs, rhs) => {
-                let lhs = self.evaluated[lhs].as_ref()?;
-                let lhs = self.ecx.read_immediate(lhs).ok()?;
-                let rhs = self.evaluated[rhs].as_ref()?;
-                let rhs = self.ecx.read_immediate(rhs).ok()?;
-                let val = self
-                    .ecx
-                    .binary_op(bin_op.wrapping_to_overflowing().unwrap(), &lhs, &rhs)
-                    .ok()?;
-                val.into()
-            }
             Cast { kind, value, from: _, to } => match kind {
                 CastKind::IntToInt | CastKind::IntToFloat => {
                     let value = self.evaluated[value].as_ref()?;
@@ -829,17 +817,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                 let lhs = lhs?;
                 let rhs = rhs?;
 
-                if let Some(op) = op.overflowing_to_wrapping() {
-                    if let Some(value) = self.simplify_binary(op, true, ty, lhs, rhs) {
-                        return Some(value);
-                    }
-                    Value::CheckedBinaryOp(op, lhs, rhs)
-                } else {
-                    if let Some(value) = self.simplify_binary(op, false, ty, lhs, rhs) {
-                        return Some(value);
-                    }
-                    Value::BinaryOp(op, lhs, rhs)
+                if let Some(value) = self.simplify_binary(op, ty, lhs, rhs) {
+                    return Some(value);
                 }
+                Value::BinaryOp(op, lhs, rhs)
             }
             Rvalue::UnaryOp(op, ref mut arg) => {
                 let arg = self.simplify_operand(arg, location)?;
@@ -970,7 +951,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
     fn simplify_binary(
         &mut self,
         op: BinOp,
-        checked: bool,
         lhs_ty: Ty<'tcx>,
         lhs: VnIndex,
         rhs: VnIndex,
@@ -999,22 +979,39 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         use Either::{Left, Right};
         let a = as_bits(lhs).map_or(Right(lhs), Left);
         let b = as_bits(rhs).map_or(Right(rhs), Left);
+
         let result = match (op, a, b) {
             // Neutral elements.
-            (BinOp::Add | BinOp::BitOr | BinOp::BitXor, Left(0), Right(p))
+            (
+                BinOp::Add
+                | BinOp::AddWithOverflow
+                | BinOp::AddUnchecked
+                | BinOp::BitOr
+                | BinOp::BitXor,
+                Left(0),
+                Right(p),
+            )
             | (
                 BinOp::Add
+                | BinOp::AddWithOverflow
+                | BinOp::AddUnchecked
                 | BinOp::BitOr
                 | BinOp::BitXor
                 | BinOp::Sub
+                | BinOp::SubWithOverflow
+                | BinOp::SubUnchecked
                 | BinOp::Offset
                 | BinOp::Shl
                 | BinOp::Shr,
                 Right(p),
                 Left(0),
             )
-            | (BinOp::Mul, Left(1), Right(p))
-            | (BinOp::Mul | BinOp::Div, Right(p), Left(1)) => p,
+            | (BinOp::Mul | BinOp::MulWithOverflow | BinOp::MulUnchecked, Left(1), Right(p))
+            | (
+                BinOp::Mul | BinOp::MulWithOverflow | BinOp::MulUnchecked | BinOp::Div,
+                Right(p),
+                Left(1),
+            ) => p,
             // Attempt to simplify `x & ALL_ONES` to `x`, with `ALL_ONES` depending on type size.
             (BinOp::BitAnd, Right(p), Left(ones)) | (BinOp::BitAnd, Left(ones), Right(p))
                 if ones == layout.size.truncate(u128::MAX)
@@ -1023,10 +1020,21 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                 p
             }
             // Absorbing elements.
-            (BinOp::Mul | BinOp::BitAnd, _, Left(0))
+            (
+                BinOp::Mul | BinOp::MulWithOverflow | BinOp::MulUnchecked | BinOp::BitAnd,
+                _,
+                Left(0),
+            )
             | (BinOp::Rem, _, Left(1))
             | (
-                BinOp::Mul | BinOp::Div | BinOp::Rem | BinOp::BitAnd | BinOp::Shl | BinOp::Shr,
+                BinOp::Mul
+                | BinOp::MulWithOverflow
+                | BinOp::MulUnchecked
+                | BinOp::Div
+                | BinOp::Rem
+                | BinOp::BitAnd
+                | BinOp::Shl
+                | BinOp::Shr,
                 Left(0),
                 _,
             ) => self.insert_scalar(Scalar::from_uint(0u128, layout.size), lhs_ty),
@@ -1038,7 +1046,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                 self.insert_scalar(Scalar::from_uint(ones, layout.size), lhs_ty)
             }
             // Sub/Xor with itself.
-            (BinOp::Sub | BinOp::BitXor, a, b) if a == b => {
+            (BinOp::Sub | BinOp::SubWithOverflow | BinOp::SubUnchecked | BinOp::BitXor, a, b)
+                if a == b =>
+            {
                 self.insert_scalar(Scalar::from_uint(0u128, layout.size), lhs_ty)
             }
             // Comparison:
@@ -1052,7 +1062,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             _ => return None,
         };
 
-        if checked {
+        if op.is_overflowing() {
             let false_val = self.insert_bool(false);
             Some(self.insert_tuple(vec![result, false_val]))
         } else {
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 57db765c07e..78bd3c4e49f 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -965,6 +965,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         // if it can then our result is not determined and can be invalidated.
         for single_import in &resolution.single_imports {
             let Some(import_vis) = single_import.vis.get() else {
+                // This branch handles a cycle in single imports, which occurs
+                // when we've previously captured the `vis` value during an import
+                // process.
+                //
+                // For example:
+                // ```
+                // use a::b;
+                // use b as a;
+                // ```
+                // 1. Steal the `vis` in `use a::b` and attempt to locate `a` in the
+                //    current module.
+                // 2. Encounter the import `use b as a`, which is a `single_import` for `a`,
+                //    and try to find `b` in the current module.
+                // 3. Re-encounter the `use a::b` import since it's a `single_import` of `b`.
+                //    This leads to entering this branch.
                 continue;
             };
             if !self.is_accessible_from(import_vis, parent_scope.module) {
@@ -979,15 +994,25 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 // named imports.
                 continue;
             }
+
             let Some(module) = single_import.imported_module.get() else {
                 return Err((Undetermined, Weak::No));
             };
-            let ImportKind::Single { source: ident, .. } = single_import.kind else {
+            let ImportKind::Single { source: ident, source_bindings, .. } = &single_import.kind
+            else {
                 unreachable!();
             };
+            if binding.map_or(false, |binding| binding.module().is_some())
+                && source_bindings.iter().all(|binding| matches!(binding.get(), Err(Undetermined)))
+            {
+                // This branch allows the binding to be defined or updated later,
+                // avoiding module inconsistency between the resolve process and the finalize process.
+                // See more details in #124840
+                return Err((Undetermined, Weak::No));
+            }
             match self.resolve_ident_in_module(
                 module,
-                ident,
+                *ident,
                 ns,
                 &single_import.parent_scope,
                 None,
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 6bbde26db34..27ea7760f58 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -352,9 +352,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     (old_glob @ true, false) | (old_glob @ false, true) => {
                         let (glob_binding, nonglob_binding) =
                             if old_glob { (old_binding, binding) } else { (binding, old_binding) };
-                        if glob_binding.res() != nonglob_binding.res()
-                            && key.ns == MacroNS
+                        if key.ns == MacroNS
                             && nonglob_binding.expansion != LocalExpnId::ROOT
+                            && glob_binding.res() != nonglob_binding.res()
                         {
                             resolution.binding = Some(this.ambiguity(
                                 AmbiguityKind::GlobVsExpanded,
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 7723f2229bf..5cfc41cc2a2 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -924,11 +924,12 @@ where
                 }
             }
 
-            ty::Alias(kind @ (ty::Projection | ty::Inherent | ty::Weak), ..) => {
-                if ty.has_type_flags(ty::TypeFlags::HAS_TY_PARAM) {
-                    bug!("unexpected ty param in alias ty");
-                }
-
+            // A rigid alias may normalize to anything.
+            // * If it references an infer var, placeholder or bound ty, it may
+            //   normalize to that, so we have to treat it as an uncovered ty param.
+            // * Otherwise it may normalize to any non-type-generic type
+            //   be it local or non-local.
+            ty::Alias(kind, _) => {
                 if ty.has_type_flags(
                     ty::TypeFlags::HAS_TY_PLACEHOLDER
                         | ty::TypeFlags::HAS_TY_BOUND
@@ -948,7 +949,24 @@ where
                         }
                     }
                 } else {
-                    ControlFlow::Continue(())
+                    // Regarding *opaque types* specifically, we choose to treat them as non-local,
+                    // even those that appear within the same crate. This seems somewhat surprising
+                    // at first, but makes sense when you consider that opaque types are supposed
+                    // to hide the underlying type *within the same crate*. When an opaque type is
+                    // used from outside the module where it is declared, it should be impossible to
+                    // observe anything about it other than the traits that it implements.
+                    //
+                    // The alternative would be to look at the underlying type to determine whether
+                    // or not the opaque type itself should be considered local.
+                    //
+                    // However, this could make it a breaking change to switch the underlying hidden
+                    // type from a local type to a remote type. This would violate the rule that
+                    // opaque types should be completely opaque apart from the traits that they
+                    // implement, so we don't use this behavior.
+                    // Addendum: Moreover, revealing the underlying type is likely to cause cycle
+                    // errors as we rely on coherence / the specialization graph during typeck.
+
+                    self.found_non_local_ty(ty)
                 }
             }
 
@@ -990,35 +1008,6 @@ where
             // auto trait impl applies. There will never be multiple impls, so we can just
             // act as if it were a local type here.
             ty::CoroutineWitness(..) => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)),
-            ty::Alias(ty::Opaque, ..) => {
-                // This merits some explanation.
-                // Normally, opaque types are not involved when performing
-                // coherence checking, since it is illegal to directly
-                // implement a trait on an opaque type. However, we might
-                // end up looking at an opaque type during coherence checking
-                // if an opaque type gets used within another type (e.g. as
-                // the type of a field) when checking for auto trait or `Sized`
-                // impls. This requires us to decide whether or not an opaque
-                // type should be considered 'local' or not.
-                //
-                // We choose to treat all opaque types as non-local, even
-                // those that appear within the same crate. This seems
-                // somewhat surprising at first, but makes sense when
-                // you consider that opaque types are supposed to hide
-                // the underlying type *within the same crate*. When an
-                // opaque type is used from outside the module
-                // where it is declared, it should be impossible to observe
-                // anything about it other than the traits that it implements.
-                //
-                // The alternative would be to look at the underlying type
-                // to determine whether or not the opaque type itself should
-                // be considered local. However, this could make it a breaking change
-                // to switch the underlying ('defining') type from a local type
-                // to a remote type. This would violate the rule that opaque
-                // types should be completely opaque apart from the traits
-                // that they implement, so we don't use this behavior.
-                self.found_non_local_ty(ty)
-            }
         };
         // A bit of a hack, the `OrphanChecker` is only used to visit a `TraitRef`, so
         // the first type we visit is always the self type.
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs
index c8968b74b12..9aee2bb5e1c 100644
--- a/library/std/src/io/stdio.rs
+++ b/library/std/src/io/stdio.rs
@@ -1190,9 +1190,8 @@ pub trait IsTerminal: crate::sealed::Sealed {
     ///
     /// - If you run this example by piping some text to it, e.g. `echo "foo" | path/to/executable`
     ///   it will print: `Hello foo`.
-    /// - If you instead run the example interactively by running the executable directly, it will
-    ///   panic with the message "Expected input to be piped to the process".
-    ///
+    /// - If you instead run the example interactively by running `path/to/executable` directly, it will
+    ///   prompt for input.
     ///
     /// [changes]: io#platform-specific-behavior
     /// [`Stdin`]: crate::io::Stdin
diff --git a/library/std/src/sys/pal/sgx/thread.rs b/library/std/src/sys/pal/sgx/thread.rs
index 7d271e6d2b6..446cdd18b7e 100644
--- a/library/std/src/sys/pal/sgx/thread.rs
+++ b/library/std/src/sys/pal/sgx/thread.rs
@@ -15,7 +15,7 @@ pub use self::task_queue::JoinNotifier;
 
 mod task_queue {
     use super::wait_notify;
-    use crate::sync::{Mutex, MutexGuard, Once};
+    use crate::sync::{Mutex, MutexGuard};
 
     pub type JoinHandle = wait_notify::Waiter;
 
@@ -28,12 +28,12 @@ mod task_queue {
     }
 
     pub(super) struct Task {
-        p: Box<dyn FnOnce()>,
+        p: Box<dyn FnOnce() + Send>,
         done: JoinNotifier,
     }
 
     impl Task {
-        pub(super) fn new(p: Box<dyn FnOnce()>) -> (Task, JoinHandle) {
+        pub(super) fn new(p: Box<dyn FnOnce() + Send>) -> (Task, JoinHandle) {
             let (done, recv) = wait_notify::new();
             let done = JoinNotifier(Some(done));
             (Task { p, done }, recv)
@@ -46,17 +46,11 @@ mod task_queue {
     }
 
     #[cfg_attr(test, linkage = "available_externally")]
-    #[export_name = "_ZN16__rust_internals3std3sys3sgx6thread15TASK_QUEUE_INITE"]
-    static TASK_QUEUE_INIT: Once = Once::new();
-    #[cfg_attr(test, linkage = "available_externally")]
     #[export_name = "_ZN16__rust_internals3std3sys3sgx6thread10TASK_QUEUEE"]
-    static mut TASK_QUEUE: Option<Mutex<Vec<Task>>> = None;
+    static TASK_QUEUE: Mutex<Vec<Task>> = Mutex::new(Vec::new());
 
     pub(super) fn lock() -> MutexGuard<'static, Vec<Task>> {
-        unsafe {
-            TASK_QUEUE_INIT.call_once(|| TASK_QUEUE = Some(Default::default()));
-            TASK_QUEUE.as_ref().unwrap().lock().unwrap()
-        }
+        TASK_QUEUE.lock().unwrap()
     }
 }
 
@@ -101,7 +95,7 @@ pub mod wait_notify {
 
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
-    pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
+    pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce() + Send>) -> io::Result<Thread> {
         let mut queue_lock = task_queue::lock();
         unsafe { usercalls::launch_thread()? };
         let (task, handle) = task_queue::Task::new(p);
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 22215873933..83e27dfb746 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -561,7 +561,8 @@ impl Builder {
         let main = Box::new(main);
         // SAFETY: dynamic size and alignment of the Box remain the same. See below for why the
         // lifetime change is justified.
-        let main = unsafe { Box::from_raw(Box::into_raw(main) as *mut (dyn FnOnce() + 'static)) };
+        let main =
+            unsafe { Box::from_raw(Box::into_raw(main) as *mut (dyn FnOnce() + Send + 'static)) };
 
         Ok(JoinInner {
             // SAFETY:
@@ -1544,7 +1545,7 @@ struct Packet<'scope, T> {
 // The type `T` should already always be Send (otherwise the thread could not
 // have been created) and the Packet is Sync because all access to the
 // `UnsafeCell` synchronized (by the `join()` boundary), and `ScopeData` is Sync.
-unsafe impl<'scope, T: Sync> Sync for Packet<'scope, T> {}
+unsafe impl<'scope, T: Send> Sync for Packet<'scope, T> {}
 
 impl<'scope, T> Drop for Packet<'scope, T> {
     fn drop(&mut self) {
diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh
index 22dcb808c74..a4c59b3067e 100755
--- a/src/ci/docker/run.sh
+++ b/src/ci/docker/run.sh
@@ -270,7 +270,6 @@ else
   args="$args --volume $root_dir:/checkout$SRC_MOUNT_OPTION"
   args="$args --volume $objdir:/checkout/obj"
   args="$args --volume $HOME/.cargo:/cargo"
-  args="$args --volume $HOME/rustsrc:$HOME/rustsrc"
   args="$args --volume /tmp/toolstate:/tmp/toolstate"
 
   id=$(id -u)
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index ca86f3f0110..d4325862248 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -61,6 +61,12 @@ envs:
 
   try:
     <<: *production
+    # The following env var activates faster `try` builds in `opt-dist` by, e.g.
+    # - building only the more commonly useful components (we rarely need e.g. rust-docs in try
+    #   builds)
+    # - not running `opt-dist`'s post-optimization smoke tests on the resulting toolchain
+    #
+    # If you *want* these to happen however, temporarily uncomment it before triggering a try build.
     DIST_TRY_BUILD: 1
 
   auto:
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index d10b9c7b626..91d11c1ae17 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -1268,6 +1268,8 @@ fn expand_variables(mut value: String, config: &Config) -> String {
     const CWD: &str = "{{cwd}}";
     const SRC_BASE: &str = "{{src-base}}";
     const BUILD_BASE: &str = "{{build-base}}";
+    const SYSROOT_BASE: &str = "{{sysroot-base}}";
+    const TARGET_LINKER: &str = "{{target-linker}}";
 
     if value.contains(CWD) {
         let cwd = env::current_dir().unwrap();
@@ -1282,6 +1284,14 @@ fn expand_variables(mut value: String, config: &Config) -> String {
         value = value.replace(BUILD_BASE, &config.build_base.to_string_lossy());
     }
 
+    if value.contains(SYSROOT_BASE) {
+        value = value.replace(SYSROOT_BASE, &config.sysroot_base.to_string_lossy());
+    }
+
+    if value.contains(TARGET_LINKER) {
+        value = value.replace(TARGET_LINKER, config.target_linker.as_deref().unwrap_or(""));
+    }
+
     value
 }
 
diff --git a/src/tools/miri/tests/pass/function_calls/abi_compat.rs b/src/tools/miri/tests/pass/function_calls/abi_compat.rs
index 136660a305a..0cfcd532ff4 100644
--- a/src/tools/miri/tests/pass/function_calls/abi_compat.rs
+++ b/src/tools/miri/tests/pass/function_calls/abi_compat.rs
@@ -83,12 +83,24 @@ fn main() {
     test_abi_compat(main as fn(), id::<i32> as fn(i32) -> i32);
     // - 1-ZST
     test_abi_compat((), [0u8; 0]);
-    // - Guaranteed null-pointer-optimizations (RFC 3391).
+    // - Guaranteed Option<X> null-pointer-optimizations (RFC 3391).
     test_abi_compat(&0u32 as *const u32, Some(&0u32));
     test_abi_compat(main as fn(), Some(main as fn()));
     test_abi_compat(0u32, Some(num::NonZero::new(1u32).unwrap()));
     test_abi_compat(&0u32 as *const u32, Some(Wrapper(&0u32)));
-    test_abi_compat(0u32, Some(Wrapper(num::NonZero::new(1u32).unwrap())));
+    test_abi_compat(0u32, Some(Wrapper(num::NonZeroU32::new(1u32).unwrap())));
+    // - Guaranteed Result<X, ZST1> does the same as Option<X> (RFC 3391)
+    test_abi_compat(&0u32 as *const u32, Result::<_, ()>::Ok(&0u32));
+    test_abi_compat(main as fn(), Result::<_, ()>::Ok(main as fn()));
+    test_abi_compat(0u32, Result::<_, ()>::Ok(num::NonZeroU32::new(1).unwrap()));
+    test_abi_compat(&0u32 as *const u32, Result::<_, ()>::Ok(Wrapper(&0u32)));
+    test_abi_compat(0u32, Result::<_, ()>::Ok(Wrapper(num::NonZeroU32::new(1).unwrap())));
+    // - Guaranteed Result<ZST1, X> also does the same as Option<X> (RFC 3391)
+    test_abi_compat(&0u32 as *const u32, Result::<(), _>::Err(&0u32));
+    test_abi_compat(main as fn(), Result::<(), _>::Err(main as fn()));
+    test_abi_compat(0u32, Result::<(), _>::Err(num::NonZeroU32::new(1).unwrap()));
+    test_abi_compat(&0u32 as *const u32, Result::<(), _>::Err(Wrapper(&0u32)));
+    test_abi_compat(0u32, Result::<(), _>::Err(Wrapper(num::NonZeroU32::new(1).unwrap())));
 
     // These must work for *any* type, since we guarantee that `repr(transparent)` is ABI-compatible
     // with the wrapped field.
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index 398a6fd0fba..a6ba8959f0c 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -2445,7 +2445,6 @@ ui/issues/issue-53300.rs
 ui/issues/issue-53333.rs
 ui/issues/issue-53348.rs
 ui/issues/issue-53419.rs
-ui/issues/issue-53498.rs
 ui/issues/issue-53568.rs
 ui/issues/issue-5358-1.rs
 ui/issues/issue-53728.rs
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index cce0fb2c1a2..f2eeda339d8 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -15,7 +15,7 @@ use std::path::{Path, PathBuf};
 const ENTRY_LIMIT: u32 = 900;
 // FIXME: The following limits should be reduced eventually.
 
-const ISSUES_ENTRY_LIMIT: u32 = 1674;
+const ISSUES_ENTRY_LIMIT: u32 = 1672;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
     "rs",     // test source files
diff --git a/tests/crashes/124490.rs b/tests/crashes/124490.rs
deleted file mode 100644
index 9f605c32cf2..00000000000
--- a/tests/crashes/124490.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-//@ known-bug: rust-lang/rust#124490
-use io::{self as std};
-use std::collections::{self as io};
-
-mod a {
-    pub mod b {
-        pub mod c {}
-    }
-}
-
-use a::*;
-
-use b::c;
-use c as b;
-
-fn main() {}
diff --git a/tests/crashes/125013-1.rs b/tests/crashes/125013-1.rs
deleted file mode 100644
index ae66d7a1466..00000000000
--- a/tests/crashes/125013-1.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-//@ known-bug: rust-lang/rust#125013
-//@ edition:2021
-use io::{self as std};
-use std::ops::Deref::{self as io};
-pub fn main() {}
diff --git a/tests/crashes/125013-2.rs b/tests/crashes/125013-2.rs
deleted file mode 100644
index a14c8a76b63..00000000000
--- a/tests/crashes/125013-2.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-//@ known-bug: rust-lang/rust#125013
-//@ edition:2021
-mod a {
-  pub mod b {
-    pub mod c {
-      pub trait D {}
-    }
-  }
-}
-
-use a::*;
-
-use e as b;
-use b::c::D as e;
-
-fn main() { }
diff --git a/tests/run-make-fulldeps/issue-19371/Makefile b/tests/run-make-fulldeps/issue-19371/Makefile
deleted file mode 100644
index edec68f0862..00000000000
--- a/tests/run-make-fulldeps/issue-19371/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-include ../../run-make/tools.mk
-
-# This test ensures that rustc compile_input can be called twice in one task
-# without causing a panic.
-# The program needs the path to rustc to get sysroot.
-
-all:
-	$(RUSTC) foo.rs
-	$(call RUN,foo $(TMPDIR) $(RUSTC))
diff --git a/tests/run-make-fulldeps/issue-19371/foo.rs b/tests/ui-fulldeps/run-compiler-twice.rs
index 327c99a02c6..02748626723 100644
--- a/tests/run-make-fulldeps/issue-19371/foo.rs
+++ b/tests/ui-fulldeps/run-compiler-twice.rs
@@ -1,3 +1,13 @@
+//@ edition: 2021
+//@ run-pass
+//@ run-flags: {{sysroot-base}} {{target-linker}}
+//@ ignore-stage1 (requires matching sysroot built with in-tree compiler)
+
+// Regression test for <https://github.com/rust-lang/rust/issues/19371>.
+//
+// This test ensures that `compile_input` can be called twice in one task
+// without causing a panic.
+
 #![feature(rustc_private)]
 
 extern crate rustc_driver;
@@ -5,12 +15,12 @@ extern crate rustc_interface;
 extern crate rustc_session;
 extern crate rustc_span;
 
+use std::path::{Path, PathBuf};
+
 use rustc_interface::interface;
 use rustc_session::config::{Input, Options, OutFileName, OutputType, OutputTypes};
 use rustc_span::FileName;
 
-use std::path::PathBuf;
-
 fn main() {
     let src = r#"
     fn main() {}
@@ -18,28 +28,28 @@ fn main() {
 
     let args: Vec<String> = std::env::args().collect();
 
-    if args.len() < 4 {
-        panic!("expected rustc path");
+    if args.len() < 2 {
+        panic!("expected sysroot (and optional linker)");
     }
 
-    let tmpdir = PathBuf::from(&args[1]);
-
-    let mut sysroot = PathBuf::from(&args[3]);
-    sysroot.pop();
-    sysroot.pop();
+    let sysroot = PathBuf::from(&args[1]);
+    let linker = args.get(2).map(PathBuf::from);
 
-    compile(src.to_string(), tmpdir.join("out"), sysroot.clone());
+    // compiletest sets the current dir to `output_base_dir` when running.
+    let tmpdir = std::env::current_dir().unwrap().join("tmp");
+    std::fs::create_dir_all(&tmpdir).unwrap();
 
-    compile(src.to_string(), tmpdir.join("out"), sysroot.clone());
+    compile(src.to_string(), tmpdir.join("out"), sysroot.clone(), linker.as_deref());
+    compile(src.to_string(), tmpdir.join("out"), sysroot.clone(), linker.as_deref());
 }
 
-fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
+fn compile(code: String, output: PathBuf, sysroot: PathBuf, linker: Option<&Path>) {
     let mut opts = Options::default();
     opts.output_types = OutputTypes::new(&[(OutputType::Exe, None)]);
     opts.maybe_sysroot = Some(sysroot);
 
-    if let Ok(linker) = std::env::var("RUSTC_LINKER") {
-        opts.cg.linker = Some(linker.into());
+    if let Some(linker) = linker {
+        opts.cg.linker = Some(linker.to_owned());
     }
 
     let name = FileName::anon_source_code(&code);
diff --git a/tests/ui/coherence/orphan-check-opaque-types-not-covering.classic.stderr b/tests/ui/coherence/orphan-check-opaque-types-not-covering.classic.stderr
new file mode 100644
index 00000000000..44f76f321cf
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-opaque-types-not-covering.classic.stderr
@@ -0,0 +1,21 @@
+error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+  --> $DIR/orphan-check-opaque-types-not-covering.rs:17:6
+   |
+LL | impl<T> foreign::Trait0<Local, T, ()> for Identity<T> {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+   |
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+
+error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+  --> $DIR/orphan-check-opaque-types-not-covering.rs:26:6
+   |
+LL | impl<T> foreign::Trait1<Local, T> for Opaque<T> {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+   |
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/tests/ui/coherence/orphan-check-opaque-types-not-covering.next.stderr b/tests/ui/coherence/orphan-check-opaque-types-not-covering.next.stderr
new file mode 100644
index 00000000000..44f76f321cf
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-opaque-types-not-covering.next.stderr
@@ -0,0 +1,21 @@
+error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+  --> $DIR/orphan-check-opaque-types-not-covering.rs:17:6
+   |
+LL | impl<T> foreign::Trait0<Local, T, ()> for Identity<T> {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+   |
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+
+error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+  --> $DIR/orphan-check-opaque-types-not-covering.rs:26:6
+   |
+LL | impl<T> foreign::Trait1<Local, T> for Opaque<T> {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+   |
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs b/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs
new file mode 100644
index 00000000000..8dc02b081c5
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs
@@ -0,0 +1,31 @@
+// Opaque types never cover type parameters.
+
+//@ revisions: classic next
+//@[next] compile-flags: -Znext-solver
+
+//@ aux-crate:foreign=parametrized-trait.rs
+//@ edition:2021
+
+#![feature(type_alias_impl_trait)]
+
+type Identity<T> = impl Sized;
+
+fn define_identity<T>(x: T) -> Identity<T> {
+    x
+}
+
+impl<T> foreign::Trait0<Local, T, ()> for Identity<T> {}
+//~^ ERROR type parameter `T` must be covered by another type
+
+type Opaque<T> = impl Sized;
+
+fn define_local<T>() -> Opaque<T> {
+    Local
+}
+
+impl<T> foreign::Trait1<Local, T> for Opaque<T> {}
+//~^ ERROR type parameter `T` must be covered by another type
+
+struct Local;
+
+fn main() {}
diff --git a/tests/ui/imports/cycle-import-in-diff-module-0.rs b/tests/ui/imports/cycle-import-in-diff-module-0.rs
new file mode 100644
index 00000000000..962603a8971
--- /dev/null
+++ b/tests/ui/imports/cycle-import-in-diff-module-0.rs
@@ -0,0 +1,14 @@
+//@ check-pass
+
+// https://github.com/rust-lang/rust/pull/124840#issuecomment-2098148587
+
+mod a {
+    pub(crate) use crate::S;
+}
+mod b {
+    pub struct S;
+}
+use self::a::S;
+use self::b::*;
+
+fn main() {}
diff --git a/tests/ui/imports/cycle-import-in-diff-module-1.rs b/tests/ui/imports/cycle-import-in-diff-module-1.rs
new file mode 100644
index 00000000000..8c67df376c3
--- /dev/null
+++ b/tests/ui/imports/cycle-import-in-diff-module-1.rs
@@ -0,0 +1,14 @@
+//@ check-pass
+
+// similar `cycle-import-in-diff-module-0.rs`
+
+mod a {
+    pub(crate) use crate::s;
+}
+mod b {
+    pub mod s {}
+}
+use self::b::*;
+use self::a::s;
+
+fn main() {}
diff --git a/tests/ui/imports/shadow-glob-module-resolution-1.rs b/tests/ui/imports/shadow-glob-module-resolution-1.rs
new file mode 100644
index 00000000000..ba1e65cddc6
--- /dev/null
+++ b/tests/ui/imports/shadow-glob-module-resolution-1.rs
@@ -0,0 +1,17 @@
+// https://github.com/rust-lang/rust/issues/124490
+
+mod a {
+    pub mod b {
+        pub mod c {}
+    }
+}
+
+use a::*;
+
+use b::c;
+//~^ ERROR: cannot determine resolution for the import
+//~| ERROR: cannot determine resolution for the import
+//~| ERROR: unresolved import `b::c`
+use c as b;
+
+fn main() {}
diff --git a/tests/ui/imports/shadow-glob-module-resolution-1.stderr b/tests/ui/imports/shadow-glob-module-resolution-1.stderr
new file mode 100644
index 00000000000..f9135963fe9
--- /dev/null
+++ b/tests/ui/imports/shadow-glob-module-resolution-1.stderr
@@ -0,0 +1,23 @@
+error: cannot determine resolution for the import
+  --> $DIR/shadow-glob-module-resolution-1.rs:11:5
+   |
+LL | use b::c;
+   |     ^^^^
+
+error: cannot determine resolution for the import
+  --> $DIR/shadow-glob-module-resolution-1.rs:11:5
+   |
+LL | use b::c;
+   |     ^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0432]: unresolved import `b::c`
+  --> $DIR/shadow-glob-module-resolution-1.rs:11:5
+   |
+LL | use b::c;
+   |     ^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0432`.
diff --git a/tests/ui/imports/shadow-glob-module-resolution-2.rs b/tests/ui/imports/shadow-glob-module-resolution-2.rs
new file mode 100644
index 00000000000..36bd72658ae
--- /dev/null
+++ b/tests/ui/imports/shadow-glob-module-resolution-2.rs
@@ -0,0 +1,19 @@
+// https://github.com/rust-lang/rust/issues/125013
+
+mod a {
+  pub mod b {
+    pub mod c {
+      pub trait D {}
+    }
+  }
+}
+
+use a::*;
+
+use e as b;
+//~^ ERROR: unresolved import `e`
+use b::c::D as e;
+//~^ ERROR: cannot determine resolution for the import
+//~| ERROR: cannot determine resolution for the import
+
+fn main() { }
diff --git a/tests/ui/imports/shadow-glob-module-resolution-2.stderr b/tests/ui/imports/shadow-glob-module-resolution-2.stderr
new file mode 100644
index 00000000000..644fcb84162
--- /dev/null
+++ b/tests/ui/imports/shadow-glob-module-resolution-2.stderr
@@ -0,0 +1,26 @@
+error: cannot determine resolution for the import
+  --> $DIR/shadow-glob-module-resolution-2.rs:15:5
+   |
+LL | use b::c::D as e;
+   |     ^^^^^^^^^^^^
+
+error: cannot determine resolution for the import
+  --> $DIR/shadow-glob-module-resolution-2.rs:15:5
+   |
+LL | use b::c::D as e;
+   |     ^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0432]: unresolved import `e`
+  --> $DIR/shadow-glob-module-resolution-2.rs:13:5
+   |
+LL | use e as b;
+   |     -^^^^^
+   |     |
+   |     no `e` in the root
+   |     help: a similar name exists in the module: `a`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0432`.
diff --git a/tests/ui/issues/issue-53498.rs b/tests/ui/issues/issue-53498.rs
deleted file mode 100644
index 9e0437c46f4..00000000000
--- a/tests/ui/issues/issue-53498.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-pub mod test {
-    pub struct A;
-    pub struct B;
-    pub struct Foo<T>(T);
-
-    impl Foo<A> {
-        fn foo() {}
-    }
-
-    impl Foo<B> {
-        fn foo() {}
-    }
-}
-
-fn main() {
-    test::Foo::<test::B>::foo(); //~ ERROR associated function `foo` is private
-}
diff --git a/tests/ui/privacy/ufc-method-call.different_name.stderr b/tests/ui/privacy/ufc-method-call.different_name.stderr
new file mode 100644
index 00000000000..16496c480dd
--- /dev/null
+++ b/tests/ui/privacy/ufc-method-call.different_name.stderr
@@ -0,0 +1,15 @@
+error[E0599]: no function or associated item named `foo` found for struct `Foo<B>` in the current scope
+  --> $DIR/ufc-method-call.rs:27:27
+   |
+LL |     pub struct Foo<T>(T);
+   |     ----------------- function or associated item `foo` not found for this struct
+...
+LL |     test::Foo::<test::B>::foo();
+   |                           ^^^ function or associated item not found in `Foo<B>`
+   |
+   = note: the function or associated item was found for
+           - `Foo<A>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/privacy/ufc-method-call.rs b/tests/ui/privacy/ufc-method-call.rs
new file mode 100644
index 00000000000..525d9a9eee9
--- /dev/null
+++ b/tests/ui/privacy/ufc-method-call.rs
@@ -0,0 +1,30 @@
+//! This test used to report that the method call cannot
+//! call the private method `Foo<A>::foo`, even though the user
+//! explicitly selected `Foo<B>::foo`. This is because we only
+//! looked for methods of the right name, without properly checking
+//! the `Self` type
+
+//@ revisions: same_name different_name
+
+pub mod test {
+    pub struct A;
+    pub struct B;
+    pub struct Foo<T>(T);
+
+    impl Foo<A> {
+        fn foo() {}
+    }
+
+    impl Foo<B> {
+        #[cfg(same_name)]
+        fn foo() {}
+        #[cfg(different_name)]
+        fn bar() {}
+    }
+}
+
+fn main() {
+    test::Foo::<test::B>::foo();
+    //[same_name]~^ ERROR associated function `foo` is private
+    //[different_name]~^^ ERROR no function or associated item named `foo` found for struct `Foo<B>`
+}
diff --git a/tests/ui/issues/issue-53498.stderr b/tests/ui/privacy/ufc-method-call.same_name.stderr
index 61a1aedf508..194ba42cbf9 100644
--- a/tests/ui/issues/issue-53498.stderr
+++ b/tests/ui/privacy/ufc-method-call.same_name.stderr
@@ -1,5 +1,5 @@
 error[E0624]: associated function `foo` is private
-  --> $DIR/issue-53498.rs:16:27
+  --> $DIR/ufc-method-call.rs:27:27
    |
 LL |         fn foo() {}
    |         -------- private associated function defined here
diff --git a/tests/ui/type-alias-impl-trait/coherence.stderr b/tests/ui/type-alias-impl-trait/coherence.classic.stderr
index 266a532a1db..ff059bc5806 100644
--- a/tests/ui/type-alias-impl-trait/coherence.stderr
+++ b/tests/ui/type-alias-impl-trait/coherence.classic.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence.rs:14:1
+  --> $DIR/coherence.rs:16:1
    |
 LL | impl foreign_crate::ForeignTrait for AliasOfForeignType<()> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------
diff --git a/tests/ui/type-alias-impl-trait/coherence.next.stderr b/tests/ui/type-alias-impl-trait/coherence.next.stderr
new file mode 100644
index 00000000000..dab2786c1f0
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/coherence.next.stderr
@@ -0,0 +1,14 @@
+error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
+  --> $DIR/coherence.rs:16:1
+   |
+LL | impl foreign_crate::ForeignTrait for AliasOfForeignType<()> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------
+   | |                                    |
+   | |                                    `AliasOfForeignType<()>` is not defined in the current crate
+   | impl doesn't use only types from inside the current crate
+   |
+   = note: define and implement a trait or new type instead
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0117`.
diff --git a/tests/ui/type-alias-impl-trait/coherence.rs b/tests/ui/type-alias-impl-trait/coherence.rs
index 641c0fac17a..760e5210c5b 100644
--- a/tests/ui/type-alias-impl-trait/coherence.rs
+++ b/tests/ui/type-alias-impl-trait/coherence.rs
@@ -1,4 +1,6 @@
 //@ aux-build:foreign-crate.rs
+//@ revisions: classic next
+//@[next] compile-flags: -Znext-solver
 #![feature(type_alias_impl_trait)]
 
 extern crate foreign_crate;