Skip to content

Commit 039888f

Browse files
Auto merge of #141681 - compiler-errors:fast-path-stalled, r=<try>
Fast path for stalled obligations on self ty If we see that the `self` type of a goal is an infer var, then don't try to compute the goal at all, since we know that it'll be forced ambiguous. This is currently only implemented when there are no opaques in the environment. We could extend it to check that the self type is not related to any already defined opaques via subtyping, but I'll leave that as a follow-up. --- Also stall coerce and subtype predicates if both of their vars are not resolved to concrete types. --- ~~Also, we don't care if the goal is higher-ranked for the sized and copy/clone fast path.~~ pulling this out into another PR. r? lcnr
2 parents 2398bd6 + 9899464 commit 039888f

File tree

3 files changed

+24
-6
lines changed

3 files changed

+24
-6
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_trait_selection/src/solve/delegate.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,16 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
6464
span: Span,
6565
) -> Option<Certainty> {
6666
if let Some(trait_pred) = goal.predicate.as_trait_clause() {
67+
if self.shallow_resolve(trait_pred.self_ty().skip_binder()).is_ty_var()
68+
// We don't do this fast path when opaques are defined since we may
69+
// eventually use opaques to incompletely guide inference via ty var
70+
// self types.
71+
// FIXME: Properly consider opaques here.
72+
&& self.inner.borrow_mut().opaque_types().is_empty()
73+
{
74+
return Some(Certainty::AMBIGUOUS);
75+
}
76+
6777
if trait_pred.polarity() == ty::PredicatePolarity::Positive {
6878
match self.0.tcx.as_lang_item(trait_pred.def_id()) {
6979
Some(LangItem::Sized)
@@ -115,6 +125,17 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
115125

116126
Some(Certainty::Yes)
117127
}
128+
ty::PredicateKind::Subtype(ty::SubtypePredicate { a, b, .. })
129+
| ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => {
130+
if self.shallow_resolve(a).is_ty_var() && self.shallow_resolve(b).is_ty_var() {
131+
// FIXME: We also need to register a subtype relation between these vars
132+
// when those are added, and if they aren't in the same sub root then
133+
// we should mark this goal as `has_changed`.
134+
Some(Certainty::AMBIGUOUS)
135+
} else {
136+
None
137+
}
138+
}
118139
_ => None,
119140
}
120141
}

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)