about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs23
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs12
-rw-r--r--compiler/rustc_infer/src/traits/error_reporting/mod.rs8
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs8
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs27
-rw-r--r--library/alloc/src/boxed.rs35
-rw-r--r--library/std/src/io/buffered/bufreader.rs2
-rw-r--r--library/std/src/io/buffered/bufwriter.rs2
-rw-r--r--tests/ui/async-await/in-trait/return-not-existing-pair.current.stderr39
-rw-r--r--tests/ui/async-await/in-trait/return-not-existing-pair.next.stderr39
-rw-r--r--tests/ui/async-await/in-trait/return-not-existing-pair.rs19
-rw-r--r--tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.current.stderr9
-rw-r--r--tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.next.stderr9
-rw-r--r--tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs20
-rw-r--r--tests/ui/traits/new-solver/dont-remap-tait-substs.rs2
-rw-r--r--tests/ui/traits/new-solver/dont-remap-tait-substs.stderr99
-rw-r--r--tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.not_send.stderr16
-rw-r--r--tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.rs22
-rw-r--r--tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs13
-rw-r--r--tests/ui/type-alias-impl-trait/issue-109054.rs22
-rw-r--r--tests/ui/type-alias-impl-trait/issue-109054.stderr12
-rw-r--r--tests/ui/type-inference/issue-113283-alllocator-trait-eq.rs18
23 files changed, 307 insertions, 151 deletions
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 7ed73a3f6fe..2a6c341b662 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -67,8 +67,8 @@ impl<'tcx> MirPass<'tcx> for Validator {
             unwind_edge_count: 0,
             reachable_blocks: traversal::reachable_as_bitset(body),
             storage_liveness,
-            place_cache: Vec::new(),
-            value_cache: Vec::new(),
+            place_cache: FxHashSet::default(),
+            value_cache: FxHashSet::default(),
         };
         checker.visit_body(body);
         checker.check_cleanup_control_flow();
@@ -95,8 +95,8 @@ struct TypeChecker<'a, 'tcx> {
     unwind_edge_count: usize,
     reachable_blocks: BitSet<BasicBlock>,
     storage_liveness: ResultsCursor<'a, 'tcx, MaybeStorageLive<'static>>,
-    place_cache: Vec<PlaceRef<'tcx>>,
-    value_cache: Vec<u128>,
+    place_cache: FxHashSet<PlaceRef<'tcx>>,
+    value_cache: FxHashSet<u128>,
 }
 
 impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
@@ -951,10 +951,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
 
                 self.value_cache.clear();
                 self.value_cache.extend(targets.iter().map(|(value, _)| value));
