about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-04-29 06:17:37 +0000
committerbors <bors@rust-lang.org>2023-04-29 06:17:37 +0000
commitaf2c7e0f9b5730b9598ca70fc67360fa69b469c8 (patch)
tree7e0605d54f2d79e843fcacde49c3c51ccd478f21
parent572c0d553f2bd1b934b08fe240310112369a5c76 (diff)
parent81910a1b21ecb05980df8d18970595c1729cc030 (diff)
downloadrust-af2c7e0f9b5730b9598ca70fc67360fa69b469c8.tar.gz
rust-af2c7e0f9b5730b9598ca70fc67360fa69b469c8.zip
Auto merge of #110978 - Dylan-DPC:rollup-xclzwax, r=Dylan-DPC
Rollup of 6 pull requests

Successful merges:

 - #110614 (Clear response values for overflow in new solver)
 - #110894 (Bump libffi-sys to 2.3.0)
 - #110932 (include source error for LoadLibraryExW)
 - #110958 (Make sure that some stdlib method signatures aren't accidental refinements)
 - #110962 (Make drop_flags an IndexVec.)
 - #110965 (Don't duplicate anonymous lifetimes for async fn in traits)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--Cargo.lock4
-rw-r--r--compiler/rustc_metadata/src/creader.rs10
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drops.rs15
-rw-r--r--compiler/rustc_resolve/src/late.rs6
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt.rs19
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs58
-rw-r--r--compiler/rustc_trait_selection/src/solve/mod.rs22
-rw-r--r--library/alloc/src/collections/btree/map.rs60
-rw-r--r--library/alloc/src/collections/btree/set.rs20
-rw-r--r--library/alloc/src/collections/vec_deque/mod.rs2
-rw-r--r--library/core/src/array/mod.rs4
-rw-r--r--library/core/src/iter/range.rs20
-rw-r--r--library/portable-simd/crates/core_simd/src/ops/deref.rs2
-rw-r--r--tests/mir-opt/issue_41888.main.ElaborateDrops.diff2
-rw-r--r--tests/ui/async-await/in-trait/nested-rpit.rs4
-rw-r--r--tests/ui/async-await/return-type-notation/issue-110963-early.rs48
-rw-r--r--tests/ui/async-await/return-type-notation/issue-110963-early.stderr45
-rw-r--r--tests/ui/async-await/return-type-notation/issue-110963-late.rs50
-rw-r--r--tests/ui/async-await/return-type-notation/issue-110963-late.stderr19
-rw-r--r--tests/ui/traits/new-solver/exponential-trait-goals.rs20
-rw-r--r--tests/ui/traits/new-solver/exponential-trait-goals.stderr23
21 files changed, 390 insertions, 63 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 06a2a36f455..683331d4724 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1956,9 +1956,9 @@ dependencies = [
 
 [[package]]
 name = "libffi-sys"
-version = "2.2.1"
+version = "2.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc65067b78c0fc069771e8b9a9e02df71e08858bec92c1f101377c67b9dca7c7"
+checksum = "f36115160c57e8529781b4183c2bb51fdc1f6d6d1ed345591d84be7703befb3c"
 dependencies = [
  "cc",
 ]
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 179453238f2..01b69966ca9 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -27,6 +27,7 @@ use rustc_span::{Span, DUMMY_SP};
 use rustc_target::spec::{PanicStrategy, TargetTriple};
 
 use proc_macro::bridge::client::ProcMacro;
+use std::error::Error;
 use std::ops::Fn;
 use std::path::Path;
 use std::time::Duration;
@@ -1094,5 +1095,12 @@ fn load_dylib(path: &Path, max_attempts: usize) -> Result<libloading::Library, S
     }
 
     debug!("Failed to load proc-macro `{}` even after {} attempts.", path.display(), max_attempts);
-    Err(format!("{} (retried {} times)", last_error.unwrap(), max_attempts))
+
+    let last_error = last_error.unwrap();
+    let message = if let Some(src) = last_error.source() {
+        format!("{last_error} ({src}) (retried {max_attempts} times)")
+    } else {
+        format!("{last_error} (retried {max_attempts} times)")
+    };
+    Err(message)
 }
diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs
index 1e115be2c2a..443f469ce52 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs
@@ -1,7 +1,7 @@
 use crate::deref_separator::deref_finder;
 use crate::MirPass;
