summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2025-07-25 20:34:36 +1000
committerNicholas Nethercote <n.nethercote@gmail.com>2025-07-31 20:04:51 +1000
commit066a973312066b792c5de4b41b92dcb437f22bac (patch)
treec23a8cdb7b9ca7579eb485cec461e80511b91f89 /compiler
parent75a1f47750fb34031f00cc2ee2b0d385426bec94 (diff)
downloadrust-066a973312066b792c5de4b41b92dcb437f22bac.tar.gz
rust-066a973312066b792c5de4b41b92dcb437f22bac.zip
Overhaul `Constraint`.
This commit changes it to store a `Region` instead of a `RegionVid` for the `Var` cases:
- We avoid having to call `Region::new_var` to re-create `Region`s from
  `RegionVid`s in a few places, avoiding the interning process, giving a
  small perf win. (At the cost of the type allowing some invalid
  combinations of values.)
- All the cases now store two `Region`s, so the commit also separates
  the `ConstraintKind` (a new type) from the `sub` and `sup` arguments
  in `Constraint`.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs39
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs25
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs234
-rw-r--r--compiler/rustc_infer/src/infer/outlives/mod.rs8
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/leak_check.rs29
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/mod.rs46
-rw-r--r--compiler/rustc_trait_selection/src/solve/delegate.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs44
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs1
-rw-r--r--compiler/rustc_traits/src/coroutine_witnesses.rs1
10 files changed, 205 insertions, 223 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
index 0de4bd67f0c..6ccded01e88 100644
--- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
@@ -3,7 +3,7 @@ use std::rc::Rc;
 
 use rustc_errors::Diag;
 use rustc_hir::def_id::LocalDefId;
-use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
+use rustc_infer::infer::region_constraints::{Constraint, ConstraintKind, RegionConstraintData};
 use rustc_infer::infer::{
     InferCtxt, RegionResolutionError, RegionVariableOrigin, SubregionOrigin, TyCtxtInferExt as _,
 };
@@ -454,25 +454,24 @@ fn try_extract_error_from_region_constraints<'a, 'tcx>(
             (RePlaceholder(a_p), RePlaceholder(b_p)) => a_p.bound == b_p.bound,
             _ => a_region == b_region,
         };
