diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-05-08 08:14:18 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-08 08:14:18 +0200 |
| commit | 74b79aee60a5fba5fbe773ec45e205b46622ee37 (patch) | |
| tree | f1d4d9018b4e882f648ae09813bfa017eba1c287 /compiler/rustc_next_trait_solver | |
| parent | aace48811beab19e404eb38b5b415e59de695a37 (diff) | |
| parent | a910329c671aea4342413ecd8f88f09e47f8b85a (diff) | |
| download | rust-74b79aee60a5fba5fbe773ec45e205b46622ee37.tar.gz rust-74b79aee60a5fba5fbe773ec45e205b46622ee37.zip | |
Rollup merge of #140711 - compiler-errors:combine-maybes, r=lcnr
Do not discard constraints on overflow if there was candidate ambiguity Fixes https://github.com/rust-lang/trait-system-refactor-initiative/issues/201. There's a pretty chunky justification in the test. r? lcnr
Diffstat (limited to 'compiler/rustc_next_trait_solver')
3 files changed, 19 insertions, 14 deletions
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs index f87b1367d6a..36f68808a2c 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs @@ -132,12 +132,14 @@ where (Certainty::Yes, NestedNormalizationGoals(goals)) } _ => { - let certainty = shallow_certainty.unify_with(goals_certainty); + let certainty = shallow_certainty.and(goals_certainty); (certainty, NestedNormalizationGoals::empty()) } }; - if let Certainty::Maybe(cause @ MaybeCause::Overflow { .. }) = certainty { + if let Certainty::Maybe(cause @ MaybeCause::Overflow { keep_constraints: false, .. }) = + certainty + { // If we have overflow, it's probable that we're substituting a type // into itself infinitely and any partial substitutions in the query // response are probably not useful anyways, so just return an empty @@ -193,6 +195,7 @@ where debug!(?num_non_region_vars, "too many inference variables -> overflow"); return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow { suggest_increasing_limit: true, + keep_constraints: false, })); } } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index c8c914be63b..fc5dad9a3ed 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -661,7 +661,7 @@ where Certainty::Yes => {} Certainty::Maybe(_) => { self.nested_goals.push((source, with_resolved_vars)); - unchanged_certainty = unchanged_certainty.map(|c| c.unify_with(certainty)); + unchanged_certainty = unchanged_certainty.map(|c| c.and(certainty)); } } } else { @@ -675,7 +675,7 @@ where Certainty::Yes => {} Certainty::Maybe(_) => { self.nested_goals.push((source, goal)); - unchanged_certainty = unchanged_certainty.map(|c| c.unify_with(certainty)); + unchanged_certainty = unchanged_certainty.map(|c| c.and(certainty)); } } } diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index c9f4fc649b5..8173146e2fe 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -253,16 +253,18 @@ where } fn bail_with_ambiguity(&mut self, responses: &[CanonicalResponse<I>]) -> CanonicalResponse<I> { - debug_assert!(!responses.is_empty()); - if let Certainty::Maybe(maybe_cause) = - responses.iter().fold(Certainty::AMBIGUOUS, |certainty, response| { - certainty.unify_with(response.value.certainty) - }) - { - self.make_ambiguous_response_no_constraints(maybe_cause) - } else { - panic!("expected flounder response to be ambiguous") - } + debug_assert!(responses.len() > 1); + let maybe_cause = responses.iter().fold(MaybeCause::Ambiguity, |maybe_cause, response| { + // Pull down the certainty of `Certainty::Yes` to ambiguity when combining + // these responses, b/c we're combining more than one response and this we + // don't know which one applies. + let candidate = match response.value.certainty { + Certainty::Yes => MaybeCause::Ambiguity, + Certainty::Maybe(candidate) => candidate, + }; + maybe_cause.or(candidate) + }); + self.make_ambiguous_response_no_constraints(maybe_cause) } /// If we fail to merge responses we flounder and return overflow or ambiguity. |