-use rustc_data_structures::fx::FxHashMap;
 use rustc_index::bit_set::BitSet;
+use rustc_index::IndexVec;
 use rustc_middle::mir::patch::MirPatch;
 use rustc_middle::mir::*;
 use rustc_middle::ty::{self, TyCtxt};
@@ -84,12 +84,13 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
 
             let reachable = traversal::reachable_as_bitset(body);
 
+            let drop_flags = IndexVec::from_elem(None, &env.move_data.move_paths);
             ElaborateDropsCtxt {
                 tcx,
                 body,
                 env: &env,
                 init_data: InitializationData { inits, uninits },
-                drop_flags: Default::default(),
+                drop_flags,
                 patch: MirPatch::new(body),
                 un_derefer: un_derefer,
                 reachable,
@@ -293,7 +294,7 @@ struct ElaborateDropsCtxt<'a, 'tcx> {
     body: &'a Body<'tcx>,
     env: &'a MoveDataParamEnv<'tcx>,
     init_data: InitializationData<'a, 'tcx>,
-    drop_flags: FxHashMap<MovePathIndex, Local>,
+    drop_flags: IndexVec<MovePathIndex, Option<Local>>,
     patch: MirPatch<'tcx>,
     un_derefer: UnDerefer<'tcx>,
     reachable: BitSet<BasicBlock>,
@@ -312,11 +313,11 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
         let tcx = self.tcx;
         let patch = &mut self.patch;
         debug!("create_drop_flag({:?})", self.body.span);
-        self.drop_flags.entry(index).or_insert_with(|| patch.new_internal(tcx.types.bool, span));
+        self.drop_flags[index].get_or_insert_with(|| patch.new_internal(tcx.types.bool, span));
     }
 
     fn drop_flag(&mut self, index: MovePathIndex) -> Option<Place<'tcx>> {
-        self.drop_flags.get(&index).map(|t| Place::from(*t))
+        self.drop_flags[index].map(Place::from)
     }
 
     /// create a patch that elaborates all drops in the input
@@ -463,7 +464,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
     }
 
     fn set_drop_flag(&mut self, loc: Location, path: MovePathIndex, val: DropFlagState) {
-        if let Some(&flag) = self.drop_flags.get(&path) {
+        if let Some(flag) = self.drop_flags[path] {
             let span = self.patch.source_info_for_location(self.body, loc).span;
             let val = self.constant_bool(span, val.value());
             self.patch.add_assign(loc, Place::from(flag), val);
@@ -474,7 +475,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
         let loc = Location::START;
         let span = self.patch.source_info_for_location(self.body, loc).span;
         let false_ = self.constant_bool(span, false);
-        for flag in self.drop_flags.values() {
+        for flag in self.drop_flags.iter().flatten() {
             self.patch.add_assign(loc, Place::from(*flag), false_.clone());
         }
     }
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index a97857e05e2..5c02e7193a2 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -859,13 +859,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
                             sig.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)),
                             &sig.decl.output,
                         );
-
-                        this.record_lifetime_params_for_async(
-                            fn_id,
-                            sig.header.asyncness.opt_return_id(),
-                        );
                     },
                 );
