Skip to main content

rustc_borrowck/type_check/
constraint_conversion.rs

1use rustc_data_structures::fx::FxHashSet;
2use rustc_hir::def_id::LocalDefId;
3use rustc_infer::infer::SubregionOrigin;
4use rustc_infer::infer::canonical::{QueryRegionConstraint, QueryRegionConstraints};
5use rustc_infer::infer::outlives::env::RegionBoundPairs;
6use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
7use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
8use rustc_middle::ty::{
9    self, GenericArgKind, RegionExt, TyCtxt, TypeFoldable, TypeVisitableExt, elaborate,
10    fold_regions,
11};
12use rustc_span::Span;
13use tracing::{debug, instrument};
14
15use crate::constraints::OutlivesConstraint;
16use crate::region_infer::TypeTest;
17use crate::type_check::{Locations, MirTypeckRegionConstraints};
18use crate::universal_regions::UniversalRegions;
19use crate::{
20    BorrowckInferCtxt, ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory,
21};
22
23pub(crate) struct ConstraintConversion<'a, 'tcx> {
24    infcx: &'a BorrowckInferCtxt<'tcx>,
25    universal_regions: &'a UniversalRegions<'tcx>,
26    /// Each RBP `GK: 'a` is assumed to be true. These encode
27    /// relationships like `T: 'a` that are added via implicit bounds
28    /// or the `param_env`.
29    ///
30    /// Each region here is guaranteed to be a key in the `indices`
31    /// map. We use the "original" regions (i.e., the keys from the
32    /// map, and not the values) because the code in
33    /// `process_registered_region_obligations` has some special-cased
34    /// logic expecting to see (e.g.) `ReStatic`, and if we supplied
35    /// our special inference variable there, we would mess that up.
36    region_bound_pairs: &'a RegionBoundPairs<'tcx>,
37    known_type_outlives_obligations: &'a [ty::PolyTypeOutlivesClause<'tcx>],
38    locations: Locations,
39    span: Span,
40    category: ConstraintCategory<'tcx>,
41    from_closure: bool,
42    constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
43}
44
45impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
46    pub(crate) fn new(
47        infcx: &'a BorrowckInferCtxt<'tcx>,
48        universal_regions: &'a UniversalRegions<'tcx>,
49        region_bound_pairs: &'a RegionBoundPairs<'tcx>,
50        known_type_outlives_obligations: &'a [ty::PolyTypeOutlivesClause<'tcx>],
51        locations: Locations,
52        span: Span,
53        category: ConstraintCategory<'tcx>,
54        constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
55    ) -> Self {
56        Self {
57            infcx,
58            universal_regions,
59            region_bound_pairs,
60            known_type_outlives_obligations,
61            locations,
62            span,
63            category,
64            constraints,
65            from_closure: false,
66        }
67    }
68
69    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("convert_all",
                                    "rustc_borrowck::type_check::constraint_conversion",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/constraint_conversion.rs"),
                                    ::tracing_core::__macro_support::Option::Some(69u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check::constraint_conversion"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("query_constraints")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("query_constraints");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&query_constraints)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let QueryRegionConstraints { constraints, assumptions } =
                query_constraints;
            let assumptions =
                elaborate::elaborate_outlives_assumptions(self.infcx.tcx,
                    assumptions.iter().copied());
            for &QueryRegionConstraint { constraint, category, .. } in
                constraints {
                constraint.iter_outlives().for_each(|predicate|
                        { self.convert(predicate, category, &assumptions); });
            }
        }
    }
}#[instrument(skip(self), level = "debug")]
70    pub(super) fn convert_all(&mut self, query_constraints: &QueryRegionConstraints<'tcx>) {
71        let QueryRegionConstraints { constraints, assumptions } = query_constraints;
72        let assumptions =
73            elaborate::elaborate_outlives_assumptions(self.infcx.tcx, assumptions.iter().copied());
74
75        for &QueryRegionConstraint { constraint, category, .. } in constraints {
76            constraint.iter_outlives().for_each(|predicate| {
77                self.convert(predicate, category, &assumptions);
78            });
79        }
80    }
81
82    /// Given an instance of the closure type, this method instantiates the "extra" requirements
83    /// that we computed for the closure. This has the effect of adding new outlives obligations
84    /// to existing region variables in `closure_args`.
85    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("apply_closure_requirements",
                                    "rustc_borrowck::type_check::constraint_conversion",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/constraint_conversion.rs"),
                                    ::tracing_core::__macro_support::Option::Some(85u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check::constraint_conversion"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("closure_requirements")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("closure_requirements");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("closure_def_id")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("closure_def_id");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("closure_args")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("closure_args");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&closure_requirements)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&closure_def_id)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&closure_args)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let closure_mapping =
                &UniversalRegions::closure_mapping(self.infcx.tcx,
                        closure_args, closure_requirements.num_external_vids,
                        closure_def_id);
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/constraint_conversion.rs:101",
                                    "rustc_borrowck::type_check::constraint_conversion",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/constraint_conversion.rs"),
                                    ::tracing_core::__macro_support::Option::Some(101u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check::constraint_conversion"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("closure_mapping")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("closure_mapping");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&closure_mapping)
                                                        as &dyn ::tracing::field::Value))])
                        });
                } else { ; }
            };
            let backup = (self.category, self.span, self.from_closure);
            self.from_closure = true;
            for outlives_requirement in
                &closure_requirements.outlives_requirements {
                let outlived_region =
                    closure_mapping[outlives_requirement.outlived_free_region];
                let subject =
                    match outlives_requirement.subject {
                        ClosureOutlivesSubject::Region(re) =>
                            closure_mapping[re].into(),
                        ClosureOutlivesSubject::Ty(subject_ty) => {
                            subject_ty.instantiate(self.infcx.tcx,
                                    |vid| closure_mapping[vid]).into()
                        }
                    };
                self.category = outlives_requirement.category;
                self.span = outlives_requirement.blame_span;
                self.convert(ty::OutlivesClause(subject, outlived_region),
                    self.category, &Default::default());
            }
            (self.category, self.span, self.from_closure) = backup;
        }
    }
}#[instrument(skip(self), level = "debug")]
86    pub(crate) fn apply_closure_requirements(
87        &mut self,
88        closure_requirements: &ClosureRegionRequirements<'tcx>,
89        closure_def_id: LocalDefId,
90        closure_args: ty::GenericArgsRef<'tcx>,
91    ) {
92        // Extract the values of the free regions in `closure_args`
93        // into a vector. These are the regions that we will be
94        // relating to one another.
95        let closure_mapping = &UniversalRegions::closure_mapping(
96            self.infcx.tcx,
97            closure_args,
98            closure_requirements.num_external_vids,
99            closure_def_id,
100        );
101        debug!(?closure_mapping);
102
103        // Create the predicates.
104        let backup = (self.category, self.span, self.from_closure);
105        self.from_closure = true;
106        for outlives_requirement in &closure_requirements.outlives_requirements {
107            let outlived_region = closure_mapping[outlives_requirement.outlived_free_region];
108            let subject = match outlives_requirement.subject {
109                ClosureOutlivesSubject::Region(re) => closure_mapping[re].into(),
110                ClosureOutlivesSubject::Ty(subject_ty) => {
111                    subject_ty.instantiate(self.infcx.tcx, |vid| closure_mapping[vid]).into()
112                }
113            };
114
115            self.category = outlives_requirement.category;
116            self.span = outlives_requirement.blame_span;
117            self.convert(
118                ty::OutlivesClause(subject, outlived_region),
119                self.category,
120                &Default::default(),
121            );
122        }
123        (self.category, self.span, self.from_closure) = backup;
124    }
125
126    fn convert(
127        &mut self,
128        clause: ty::ArgOutlivesClause<'tcx>,
129        constraint_category: ConstraintCategory<'tcx>,
130        higher_ranked_assumptions: &FxHashSet<ty::ArgOutlivesClause<'tcx>>,
131    ) {
132        let tcx = self.infcx.tcx;
133        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/constraint_conversion.rs:133",
                        "rustc_borrowck::type_check::constraint_conversion",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/constraint_conversion.rs"),
                        ::tracing_core::__macro_support::Option::Some(133u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check::constraint_conversion"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("generate: constraints at: {0:#?}",
                                                    self.locations) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("generate: constraints at: {:#?}", self.locations);
134
135        // Extract out various useful fields we'll need below.
136        let ConstraintConversion {
137            infcx: _,
138            universal_regions,
139            region_bound_pairs,
140            known_type_outlives_obligations,
141            ..
142        } = *self;
143
144        // Constraint is implied by a coroutine's well-formedness.
145        if self.infcx.tcx.sess.opts.unstable_opts.higher_ranked_assumptions
146            && higher_ranked_assumptions.contains(&clause)
147        {
148            return;
149        }
150
151        let ty::OutlivesClause(k1, r2) = clause;
152        match k1.kind() {
153            GenericArgKind::Lifetime(r1) => {
154                let r1_vid = self.to_region_vid(r1);
155                let r2_vid = self.to_region_vid(r2);
156                self.add_outlives(r1_vid, r2_vid, constraint_category);
157            }
158
159            GenericArgKind::Type(mut t1) => {
160                // Scraped constraints may have had inference vars.
161                t1 = self.infcx.resolve_vars_if_possible(t1);
162
163                let implicit_region_bound =
164                    ty::Region::new_var(tcx, universal_regions.implicit_region_bound());
165                // we don't actually use this for anything, but
166                // the `TypeOutlives` code needs an origin.
167                let origin = SubregionOrigin::RelateParamBound(self.span, t1, None);
168                TypeOutlives::new(
169                    &mut *self,
170                    tcx,
171                    region_bound_pairs,
172                    Some(implicit_region_bound),
173                    known_type_outlives_obligations,
174                )
175                .type_must_outlive(origin, t1, r2, constraint_category);
176            }
177
178            GenericArgKind::Const(_) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
179        }
180    }
181
182    /// Placeholder regions need to be converted eagerly because it may
183    /// create new region variables, which we must not do when verifying
184    /// our region bounds.
185    ///
186    /// FIXME: This should get removed once higher ranked region obligations
187    /// are dealt with during trait solving.
188    fn replace_placeholders_with_nll<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, value: T) -> T {
189        if value.has_placeholders() {
190            fold_regions(self.infcx.tcx, value, |r, _| match r.kind() {
191                ty::RePlaceholder(placeholder) => {
192                    self.constraints.placeholder_region(self.infcx, placeholder)
193                }
194                _ => r,
195            })
196        } else {
197            value
198        }
199    }
200
201    fn verify_to_type_test(
202        &mut self,
203        generic_kind: GenericKind<'tcx>,
204        region: ty::Region<'tcx>,
205        verify_bound: VerifyBound<'tcx>,
206    ) -> TypeTest<'tcx> {
207        let lower_bound = self.to_region_vid(region);
208        TypeTest { generic_kind, lower_bound, span: self.span, verify_bound }
209    }
210
211    fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid {
212        if let ty::RePlaceholder(placeholder) = r.kind() {
213            self.constraints.placeholder_region(self.infcx, placeholder).as_var()
214        } else {
215            self.universal_regions.to_region_vid(r)
216        }
217    }
218
219    fn add_outlives(
220        &mut self,
221        sup: ty::RegionVid,
222        sub: ty::RegionVid,
223        category: ConstraintCategory<'tcx>,
224    ) {
225        let category = match self.category {
226            ConstraintCategory::Boring | ConstraintCategory::BoringNoLocation => category,
227            _ => self.category,
228        };
229        self.constraints.outlives_constraints.push(OutlivesConstraint {
230            locations: self.locations,
231            category,
232            span: self.span,
233            sub,
234            sup,
235            variance_info: ty::VarianceDiagInfo::default(),
236            from_closure: self.from_closure,
237        });
238    }
239
240    fn add_type_test(&mut self, type_test: TypeTest<'tcx>) {
241        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/constraint_conversion.rs:241",
                        "rustc_borrowck::type_check::constraint_conversion",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/constraint_conversion.rs"),
                        ::tracing_core::__macro_support::Option::Some(241u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check::constraint_conversion"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("add_type_test(type_test={0:?})",
                                                    type_test) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("add_type_test(type_test={:?})", type_test);
242        self.constraints.type_tests.push(type_test);
243    }
244}
245
246impl<'a, 'b, 'tcx> TypeOutlivesDelegate<'tcx> for &'a mut ConstraintConversion<'b, 'tcx> {
247    fn push_sub_region_constraint(
248        &mut self,
249        _origin: SubregionOrigin<'tcx>,
250        a: ty::Region<'tcx>,
251        b: ty::Region<'tcx>,
252        constraint_category: ConstraintCategory<'tcx>,
253    ) {
254        let b = self.to_region_vid(b);
255        let a = self.to_region_vid(a);
256        self.add_outlives(b, a, constraint_category);
257    }
258
259    fn push_verify(
260        &mut self,
261        _origin: SubregionOrigin<'tcx>,
262        kind: GenericKind<'tcx>,
263        a: ty::Region<'tcx>,
264        bound: VerifyBound<'tcx>,
265    ) {
266        let kind = self.replace_placeholders_with_nll(kind);
267        let bound = self.replace_placeholders_with_nll(bound);
268        let type_test = self.verify_to_type_test(kind, a, bound);
269        self.add_type_test(type_test);
270    }
271}