about summary refs log tree commit diff
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2024-12-19 10:08:05 +0100
committerlcnr <rust@lcnr.de>2024-12-20 10:04:01 +0100
commit9792cf0d6b865727c0978fb8adef7b1254f2d5e5 (patch)
treee8b90d42f60ae45c82f6ae461af1a465566130e0
parent674c6577a7a3a966ea85d5c8c1ba025b698d5b34 (diff)
downloadrust-9792cf0d6b865727c0978fb8adef7b1254f2d5e5.tar.gz
rust-9792cf0d6b865727c0978fb8adef7b1254f2d5e5.zip
remove non-borrowck member constraints
-rw-r--r--compiler/rustc_borrowck/src/member_constraints.rs22
-rw-r--r--compiler/rustc_borrowck/src/type_check/constraint_conversion.rs21
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs4
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs14
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs21
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/mod.rs287
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/mod.rs36
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs4
-rw-r--r--compiler/rustc_middle/src/infer/mod.rs32
-rw-r--r--compiler/rustc_trait_selection/src/solve/delegate.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/outlives_bounds.rs11
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs7
12 files changed, 25 insertions, 436 deletions
diff --git a/compiler/rustc_borrowck/src/member_constraints.rs b/compiler/rustc_borrowck/src/member_constraints.rs
index 60a6a37bc30..a0adf471fd3 100644
--- a/compiler/rustc_borrowck/src/member_constraints.rs
+++ b/compiler/rustc_borrowck/src/member_constraints.rs
@@ -22,7 +22,7 @@ where
     /// Stores the data about each `R0 member of [R1..Rn]` constraint.
     /// These are organized into a linked list, so each constraint
     /// contains the index of the next constraint with the same `R0`.
-    constraints: IndexVec<NllMemberConstraintIndex, NllMemberConstraint<'tcx>>,
+    constraints: IndexVec<NllMemberConstraintIndex, MemberConstraint<'tcx>>,
 
     /// Stores the `R1..Rn` regions for *all* sets. For any given
     /// constraint, we keep two indices so that we can pull out a
@@ -32,7 +32,7 @@ where
 
 /// Represents a `R0 member of [R1..Rn]` constraint
 #[derive(Debug)]
-pub(crate) struct NllMemberConstraint<'tcx> {
+pub(crate) struct MemberConstraint<'tcx> {
     next_constraint: Option<NllMemberConstraintIndex>,
 
     /// The span where the hidden type was instantiated.
