Skip to main content

rustc_borrowck/region_infer/opaque_types/
member_constraints.rs

1use rustc_data_structures::fx::FxHashMap;
2use rustc_hir::def_id::DefId;
3use rustc_middle::bug;
4use rustc_middle::ty::{
5    self, GenericArgsRef, Region, RegionVid, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
6    TypeVisitor,
7};
8use tracing::{debug, instrument};
9
10use super::DefiningUse;
11use super::region_ctxt::RegionCtxt;
12use crate::constraints::ConstraintSccIndex;
13
14pub(super) fn apply_member_constraints<'tcx>(
15    rcx: &mut RegionCtxt<'_, 'tcx>,
16    defining_uses: &[DefiningUse<'tcx>],
17) {
18    // Start by collecting the member constraints of all defining uses.
19    //
20    // Applying member constraints can influence other member constraints,
21    // so we first collect and then apply them.
22    let mut member_constraints = Default::default();
23    for defining_use in defining_uses {
24        let mut visitor = CollectMemberConstraintsVisitor {
25            rcx,
26            defining_use,
27            member_constraints: &mut member_constraints,
28        };
29        defining_use.hidden_type.ty.visit_with(&mut visitor);
30    }
31
32    // Now walk over the region graph, visiting the smallest regions first and then all
33    // regions which have to outlive that one.
34    //
35    // Whenever we encounter a member region, we mutate the value of this SCC. This is
36    // as if we'd introduce new outlives constraints. However, we discard these region
37    // values after we've inferred the hidden types of opaques and apply the region
38    // constraints by simply equating the actual hidden type with the inferred one.
39    {
    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/region_infer/opaque_types/member_constraints.rs:39",
                        "rustc_borrowck::region_infer::opaque_types::member_constraints",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs"),
                        ::tracing_core::__macro_support::Option::Some(39u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer::opaque_types::member_constraints"),
                        ::tracing_core::field::FieldSet::new(&["member_constraints"],
                            ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&member_constraints)
                                            as &dyn Value))])
            });
    } else { ; }
};debug!(?member_constraints);
40    for scc_a in rcx.constraint_sccs.all_sccs() {
41        {
    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/region_infer/opaque_types/member_constraints.rs:41",
                        "rustc_borrowck::region_infer::opaque_types::member_constraints",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs"),
                        ::tracing_core::__macro_support::Option::Some(41u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer::opaque_types::member_constraints"),
                        ::tracing_core::field::FieldSet::new(&["scc_a"],
                            ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&scc_a) as
                                            &dyn Value))])
            });
    } else { ; }
};debug!(?scc_a);
42        // Start by adding the region values required by outlives constraints. This
43        // matches how we compute the final region values in `fn compute_regions`.
44        //
45        // We need to do this here to get a lower bound when applying member constraints.
46        // This propagates the region values added by previous member constraints.
47        for &scc_b in rcx.constraint_sccs.successors(scc_a) {
48            {
    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/region_infer/opaque_types/member_constraints.rs:48",
                        "rustc_borrowck::region_infer::opaque_types::member_constraints",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs"),
                        ::tracing_core::__macro_support::Option::Some(48u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer::opaque_types::member_constraints"),
                        ::tracing_core::field::FieldSet::new(&["scc_b"],
                            ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&scc_b) as
                                            &dyn Value))])
            });
    } else { ; }
};debug!(?scc_b);
49            rcx.scc_values.add_region(scc_a, scc_b);
50        }
51
52        for defining_use in member_constraints.get(&scc_a).into_iter().flatten() {
53            apply_member_constraint(rcx, scc_a, &defining_use.arg_regions);
54        }
55    }
56}
57
58#[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_member_constraint",
                                    "rustc_borrowck::region_infer::opaque_types::member_constraints",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs"),
                                    ::tracing_core::__macro_support::Option::Some(58u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer::opaque_types::member_constraints"),
                                    ::tracing_core::field::FieldSet::new(&["member",
                                                    "arg_regions"],
                                        ::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};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&member)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&arg_regions)
                                                            as &dyn 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;
        }
        {
            if !rcx.max_placeholder_universe_reached(member).is_root() {
                {
                    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/region_infer/opaque_types/member_constraints.rs:67",
                                        "rustc_borrowck::region_infer::opaque_types::member_constraints",
                                        ::tracing::Level::DEBUG,
                                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs"),
                                        ::tracing_core::__macro_support::Option::Some(67u32),
                                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer::opaque_types::member_constraints"),
                                        ::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};
                                let mut iter = __CALLSITE.metadata().fields().iter();
                                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&format_args!("member region reached non root universe, bailing")
                                                            as &dyn Value))])
                            });
                    } else { ; }
                };
                return;
            }
            let mut choice_regions =
                arg_regions.iter().copied().map(|r|
                                rcx.representative(r).rvid()).filter(|&choice_region|
                            {
                                rcx.scc_values.universal_regions_outlived_by(member).all(|lower_bound|
                                        {
                                            rcx.universal_region_relations.outlives(choice_region,
                                                lower_bound)
                                        })
                            }).collect::<Vec<_>>();
            {
                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/region_infer/opaque_types/member_constraints.rs:84",
                                    "rustc_borrowck::region_infer::opaque_types::member_constraints",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs"),
                                    ::tracing_core::__macro_support::Option::Some(84u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer::opaque_types::member_constraints"),
                                    ::tracing_core::field::FieldSet::new(&["message",
                                                    "choice_regions"],
                                        ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&format_args!("after enforcing lower-bound")
                                                        as &dyn Value)),
                                            (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&choice_regions)
                                                        as &dyn Value))])
                        });
                } else { ; }
            };
            for ub in rcx.rev_scc_graph.upper_bounds(member) {
                choice_regions.retain(|&choice_region|
                        rcx.universal_region_relations.outlives(ub, choice_region));
            }
            {
                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/region_infer/opaque_types/member_constraints.rs:98",
                                    "rustc_borrowck::region_infer::opaque_types::member_constraints",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs"),
                                    ::tracing_core::__macro_support::Option::Some(98u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer::opaque_types::member_constraints"),
                                    ::tracing_core::field::FieldSet::new(&["message",
                                                    "choice_regions"],
                                        ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&format_args!("after enforcing upper-bound")
                                                        as &dyn Value)),
                                            (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&choice_regions)
                                                        as &dyn Value))])
                        });
                } else { ; }
            };
            let totally_ordered_subset =
                choice_regions.iter().copied().filter(|&r1|
                        {
                            choice_regions.iter().all(|&r2|
                                    {
                                        rcx.universal_region_relations.outlives(r1, r2) ||
                                            rcx.universal_region_relations.outlives(r2, r1)
                                    })
                        });
            let Some(min_choice) =
                totally_ordered_subset.reduce(|r1, r2|
                        {
                            let r1_outlives_r2 =
                                rcx.universal_region_relations.outlives(r1, r2);
                            let r2_outlives_r1 =
                                rcx.universal_region_relations.outlives(r2, r1);
                            match (r1_outlives_r2, r2_outlives_r1) {
                                (true, true) => r1.min(r2),
                                (true, false) => r2,
                                (false, true) => r1,
                                (false, false) =>
                                    ::rustc_middle::util::bug::bug_fmt(format_args!("incomparable regions in total order")),
                            }
                        }) else {
                    {
                        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/region_infer/opaque_types/member_constraints.rs:128",
                                            "rustc_borrowck::region_infer::opaque_types::member_constraints",
                                            ::tracing::Level::DEBUG,
                                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs"),
                                            ::tracing_core::__macro_support::Option::Some(128u32),
                                            ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer::opaque_types::member_constraints"),
                                            ::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};
                                    let mut iter = __CALLSITE.metadata().fields().iter();
                                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                        ::tracing::__macro_support::Option::Some(&format_args!("no unique minimum choice")
                                                                as &dyn Value))])
                                });
                        } else { ; }
                    };
                    return;
                };
            {
                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/region_infer/opaque_types/member_constraints.rs:132",
                                    "rustc_borrowck::region_infer::opaque_types::member_constraints",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs"),
                                    ::tracing_core::__macro_support::Option::Some(132u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer::opaque_types::member_constraints"),
                                    ::tracing_core::field::FieldSet::new(&["min_choice"],
                                        ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&min_choice)
                                                        as &dyn Value))])
                        });
                } else { ; }
            };
            let min_choice_scc = rcx.constraint_sccs.scc(min_choice);
            rcx.scc_values.add_region(member, min_choice_scc);
        }
    }
}#[instrument(level = "debug", skip(rcx))]
59fn apply_member_constraint<'tcx>(
60    rcx: &mut RegionCtxt<'_, 'tcx>,
61    member: ConstraintSccIndex,
62    arg_regions: &[RegionVid],
63) {
64    // If the member region lives in a higher universe, we currently choose
65    // the most conservative option by leaving it unchanged.
66    if !rcx.max_placeholder_universe_reached(member).is_root() {
67        debug!("member region reached non root universe, bailing");
68        return;
69    }
70
71    // The existing value of `'member` is a lower-bound. If its is already larger than
72    // some universal region, we cannot equate it with that region. Said differently, we
73    // ignore choice regions which are smaller than this member region.
74    let mut choice_regions = arg_regions
75        .iter()
76        .copied()
77        .map(|r| rcx.representative(r).rvid())
78        .filter(|&choice_region| {
79            rcx.scc_values.universal_regions_outlived_by(member).all(|lower_bound| {
80                rcx.universal_region_relations.outlives(choice_region, lower_bound)
81            })
82        })
83        .collect::<Vec<_>>();
84    debug!(?choice_regions, "after enforcing lower-bound");
85
86    // Now find all the *upper bounds* -- that is, each UB is a
87    // free region that must outlive the member region `R0` (`UB:
88    // R0`). Therefore, we need only keep an option `O` if `UB: O`
89    // for all UB.
90    //
91    // If we have a requirement `'upper_bound: 'member`, equating `'member`
92    // with some region `'choice` means we now also require `'upper_bound: 'choice`.
93    // Avoid choice regions for which this does not hold.
94    for ub in rcx.rev_scc_graph.upper_bounds(member) {
95        choice_regions
96            .retain(|&choice_region| rcx.universal_region_relations.outlives(ub, choice_region));
97    }
98    debug!(?choice_regions, "after enforcing upper-bound");
99
100    // At this point we can pick any member of `choice_regions` and would like to choose
101    // it to be a small as possible. To avoid potential non-determinism we will pick the
102    // smallest such choice.
103    //
104    // Because universal regions are only partially ordered (i.e, not every two regions are
105    // comparable), we will ignore any region that doesn't compare to all others when picking
106    // the minimum choice.
107    //
108    // For example, consider `choice_regions = ['static, 'a, 'b, 'c, 'd, 'e]`, where
109    // `'static: 'a, 'static: 'b, 'a: 'c, 'b: 'c, 'c: 'd, 'c: 'e`.
110    // `['d, 'e]` are ignored because they do not compare - the same goes for `['a, 'b]`.
111    let totally_ordered_subset = choice_regions.iter().copied().filter(|&r1| {
112        choice_regions.iter().all(|&r2| {
113            rcx.universal_region_relations.outlives(r1, r2)
114                || rcx.universal_region_relations.outlives(r2, r1)
115        })
116    });
117    // Now we're left with `['static, 'c]`. Pick `'c` as the minimum!
118    let Some(min_choice) = totally_ordered_subset.reduce(|r1, r2| {
119        let r1_outlives_r2 = rcx.universal_region_relations.outlives(r1, r2);
120        let r2_outlives_r1 = rcx.universal_region_relations.outlives(r2, r1);
121        match (r1_outlives_r2, r2_outlives_r1) {
122            (true, true) => r1.min(r2),
123            (true, false) => r2,
124            (false, true) => r1,
125            (false, false) => bug!("incomparable regions in total order"),
126        }
127    }) else {
128        debug!("no unique minimum choice");
129        return;
130    };
131
132    debug!(?min_choice);
133    // Lift the member region to be at least as large as this `min_choice` by directly
134    // mutating the `scc_values` as we compute it. This acts as if we've added a
135    // `'member: 'min_choice` while not recomputing sccs. This means different sccs
136    // may now actually be equal.
137    let min_choice_scc = rcx.constraint_sccs.scc(min_choice);
138    rcx.scc_values.add_region(member, min_choice_scc);
139}
140
141struct CollectMemberConstraintsVisitor<'a, 'b, 'tcx> {
142    rcx: &'a RegionCtxt<'a, 'tcx>,
143    defining_use: &'b DefiningUse<'tcx>,
144    member_constraints: &'a mut FxHashMap<ConstraintSccIndex, Vec<&'b DefiningUse<'tcx>>>,
145}
146impl<'tcx> CollectMemberConstraintsVisitor<'_, '_, 'tcx> {
147    fn cx(&self) -> TyCtxt<'tcx> {
148        self.rcx.infcx.tcx
149    }
150    fn visit_closure_args(&mut self, def_id: DefId, args: GenericArgsRef<'tcx>) {
151        let generics = self.cx().generics_of(def_id);
152        for arg in args.iter().skip(generics.parent_count) {
153            arg.visit_with(self);
154        }
155    }
156}
157impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for CollectMemberConstraintsVisitor<'_, '_, 'tcx> {
158    fn visit_region(&mut self, r: Region<'tcx>) {
159        match r.kind() {
160            ty::ReBound(..) => return,
161            ty::ReVar(vid) => {
162                let scc = self.rcx.constraint_sccs.scc(vid);
163                self.member_constraints.entry(scc).or_default().push(self.defining_use);
164            }
165            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
166        }
167    }
168
169    fn visit_ty(&mut self, ty: Ty<'tcx>) {
170        if !ty.flags().intersects(ty::TypeFlags::HAS_FREE_REGIONS) {
171            return;
172        }
173
174        match *ty.kind() {
175            ty::Closure(def_id, args)
176            | ty::CoroutineClosure(def_id, args)
177            | ty::Coroutine(def_id, args) => self.visit_closure_args(def_id, args),
178
179            ty::Alias(ty::AliasTy { kind, args, .. })
180                if let Some(variances) = self.cx().opt_alias_variances(kind, kind.def_id()) =>
181            {
182                // Skip lifetime parameters that are not captured, since they do
183                // not need member constraints registered for them; we'll erase
184                // them (and hopefully in the future replace them with placeholders).
185                for (&v, arg) in std::iter::zip(variances, args.iter()) {
186                    if v != ty::Bivariant {
187                        arg.visit_with(self)
188                    }
189                }
190            }
191
192            _ => ty.super_visit_with(self),
193        }
194    }
195}