-                let all_len = self.value_cache.len();
-                self.value_cache.sort_unstable();
-                self.value_cache.dedup();
-                let has_duplicates = all_len != self.value_cache.len();
+                let has_duplicates = targets.iter().len() != self.value_cache.len();
                 if has_duplicates {
                     self.fail(
                         location,
@@ -987,16 +984,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                 // passed by a reference to the callee. Consequently they must be non-overlapping.
                 // Currently this simply checks for duplicate places.
                 self.place_cache.clear();
-                self.place_cache.push(destination.as_ref());
+                self.place_cache.insert(destination.as_ref());
+                let mut has_duplicates = false;
                 for arg in args {
                     if let Operand::Move(place) = arg {
-                        self.place_cache.push(place.as_ref());
+                        has_duplicates |= !self.place_cache.insert(place.as_ref());
                     }
                 }
-                let all_len = self.place_cache.len();
-                let mut dedup = FxHashSet::default();
-                self.place_cache.retain(|p| dedup.insert(*p));
-                let has_duplicates = all_len != self.place_cache.len();
+
                 if has_duplicates {
                     self.fail(
                         location,
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 2999e1fd89b..22e576e345e 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -669,11 +669,13 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
         )
         .fold_with(&mut collector);
 
-    debug_assert_ne!(
-        collector.types.len(),
-        0,
-        "expect >1 RPITITs in call to `collect_return_position_impl_trait_in_trait_tys`"
-    );
+    if !unnormalized_trait_sig.output().references_error() {
+        debug_assert_ne!(
+            collector.types.len(),
+            0,
+            "expect >1 RPITITs in call to `collect_return_position_impl_trait_in_trait_tys`"
+        );
+    }
 
     let trait_sig = ocx.normalize(&norm_cause, param_env, unnormalized_trait_sig);
     trait_sig.error_reported()?;
diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
index b5a7d0326a8..9f440f39849 100644
--- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
@@ -25,9 +25,11 @@ impl<'tcx> InferCtxt<'tcx> {
             "impl has stricter requirements than trait"
         );
 
-        if let Some(span) = self.tcx.hir().span_if_local(trait_item_def_id) {
-            let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
-            err.span_label(span, format!("definition of `{}` from trait", item_name));
+        if !self.tcx.is_impl_trait_in_trait(trait_item_def_id) {
+            if let Some(span) = self.tcx.hir().span_if_local(trait_item_def_id) {
+                let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
+                err.span_label(span, format!("definition of `{}` from trait", item_name));
+            }
         }
 
         err.span_label(error_span, format!("impl has extra requirement {}", requirement));
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
index 6fb788e296f..74dfbdddbab 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
@@ -837,7 +837,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         }
     }
 
-    pub(super) fn can_define_opaque_ty(&mut self, def_id: LocalDefId) -> bool {
+    pub(super) fn can_define_opaque_ty(&self, def_id: LocalDefId) -> bool {
         self.infcx.opaque_type_origin(def_id).is_some()
     }
 
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
index 366e9aa793d..0800738a3f2 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
@@ -173,10 +173,18 @@ fn candidate_should_be_dropped_in_favor_of<'tcx>(
             victim_idx >= other_idx
         }
         (_, CandidateSource::ParamEnv(_)) => true,
+
+        (
+            CandidateSource::BuiltinImpl(BuiltinImplSource::Object),
+            CandidateSource::BuiltinImpl(BuiltinImplSource::Object),
+        ) => false,
+        (_, CandidateSource::BuiltinImpl(BuiltinImplSource::Object)) => true,
+
         (CandidateSource::Impl(victim_def_id), CandidateSource::Impl(other_def_id)) => {
             tcx.specializes((other_def_id, victim_def_id))
                 && other.result.value.certainty == Certainty::Yes
         }
+
         _ => false,
     }
 }
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index 7ff47295e7c..cd68626bed1 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -7,6 +7,7 @@ use rustc_hir::{LangItem, Movability};
 use rustc_infer::traits::query::NoSolution;
 use rustc_infer::traits::util::supertraits;
 use rustc_middle::traits::solve::{CanonicalResponse, Certainty, Goal, QueryResult};
+use rustc_middle::traits::Reveal;
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, TreatProjections};
 use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
 use rustc_middle::ty::{TraitPredicate, TypeVisitableExt};
@@ -118,6 +119,32 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
             return result;
         }
 