@@ -87,7 +87,7 @@ impl<'tcx> MemberConstraintSet<'tcx, ty::RegionVid> {
         let start_index = self.choice_regions.len();
         self.choice_regions.extend(choice_regions);
         let end_index = self.choice_regions.len();
-        let constraint_index = self.constraints.push(NllMemberConstraint {
+        let constraint_index = self.constraints.push(MemberConstraint {
             next_constraint,
             member_region_vid,
             definition_span,
@@ -98,14 +98,6 @@ impl<'tcx> MemberConstraintSet<'tcx, ty::RegionVid> {
         });
         self.first_constraints.insert(member_region_vid, constraint_index);
     }
-
-    // TODO: removed in the next commit
-    pub(crate) fn push_constraint(
-        &mut self,
-        _: &rustc_middle::infer::MemberConstraint<'tcx>,
-        _: impl FnMut(ty::Region<'tcx>) -> ty::RegionVid,
-    ) {
-    }
 }
 
 impl<'tcx, R1> MemberConstraintSet<'tcx, R1>
@@ -186,7 +178,7 @@ where
     /// R0 member of [R1..Rn]
     /// ```
     pub(crate) fn choice_regions(&self, pci: NllMemberConstraintIndex) -> &[ty::RegionVid] {
-        let NllMemberConstraint { start_index, end_index, .. } = &self.constraints[pci];
+        let MemberConstraint { start_index, end_index, .. } = &self.constraints[pci];
         &self.choice_regions[*start_index..*end_index]
     }
 }
@@ -195,9 +187,9 @@ impl<'tcx, R> Index<NllMemberConstraintIndex> for MemberConstraintSet<'tcx, R>
 where
     R: Copy + Eq,
 {
-    type Output = NllMemberConstraint<'tcx>;
+    type Output = MemberConstraint<'tcx>;
 
-    fn index(&self, i: NllMemberConstraintIndex) -> &NllMemberConstraint<'tcx> {
+    fn index(&self, i: NllMemberConstraintIndex) -> &MemberConstraint<'tcx> {
         &self.constraints[i]
     }
 }
@@ -219,7 +211,7 @@ where
 /// target_list: A -> B -> C -> D -> E -> F -> (None)
 /// ```
 fn append_list(
-    constraints: &mut IndexSlice<NllMemberConstraintIndex, NllMemberConstraint<'_>>,
+    constraints: &mut IndexSlice<NllMemberConstraintIndex, MemberConstraint<'_>>,
     target_list: NllMemberConstraintIndex,
     source_list: NllMemberConstraintIndex,
 ) {
diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
index 918efac2a20..4b7f5321388 100644
--- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
+++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
@@ -77,17 +77,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
 
     #[instrument(skip(self), level = "debug")]
     pub(super) fn convert_all(&mut self, query_constraints: &QueryRegionConstraints<'tcx>) {
-        let QueryRegionConstraints { outlives, member_constraints } = query_constraints;
-
-        // Annoying: to invoke `self.to_region_vid`, we need access to
-        // `self.constraints`, but we also want to be mutating
-        // `self.member_constraints`. For now, just swap out the value
-        // we want and replace at the end.
-        let mut tmp = std::mem::take(&mut self.constraints.member_constraints);
-        for member_constraint in member_constraints {
-            tmp.push_constraint(member_constraint, |r| self.to_region_vid(r));
-        }
-        self.constraints.member_constraints = tmp;
+        let QueryRegionConstraints { outlives } = query_constraints;
 
         for &(predicate, constraint_category) in outlives {
             self.convert(predicate, constraint_category);
@@ -295,13 +285,8 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
 
         match result {
             Ok(TypeOpOutput { output: ty, constraints, .. }) => {
-                if let Some(constraints) = constraints {
-                    assert!(
-                        constraints.member_constraints.is_empty(),
-                        "no member constraints expected from normalizing: {:#?}",
-                        constraints.member_constraints
-                    );
-                    next_outlives_predicates.extend(constraints.outlives.iter().copied());
+                if let Some(QueryRegionConstraints { outlives }) = constraints {
+                    next_outlives_predicates.extend(outlives.iter().copied());
                 }
                 ty
             }
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 6b7bf718766..19f6a2606be 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -880,6 +880,10 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
     /// reference those regions from the `ParamEnv`. It is also used
     /// during initialization. Relies on the `indices` map having been
     /// fully initialized.
+    ///
+    /// Panics if `r` is not a registered universal region, most notably
+    /// if it is a placeholder. Handling placeholders requires access to the
+    /// `MirTypeckRegionConstraints`.
     fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
         if let ty::ReVar(..) = *r {
             r.as_var()
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index 1d3d32ef749..d5aab4781de 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -316,16 +316,6 @@ impl<'tcx> InferCtxt<'tcx> {
             }),
         );
 
-        // ...also include the query member constraints.
-        output_query_region_constraints.member_constraints.extend(
-            query_response
-                .value
-                .region_constraints
-                .member_constraints
-                .iter()
-                .map(|p_c| instantiate_value(self.tcx, &result_args, p_c.clone())),
-        );
-
         let user_result: R =
             query_response.instantiate_projected(self.tcx, &result_args, |q_r| q_r.value.clone());
 
@@ -643,7 +633,7 @@ pub fn make_query_region_constraints<'tcx>(
     outlives_obligations: impl Iterator<Item = (Ty<'tcx>, ty::Region<'tcx>, ConstraintCategory<'tcx>)>,
     region_constraints: &RegionConstraintData<'tcx>,
 ) -> QueryRegionConstraints<'tcx> {
-    let RegionConstraintData { constraints, verifys, member_constraints } = region_constraints;
+    let RegionConstraintData { constraints, verifys } = region_constraints;
 
     assert!(verifys.is_empty());
 
@@ -674,5 +664,5 @@ pub fn make_query_region_constraints<'tcx>(
         }))
         .collect();
 
-    QueryRegionConstraints { outlives, member_constraints: member_constraints.clone() }
+    QueryRegionConstraints { outlives }
 }
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 5086b741a83..c5a56005c06 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -17,7 +17,6 @@ pub use relate::StructurallyRelateAliases;
 pub use relate::combine::PredicateEmittingRelation;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
-use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::undo_log::{Rollback, UndoLogs};
 use rustc_data_structures::unify as ut;
 use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed};
