Skip to content

Commit fda5795

Browse files
ShoyuVanillalcnr
authored andcommitted
-Znext-solver Remove the forced ambiguity hack from search graph
1 parent 7ebf298 commit fda5795

File tree

2 files changed

+48
-28
lines changed

2 files changed

+48
-28
lines changed

compiler/rustc_type_ir/src/search_graph/mod.rs

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -916,10 +916,9 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
916916
/// heads from the stack. This may not necessarily mean that we've actually
917917
/// reached a fixpoint for that cycle head, which impacts the way we rebase
918918
/// provisional cache entries.
919-
#[derive_where(Debug; X: Cx)]
920-
enum RebaseReason<X: Cx> {
919+
#[derive(Debug)]
920+
enum RebaseReason {
921921
NoCycleUsages,
922-
Ambiguity(X::AmbiguityInfo),
923922
Overflow,
924923
/// We've actually reached a fixpoint.
925924
///
@@ -956,7 +955,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D, X> {
956955
&mut self,
957956
cx: X,
958957
stack_entry: &StackEntry<X>,
959-
rebase_reason: RebaseReason<X>,
958+
rebase_reason: RebaseReason,
960959
) {
961960
let popped_head_index = self.stack.next_index();
962961
#[allow(rustc::potential_query_instability)]
@@ -1035,9 +1034,6 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D, X> {
10351034
// is not actually equal to the final provisional result. We
10361035
// need to discard the provisional cache entry in this case.
10371036
RebaseReason::NoCycleUsages => return false,
1038-
RebaseReason::Ambiguity(info) => {
1039-
*result = D::propagate_ambiguity(cx, input, info);
1040-
}
10411037
RebaseReason::Overflow => *result = D::fixpoint_overflow_result(cx, input),
10421038
RebaseReason::ReachedFixpoint(None) => {}
10431039
RebaseReason::ReachedFixpoint(Some(path_kind)) => {
@@ -1352,27 +1348,6 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D, X> {
13521348
return EvaluationResult::finalize(stack_entry, encountered_overflow, result);
13531349
}
13541350

1355-
// If computing this goal results in ambiguity with no constraints,
1356-
// we do not rerun it. It's incredibly difficult to get a different
1357-
// response in the next iteration in this case. These changes would
1358-
// likely either be caused by incompleteness or can change the maybe
1359-
// cause from ambiguity to overflow. Returning ambiguity always
1360-
// preserves soundness and completeness even if the goal is be known
1361-
// to succeed or fail.
1362-
//
1363-
// This prevents exponential blowup affecting multiple major crates.
1364-
// As we only get to this branch if we haven't yet reached a fixpoint,
1365-
// we also taint all provisional cache entries which depend on the
1366-
// current goal.
1367-
if let Some(info) = D::is_ambiguous_result(result) {
1368-
self.rebase_provisional_cache_entries(
1369-
cx,
1370-
&stack_entry,
1371-
RebaseReason::Ambiguity(info),
1372-
);
1373-
return EvaluationResult::finalize(stack_entry, encountered_overflow, result);
1374-
};
1375-
13761351
// If we've reached the fixpoint step limit, we bail with overflow and taint all
13771352
// provisional cache entries which depend on the current goal.
13781353
i += 1;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//@ check-pass
2+
//@ compile-flags: -Znext-solver
3+
4+
// Regression test for https://github.com/rust-lang/trait-system-refactor-initiative/issues/257.
5+
6+
#![feature(rustc_attrs)]
7+
#![expect(internal_features)]
8+
#![rustc_no_implicit_bounds]
9+
10+
pub trait Bound {}
11+
impl Bound for u8 {}
12+
13+
pub trait Proj {
14+
type Assoc;
15+
}
16+
impl<U: Bound> Proj for U {
17+
type Assoc = U;
18+
}
19+
impl Proj for MyField {
20+
type Assoc = u8;
21+
}
22+
23+
// While wf-checking the global bounds of `fn foo`, elaborating this outlives predicate triggered a
24+
// cycle in the search graph along a particular probe path, which was not an actual solution.
25+
// That cycle then resulted in a forced false-positive ambiguity due to a performance hack in the
26+
// search graph and then ended up floundering the root goal evaluation.
27+
pub trait Field: Proj<Assoc: Bound + 'static> {}
28+
29+
struct MyField;
30+
impl Field for MyField {}
31+
32+
trait IdReqField {
33+
type This;
34+
}
35+
impl<F: Field> IdReqField for F {
36+
type This = F;
37+
}
38+
39+
fn foo()
40+
where
41+
<MyField as IdReqField>::This: Field,
42+
{
43+
}
44+
45+
fn main() {}

0 commit comments

Comments
 (0)