+        // Don't call `type_of` on a local TAIT that's in the defining scope,
+        // since that may require calling `typeck` on the same item we're
+        // currently type checking, which will result in a fatal cycle that
+        // ideally we want to avoid, since we can make progress on this goal
+        // via an alias bound or a locally-inferred hidden type instead.
+        //
+        // Also, don't call `type_of` on a TAIT in `Reveal::All` mode, since
+        // we already normalize the self type in
+        // `assemble_candidates_after_normalizing_self_ty`, and we'd
+        // just be registering an identical candidate here.
+        //
+        // Returning `Err(NoSolution)` here is ok in `SolverMode::Coherence`
+        // since we'll always be registering an ambiguous candidate in
+        // `assemble_candidates_after_normalizing_self_ty` due to normalizing
+        // the TAIT.
+        if let ty::Alias(ty::Opaque, opaque_ty) = goal.predicate.self_ty().kind() {
+            if matches!(goal.param_env.reveal(), Reveal::All)
+                || opaque_ty
+                    .def_id
+                    .as_local()
+                    .is_some_and(|def_id| ecx.can_define_opaque_ty(def_id))
+            {
+                return Err(NoSolution);
+            }
+        }
+
         ecx.probe_and_evaluate_goal_for_constituent_tys(
             goal,
             structural_traits::instantiate_constituent_tys_for_auto_trait,
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index fa23367593d..8ef2bac9282 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -1319,56 +1319,39 @@ impl Clone for Box<str> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, A1, A2> PartialEq<Box<T, A2>> for Box<T, A1>
-where
-    T: ?Sized + PartialEq,
-    A1: Allocator,
-    A2: Allocator,
-{
+impl<T: ?Sized + PartialEq, A: Allocator> PartialEq for Box<T, A> {
     #[inline]
-    fn eq(&self, other: &Box<T, A2>) -> bool {
+    fn eq(&self, other: &Self) -> bool {
         PartialEq::eq(&**self, &**other)
     }
-
     #[inline]
-    fn ne(&self, other: &Box<T, A2>) -> bool {
+    fn ne(&self, other: &Self) -> bool {
         PartialEq::ne(&**self, &**other)
     }
 }
-
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, A1, A2> PartialOrd<Box<T, A2>> for Box<T, A1>
-where
-    T: ?Sized + PartialOrd,
-    A1: Allocator,
-    A2: Allocator,
-{
+impl<T: ?Sized + PartialOrd, A: Allocator> PartialOrd for Box<T, A> {
     #[inline]
-    fn partial_cmp(&self, other: &Box<T, A2>) -> Option<Ordering> {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
         PartialOrd::partial_cmp(&**self, &**other)
     }
-
     #[inline]
-    fn lt(&self, other: &Box<T, A2>) -> bool {
+    fn lt(&self, other: &Self) -> bool {
         PartialOrd::lt(&**self, &**other)
     }
-
     #[inline]
-    fn le(&self, other: &Box<T, A2>) -> bool {
+    fn le(&self, other: &Self) -> bool {
         PartialOrd::le(&**self, &**other)
     }
-
     #[inline]
-    fn ge(&self, other: &Box<T, A2>) -> bool {
+    fn ge(&self, other: &Self) -> bool {
         PartialOrd::ge(&**self, &**other)
     }
-
     #[inline]
-    fn gt(&self, other: &Box<T, A2>) -> bool {
+    fn gt(&self, other: &Self) -> bool {
         PartialOrd::gt(&**self, &**other)
     }
 }
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + Ord, A: Allocator> Ord for Box<T, A> {
     #[inline]
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs
index a66e6ccf673..7097dfef88d 100644
--- a/library/std/src/io/buffered/bufreader.rs
+++ b/library/std/src/io/buffered/bufreader.rs
@@ -53,7 +53,7 @@ pub struct BufReader<R: ?Sized> {
 }
 
 impl<R: Read> BufReader<R> {
-    /// Creates a new `BufReader<R>` with a default buffer capacity. The default is currently 8 KB,
+    /// Creates a new `BufReader<R>` with a default buffer capacity. The default is currently 8 KiB,
     /// but may change in the future.
     ///
     /// # Examples
diff --git a/library/std/src/io/buffered/bufwriter.rs b/library/std/src/io/buffered/bufwriter.rs
index 0e2450655e5..0f04f291117 100644
--- a/library/std/src/io/buffered/bufwriter.rs
+++ b/library/std/src/io/buffered/bufwriter.rs
@@ -81,7 +81,7 @@ pub struct BufWriter<W: ?Sized + Write> {
 }
 
 impl<W: Write> BufWriter<W> {
-    /// Creates a new `BufWriter<W>` with a default buffer capacity. The default is currently 8 KB,
+    /// Creates a new `BufWriter<W>` with a default buffer capacity. The default is currently 8 KiB,
     /// but may change in the future.
     ///
     /// # Examples
diff --git a/tests/ui/async-await/in-trait/return-not-existing-pair.current.stderr b/tests/ui/async-await/in-trait/return-not-existing-pair.current.stderr
new file mode 100644
index 00000000000..56973a1d11a
--- /dev/null
+++ b/tests/ui/async-await/in-trait/return-not-existing-pair.current.stderr
@@ -0,0 +1,39 @@
+error[E0726]: implicit elided lifetime not allowed here
+  --> $DIR/return-not-existing-pair.rs:12:20
+   |
+LL | impl<'a, 'b, T, U> MyTrait<T> for U {
+   |                    ^^^^^^^^^^ expected lifetime parameters
+   |
+help: indicate the anonymous lifetimes
+   |
+LL | impl<'a, 'b, T, U> MyTrait<'_, '_, T> for U {
+   |                            +++++++
+
+error[E0412]: cannot find type `ConnImpl` in this scope
+  --> $DIR/return-not-existing-pair.rs:8:48
+   |
+LL |     async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T);
+   |                                                ^^^^^^^^ not found in this scope
+
+error[E0186]: method `foo` has a `&self` declaration in the trait, but not in the impl
+  --> $DIR/return-not-existing-pair.rs:14:5
+   |
+LL |     async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T);
+   |     ------------------------------------------------------------ `&self` used in trait
+...
+LL |     async fn foo(_: T) -> (&'a U, &'b T) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&self` in impl
+
+error[E0308]: mismatched types
+  --> $DIR/return-not-existing-pair.rs:14:42
+   |
+LL |     async fn foo(_: T) -> (&'a U, &'b T) {}
+   |                                          ^^ expected `(&U, &T)`, found `()`
+   |
+   = note:  expected tuple `(&'a U, &'b T)`
+           found unit type `()`
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0186, E0308, E0412, E0726.
+For more information about an error, try `rustc --explain E0186`.
diff --git a/tests/ui/async-await/in-trait/return-not-existing-pair.next.stderr b/tests/ui/async-await/in-trait/return-not-existing-pair.next.stderr
new file mode 100644
index 00000000000..56973a1d11a
--- /dev/null
+++ b/tests/ui/async-await/in-trait/return-not-existing-pair.next.stderr
@@ -0,0 +1,39 @@
+error[E0726]: implicit elided lifetime not allowed here
+  --> $DIR/return-not-existing-pair.rs:12:20
+   |
+LL | impl<'a, 'b, T, U> MyTrait<T> for U {
+   |                    ^^^^^^^^^^ expected lifetime parameters
+   |
+help: indicate the anonymous lifetimes
+   |
+LL | impl<'a, 'b, T, U> MyTrait<'_, '_, T> for U {
+   |                            +++++++
+
+error[E0412]: cannot find type `ConnImpl` in this scope
+  --> $DIR/return-not-existing-pair.rs:8:48
+   |
+LL |     async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T);
+   |                                                ^^^^^^^^ not found in this scope
+
+error[E0186]: method `foo` has a `&self` declaration in the trait, but not in the impl
+  --> $DIR/return-not-existing-pair.rs:14:5
+   |
+LL |     async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T);
+   |     ------------------------------------------------------------ `&self` used in trait
+...
+LL |     async fn foo(_: T) -> (&'a U, &'b T) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&self` in impl
+
+error[E0308]: mismatched types
+  --> $DIR/return-not-existing-pair.rs:14:42
+   |
+LL |     async fn foo(_: T) -> (&'a U, &'b T) {}
+   |                                          ^^ expected `(&U, &T)`, found `()`
+   |
+   = note:  expected tuple `(&'a U, &'b T)`
+           found unit type `()`
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0186, E0308, E0412, E0726.
+For more information about an error, try `rustc --explain E0186`.
diff --git a/tests/ui/async-await/in-trait/return-not-existing-pair.rs b/tests/ui/async-await/in-trait/return-not-existing-pair.rs
new file mode 100644
index 00000000000..d1b3832d12b
--- /dev/null
+++ b/tests/ui/async-await/in-trait/return-not-existing-pair.rs
@@ -0,0 +1,19 @@
+// edition:2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
+
+#![feature(async_fn_in_trait)]
+
+trait MyTrait<'a, 'b, T> {
+    async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T);
+    //~^ ERROR: cannot find type `ConnImpl` in this scope [E0412]
+}
+
+impl<'a, 'b, T, U> MyTrait<T> for U {
+    //~^ ERROR: implicit elided lifetime not allowed here [E0726]
+    async fn foo(_: T) -> (&'a U, &'b T) {}
+    //~^ ERROR: method `foo` has a `&self` declaration in the trait, but not in the impl [E0186]
+    //~| ERROR: mismatched types [E0308]
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.current.stderr b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.current.stderr
new file mode 100644
index 00000000000..2564d68d591
--- /dev/null
+++ b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.current.stderr
@@ -0,0 +1,9 @@
+error[E0412]: cannot find type `Missing` in this scope
+  --> $DIR/return-not-existing-type-wrapping-rpitit.rs:10:25
+   |
+LL |     fn bar() -> Wrapper<Missing<impl Sized>>;
+   |                         ^^^^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.next.stderr b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.next.stderr
new file mode 100644
index 00000000000..2564d68d591
--- /dev/null
+++ b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.next.stderr
@@ -0,0 +1,9 @@
+error[E0412]: cannot find type `Missing` in this scope
+  --> $DIR/return-not-existing-type-wrapping-rpitit.rs:10:25
+   |
+LL |     fn bar() -> Wrapper<Missing<impl Sized>>;
+   |                         ^^^^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs
new file mode 100644
index 00000000000..37c02827e8d
--- /dev/null
+++ b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs
@@ -0,0 +1,20 @@
+// edition:2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
+
+#![feature(return_position_impl_trait_in_trait)]
+
+struct Wrapper<T>(T);
+
+trait Foo {
+    fn bar() -> Wrapper<Missing<impl Sized>>;
+    //~^ ERROR: cannot find type `Missing` in this scope [E0412]
+}
+
+impl Foo for () {
+    fn bar() -> Wrapper<i32> {
+        Wrapper(0)
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/new-solver/dont-remap-tait-substs.rs b/tests/ui/traits/new-solver/dont-remap-tait-substs.rs
index 08c08e83076..028222f4e6d 100644
--- a/tests/ui/traits/new-solver/dont-remap-tait-substs.rs
+++ b/tests/ui/traits/new-solver/dont-remap-tait-substs.rs
@@ -1,5 +1,5 @@
 // compile-flags: -Ztrait-solver=next
-// known-bug: #112825
+// check-pass
 
 // Makes sure we don't prepopulate the MIR typeck of `define`
 // with `Foo<T, U> = T`, but instead, `Foo<B, A> = B`, so that
diff --git a/tests/ui/traits/new-solver/dont-remap-tait-substs.stderr b/tests/ui/traits/new-solver/dont-remap-tait-substs.stderr
deleted file mode 100644
index 769eea7dfd6..00000000000
--- a/tests/ui/traits/new-solver/dont-remap-tait-substs.stderr
+++ /dev/null
@@ -1,99 +0,0 @@
-error[E0391]: cycle detected when computing type of `Foo::{opaque#0}`
-  --> $DIR/dont-remap-tait-substs.rs:10:24
-   |
-LL | type Foo<T: Send, U> = impl NeedsSend<T>;
-   |                        ^^^^^^^^^^^^^^^^^
-   |
-note: ...which requires borrow-checking `define`...
-  --> $DIR/dont-remap-tait-substs.rs:15:1
-   |
-LL | fn define<A, B: Send>(a: A, b: B) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle
-note: cycle used when checking item types in top-level module
-  --> $DIR/dont-remap-tait-substs.rs:8:1
-   |
-LL | / #![feature(type_alias_impl_trait)]
-LL | |
-LL | | type Foo<T: Send, U> = impl NeedsSend<T>;
-LL | |
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
-
-error[E0391]: cycle detected when computing type of `Foo::{opaque#0}`
-  --> $DIR/dont-remap-tait-substs.rs:10:24
-   |
-LL | type Foo<T: Send, U> = impl NeedsSend<T>;
-   |                        ^^^^^^^^^^^^^^^^^
-   |
-note: ...which requires borrow-checking `define`...
-  --> $DIR/dont-remap-tait-substs.rs:15:1
-   |
-LL | fn define<A, B: Send>(a: A, b: B) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle
-note: cycle used when checking item types in top-level module
-  --> $DIR/dont-remap-tait-substs.rs:8:1
-   |
-LL | / #![feature(type_alias_impl_trait)]
-LL | |
-LL | | type Foo<T: Send, U> = impl NeedsSend<T>;
-LL | |
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
-
-error[E0391]: cycle detected when computing type of `Foo::{opaque#0}`
-  --> $DIR/dont-remap-tait-substs.rs:10:24
-   |
-LL | type Foo<T: Send, U> = impl NeedsSend<T>;
-   |                        ^^^^^^^^^^^^^^^^^
-   |
-note: ...which requires borrow-checking `define`...
-  --> $DIR/dont-remap-tait-substs.rs:15:1
-   |
-LL | fn define<A, B: Send>(a: A, b: B) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle
-note: cycle used when checking item types in top-level module
-  --> $DIR/dont-remap-tait-substs.rs:8:1
-   |
-LL | / #![feature(type_alias_impl_trait)]
-LL | |
-LL | | type Foo<T: Send, U> = impl NeedsSend<T>;
-LL | |
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
-
-error[E0391]: cycle detected when computing type of `Foo::{opaque#0}`
-  --> $DIR/dont-remap-tait-substs.rs:10:24
-   |
-LL | type Foo<T: Send, U> = impl NeedsSend<T>;
-   |                        ^^^^^^^^^^^^^^^^^
-   |
-note: ...which requires borrow-checking `define`...
-  --> $DIR/dont-remap-tait-substs.rs:15:1
-   |
-LL | fn define<A, B: Send>(a: A, b: B) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle
-note: cycle used when checking item types in top-level module
-  --> $DIR/dont-remap-tait-substs.rs:8:1
-   |
-LL | / #![feature(type_alias_impl_trait)]
-LL | |
-LL | | type Foo<T: Send, U> = impl NeedsSend<T>;
-LL | |
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.not_send.stderr b/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.not_send.stderr
new file mode 100644
index 00000000000..ec1c3231abc
--- /dev/null
+++ b/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.not_send.stderr
@@ -0,0 +1,16 @@
+error[E0283]: type annotations needed: cannot satisfy `Foo: Send`
+  --> $DIR/dont-type_of-tait-in-defining-scope.rs:16:5
+   |
+LL |     needs_send::<Foo>();
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: cannot satisfy `Foo: Send`
+note: required by a bound in `needs_send`
+  --> $DIR/dont-type_of-tait-in-defining-scope.rs:13:18
+   |
+LL | fn needs_send<T: Send>() {}
+   |                  ^^^^ required by this bound in `needs_send`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.rs b/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.rs
new file mode 100644
index 00000000000..5a0dcd0e8cc
--- /dev/null
+++ b/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.rs
@@ -0,0 +1,22 @@
+// revisions: is_send not_send
+// compile-flags: -Ztrait-solver=next
+//[is_send] check-pass
+
+#![feature(type_alias_impl_trait)]
+
+#[cfg(is_send)]
+type Foo = impl Send;
+
+#[cfg(not_send)]
+type Foo = impl Sized;
+
+fn needs_send<T: Send>() {}
+
+fn test() {
+    needs_send::<Foo>();
+    //[not_send]~^ ERROR type annotations needed: cannot satisfy `Foo: Send`
+}
+
+fn main() {
+    let _: Foo = ();
+}
diff --git a/tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs b/tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs
new file mode 100644
index 00000000000..7d15b8c6392
--- /dev/null
+++ b/tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs
@@ -0,0 +1,13 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+use std::any::Any;
+
+fn needs_usize(_: &usize) {}
+
+fn main() {
+    let x: &dyn Any = &1usize;
+    if let Some(x) = x.downcast_ref::<usize>() {
+        needs_usize(x);
+    }
+}
diff --git a/tests/ui/type-alias-impl-trait/issue-109054.rs b/tests/ui/type-alias-impl-trait/issue-109054.rs
new file mode 100644
index 00000000000..1fbec47b14b
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-109054.rs
@@ -0,0 +1,22 @@
+// edition:2021
+
+#![feature(type_alias_impl_trait)]
+
+struct CallMe;
+
+type ReturnType<'a> = impl std::future::Future<Output = u32> + 'a;
+type FnType = impl Fn(&u32) -> ReturnType;
+
+impl std::ops::Deref for CallMe {
+    type Target = FnType;
+
+    fn deref(&self) -> &Self::Target {
+        fn inner(val: &u32) -> ReturnType {
+            async move { *val * 2 }
+        }
+
+        &inner //~ ERROR: expected generic lifetime parameter, found `'_`
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/issue-109054.stderr b/tests/ui/type-alias-impl-trait/issue-109054.stderr
new file mode 100644
index 00000000000..a611b9fe448
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-109054.stderr
@@ -0,0 +1,12 @@
+error[E0792]: expected generic lifetime parameter, found `'_`
+  --> $DIR/issue-109054.rs:18:9
+   |
+LL | type ReturnType<'a> = impl std::future::Future<Output = u32> + 'a;
+   |                 -- this generic parameter must be used with a generic lifetime parameter
+...
+LL |         &inner
+   |         ^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/type-inference/issue-113283-alllocator-trait-eq.rs b/tests/ui/type-inference/issue-113283-alllocator-trait-eq.rs
new file mode 100644
index 00000000000..5d0e456d9dd
--- /dev/null
+++ b/tests/ui/type-inference/issue-113283-alllocator-trait-eq.rs
@@ -0,0 +1,18 @@
+// run-pass
+// Verify that PartialEq implementations do not break type inference when
+// accepting types with different allocators
+
+use std::rc::Rc;
+use std::sync::Arc;
+
+
+fn main() {
+    let boxed: Vec<Box<i32>> = vec![];
+    assert_eq!(boxed, vec![]);
+
+    let rc: Vec<Rc<i32>> = vec![];
+    assert_eq!(rc, vec![]);
+
+    let arc: Vec<Arc<i32>> = vec![];
+    assert_eq!(arc, vec![]);
+}