@@ -685,26 +684,6 @@ impl<'tcx> InferCtxt<'tcx> {
         self.inner.borrow_mut().unwrap_region_constraints().make_subregion(origin, a, b);
     }
 
-    /// Require that the region `r` be equal to one of the regions in
-    /// the set `regions`.
-    #[instrument(skip(self), level = "debug")]
-    pub fn add_member_constraint(
-        &self,
-        key: ty::OpaqueTypeKey<'tcx>,
-        definition_span: Span,
-        hidden_ty: Ty<'tcx>,
-        region: ty::Region<'tcx>,
-        in_regions: Lrc<Vec<ty::Region<'tcx>>>,
-    ) {
-        self.inner.borrow_mut().unwrap_region_constraints().add_member_constraint(
-            key,
-            definition_span,
-            hidden_ty,
-            region,
-            in_regions,
-        );
-    }
-
     /// Processes a `Coerce` predicate from the fulfillment context.
     /// This is NOT the preferred way to handle coercion, which is to
     /// invoke `FnCtxt::coerce` or a similar method (see `coercion.rs`).
diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
index 8650c20559f..137d438a479 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
@@ -1,6 +1,5 @@
 use hir::def_id::{DefId, LocalDefId};
 use rustc_data_structures::fx::FxIndexMap;
-use rustc_data_structures::sync::Lrc;
 use rustc_hir as hir;
 use rustc_middle::bug;
 use rustc_middle::traits::ObligationCause;
@@ -8,8 +7,7 @@ use rustc_middle::traits::solve::Goal;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::{
-    self, GenericArgKind, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable,
-    TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
+    self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitableExt,
 };
 use rustc_span::Span;
 use tracing::{debug, instrument};
@@ -181,289 +179,6 @@ impl<'tcx> InferCtxt<'tcx> {
             Err(TypeError::Sorts(ExpectedFound::new(a, b)))
         }
     }
