diff options
| author | Michael Goulet <michael@errs.io> | 2025-06-26 20:15:20 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-26 20:15:20 -0400 |
| commit | 25e239c193b3e22d0dc5e8e3eaebd66ed9b7374b (patch) | |
| tree | f64aa341aafbc40ce3aa5678865cf8acaa6db015 | |
| parent | 48d311898b2f4fd2437df206e910c0d63d20061f (diff) | |
| parent | 83044357930a7c55f8d429bd4cd7dcb7426d4b01 (diff) | |
| download | rust-25e239c193b3e22d0dc5e8e3eaebd66ed9b7374b.tar.gz rust-25e239c193b3e22d0dc5e8e3eaebd66ed9b7374b.zip | |
Rollup merge of #142647 - compiler-errors:less-work-in-coherence, r=lcnr
[perf] Compute hard errors without diagnostics in impl_intersection_has_impossible_obligation First compute hard errors without diagnostics, then ambiguities with diagnostics since we need to know if any of them overflowed.
| -rw-r--r-- | compiler/rustc_infer/src/traits/engine.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/coherence.rs | 43 | ||||
| -rw-r--r-- | tests/crashes/139905.rs | 6 |
3 files changed, 28 insertions, 24 deletions
diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index 9e51a53ae95..9a66bd0574c 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -19,7 +19,8 @@ pub enum ScrubbedTraitError<'tcx> { TrueError, /// An ambiguity. This goal may hold if further inference is done. Ambiguity, - /// An old-solver-style cycle error, which will fatal. + /// An old-solver-style cycle error, which will fatal. This is not + /// returned by the new solver. Cycle(PredicateObligations<'tcx>), } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 81893cdcc7e..ce5a4edeaaa 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -356,29 +356,38 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>( return IntersectionHasImpossibleObligations::Yes; } - let ocx = ObligationCtxt::new_with_diagnostics(infcx); + let ocx = ObligationCtxt::new(infcx); ocx.register_obligations(obligations.iter().cloned()); + let hard_errors = ocx.select_where_possible(); + if !hard_errors.is_empty() { + assert!( + hard_errors.iter().all(|e| e.is_true_error()), + "should not have detected ambiguity during first pass" + ); + return IntersectionHasImpossibleObligations::Yes; + } + + // Make a new `ObligationCtxt` and re-prove the ambiguities with a richer + // `FulfillmentError`. This is so that we can detect overflowing obligations + // without needing to run the `BestObligation` visitor on true errors. + let ambiguities = ocx.into_pending_obligations(); + let ocx = ObligationCtxt::new_with_diagnostics(infcx); + ocx.register_obligations(ambiguities); let errors_and_ambiguities = ocx.select_all_or_error(); // We only care about the obligations that are *definitely* true errors. // Ambiguities do not prove the disjointness of two impls. let (errors, ambiguities): (Vec<_>, Vec<_>) = errors_and_ambiguities.into_iter().partition(|error| error.is_true_error()); - - if errors.is_empty() { - IntersectionHasImpossibleObligations::No { - overflowing_predicates: ambiguities - .into_iter() - .filter(|error| { - matches!( - error.code, - FulfillmentErrorCode::Ambiguity { overflow: Some(true) } - ) - }) - .map(|e| infcx.resolve_vars_if_possible(e.obligation.predicate)) - .collect(), - } - } else { - IntersectionHasImpossibleObligations::Yes + assert!(errors.is_empty(), "should not have ambiguities during second pass"); + + IntersectionHasImpossibleObligations::No { + overflowing_predicates: ambiguities + .into_iter() + .filter(|error| { + matches!(error.code, FulfillmentErrorCode::Ambiguity { overflow: Some(true) }) + }) + .map(|e| infcx.resolve_vars_if_possible(e.obligation.predicate)) + .collect(), } } else { for obligation in obligations { diff --git a/tests/crashes/139905.rs b/tests/crashes/139905.rs deleted file mode 100644 index 7da622aaaba..00000000000 --- a/tests/crashes/139905.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ known-bug: #139905 -trait a<const b: bool> {} -impl a<{}> for () {} -trait c {} -impl<const d: u8> c for () where (): a<d> {} -impl c for () {} |
