Skip to content

Commit

Permalink
Rollup merge of #112442 - compiler-errors:next-solver-deduplicate-reg…
Browse files Browse the repository at this point in the history
…ion-constraints, r=lcnr

Deduplicate identical region constraints in new solver

the new solver doesn't track whether we've already proven a goal like the fulfillment context's obligation forest does, so we may be instantiating a canonical response (and specifically, its nested region obligations) quite a few times.

This may lead to exponentially gathering up identical region constraints for things like auto traits, so let's deduplicate region constraints when in `compute_external_query_constraints`.

r? ``@lcnr``
  • Loading branch information
GuillaumeGomez authored Jun 9, 2023
2 parents f83c8e4 + d5e25d4 commit 4ef7257
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use super::{CanonicalInput, Certainty, EvalCtxt, Goal};
use crate::solve::canonicalize::{CanonicalizeMode, Canonicalizer};
use crate::solve::{CanonicalResponse, QueryResult, Response};
use rustc_data_structures::fx::FxHashSet;
use rustc_index::IndexVec;
use rustc_infer::infer::canonical::query_response::make_query_region_constraints;
use rustc_infer::infer::canonical::CanonicalVarValues;
Expand Down Expand Up @@ -147,7 +148,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
// Cannot use `take_registered_region_obligations` as we may compute the response
// inside of a `probe` whenever we have multiple choices inside of the solver.
let region_obligations = self.infcx.inner.borrow().region_obligations().to_owned();
let region_constraints = self.infcx.with_region_constraints(|region_constraints| {
let mut region_constraints = self.infcx.with_region_constraints(|region_constraints| {
make_query_region_constraints(
self.tcx(),
region_obligations
Expand All @@ -157,6 +158,9 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
)
});

let mut seen = FxHashSet::default();
region_constraints.outlives.retain(|outlives| seen.insert(*outlives));

let mut opaque_types = self.infcx.clone_opaque_types_for_query_response();
// Only return opaque type keys for newly-defined opaques
opaque_types.retain(|(a, _)| {
Expand Down
31 changes: 31 additions & 0 deletions tests/ui/traits/new-solver/dedup-regions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// compile-flags: -Ztrait-solver=next
// check-pass

struct A(*mut ());

unsafe impl Send for A where A: 'static {}

macro_rules! mk {
($name:ident $ty:ty) => {
struct $name($ty, $ty, $ty, $ty, $ty, $ty, $ty, $ty, $ty, $ty);
};
}

mk!(B A);
mk!(C B);
mk!(D C);
mk!(E D);
mk!(F E);
mk!(G F);
mk!(H G);
mk!(I H);
mk!(J I);
mk!(K J);
mk!(L K);
mk!(M L);

fn needs_send<T: Send>() {}

fn main() {
needs_send::<M>();
}

0 comments on commit 4ef7257

Please sign in to comment.