-
-    /// Given the map `opaque_types` containing the opaque
-    /// `impl Trait` types whose underlying, hidden types are being
-    /// inferred, this method adds constraints to the regions
-    /// appearing in those underlying hidden types to ensure that they
-    /// at least do not refer to random scopes within the current
-    /// function. These constraints are not (quite) sufficient to
-    /// guarantee that the regions are actually legal values; that
-    /// final condition is imposed after region inference is done.
-    ///
-    /// # The Problem
-    ///
-    /// Let's work through an example to explain how it works. Assume
-    /// the current function is as follows:
-    ///
-    /// ```text
-    /// fn foo<'a, 'b>(..) -> (impl Bar<'a>, impl Bar<'b>)
-    /// ```
-    ///
-    /// Here, we have two `impl Trait` types whose values are being
-    /// inferred (the `impl Bar<'a>` and the `impl
-    /// Bar<'b>`). Conceptually, this is sugar for a setup where we
-    /// define underlying opaque types (`Foo1`, `Foo2`) and then, in
-    /// the return type of `foo`, we *reference* those definitions:
-    ///
-    /// ```text
-    /// type Foo1<'x> = impl Bar<'x>;
-    /// type Foo2<'x> = impl Bar<'x>;
-    /// fn foo<'a, 'b>(..) -> (Foo1<'a>, Foo2<'b>) { .. }
-    ///                    //  ^^^^ ^^
-    ///                    //  |    |
-    ///                    //  |    args
-    ///                    //  def_id
-    /// ```
-    ///
-    /// As indicating in the comments above, each of those references
-    /// is (in the compiler) basically generic parameters (`args`)
-    /// applied to the type of a suitable `def_id` (which identifies
-    /// `Foo1` or `Foo2`).
-    ///
-    /// Now, at this point in compilation, what we have done is to
-    /// replace each of the references (`Foo1<'a>`, `Foo2<'b>`) with
-    /// fresh inference variables C1 and C2. We wish to use the values
-    /// of these variables to infer the underlying types of `Foo1` and
-    /// `Foo2`. That is, this gives rise to higher-order (pattern) unification
-    /// constraints like:
-    ///
-    /// ```text
-    /// for<'a> (Foo1<'a> = C1)
-    /// for<'b> (Foo1<'b> = C2)
-    /// ```
-    ///
-    /// For these equation to be satisfiable, the types `C1` and `C2`
-    /// can only refer to a limited set of regions. For example, `C1`
-    /// can only refer to `'static` and `'a`, and `C2` can only refer
-    /// to `'static` and `'b`. The job of this function is to impose that
-    /// constraint.
-    ///
-    /// Up to this point, C1 and C2 are basically just random type
-    /// inference variables, and hence they may contain arbitrary
-    /// regions. In fact, it is fairly likely that they do! Consider
-    /// this possible definition of `foo`:
-    ///
-    /// ```text
-    /// fn foo<'a, 'b>(x: &'a i32, y: &'b i32) -> (impl Bar<'a>, impl Bar<'b>) {
-    ///         (&*x, &*y)
-    ///     }
-    /// ```
-    ///
-    /// Here, the values for the concrete types of the two impl
-    /// traits will include inference variables:
-    ///
-    /// ```text
-    /// &'0 i32
-    /// &'1 i32
-    /// ```
-    ///
-    /// Ordinarily, the subtyping rules would ensure that these are
-    /// sufficiently large. But since `impl Bar<'a>` isn't a specific
-    /// type per se, we don't get such constraints by default. This
-    /// is where this function comes into play. It adds extra
-    /// constraints to ensure that all the regions which appear in the
-    /// inferred type are regions that could validly appear.
-    ///
-    /// This is actually a bit of a tricky constraint in general. We
-    /// want to say that each variable (e.g., `'0`) can only take on
-    /// values that were supplied as arguments to the opaque type
-    /// (e.g., `'a` for `Foo1<'a>`) or `'static`, which is always in
-    /// scope. We don't have a constraint quite of this kind in the current
-    /// region checker.
-    ///
-    /// # The Solution
-    ///
-    /// We generally prefer to make `<=` constraints, since they
-    /// integrate best into the region solver. To do that, we find the
-    /// "minimum" of all the arguments that appear in the args: that
-    /// is, some region which is less than all the others. In the case
-    /// of `Foo1<'a>`, that would be `'a` (it's the only choice, after
-    /// all). Then we apply that as a least bound to the variables
-    /// (e.g., `'a <= '0`).
-    ///
-    /// In some cases, there is no minimum. Consider this example:
-    ///
-    /// ```text
-    /// fn baz<'a, 'b>() -> impl Trait<'a, 'b> { ... }
-    /// ```
-    ///
-    /// Here we would report a more complex "in constraint", like `'r
-    /// in ['a, 'b, 'static]` (where `'r` is some region appearing in
-    /// the hidden type).
-    ///
-    /// # Constrain regions, not the hidden concrete type
-    ///
-    /// Note that generating constraints on each region `Rc` is *not*
-    /// the same as generating an outlives constraint on `Tc` itself.
-    /// For example, if we had a function like this:
-    ///
-    /// ```
-    /// # #![feature(type_alias_impl_trait)]
-    /// # fn main() {}
-    /// # trait Foo<'a> {}
-    /// # impl<'a, T> Foo<'a> for (&'a u32, T) {}
-    /// fn foo<'a, T>(x: &'a u32, y: T) -> impl Foo<'a> {
-    ///   (x, y)
-    /// }
-    ///
-    /// // Equivalent to:
-    /// # mod dummy { use super::*;
-    /// type FooReturn<'a, T> = impl Foo<'a>;
-    /// fn foo<'a, T>(x: &'a u32, y: T) -> FooReturn<'a, T> {
-    ///   (x, y)
-    /// }
-    /// # }
-    /// ```
-    ///
-    /// then the hidden type `Tc` would be `(&'0 u32, T)` (where `'0`
-    /// is an inference variable). If we generated a constraint that
-    /// `Tc: 'a`, then this would incorrectly require that `T: 'a` --
-    /// but this is not necessary, because the opaque type we
-    /// create will be allowed to reference `T`. So we only generate a
-    /// constraint that `'0: 'a`.
-    #[instrument(level = "debug", skip(self))]
-    pub fn register_member_constraints(
-        &self,
-        opaque_type_key: OpaqueTypeKey<'tcx>,
-        concrete_ty: Ty<'tcx>,
-        span: Span,
-    ) {
-        let concrete_ty = self.resolve_vars_if_possible(concrete_ty);
-        debug!(?concrete_ty);
-
-        let variances = self.tcx.variances_of(opaque_type_key.def_id);
-        debug!(?variances);
-
-        // For a case like `impl Foo<'a, 'b>`, we would generate a constraint
-        // `'r in ['a, 'b, 'static]` for each region `'r` that appears in the
-        // hidden type (i.e., it must be equal to `'a`, `'b`, or `'static`).
-        //
-        // `conflict1` and `conflict2` are the two region bounds that we
-        // detected which were unrelated. They are used for diagnostics.
-
-        // Create the set of choice regions: each region in the hidden
-        // type can be equal to any of the region parameters of the
-        // opaque type definition.
-        let choice_regions: Lrc<Vec<ty::Region<'tcx>>> = Lrc::new(
-            opaque_type_key
-                .args
-                .iter()
-                .enumerate()
-                .filter(|(i, _)| variances[*i] == ty::Invariant)
-                .filter_map(|(_, arg)| match arg.unpack() {
-                    GenericArgKind::Lifetime(r) => Some(r),
-                    GenericArgKind::Type(_) | GenericArgKind::Const(_) => None,
-                })
-                .chain(std::iter::once(self.tcx.lifetimes.re_static))
-                .collect(),
-        );
-
-        // FIXME(#42940): This should use the `FreeRegionsVisitor`, but that's
-        // not currently sound until we have existential regions.
-        concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor {
-            tcx: self.tcx,
-            op: |r| {
-                self.add_member_constraint(
-                    opaque_type_key,
-                    span,
-                    concrete_ty,
-                    r,
-                    Lrc::clone(&choice_regions),
-                )
-            },
-        });
-    }
-}
-
-/// Visitor that requires that (almost) all regions in the type visited outlive
-/// `least_region`. We cannot use `push_outlives_components` because regions in
-/// closure signatures are not included in their outlives components. We need to
-/// ensure all regions outlive the given bound so that we don't end up with,
-/// say, `ReVar` appearing in a return type and causing ICEs when other
-/// functions end up with region constraints involving regions from other
-/// functions.
-///
-/// We also cannot use `for_each_free_region` because for closures it includes
-/// the regions parameters from the enclosing item.
-///
-/// We ignore any type parameters because impl trait values are assumed to
-/// capture all the in-scope type parameters.
-struct ConstrainOpaqueTypeRegionVisitor<'tcx, OP: FnMut(ty::Region<'tcx>)> {
-    tcx: TyCtxt<'tcx>,
-    op: OP,
-}
-
-impl<'tcx, OP> TypeVisitor<TyCtxt<'tcx>> for ConstrainOpaqueTypeRegionVisitor<'tcx, OP>
-where
-    OP: FnMut(ty::Region<'tcx>),
-{
-    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
-        t.super_visit_with(self);
-    }
-
-    fn visit_region(&mut self, r: ty::Region<'tcx>) {
-        match *r {
-            // ignore bound regions, keep visiting
-            ty::ReBound(_, _) => {}
-            _ => (self.op)(r),
-        }
-    }
-
-    fn visit_ty(&mut self, ty: Ty<'tcx>) {
-        // We're only interested in types involving regions
-        if !ty.flags().intersects(ty::TypeFlags::HAS_FREE_REGIONS) {
-            return;
-        }
-
-        match ty.kind() {
-            ty::Closure(_, args) => {
-                // Skip lifetime parameters of the enclosing item(s)
-
-                for upvar in args.as_closure().upvar_tys() {
-                    upvar.visit_with(self);
-                }
-                args.as_closure().sig_as_fn_ptr_ty().visit_with(self);
-            }
-
-            ty::CoroutineClosure(_, args) => {
-                // Skip lifetime parameters of the enclosing item(s)
-
-                for upvar in args.as_coroutine_closure().upvar_tys() {
-                    upvar.visit_with(self);
-                }
-
-                args.as_coroutine_closure().signature_parts_ty().visit_with(self);
-            }
-
-            ty::Coroutine(_, args) => {
-                // Skip lifetime parameters of the enclosing item(s)
-                // Also skip the witness type, because that has no free regions.
-
-                for upvar in args.as_coroutine().upvar_tys() {
-                    upvar.visit_with(self);
-                }
-                args.as_coroutine().return_ty().visit_with(self);
-                args.as_coroutine().yield_ty().visit_with(self);
-                args.as_coroutine().resume_ty().visit_with(self);
-            }
-
-            ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
-                // Skip lifetime parameters that are not captures.
-                let variances = self.tcx.variances_of(*def_id);
-
-                for (v, s) in std::iter::zip(variances, args.iter()) {
-                    if *v != ty::Bivariant {
-                        s.visit_with(self);
-                    }
-                }
-            }
-
-            _ => {
-                ty.super_visit_with(self);
-            }
-        }
-    }
 }
 
 impl<'tcx> InferCtxt<'tcx> {
diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
index 61ce86e7767..6dce4b2b21d 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
@@ -4,7 +4,6 @@ use std::ops::Range;
 use std::{cmp, fmt, mem};
 
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::undo_log::UndoLogs;
 use rustc_data_structures::unify as ut;
 use rustc_index::IndexVec;
@@ -12,7 +11,6 @@ use rustc_macros::{TypeFoldable, TypeVisitable};
 use rustc_middle::infer::unify_key::{RegionVariableValue, RegionVidKey};
 use rustc_middle::ty::{self, ReBound, ReStatic, ReVar, Region, RegionVid, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
-use rustc_span::Span;
 use tracing::{debug, instrument};
 
 use self::CombineMapType::*;
@@ -22,8 +20,6 @@ use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, Snapshot};
 
 mod leak_check;
 
-pub use rustc_middle::infer::MemberConstraint;
-
 #[derive(Clone, Default)]
 pub struct RegionConstraintStorage<'tcx> {
     /// For each `RegionVid`, the corresponding `RegionVariableOrigin`.
@@ -73,11 +69,6 @@ pub struct RegionConstraintData<'tcx> {
     /// be a region variable (or neither, as it happens).
     pub constraints: Vec<(Constraint<'tcx>, SubregionOrigin<'tcx>)>,
 
-    /// Constraints of the form `R0 member of [R1, ..., Rn]`, meaning that
-    /// `R0` must be equal to one of the regions `R1..Rn`. These occur
-    /// with `impl Trait` quite frequently.
-    pub member_constraints: Vec<MemberConstraint<'tcx>>,
-
     /// A "verify" is something that we need to verify after inference
     /// is done, but which does not directly affect inference in any
     /// way.
@@ -466,29 +457,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
         }
     }
 