-    let mut check =
-        |constraint: &Constraint<'tcx>, cause: &SubregionOrigin<'tcx>, exact| match *constraint {
-            Constraint::RegSubReg(sub, sup)
-                if ((exact && sup == placeholder_region)
-                    || (!exact && regions_the_same(sup, placeholder_region)))
-                    && sup != sub =>
-            {
-                Some((sub, cause.clone()))
-            }
-            Constraint::VarSubReg(vid, sup)
-                if (exact
-                    && sup == placeholder_region
-                    && !universe_of_region(vid).can_name(placeholder_universe))
-                    || (!exact && regions_the_same(sup, placeholder_region)) =>
-            {
-                Some((ty::Region::new_var(infcx.tcx, vid), cause.clone()))
-            }
-            _ => None,
-        };
+    let mut check = |c: &Constraint<'tcx>, cause: &SubregionOrigin<'tcx>, exact| match c.kind {
+        ConstraintKind::RegSubReg
+            if ((exact && c.sup == placeholder_region)
+                || (!exact && regions_the_same(c.sup, placeholder_region)))
+                && c.sup != c.sub =>
+        {
+            Some((c.sub, cause.clone()))
+        }
+        ConstraintKind::VarSubReg
+            if (exact
+                && c.sup == placeholder_region
+                && !universe_of_region(c.sub.as_var()).can_name(placeholder_universe))
+                || (!exact && regions_the_same(c.sup, placeholder_region)) =>
+        {
+            Some((c.sub, cause.clone()))
+        }
+        _ => None,
+    };
 
     let mut find_culprit = |exact_match: bool| {
         region_constraints
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index 6be53c948c8..d92f4c2444b 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -21,7 +21,7 @@ use crate::infer::canonical::{
     Canonical, CanonicalQueryResponse, CanonicalVarValues, Certainty, OriginalQueryValues,
     QueryRegionConstraints, QueryResponse,
 };
-use crate::infer::region_constraints::{Constraint, RegionConstraintData};
+use crate::infer::region_constraints::RegionConstraintData;
 use crate::infer::{
     DefineOpaqueTypes, InferCtxt, InferOk, InferResult, SubregionOrigin, TypeOutlivesConstraint,
 };
@@ -105,8 +105,6 @@ impl<'tcx> InferCtxt<'tcx> {
     where
         T: Debug + TypeFoldable<TyCtxt<'tcx>>,
     {
-        let tcx = self.tcx;
-
         // Select everything, returning errors.
         let errors = fulfill_cx.select_all_or_error(self);
 
@@ -120,7 +118,6 @@ impl<'tcx> InferCtxt<'tcx> {
         debug!(?region_obligations);
         let region_constraints = self.with_region_constraints(|region_constraints| {
             make_query_region_constraints(
-                tcx,
                 region_obligations,
                 region_constraints,
                 region_assumptions,
@@ -587,7 +584,6 @@ impl<'tcx> InferCtxt<'tcx> {
 /// Given the region obligations and constraints scraped from the infcx,
 /// creates query region constraints.
 pub fn make_query_region_constraints<'tcx>(
-    tcx: TyCtxt<'tcx>,
     outlives_obligations: Vec<TypeOutlivesConstraint<'tcx>>,
     region_constraints: &RegionConstraintData<'tcx>,
     assumptions: Vec<ty::ArgOutlivesPredicate<'tcx>>,
@@ -600,22 +596,9 @@ pub fn make_query_region_constraints<'tcx>(
 
     let outlives: Vec<_> = constraints
         .iter()
-        .map(|(k, origin)| {
-            let constraint = match *k {
-                // Swap regions because we are going from sub (<=) to outlives
-                // (>=).
-                Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
-                    ty::Region::new_var(tcx, v2).into(),
-                    ty::Region::new_var(tcx, v1),
-                ),
-                Constraint::VarSubReg(v1, r2) => {
-                    ty::OutlivesPredicate(r2.into(), ty::Region::new_var(tcx, v1))
-                }
-                Constraint::RegSubVar(r1, v2) => {
-                    ty::OutlivesPredicate(ty::Region::new_var(tcx, v2).into(), r1)
-                }
-                Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
-            };
+        .map(|(c, origin)| {
+            // Swap regions because we are going from sub (<=) to outlives (>=).
+            let constraint = ty::OutlivesPredicate(c.sup.into(), c.sub);
             (constraint, origin.to_constraint_category())
         })
         .chain(outlives_obligations.into_iter().map(|obl| {
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index 2185886901e..3adcfb42727 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -19,7 +19,7 @@ use tracing::{debug, instrument};
 
 use super::outlives::test_type_match;
 use crate::infer::region_constraints::{
-    Constraint, GenericKind, RegionConstraintData, VarInfos, VerifyBound,
+    Constraint, ConstraintKind, GenericKind, RegionConstraintData, VarInfos, VerifyBound,
 };
 use crate::infer::{RegionRelations, RegionVariableOrigin, SubregionOrigin};
 
@@ -187,91 +187,96 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
         let mut constraints = IndexVec::from_elem(Vec::new(), &var_values.values);
         // Tracks the changed region vids.
         let mut changes = Vec::new();
-        for (constraint, _) in &self.data.constraints {
-            match *constraint {
-                Constraint::RegSubVar(a_region, b_vid) => {
-                    let b_data = var_values.value_mut(b_vid);
-
-                    if self.expand_node(a_region, b_vid, b_data) {
-                        changes.push(b_vid);
+        for (c, _) in &self.data.constraints {
+            match c.kind {
+                ConstraintKind::RegSubVar => {
+                    let sup_vid = c.sup.as_var();
+                    let sup_data = var_values.value_mut(sup_vid);
+
+                    if self.expand_node(c.sub, sup_vid, sup_data) {
+                        changes.push(sup_vid);
                     }
                 }
-                Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) {
-                    VarValue::ErrorValue => continue,
-                    VarValue::Empty(a_universe) => {
-                        let b_data = var_values.value_mut(b_vid);
-
-                        let changed = match *b_data {
-                            VarValue::Empty(b_universe) => {
-                                // Empty regions are ordered according to the universe
-                                // they are associated with.
-                                let ui = a_universe.min(b_universe);
-
-                                debug!(
-                                    "Expanding value of {:?} \
+                ConstraintKind::VarSubVar => {
+                    let sub_vid = c.sub.as_var();
+                    let sup_vid = c.sup.as_var();
+                    match *var_values.value(sub_vid) {
+                        VarValue::ErrorValue => continue,
+                        VarValue::Empty(sub_universe) => {
+                            let sup_data = var_values.value_mut(sup_vid);
+
+                            let changed = match *sup_data {
+                                VarValue::Empty(sup_universe) => {
+                                    // Empty regions are ordered according to the universe
+                                    // they are associated with.
+                                    let ui = sub_universe.min(sup_universe);
+
+                                    debug!(
+                                        "Expanding value of {:?} \
                                     from empty lifetime with universe {:?} \
                                     to empty lifetime with universe {:?}",
-                                    b_vid, b_universe, ui
-                                );
+                                        sup_vid, sup_universe, ui
+                                    );
 
-                                *b_data = VarValue::Empty(ui);
-                                true
-                            }
-                            VarValue::Value(cur_region) => {
-                                match cur_region.kind() {
-                                    // If this empty region is from a universe that can name the
-                                    // placeholder universe, then the LUB is the Placeholder region
-                                    // (which is the cur_region). Otherwise, the LUB is the Static
-                                    // lifetime.
-                                    RePlaceholder(placeholder)
-                                        if !a_universe.can_name(placeholder.universe) =>
-                                    {
-                                        let lub = self.tcx().lifetimes.re_static;
-                                        debug!(
-                                            "Expanding value of {:?} from {:?} to {:?}",
-                                            b_vid, cur_region, lub
-                                        );
-
-                                        *b_data = VarValue::Value(lub);
-                                        true
+                                    *sup_data = VarValue::Empty(ui);
+                                    true
+                                }
+                                VarValue::Value(cur_region) => {
+                                    match cur_region.kind() {
+                                        // If this empty region is from a universe that can name
+                                        // the placeholder universe, then the LUB is the
+                                        // Placeholder region (which is the cur_region). Otherwise,
+                                        // the LUB is the Static lifetime.
+                                        RePlaceholder(placeholder)
+                                            if !sub_universe.can_name(placeholder.universe) =>
+                                        {
+                                            let lub = self.tcx().lifetimes.re_static;
+                                            debug!(
+                                                "Expanding value of {:?} from {:?} to {:?}",
+                                                sup_vid, cur_region, lub
+                                            );
+
+                                            *sup_data = VarValue::Value(lub);
+                                            true
+                                        }
+
+                                        _ => false,
                                     }
-
-                                    _ => false,
                                 }
-                            }
 
-                            VarValue::ErrorValue => false,
-                        };
+                                VarValue::ErrorValue => false,
+                            };
 
-                        if changed {
-                            changes.push(b_vid);
-                        }
-                        match b_data {
-                            VarValue::Value(Region(Interned(ReStatic, _)))
-                            | VarValue::ErrorValue => (),
-                            _ => {
-                                constraints[a_vid].push((a_vid, b_vid));
-                                constraints[b_vid].push((a_vid, b_vid));
+                            if changed {
+                                changes.push(sup_vid);
+                            }
+                            match sup_data {
+                                VarValue::Value(Region(Interned(ReStatic, _)))
+                                | VarValue::ErrorValue => (),
+                                _ => {
+                                    constraints[sub_vid].push((sub_vid, sup_vid));
+                                    constraints[sup_vid].push((sub_vid, sup_vid));
+                                }
                             }
                         }
-                    }
-                    VarValue::Value(a_region) => {
-                        let b_data = var_values.value_mut(b_vid);
+                        VarValue::Value(sub_region) => {
+                            let sup_data = var_values.value_mut(sup_vid);
 
-                        if self.expand_node(a_region, b_vid, b_data) {
-                            changes.push(b_vid);
-                        }
-                        match b_data {
-                            VarValue::Value(Region(Interned(ReStatic, _)))
-                            | VarValue::ErrorValue => (),
-                            _ => {
-                                constraints[a_vid].push((a_vid, b_vid));
-                                constraints[b_vid].push((a_vid, b_vid));
+                            if self.expand_node(sub_region, sup_vid, sup_data) {
+                                changes.push(sup_vid);
+                            }
+                            match sup_data {
+                                VarValue::Value(Region(Interned(ReStatic, _)))
+                                | VarValue::ErrorValue => (),
+                                _ => {
+                                    constraints[sub_vid].push((sub_vid, sup_vid));
+                                    constraints[sup_vid].push((sub_vid, sup_vid));
+                                }
                             }
                         }
                     }
-                },
-                Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => {
+                }
+                ConstraintKind::RegSubReg | ConstraintKind::VarSubReg => {
                     // These constraints are checked after expansion
                     // is done, in `collect_errors`.
                     continue;
@@ -528,49 +533,48 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
         var_data: &mut LexicalRegionResolutions<'tcx>,
         errors: &mut Vec<RegionResolutionError<'tcx>>,
     ) {
-        for (constraint, origin) in &self.data.constraints {
-            debug!(?constraint, ?origin);
-            match *constraint {
-                Constraint::RegSubVar(..) | Constraint::VarSubVar(..) => {
+        for (c, origin) in &self.data.constraints {
+            debug!(?c, ?origin);
+            match c.kind {
+                ConstraintKind::RegSubVar | ConstraintKind::VarSubVar => {
                     // Expansion will ensure that these constraints hold. Ignore.
                 }
 
-                Constraint::RegSubReg(sub, sup) => {
-                    if self.sub_concrete_regions(sub, sup) {
+                ConstraintKind::RegSubReg => {
+                    if self.sub_concrete_regions(c.sub, c.sup) {
                         continue;
                     }
 
                     debug!(
-                        "region error at {:?}: \
-                         cannot verify that {:?} <= {:?}",
-                        origin, sub, sup
+                        "region error at {:?}: cannot verify that {:?} <= {:?}",
+                        origin, c.sub, c.sup
                     );
 
                     errors.push(RegionResolutionError::ConcreteFailure(
                         (*origin).clone(),
-                        sub,
-                        sup,
+                        c.sub,
+                        c.sup,
                     ));
                 }
 
-                Constraint::VarSubReg(a_vid, b_region) => {
-                    let a_data = var_data.value_mut(a_vid);
-                    debug!("contraction: {:?} == {:?}, {:?}", a_vid, a_data, b_region);
+                ConstraintKind::VarSubReg => {
+                    let sub_vid = c.sub.as_var();
+                    let sub_data = var_data.value_mut(sub_vid);
+                    debug!("contraction: {:?} == {:?}, {:?}", sub_vid, sub_data, c.sup);
 
-                    let VarValue::Value(a_region) = *a_data else {
+                    let VarValue::Value(sub_region) = *sub_data else {
                         continue;
                     };
 
                     // Do not report these errors immediately:
                     // instead, set the variable value to error and
                     // collect them later.
-                    if !self.sub_concrete_regions(a_region, b_region) {
+                    if !self.sub_concrete_regions(sub_region, c.sup) {
                         debug!(
-                            "region error at {:?}: \
-                            cannot verify that {:?}={:?} <= {:?}",
-                            origin, a_vid, a_region, b_region
+                            "region error at {:?}: cannot verify that {:?}={:?} <= {:?}",
+                            origin, sub_vid, sub_region, c.sup
                         );
-                        *a_data = VarValue::ErrorValue;
+                        *sub_data = VarValue::ErrorValue;
                     }
                 }
             }
@@ -682,18 +686,20 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
         let dummy_source = graph.add_node(());
         let dummy_sink = graph.add_node(());
 
-        for (constraint, _) in &self.data.constraints {
-            match *constraint {
-                Constraint::VarSubVar(a_id, b_id) => {
-                    graph.add_edge(NodeIndex(a_id.index()), NodeIndex(b_id.index()), *constraint);
+        for (c, _) in &self.data.constraints {
+            match c.kind {
+                ConstraintKind::VarSubVar => {
+                    let sub_vid = c.sub.as_var();
+                    let sup_vid = c.sup.as_var();
+                    graph.add_edge(NodeIndex(sub_vid.index()), NodeIndex(sup_vid.index()), *c);
                 }
-                Constraint::RegSubVar(_, b_id) => {
-                    graph.add_edge(dummy_source, NodeIndex(b_id.index()), *constraint);
+                ConstraintKind::RegSubVar => {
+                    graph.add_edge(dummy_source, NodeIndex(c.sup.as_var().index()), *c);
                 }
-                Constraint::VarSubReg(a_id, _) => {
-                    graph.add_edge(NodeIndex(a_id.index()), dummy_sink, *constraint);
+                ConstraintKind::VarSubReg => {
+                    graph.add_edge(NodeIndex(c.sub.as_var().index()), dummy_sink, *c);
                 }
-                Constraint::RegSubReg(..) => {
+                ConstraintKind::RegSubReg => {
                     // this would be an edge from `dummy_source` to
                     // `dummy_sink`; just ignore it.
                 }
@@ -878,26 +884,30 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
 
             let source_node_index = NodeIndex(source_vid.index());
             for (_, edge) in graph.adjacent_edges(source_node_index, dir) {
-                match edge.data {
-                    Constraint::VarSubVar(from_vid, to_vid) => {
+                let get_origin =
+                    || this.constraints.iter().find(|(c, _)| *c == edge.data).unwrap().1.clone();
+
+                match edge.data.kind {
+                    ConstraintKind::VarSubVar => {
+                        let from_vid = edge.data.sub.as_var();
+                        let to_vid = edge.data.sup.as_var();
                         let opp_vid = if from_vid == source_vid { to_vid } else { from_vid };
                         if state.set.insert(opp_vid) {
                             state.stack.push(opp_vid);
                         }
                     }
 
-                    Constraint::RegSubVar(region, _) | Constraint::VarSubReg(_, region) => {
-                        let origin = this
-                            .constraints
-                            .iter()
-                            .find(|(c, _)| *c == edge.data)
-                            .unwrap()
-                            .1
-                            .clone();
-                        state.result.push(RegionAndOrigin { region, origin });
+                    ConstraintKind::RegSubVar => {
+                        let origin = get_origin();
+                        state.result.push(RegionAndOrigin { region: edge.data.sub, origin });
+                    }
+
+                    ConstraintKind::VarSubReg => {
+                        let origin = get_origin();
+                        state.result.push(RegionAndOrigin { region: edge.data.sup, origin });
                     }
 
-                    Constraint::RegSubReg(..) => panic!(
+                    ConstraintKind::RegSubReg => panic!(
                         "cannot reach reg-sub-reg edge in region inference \
                          post-processing"
                     ),
diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs
index 19911bfbd48..c992cda8aae 100644
--- a/compiler/rustc_infer/src/infer/outlives/mod.rs
+++ b/compiler/rustc_infer/src/infer/outlives/mod.rs
@@ -10,7 +10,7 @@ use super::region_constraints::{RegionConstraintData, UndoLog};
 use super::{InferCtxt, RegionResolutionError, SubregionOrigin};
 use crate::infer::free_regions::RegionRelations;
 use crate::infer::lexical_region_resolve;
-use crate::infer::region_constraints::Constraint;
+use crate::infer::region_constraints::ConstraintKind;
 
 pub mod env;
 pub mod for_liveness;
@@ -70,10 +70,10 @@ impl<'tcx> InferCtxt<'tcx> {
         // Filter out any region-region outlives assumptions that are implied by
         // coroutine well-formedness.
         if self.tcx.sess.opts.unstable_opts.higher_ranked_assumptions {
-            storage.data.constraints.retain(|(constraint, _)| match *constraint {
-                Constraint::RegSubReg(r1, r2) => !outlives_env
+            storage.data.constraints.retain(|(c, _)| match c.kind {
+                ConstraintKind::RegSubReg => !outlives_env
                     .higher_ranked_assumptions()
-                    .contains(&ty::OutlivesPredicate(r2.into(), r1)),
+                    .contains(&ty::OutlivesPredicate(c.sup.into(), c.sub)),
                 _ => true,
             });
         }
diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
index e332b6d0447..4d76bc2e17a 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
@@ -83,7 +83,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
             return Ok(());
         }
 
-        let mini_graph = MiniGraph::new(tcx, &self, only_consider_snapshot);
+        let mini_graph = MiniGraph::new(&self, only_consider_snapshot);
 
         let mut leak_check = LeakCheck::new(tcx, outer_universe, max_universe, mini_graph, self);
         leak_check.assign_placeholder_values()?;
@@ -359,7 +359,6 @@ struct MiniGraph<'tcx> {
 
 impl<'tcx> MiniGraph<'tcx> {
     fn new(
-        tcx: TyCtxt<'tcx>,
         region_constraints: &RegionConstraintCollector<'_, 'tcx>,
         only_consider_snapshot: Option<&CombinedSnapshot<'tcx>>,
     ) -> Self {
@@ -368,7 +367,6 @@ impl<'tcx> MiniGraph<'tcx> {
 
         // Note that if `R2: R1`, we get a callback `r1, r2`, so `target` is first parameter.
         Self::iterate_region_constraints(
-            tcx,
             region_constraints,
             only_consider_snapshot,
             |target, source| {
@@ -384,33 +382,18 @@ impl<'tcx> MiniGraph<'tcx> {
 
     /// Invokes `each_edge(R1, R2)` for each edge where `R2: R1`
     fn iterate_region_constraints(
-        tcx: TyCtxt<'tcx>,
         region_constraints: &RegionConstraintCollector<'_, 'tcx>,
         only_consider_snapshot: Option<&CombinedSnapshot<'tcx>>,
         mut each_edge: impl FnMut(ty::Region<'tcx>, ty::Region<'tcx>),
     ) {
-        let mut each_constraint = |constraint| match constraint {
-            &Constraint::VarSubVar(a, b) => {
-                each_edge(ty::Region::new_var(tcx, a), ty::Region::new_var(tcx, b));
-            }
-            &Constraint::RegSubVar(a, b) => {
-                each_edge(a, ty::Region::new_var(tcx, b));
-            }
-            &Constraint::VarSubReg(a, b) => {
-                each_edge(ty::Region::new_var(tcx, a), b);
-            }
-            &Constraint::RegSubReg(a, b) => {
-                each_edge(a, b);
-            }
-        };
-
         if let Some(snapshot) = only_consider_snapshot {
             for undo_entry in
                 region_constraints.undo_log.region_constraints_in_snapshot(&snapshot.undo_snapshot)
             {
                 match undo_entry {
                     &AddConstraint(i) => {
-                        each_constraint(&region_constraints.data().constraints[i].0);
+                        let c = region_constraints.data().constraints[i].0;
+                        each_edge(c.sub, c.sup);
                     }
                     &AddVerify(i) => span_bug!(
                         region_constraints.data().verifys[i].origin.span(),
@@ -420,11 +403,7 @@ impl<'tcx> MiniGraph<'tcx> {
                 }
             }
         } else {
-            region_constraints
-                .data()
-                .constraints
-                .iter()
-                .for_each(|(constraint, _)| each_constraint(constraint));
+            region_constraints.data().constraints.iter().for_each(|(c, _)| each_edge(c.sub, c.sup))
         }
     }
 
diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
index 4747c203c80..85f5e55a8e1 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
@@ -80,31 +80,37 @@ pub struct RegionConstraintData<'tcx> {
 
 /// Represents a constraint that influences the inference process.
 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
-pub enum Constraint<'tcx> {
+pub enum ConstraintKind {
     /// A region variable is a subregion of another.
-    VarSubVar(RegionVid, RegionVid),
+    VarSubVar,
 
     /// A concrete region is a subregion of region variable.
-    RegSubVar(Region<'tcx>, RegionVid),
+    RegSubVar,
 
     /// A region variable is a subregion of a concrete region. This does not
     /// directly affect inference, but instead is checked after
     /// inference is complete.
-    VarSubReg(RegionVid, Region<'tcx>),
+    VarSubReg,
 
     /// A constraint where neither side is a variable. This does not
     /// directly affect inference, but instead is checked after
     /// inference is complete.
-    RegSubReg(Region<'tcx>, Region<'tcx>),
+    RegSubReg,
+}
+
+/// Represents a constraint that influences the inference process.
+#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
+pub struct Constraint<'tcx> {
+    pub kind: ConstraintKind,
+    // If `kind` is `VarSubVar` or `VarSubReg`, this must be a `ReVar`.
+    pub sub: Region<'tcx>,
+    // If `kind` is `VarSubVar` or `RegSubVar`, this must be a `ReVar`.
+    pub sup: Region<'tcx>,
 }
 
 impl Constraint<'_> {
     pub fn involves_placeholders(&self) -> bool {
-        match self {
-            Constraint::VarSubVar(_, _) => false,
-            Constraint::VarSubReg(_, r) | Constraint::RegSubVar(r, _) => r.is_placeholder(),
-            Constraint::RegSubReg(r, s) => r.is_placeholder() || s.is_placeholder(),
-        }
+        self.sub.is_placeholder() || self.sup.is_placeholder()
     }
 }
 
@@ -472,18 +478,22 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
             }
             (ReVar(sub_id), ReVar(sup_id)) => {
                 if sub_id != sup_id {
-                    self.add_constraint(Constraint::VarSubVar(sub_id, sup_id), origin);
+                    self.add_constraint(
+                        Constraint { kind: ConstraintKind::VarSubVar, sub, sup },
+                        origin,
+                    );
                 }
             }
-            (_, ReVar(sup_id)) => {
-                self.add_constraint(Constraint::RegSubVar(sub, sup_id), origin);
-            }
-            (ReVar(sub_id), _) => {
-                self.add_constraint(Constraint::VarSubReg(sub_id, sup), origin);
-            }
+            (_, ReVar(_)) => self
+                .add_constraint(Constraint { kind: ConstraintKind::RegSubVar, sub, sup }, origin),
+            (ReVar(_), _) => self
+                .add_constraint(Constraint { kind: ConstraintKind::VarSubReg, sub, sup }, origin),
             _ => {
                 if sub != sup {
-                    self.add_constraint(Constraint::RegSubReg(sub, sup), origin);
+                    self.add_constraint(
+                        Constraint { kind: ConstraintKind::RegSubReg, sub, sup },
+                        origin,
+                    )
                 }
             }
         }
diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs
index 7426504e139..96c6e589373 100644
--- a/compiler/rustc_trait_selection/src/solve/delegate.rs
+++ b/compiler/rustc_trait_selection/src/solve/delegate.rs
@@ -205,7 +205,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
         let region_assumptions = self.0.inner.borrow().region_assumptions().to_owned();
         let region_constraints = self.0.with_region_constraints(|region_constraints| {
             make_query_region_constraints(
-                self.tcx,
                 region_obligations,
                 region_constraints,
                 region_assumptions,
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 759db1d18c0..c63cc0e17ab 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -13,7 +13,7 @@ use tracing::debug;
 
 use super::*;
 use crate::errors::UnableToConstructConstantValue;
-use crate::infer::region_constraints::{Constraint, RegionConstraintData};
+use crate::infer::region_constraints::{ConstraintKind, RegionConstraintData};
 use crate::regions::OutlivesEnvironmentBuildExt;
 use crate::traits::project::ProjectAndUnifyResult;
 
@@ -452,37 +452,41 @@ impl<'tcx> AutoTraitFinder<'tcx> {
         let mut vid_map = FxIndexMap::<RegionTarget<'cx>, RegionDeps<'cx>>::default();
         let mut finished_map = FxIndexMap::default();
 
-        for (constraint, _) in &regions.constraints {
-            match constraint {
-                &Constraint::VarSubVar(r1, r2) => {
+        for (c, _) in &regions.constraints {
+            match c.kind {
+                ConstraintKind::VarSubVar => {
+                    let sub_vid = c.sub.as_var();
+                    let sup_vid = c.sup.as_var();
                     {
-                        let deps1 = vid_map.entry(RegionTarget::RegionVid(r1)).or_default();
-                        deps1.larger.insert(RegionTarget::RegionVid(r2));
+                        let deps1 = vid_map.entry(RegionTarget::RegionVid(sub_vid)).or_default();
+                        deps1.larger.insert(RegionTarget::RegionVid(sup_vid));
                     }
 
-                    let deps2 = vid_map.entry(RegionTarget::RegionVid(r2)).or_default();
-                    deps2.smaller.insert(RegionTarget::RegionVid(r1));
+                    let deps2 = vid_map.entry(RegionTarget::RegionVid(sup_vid)).or_default();
+                    deps2.smaller.insert(RegionTarget::RegionVid(sub_vid));
                 }
-                &Constraint::RegSubVar(region, vid) => {
+                ConstraintKind::RegSubVar => {
+                    let sup_vid = c.sup.as_var();
                     {
-                        let deps1 = vid_map.entry(RegionTarget::Region(region)).or_default();
-                        deps1.larger.insert(RegionTarget::RegionVid(vid));
+                        let deps1 = vid_map.entry(RegionTarget::Region(c.sub)).or_default();
+                        deps1.larger.insert(RegionTarget::RegionVid(sup_vid));
                     }
 
-                    let deps2 = vid_map.entry(RegionTarget::RegionVid(vid)).or_default();
-                    deps2.smaller.insert(RegionTarget::Region(region));
+                    let deps2 = vid_map.entry(RegionTarget::RegionVid(sup_vid)).or_default();
+                    deps2.smaller.insert(RegionTarget::Region(c.sub));
                 }
-                &Constraint::VarSubReg(vid, region) => {
-                    finished_map.insert(vid, region);
+                ConstraintKind::VarSubReg => {
+                    let sub_vid = c.sub.as_var();
+                    finished_map.insert(sub_vid, c.sup);
                 }
-                &Constraint::RegSubReg(r1, r2) => {
+                ConstraintKind::RegSubReg => {
                     {
-                        let deps1 = vid_map.entry(RegionTarget::Region(r1)).or_default();
-                        deps1.larger.insert(RegionTarget::Region(r2));
+                        let deps1 = vid_map.entry(RegionTarget::Region(c.sub)).or_default();
+                        deps1.larger.insert(RegionTarget::Region(c.sup));
                     }
 
-                    let deps2 = vid_map.entry(RegionTarget::Region(r2)).or_default();
-                    deps2.smaller.insert(RegionTarget::Region(r1));
+                    let deps2 = vid_map.entry(RegionTarget::Region(c.sup)).or_default();
+                    deps2.smaller.insert(RegionTarget::Region(c.sub));
                 }
             }
         }
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs
index f027ba1c5cb..0ca2d216228 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs
@@ -108,7 +108,6 @@ where
     let region_assumptions = infcx.take_registered_region_assumptions();
     let region_constraint_data = infcx.take_and_reset_region_constraints();
     let region_constraints = query_response::make_query_region_constraints(
-        infcx.tcx,
         region_obligations,
         &region_constraint_data,
         region_assumptions,
diff --git a/compiler/rustc_traits/src/coroutine_witnesses.rs b/compiler/rustc_traits/src/coroutine_witnesses.rs
index 87d17f3e131..8a2a0832ddb 100644
--- a/compiler/rustc_traits/src/coroutine_witnesses.rs
+++ b/compiler/rustc_traits/src/coroutine_witnesses.rs
@@ -70,7 +70,6 @@ fn compute_assumptions<'tcx>(
         let region_constraints = infcx.take_and_reset_region_constraints();
 
         let outlives = make_query_region_constraints(
-            tcx,
             region_obligations,
             &region_constraints,
             region_assumptions,