+                self.record_lifetime_params_for_async(fn_id, sig.header.asyncness.opt_return_id());
                 return;
             }
             FnKind::Fn(..) => {
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
index bd52957d162..63a73f8d50d 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
@@ -3,7 +3,8 @@ use rustc_infer::infer::at::ToTrace;
 use rustc_infer::infer::canonical::CanonicalVarValues;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::{
-    DefineOpaqueTypes, InferCtxt, InferOk, LateBoundRegionConversionTime, TyCtxtInferExt,
+    DefineOpaqueTypes, InferCtxt, InferOk, LateBoundRegionConversionTime, RegionVariableOrigin,
+    TyCtxtInferExt,
 };
 use rustc_infer::traits::query::NoSolution;
 use rustc_infer::traits::ObligationCause;
@@ -223,18 +224,20 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         {
             debug!("rerunning goal to check result is stable");
             let (_orig_values, canonical_goal) = self.canonicalize_goal(goal);
-            let canonical_response =
+            let new_canonical_response =
                 EvalCtxt::evaluate_canonical_goal(self.tcx(), self.search_graph, canonical_goal)?;
-            if !canonical_response.value.var_values.is_identity() {
+            if !new_canonical_response.value.var_values.is_identity() {
                 bug!(
                     "unstable result: re-canonicalized goal={canonical_goal:#?} \
-                     response={canonical_response:#?}"
+                    first_response={canonical_response:#?} \
+                    second_response={new_canonical_response:#?}"
                 );
             }
-            if certainty != canonical_response.value.certainty {
+            if certainty != new_canonical_response.value.certainty {
                 bug!(
                     "unstable certainty: {certainty:#?} re-canonicalized goal={canonical_goal:#?} \
-                     response={canonical_response:#?}"
+                     first_response={canonical_response:#?} \
+                     second_response={new_canonical_response:#?}"
                 );
             }
         }
@@ -434,6 +437,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         })
     }
 
+    pub(super) fn next_region_infer(&self) -> ty::Region<'tcx> {
+        self.infcx.next_region_var(RegionVariableOrigin::MiscVariable(DUMMY_SP))
+    }
+
     pub(super) fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx> {
         self.infcx.next_const_var(
             ty,
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
index 226d29687e3..67ad7fb4bd2 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
@@ -16,7 +16,7 @@ use rustc_infer::infer::canonical::query_response::make_query_region_constraints
 use rustc_infer::infer::canonical::CanonicalVarValues;
 use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints};
 use rustc_middle::traits::query::NoSolution;
-use rustc_middle::traits::solve::{ExternalConstraints, ExternalConstraintsData};
+use rustc_middle::traits::solve::{ExternalConstraints, ExternalConstraintsData, MaybeCause};
 use rustc_middle::ty::{self, BoundVar, GenericArgKind};
 use rustc_span::DUMMY_SP;
 use std::iter;
@@ -60,9 +60,27 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
 
         let certainty = certainty.unify_with(goals_certainty);
 
-        let external_constraints = self.compute_external_query_constraints()?;
+        let response = match certainty {
+            Certainty::Yes | Certainty::Maybe(MaybeCause::Ambiguity) => {
+                let external_constraints = self.compute_external_query_constraints()?;
+                Response { var_values: self.var_values, external_constraints, certainty }
+            }
+            Certainty::Maybe(MaybeCause::Overflow) => {
+                // If we have overflow, it's probable that we're substituting a type
+                // into itself infinitely and any partial substitutions in the query
+                // response are probably not useful anyways, so just return an empty
+                // query response.
+                //
+                // This may prevent us from potentially useful inference, e.g.
+                // 2 candidates, one ambiguous and one overflow, which both
+                // have the same inference constraints.
+                //
+                // Changing this to retain some constraints in the future
+                // won't be a breaking change, so this is good enough for now.
+                return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow));
+            }
+        };
 
-        let response = Response { var_values: self.var_values, external_constraints, certainty };
         let canonical = Canonicalizer::canonicalize(
             self.infcx,
             CanonicalizeMode::Response { max_input_universe: self.max_input_universe },
@@ -72,6 +90,40 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         Ok(canonical)
     }
 
+    /// Constructs a totally unconstrained, ambiguous response to a goal.
+    ///
+    /// Take care when using this, since often it's useful to respond with
+    /// ambiguity but return constrained variables to guide inference.
+    pub(in crate::solve) fn make_ambiguous_response_no_constraints(
+        &self,
+        maybe_cause: MaybeCause,
+    ) -> CanonicalResponse<'tcx> {
+        let unconstrained_response = Response {
+            var_values: CanonicalVarValues {
+                var_values: self.tcx().mk_substs_from_iter(self.var_values.var_values.iter().map(
+                    |arg| -> ty::GenericArg<'tcx> {
+                        match arg.unpack() {
+                            GenericArgKind::Lifetime(_) => self.next_region_infer().into(),
+                            GenericArgKind::Type(_) => self.next_ty_infer().into(),
+                            GenericArgKind::Const(ct) => self.next_const_infer(ct.ty()).into(),
+                        }
+                    },
+                )),
+            },
+            external_constraints: self
+                .tcx()
+                .mk_external_constraints(ExternalConstraintsData::default()),
+            certainty: Certainty::Maybe(maybe_cause),
+        };
+
+        Canonicalizer::canonicalize(
+            self.infcx,
+            CanonicalizeMode::Response { max_input_universe: self.max_input_universe },
+            &mut Default::default(),
+            unconstrained_response,
+        )
+    }
+
     #[instrument(level = "debug", skip(self), ret)]
     fn compute_external_query_constraints(&self) -> Result<ExternalConstraints<'tcx>, NoSolution> {
         // Cannot use `take_registered_region_obligations` as we may compute the response
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs
index 19bcbd46144..d94679fef28 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -340,17 +340,17 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         if responses.is_empty() {
             return Err(NoSolution);
         }