-    pub(super) fn add_member_constraint(
-        &mut self,
-        key: ty::OpaqueTypeKey<'tcx>,
-        definition_span: Span,
-        hidden_ty: Ty<'tcx>,
-        member_region: ty::Region<'tcx>,
-        choice_regions: Lrc<Vec<ty::Region<'tcx>>>,
-    ) {
-        debug!("member_constraint({:?} in {:#?})", member_region, choice_regions);
-
-        if choice_regions.iter().any(|&r| r == member_region) {
-            return;
-        }
-
-        self.storage.data.member_constraints.push(MemberConstraint {
-            key,
-            definition_span,
-            hidden_ty,
-            member_region,
-            choice_regions,
-        });
-    }
-
     #[instrument(skip(self, origin), level = "debug")]
     pub(super) fn make_subregion(
         &mut self,
@@ -745,8 +713,8 @@ impl<'tcx> RegionConstraintData<'tcx> {
     /// Returns `true` if this region constraint data contains no constraints, and `false`
     /// otherwise.
     pub fn is_empty(&self) -> bool {
-        let RegionConstraintData { constraints, member_constraints, verifys } = self;
-        constraints.is_empty() && member_constraints.is_empty() && verifys.is_empty()
+        let RegionConstraintData { constraints, verifys } = self;
+        constraints.is_empty() && verifys.is_empty()
     }
 }
 
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index ac55497f8b3..0f408375e05 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -30,7 +30,6 @@ pub use rustc_type_ir as ir;
 pub use rustc_type_ir::{CanonicalTyVarKind, CanonicalVarKind};
 use smallvec::SmallVec;
 
-use crate::infer::MemberConstraint;
 use crate::mir::ConstraintCategory;
 use crate::ty::{self, GenericArg, List, Ty, TyCtxt, TypeFlags, TypeVisitableExt};
 
@@ -91,14 +90,13 @@ pub struct QueryResponse<'tcx, R> {
 #[derive(HashStable, TypeFoldable, TypeVisitable)]
 pub struct QueryRegionConstraints<'tcx> {
     pub outlives: Vec<QueryOutlivesConstraint<'tcx>>,
-    pub member_constraints: Vec<MemberConstraint<'tcx>>,
 }
 
 impl QueryRegionConstraints<'_> {
     /// Represents an empty (trivially true) set of region
     /// constraints.
     pub fn is_empty(&self) -> bool {
-        self.outlives.is_empty() && self.member_constraints.is_empty()
+        self.outlives.is_empty()
     }
 }
 
