diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2023-06-09 16:29:02 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-09 16:29:02 +0200 |
| commit | 4ef72570189401dee5b148fd423b36cfd37fa3f7 (patch) | |
| tree | faf1c9d11e60fd3df5941ae1679293cd7d0e8d87 | |
| parent | f83c8e43170da30341d4d4cfcdf7039dc7f987d3 (diff) | |
| parent | d5e25d40c969009d0f40cbf6280339f2839e19c4 (diff) | |
| download | rust-4ef72570189401dee5b148fd423b36cfd37fa3f7.tar.gz rust-4ef72570189401dee5b148fd423b36cfd37fa3f7.zip | |
Rollup merge of #112442 - compiler-errors:next-solver-deduplicate-region-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``
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs | 6 | ||||
| -rw-r--r-- | tests/ui/traits/new-solver/dedup-regions.rs | 31 |
2 files changed, 36 insertions, 1 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index bca2343e424..72b3c3d0180 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -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; @@ -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 @@ -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, _)| { diff --git a/tests/ui/traits/new-solver/dedup-regions.rs b/tests/ui/traits/new-solver/dedup-regions.rs new file mode 100644 index 00000000000..f376f39a5a6 --- /dev/null +++ b/tests/ui/traits/new-solver/dedup-regions.rs @@ -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>(); +} |