-        let certainty = responses.iter().fold(Certainty::AMBIGUOUS, |certainty, response| {
-            certainty.unify_with(response.value.certainty)
-        });
-
-        let response = self.evaluate_added_goals_and_make_canonical_response(certainty);
-        if let Ok(response) = response {
-            assert!(response.has_no_inference_or_external_constraints());
-            Ok(response)
-        } else {
-            bug!("failed to make floundered response: {responses:?}");
-        }
+
+        let Certainty::Maybe(maybe_cause) = responses.iter().fold(
+            Certainty::AMBIGUOUS,
+            |certainty, response| {
+                certainty.unify_with(response.value.certainty)
+            },
+        ) else {
+            bug!("expected flounder response to be ambiguous")
+        };
+
+        Ok(self.make_ambiguous_response_no_constraints(maybe_cause))
     }
 }
 
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index afdc998172d..efbbc1c2331 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -1543,11 +1543,17 @@ impl<'a, K: 'a, V: 'a> Iterator for Iter<'a, K, V> {
         self.next_back()
     }
 
-    fn min(mut self) -> Option<(&'a K, &'a V)> {
+    fn min(mut self) -> Option<(&'a K, &'a V)>
+    where
+        (&'a K, &'a V): Ord,
+    {
         self.next()
     }
 
-    fn max(mut self) -> Option<(&'a K, &'a V)> {
+    fn max(mut self) -> Option<(&'a K, &'a V)>
+    where
+        (&'a K, &'a V): Ord,
+    {
         self.next_back()
     }
 }
@@ -1612,11 +1618,17 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> {
         self.next_back()
     }
 
-    fn min(mut self) -> Option<(&'a K, &'a mut V)> {
+    fn min(mut self) -> Option<(&'a K, &'a mut V)>
+    where
+        (&'a K, &'a mut V): Ord,
+    {
         self.next()
     }
 
-    fn max(mut self) -> Option<(&'a K, &'a mut V)> {
+    fn max(mut self) -> Option<(&'a K, &'a mut V)>
+    where
+        (&'a K, &'a mut V): Ord,
+    {
         self.next_back()
     }
 }
@@ -1779,11 +1791,17 @@ impl<'a, K, V> Iterator for Keys<'a, K, V> {
         self.next_back()
     }
 
-    fn min(mut self) -> Option<&'a K> {
+    fn min(mut self) -> Option<&'a K>
+    where
+        &'a K: Ord,
+    {
         self.next()
     }
 
-    fn max(mut self) -> Option<&'a K> {
+    fn max(mut self) -> Option<&'a K>
+    where
+        &'a K: Ord,
+    {
         self.next_back()
     }
 }
@@ -2008,11 +2026,17 @@ impl<'a, K, V> Iterator for Range<'a, K, V> {
         self.next_back()
     }
 
-    fn min(mut self) -> Option<(&'a K, &'a V)> {
+    fn min(mut self) -> Option<(&'a K, &'a V)>
+    where
+        (&'a K, &'a V): Ord,
+    {
         self.next()
     }
 
-    fn max(mut self) -> Option<(&'a K, &'a V)> {
+    fn max(mut self) -> Option<(&'a K, &'a V)>
+    where
+        (&'a K, &'a V): Ord,
+    {
         self.next_back()
     }
 }
@@ -2081,11 +2105,17 @@ impl<K, V, A: Allocator + Clone> Iterator for IntoKeys<K, V, A> {
         self.next_back()
     }
 
-    fn min(mut self) -> Option<K> {
+    fn min(mut self) -> Option<K>
+    where
+        K: Ord,
+    {
         self.next()
     }
 
-    fn max(mut self) -> Option<K> {
+    fn max(mut self) -> Option<K>
+    where
+        K: Ord,
+    {
         self.next_back()
     }
 }
@@ -2204,11 +2234,17 @@ impl<'a, K, V> Iterator for RangeMut<'a, K, V> {
         self.next_back()
     }
 
-    fn min(mut self) -> Option<(&'a K, &'a mut V)> {
+    fn min(mut self) -> Option<(&'a K, &'a mut V)>
+    where
+        (&'a K, &'a mut V): Ord,
+    {
         self.next()
     }
 
-    fn max(mut self) -> Option<(&'a K, &'a mut V)> {
+    fn max(mut self) -> Option<(&'a K, &'a mut V)>
+    where
+        (&'a K, &'a mut V): Ord,
+    {
         self.next_back()
     }
 }
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index da952a13f1e..940fa30afb8 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -1501,11 +1501,17 @@ impl<'a, T> Iterator for Iter<'a, T> {
         self.next_back()
     }
 
-    fn min(mut self) -> Option<&'a T> {
+    fn min(mut self) -> Option<&'a T>
+    where
+        &'a T: Ord,
+    {
         self.next()
     }
 
-    fn max(mut self) -> Option<&'a T> {
+    fn max(mut self) -> Option<&'a T>
+    where
+        &'a T: Ord,
+    {
         self.next_back()
     }
 }
@@ -1604,11 +1610,17 @@ impl<'a, T> Iterator for Range<'a, T> {
         self.next_back()
     }
 
-    fn min(mut self) -> Option<&'a T> {
+    fn min(mut self) -> Option<&'a T>
+    where
+        &'a T: Ord,
+    {
         self.next()
     }
 
-    fn max(mut self) -> Option<&'a T> {
+    fn max(mut self) -> Option<&'a T>
+    where
+        &'a T: Ord,
+    {
         self.next_back()
     }
 }
diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index 8916b42eda0..896da37f94c 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -2815,7 +2815,7 @@ impl<'a, T: 'a + Copy, A: Allocator> Extend<&'a T> for VecDeque<T, A> {
     }
 
     #[inline]
-    fn extend_one(&mut self, &elem: &T) {
+    fn extend_one(&mut self, &elem: &'a T) {
         self.push_back(elem);
     }
 
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 98c87b2c393..940558974e6 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -248,7 +248,7 @@ where
 impl<'a, T, const N: usize> TryFrom<&'a [T]> for &'a [T; N] {
     type Error = TryFromSliceError;
 
-    fn try_from(slice: &[T]) -> Result<&[T; N], TryFromSliceError> {
+    fn try_from(slice: &'a [T]) -> Result<&'a [T; N], TryFromSliceError> {
         if slice.len() == N {
             let ptr = slice.as_ptr() as *const [T; N];
             // SAFETY: ok because we just checked that the length fits
@@ -275,7 +275,7 @@ impl<'a, T, const N: usize> TryFrom<&'a [T]> for &'a [T; N] {
 impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N] {
     type Error = TryFromSliceError;
 
-    fn try_from(slice: &mut [T]) -> Result<&mut [T; N], TryFromSliceError> {
+    fn try_from(slice: &'a mut [T]) -> Result<&'a mut [T; N], TryFromSliceError> {
         if slice.len() == N {
             let ptr = slice.as_mut_ptr() as *mut [T; N];
             // SAFETY: ok because we just checked that the length fits
diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs
index 37db074293d..0171d89812f 100644
--- a/library/core/src/iter/range.rs
+++ b/library/core/src/iter/range.rs
@@ -732,12 +732,18 @@ impl<A: Step> Iterator for ops::Range<A> {
     }
 
     #[inline]
-    fn min(mut self) -> Option<A> {
+    fn min(mut self) -> Option<A>
+    where
+        A: Ord,
+    {
         self.next()
     }
 
     #[inline]
-    fn max(mut self) -> Option<A> {
+    fn max(mut self) -> Option<A>
+    where
+        A: Ord,
+    {
         self.next_back()
     }
 
@@ -1158,12 +1164,18 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> {
     }
 
     #[inline]
-    fn min(mut self) -> Option<A> {
+    fn min(mut self) -> Option<A>
+    where
+        A: Ord,
+    {
         self.next()
     }
 
     #[inline]
-    fn max(mut self) -> Option<A> {
+    fn max(mut self) -> Option<A>
+    where
+        A: Ord,
+    {
         self.next_back()
     }
 
diff --git a/library/portable-simd/crates/core_simd/src/ops/deref.rs b/library/portable-simd/crates/core_simd/src/ops/deref.rs
index 9883a74c92d..302bf148bd3 100644
--- a/library/portable-simd/crates/core_simd/src/ops/deref.rs
+++ b/library/portable-simd/crates/core_simd/src/ops/deref.rs
@@ -71,7 +71,7 @@ macro_rules! deref_ops {
 
                 #[inline]
                 #[must_use = "operator returns a new vector without mutating the inputs"]
-                fn $call(self, rhs: &$simd) -> Self::Output {
+                fn $call(self, rhs: &'rhs $simd) -> Self::Output {
                     (*self).$call(*rhs)
                 }
             }
diff --git a/tests/mir-opt/issue_41888.main.ElaborateDrops.diff b/tests/mir-opt/issue_41888.main.ElaborateDrops.diff
index d98f75e7502..46b450a4e47 100644
--- a/tests/mir-opt/issue_41888.main.ElaborateDrops.diff
+++ b/tests/mir-opt/issue_41888.main.ElaborateDrops.diff
@@ -22,9 +22,9 @@
       }
   
       bb0: {
-+         _9 = const false;                // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
 +         _7 = const false;                // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
 +         _8 = const false;                // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
++         _9 = const false;                // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
           StorageLive(_1);                 // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
           StorageLive(_2);                 // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14
           _2 = cond() -> [return: bb1, unwind: bb11]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14
diff --git a/tests/ui/async-await/in-trait/nested-rpit.rs b/tests/ui/async-await/in-trait/nested-rpit.rs
index 41d72ebb4d4..9cdc23bbc78 100644
--- a/tests/ui/async-await/in-trait/nested-rpit.rs
+++ b/tests/ui/async-await/in-trait/nested-rpit.rs
@@ -1,7 +1,5 @@
 // edition: 2021
-// known-bug: #105197
-// failure-status:101
-// dont-check-compiler-stderr
+// check-pass
 
 #![feature(async_fn_in_trait)]
 #![feature(return_position_impl_trait_in_trait)]
diff --git a/tests/ui/async-await/return-type-notation/issue-110963-early.rs b/tests/ui/async-await/return-type-notation/issue-110963-early.rs
new file mode 100644
index 00000000000..0ecbca5c13b
--- /dev/null
+++ b/tests/ui/async-await/return-type-notation/issue-110963-early.rs
@@ -0,0 +1,48 @@
+// edition: 2021
+// known-bug: #110963
+
+#![feature(return_type_notation)]
+#![feature(async_fn_in_trait)]
+
+trait HealthCheck {
+    async fn check<'a: 'a>(&'a mut self) -> bool;
+}
+
+async fn do_health_check_par<HC>(hc: HC)
+where
+    HC: HealthCheck<check(): Send> + Send + 'static,
+{
+    spawn(async move {
+        let mut hc = hc;
+        if !hc.check().await {
+            log_health_check_failure().await;
+        }
+    });
+}
+
+async fn log_health_check_failure() {}
+
+fn main() {}
+
+// Fake tokio spawn
+
+use std::future::Future;
+use std::pin::Pin;
+use std::task::{Context, Poll};
+
+fn spawn<F>(future: F) -> JoinHandle
+where
+    F: Future + Send + 'static,
+    F::Output: Send + 'static,
+{
+    loop {}
+}
+
+struct JoinHandle;
+
+impl Future for JoinHandle {
+    type Output = ();
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        loop {}
+    }
+}
diff --git a/tests/ui/async-await/return-type-notation/issue-110963-early.stderr b/tests/ui/async-await/return-type-notation/issue-110963-early.stderr
new file mode 100644
index 00000000000..b4a3924d8da
--- /dev/null
+++ b/tests/ui/async-await/return-type-notation/issue-110963-early.stderr
@@ -0,0 +1,45 @@
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/issue-110963-early.rs:4:12
+   |
+LL | #![feature(return_type_notation)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/issue-110963-early.rs:5:12
+   |
+LL | #![feature(async_fn_in_trait)]
+   |            ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+
+error: higher-ranked lifetime error
+  --> $DIR/issue-110963-early.rs:15:5
+   |
+LL | /     spawn(async move {
+LL | |         let mut hc = hc;
+LL | |         if !hc.check().await {
+LL | |             log_health_check_failure().await;
+LL | |         }
+LL | |     });
+   | |______^
+   |
+   = note: could not prove `[async block@$DIR/issue-110963-early.rs:15:11: 20:6]: Send`
+
+error: higher-ranked lifetime error
+  --> $DIR/issue-110963-early.rs:15:5
+   |
+LL | /     spawn(async move {
+LL | |         let mut hc = hc;
+LL | |         if !hc.check().await {
+LL | |             log_health_check_failure().await;
+LL | |         }
+LL | |     });
+   | |______^
+   |
+   = note: could not prove `[async block@$DIR/issue-110963-early.rs:15:11: 20:6]: Send`
+
+error: aborting due to 2 previous errors; 2 warnings emitted
+
diff --git a/tests/ui/async-await/return-type-notation/issue-110963-late.rs b/tests/ui/async-await/return-type-notation/issue-110963-late.rs
new file mode 100644
index 00000000000..2a35922eaa1
--- /dev/null
+++ b/tests/ui/async-await/return-type-notation/issue-110963-late.rs
@@ -0,0 +1,50 @@
+// edition: 2021
+// check-pass
+
+#![feature(return_type_notation)]
+//~^ WARN the feature `return_type_notation` is incomplete
+#![feature(async_fn_in_trait)]
+//~^ WARN the feature `async_fn_in_trait` is incomplete
+
+trait HealthCheck {
+    async fn check(&mut self) -> bool;
+}
+
+async fn do_health_check_par<HC>(hc: HC)
+where
+    HC: HealthCheck<check(): Send> + Send + 'static,
+{
+    spawn(async move {
+        let mut hc = hc;
+        if !hc.check().await {
+            log_health_check_failure().await;
+        }
+    });
+}
+
+async fn log_health_check_failure() {}
+
+fn main() {}
+
+// Fake tokio spawn
+
+use std::future::Future;
+use std::pin::Pin;
+use std::task::{Context, Poll};
+
+fn spawn<F>(future: F) -> JoinHandle
+where
+    F: Future + Send + 'static,
+    F::Output: Send + 'static,
+{
+    loop {}
+}
+
+struct JoinHandle;
+
+impl Future for JoinHandle {
+    type Output = ();
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        loop {}
+    }
+}
diff --git a/tests/ui/async-await/return-type-notation/issue-110963-late.stderr b/tests/ui/async-await/return-type-notation/issue-110963-late.stderr
new file mode 100644
index 00000000000..36ef3ad0a4c
--- /dev/null
+++ b/tests/ui/async-await/return-type-notation/issue-110963-late.stderr
@@ -0,0 +1,19 @@
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/issue-110963-late.rs:4:12
+   |
+LL | #![feature(return_type_notation)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/issue-110963-late.rs:6:12
+   |
+LL | #![feature(async_fn_in_trait)]
+   |            ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/traits/new-solver/exponential-trait-goals.rs b/tests/ui/traits/new-solver/exponential-trait-goals.rs
new file mode 100644
index 00000000000..b37f09ee185
--- /dev/null
+++ b/tests/ui/traits/new-solver/exponential-trait-goals.rs
@@ -0,0 +1,20 @@
+// compile-flags: -Ztrait-solver=next
+
+trait Trait {}
+
+struct W<T>(T);
+
+impl<T, U> Trait for W<(W<T>, W<U>)>
+where
+    W<T>: Trait,
+    W<U>: Trait,
+{
+}
+
+fn impls<T: Trait>() {}
+
+fn main() {
+    impls::<W<_>>();
+    //~^ ERROR type annotations needed
+    //~| ERROR overflow evaluating the requirement `W<_>: Trait`
+}
diff --git a/tests/ui/traits/new-solver/exponential-trait-goals.stderr b/tests/ui/traits/new-solver/exponential-trait-goals.stderr
new file mode 100644
index 00000000000..28a99cbbca6
--- /dev/null
+++ b/tests/ui/traits/new-solver/exponential-trait-goals.stderr
@@ -0,0 +1,23 @@
+error[E0282]: type annotations needed
+  --> $DIR/exponential-trait-goals.rs:17:5
+   |
+LL |     impls::<W<_>>();
+   |     ^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls`
+
+error[E0275]: overflow evaluating the requirement `W<_>: Trait`
+  --> $DIR/exponential-trait-goals.rs:17:5
+   |
+LL |     impls::<W<_>>();
+   |     ^^^^^^^^^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`exponential_trait_goals`)
+note: required by a bound in `impls`
+  --> $DIR/exponential-trait-goals.rs:14:13
+   |
+LL | fn impls<T: Trait>() {}
+   |             ^^^^^ required by this bound in `impls`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0275, E0282.
+For more information about an error, try `rustc --explain E0275`.