diff --git a/compiler/rustc_middle/src/infer/mod.rs b/compiler/rustc_middle/src/infer/mod.rs
index 19fe9e5a54f..3dfcf90cb93 100644
--- a/compiler/rustc_middle/src/infer/mod.rs
+++ b/compiler/rustc_middle/src/infer/mod.rs
@@ -1,34 +1,2 @@
 pub mod canonical;
 pub mod unify_key;
-
-use rustc_data_structures::sync::Lrc;
-use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
-use rustc_span::Span;
-
-use crate::ty::{OpaqueTypeKey, Region, Ty};
-
-/// Requires that `region` must be equal to one of the regions in `choice_regions`.
-/// We often denote this using the syntax:
-///
-/// ```text
-/// R0 member of [O1..On]
-/// ```
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-#[derive(HashStable, TypeFoldable, TypeVisitable)]
-pub struct MemberConstraint<'tcx> {
-    /// The `DefId` and args of the opaque type causing this constraint.
-    /// Used for error reporting.
-    pub key: OpaqueTypeKey<'tcx>,
-
-    /// The span where the hidden type was instantiated.
-    pub definition_span: Span,
-
-    /// The hidden type in which `member_region` appears: used for error reporting.
-    pub hidden_ty: Ty<'tcx>,
-
-    /// The region `R0`.
-    pub member_region: Region<'tcx>,
-
-    /// The options `O1..On`.
-    pub choice_regions: Lrc<Vec<Region<'tcx>>>,
-}
diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs
index 97cde67799c..9b8c9ff6bb8 100644
--- a/compiler/rustc_trait_selection/src/solve/delegate.rs
+++ b/compiler/rustc_trait_selection/src/solve/delegate.rs
@@ -123,8 +123,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
             )
         });
 
