From 3418d5db3aa619f19f59f4ee341f6683ed6743b4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 28 May 2025 11:14:43 +0000 Subject: [PATCH 1/2] Fast path for stalled obligations on self ty --- compiler/rustc_infer/src/infer/opaque_types/table.rs | 2 +- compiler/rustc_trait_selection/src/solve/delegate.rs | 10 ++++++++++ .../coherence/coherence-fulfill-overflow.stderr | 7 ++----- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs index ab65da3913da1..df5a66243fc15 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/table.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs @@ -53,7 +53,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> { assert!(entry.is_some()); } - pub(crate) fn is_empty(&self) -> bool { + pub fn is_empty(&self) -> bool { let OpaqueTypeStorage { opaque_types, duplicate_entries } = self; opaque_types.is_empty() && duplicate_entries.is_empty() } diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index e92e37b873849..406acdb7d8897 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -64,6 +64,16 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< span: Span, ) -> Option { if let Some(trait_pred) = goal.predicate.as_trait_clause() { + if self.shallow_resolve(trait_pred.self_ty().skip_binder()).is_ty_var() + // We don't do this fast path when opaques are defined since we may + // eventually use opaques to incompletely guide inference via ty var + // self types. + // FIXME: Properly consider opaques here. + && self.inner.borrow_mut().opaque_types().is_empty() + { + return Some(Certainty::AMBIGUOUS); + } + if trait_pred.polarity() == ty::PredicatePolarity::Positive { match self.0.tcx.as_lang_item(trait_pred.def_id()) { Some(LangItem::Sized) diff --git a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr index 57cba790b5537..7d39c82d22f76 100644 --- a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr +++ b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr @@ -1,13 +1,10 @@ -error[E0119]: conflicting implementations of trait `Trait` for type `W>>>>>>>>>>>>>>>>>>>>` +error[E0119]: conflicting implementations of trait `Trait` for type `W>>>>>>>>>>>>>>>>>>>>>>` --> $DIR/coherence-fulfill-overflow.rs:12:1 | LL | impl Trait for W {} | ------------------------------------- first implementation here LL | impl Trait for T {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W>>>>>>>>>>>>>>>>>>>>` - | - = note: overflow evaluating the requirement `W>>>>>>>>>>>>>>>>>>>>: TwoW` - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`coherence_fulfill_overflow`) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W>>>>>>>>>>>>>>>>>>>>>>` error: aborting due to 1 previous error From 9899464906c577ae39e267d1cfb6f55cbe6067cc Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 28 May 2025 22:33:57 +0000 Subject: [PATCH 2/2] Fast path for subtype and coercion goals --- compiler/rustc_trait_selection/src/solve/delegate.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index 406acdb7d8897..69a0c0809b5ed 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -125,6 +125,17 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< Some(Certainty::Yes) } + ty::PredicateKind::Subtype(ty::SubtypePredicate { a, b, .. }) + | ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => { + if self.shallow_resolve(a).is_ty_var() && self.shallow_resolve(b).is_ty_var() { + // FIXME: We also need to register a subtype relation between these vars + // when those are added, and if they aren't in the same sub root then + // we should mark this goal as `has_changed`. + Some(Certainty::AMBIGUOUS) + } else { + None + } + } _ => None, } }