about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-06-08 23:12:53 +0000
committerMichael Goulet <michael@errs.io>2023-06-08 23:38:07 +0000
commitd5e25d40c969009d0f40cbf6280339f2839e19c4 (patch)
treeeab29081914e788800f3b556ae96b42ef6e8ec7b
parenta77659a1e1807ba567f513afe59115af2604dc30 (diff)
downloadrust-d5e25d40c969009d0f40cbf6280339f2839e19c4.tar.gz
rust-d5e25d40c969009d0f40cbf6280339f2839e19c4.zip
deduplicate identical region constraints
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs6
-rw-r--r--tests/ui/traits/new-solver/dedup-regions.rs31
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>();
+}