-        assert_eq!(region_constraints.member_constraints, vec![]);
-
         let mut seen = FxHashSet::default();
         region_constraints
             .outlives
diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
index 88c11e55b7a..23dabe32ff2 100644
--- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
@@ -4,11 +4,10 @@ use rustc_infer::infer::resolve::OpportunisticRegionResolver;
 use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds;
 use rustc_macros::extension;
 use rustc_middle::infer::canonical::{OriginalQueryValues, QueryRegionConstraints};
-use rustc_middle::span_bug;
 pub use rustc_middle::traits::query::OutlivesBound;
 use rustc_middle::ty::{self, ParamEnv, Ty, TypeFolder, TypeVisitableExt};
 use rustc_span::def_id::LocalDefId;
-use tracing::{debug, instrument};
+use tracing::instrument;
 
 use crate::infer::InferCtxt;
 use crate::traits::{ObligationCause, ObligationCtxt};
@@ -86,16 +85,12 @@ fn implied_outlives_bounds<'a, 'tcx>(
     bounds.retain(|bound| !bound.has_placeholders());
 
     if !constraints.is_empty() {
-        debug!(?constraints);
-        if !constraints.member_constraints.is_empty() {
-            span_bug!(span, "{:#?}", constraints.member_constraints);
-        }
-
+        let QueryRegionConstraints { outlives } = constraints;
         // Instantiation may have produced new inference variables and constraints on those
         // variables. Process these constraints.
         let ocx = ObligationCtxt::new(infcx);
         let cause = ObligationCause::misc(span, body_id);
-        for &constraint in &constraints.outlives {
+        for &constraint in &outlives {
             ocx.register_obligation(infcx.query_outlives_constraint_to_obligation(
                 constraint,
                 cause.clone(),
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
index a618d96ce95..54fce914bb6 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
@@ -180,11 +180,8 @@ where
             span,
         )?;
         output.error_info = error_info;
-        if let Some(constraints) = output.constraints {
-            region_constraints
-                .member_constraints
-                .extend(constraints.member_constraints.iter().cloned());
-            region_constraints.outlives.extend(constraints.outlives.iter().cloned());
+        if let Some(QueryRegionConstraints { outlives }) = output.constraints {
+            region_constraints.outlives.extend(outlives.iter().cloned());
         }
         output.constraints = if region_constraints.is_empty() {
             None