Skip to content

Commit fa369e6

Browse files
committed
Auto merge of #141681 - compiler-errors:fast-path-stalled, r=<try>
Fast path for stalled obligations on self ty r? lcnr
2 parents cb678b9 + fb285af commit fa369e6

File tree

6 files changed

+31
-22
lines changed

6 files changed

+31
-22
lines changed

compiler/rustc_infer/src/infer/opaque_types/table.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> {
5353
assert!(entry.is_some());
5454
}
5555

56-
pub(crate) fn is_empty(&self) -> bool {
56+
pub fn is_empty(&self) -> bool {
5757
let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
5858
opaque_types.is_empty() && duplicate_entries.is_empty()
5959
}

compiler/rustc_next_trait_solver/src/delegate.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ use std::ops::Deref;
33
use rustc_type_ir::solve::{Certainty, Goal, NoSolution};
44
use rustc_type_ir::{self as ty, InferCtxtLike, Interner, TypeFoldable};
55

6-
use crate::solve::HasChanged;
7-
86
pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
97
type Infcx: InferCtxtLike<Interner = Self::Interner>;
108
type Interner: Interner;
@@ -23,7 +21,7 @@ pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
2321
&self,
2422
goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
2523
span: <Self::Interner as Interner>::Span,
26-
) -> Option<HasChanged>;
24+
) -> Option<Certainty>;
2725

2826
fn fresh_var_for_kind_with_span(
2927
&self,

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -671,10 +671,13 @@ where
671671
// If this loop did not result in any progress, what's our final certainty.
672672
let mut unchanged_certainty = Some(Certainty::Yes);
673673
for (source, goal, stalled_on) in mem::take(&mut self.nested_goals) {
674-
if let Some(has_changed) = self.delegate.compute_goal_fast_path(goal, self.origin_span)
675-
{
676-
if matches!(has_changed, HasChanged::Yes) {
677-
unchanged_certainty = None;
674+
if let Some(certainty) = self.delegate.compute_goal_fast_path(goal, self.origin_span) {
675+
match certainty {
676+
Certainty::Yes => {}
677+
Certainty::Maybe(_) => {
678+
self.nested_goals.push((source, goal, None));
679+
unchanged_certainty = unchanged_certainty.map(|c| c.and(certainty));
680+
}
678681
}
679682
continue;
680683
}

compiler/rustc_trait_selection/src/solve/delegate.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use rustc_infer::traits::solve::Goal;
1212
use rustc_middle::traits::query::NoSolution;
1313
use rustc_middle::traits::solve::Certainty;
1414
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitableExt as _, TypingMode};
15-
use rustc_next_trait_solver::solve::HasChanged;
1615
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
1716

1817
use crate::traits::{EvaluateConstErr, ObligationCause, specialization_graph};
@@ -61,19 +60,26 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
6160
&self,
6261
goal: Goal<'tcx, ty::Predicate<'tcx>>,
6362
span: Span,
64-
) -> Option<HasChanged> {
63+
) -> Option<Certainty> {
64+
if let Some(trait_pred) = goal.predicate.as_trait_clause()
65+
&& self.shallow_resolve(trait_pred.self_ty().skip_binder()).is_ty_var()
66+
&& self.inner.borrow_mut().opaque_types().is_empty()
67+
{
68+
return Some(Certainty::AMBIGUOUS);
69+
}
70+
6571
let pred = goal.predicate.kind();
6672
match pred.no_bound_vars()? {
6773
ty::PredicateKind::DynCompatible(def_id) if self.0.tcx.is_dyn_compatible(def_id) => {
68-
Some(HasChanged::No)
74+
Some(Certainty::Yes)
6975
}
7076
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(outlives)) => {
7177
self.0.sub_regions(
7278
SubregionOrigin::RelateRegionParamBound(span, None),
7379
outlives.1,
7480
outlives.0,
7581
);
76-
Some(HasChanged::No)
82+
Some(Certainty::Yes)
7783
}
7884
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(outlives)) => {
7985
self.0.register_type_outlives_constraint(
@@ -82,19 +88,19 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
8288
&ObligationCause::dummy_with_span(span),
8389
);
8490

85-
Some(HasChanged::No)
91+
Some(Certainty::Yes)
8692
}
8793
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => {
8894
match self.0.tcx.as_lang_item(trait_pred.def_id()) {
8995
Some(LangItem::Sized)
9096
if trait_pred.self_ty().is_trivially_sized(self.0.tcx) =>
9197
{
92-
Some(HasChanged::No)
98+
Some(Certainty::Yes)
9399
}
94100
Some(LangItem::Copy | LangItem::Clone)
95101
if trait_pred.self_ty().is_trivially_pure_clone_copy() =>
96102
{
97-
Some(HasChanged::No)
103+
Some(Certainty::Yes)
98104
}
99105
_ => None,
100106
}

compiler/rustc_trait_selection/src/solve/fulfill.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,15 @@ where
195195

196196
let goal = obligation.as_goal();
197197
let delegate = <&SolverDelegate<'tcx>>::from(infcx);
198-
if let Some(fast_path_has_changed) =
198+
if let Some(certainty) =
199199
delegate.compute_goal_fast_path(goal, obligation.cause.span)
200200
{
201-
any_changed |= matches!(fast_path_has_changed, HasChanged::Yes);
201+
match certainty {
202+
Certainty::Yes => {}
203+
Certainty::Maybe(_) => {
204+
self.obligations.register(obligation, None);
205+
}
206+
}
202207
continue;
203208
}
204209

tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
error[E0119]: conflicting implementations of trait `Trait` for type `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>`
1+
error[E0119]: conflicting implementations of trait `Trait` for type `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>>`
22
--> $DIR/coherence-fulfill-overflow.rs:12:1
33
|
44
LL | impl<T: ?Sized + TwoW> Trait for W<T> {}
55
| ------------------------------------- first implementation here
66
LL | impl<T: ?Sized + TwoW> Trait for T {}
7-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>`
8-
|
9-
= note: overflow evaluating the requirement `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>: TwoW`
10-
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`coherence_fulfill_overflow`)
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>>`
118

129
error: aborting due to 1 previous error
1310

0 commit comments

Comments
 (0)