diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index 79c1a4fb7662f..5b80da4d7ba14 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -32,6 +32,16 @@ pub fn explicit_outlives_bounds<'tcx>( } impl<'tcx> InferCtxt<'tcx> { + pub fn has_pending_region_state(&self) -> bool { + let inner = self.inner.borrow(); + !inner.region_obligations.is_empty() + || !inner.region_assumptions.is_empty() + || inner + .region_constraint_storage + .as_ref() + .is_none_or(|storage| !storage.data.is_empty()) + } + /// Process the region constraints and return any errors that /// result. After this, no more unification operations should be /// done -- or the compiler will panic -- but it is legal to use diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index 250579a2b064a..308326c63a212 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -134,6 +134,19 @@ where root_def_id: LocalDefId, span: Span, ) -> Result, ErrorGuaranteed> { + if !infcx.next_trait_solver() + && !infcx.disable_trait_solver_fast_paths() + && !infcx.in_snapshot() + && let Some(output) = Q::try_fast_path(infcx.tcx, &self) + && !infcx.has_pending_region_state() + { + return Ok(TypeOpOutput { + output: infcx.deeply_resolve_ignoring_regions(output), + constraints: None, + error_info: None, + }); + } + let mut error_info = None; let mut region_constraints = QueryRegionConstraints::default();