Skip to main content

rustc_middle/middle/
resolve_bound_vars.rs

1//! Name resolution for lifetimes and late-bound type and const variables: type declarations.
2
3use rustc_data_structures::sorted_map::SortedMap;
4use rustc_errors::ErrorGuaranteed;
5use rustc_hir::ItemLocalId;
6use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap};
7use rustc_macros::{Decodable, Encodable, HashStable, TyDecodable, TyEncodable};
8
9use crate::ty;
10
11#[derive(#[automatically_derived]
impl ::core::clone::Clone for ResolvedArg {
    #[inline]
    fn clone(&self) -> ResolvedArg {
        let _: ::core::clone::AssertParamIsClone<LocalDefId>;
        let _: ::core::clone::AssertParamIsClone<ty::DebruijnIndex>;
        let _: ::core::clone::AssertParamIsClone<u32>;
        let _: ::core::clone::AssertParamIsClone<ErrorGuaranteed>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for ResolvedArg { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for ResolvedArg {
    #[inline]
    fn eq(&self, other: &ResolvedArg) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (ResolvedArg::EarlyBound(__self_0),
                    ResolvedArg::EarlyBound(__arg1_0)) => __self_0 == __arg1_0,
                (ResolvedArg::LateBound(__self_0, __self_1, __self_2),
                    ResolvedArg::LateBound(__arg1_0, __arg1_1, __arg1_2)) =>
                    __self_1 == __arg1_1 && __self_0 == __arg1_0 &&
                        __self_2 == __arg1_2,
                (ResolvedArg::Free(__self_0, __self_1),
                    ResolvedArg::Free(__arg1_0, __arg1_1)) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (ResolvedArg::Error(__self_0), ResolvedArg::Error(__arg1_0))
                    => __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ResolvedArg {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<LocalDefId>;
        let _: ::core::cmp::AssertParamIsEq<ty::DebruijnIndex>;
        let _: ::core::cmp::AssertParamIsEq<u32>;
        let _: ::core::cmp::AssertParamIsEq<ErrorGuaranteed>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for ResolvedArg {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            ResolvedArg::EarlyBound(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            ResolvedArg::LateBound(__self_0, __self_1, __self_2) => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state);
                ::core::hash::Hash::hash(__self_2, state)
            }
            ResolvedArg::Free(__self_0, __self_1) => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
            ResolvedArg::Error(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for ResolvedArg {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        ResolvedArg::StaticLifetime => { 0usize }
                        ResolvedArg::EarlyBound(ref __binding_0) => { 1usize }
                        ResolvedArg::LateBound(ref __binding_0, ref __binding_1,
                            ref __binding_2) => {
                            2usize
                        }
                        ResolvedArg::Free(ref __binding_0, ref __binding_1) => {
                            3usize
                        }
                        ResolvedArg::Error(ref __binding_0) => { 4usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    ResolvedArg::StaticLifetime => {}
                    ResolvedArg::EarlyBound(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    ResolvedArg::LateBound(ref __binding_0, ref __binding_1,
                        ref __binding_2) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                            __encoder);
                    }
                    ResolvedArg::Free(ref __binding_0, ref __binding_1) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                    ResolvedArg::Error(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for ResolvedArg {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { ResolvedArg::StaticLifetime }
                    1usize => {
                        ResolvedArg::EarlyBound(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    2usize => {
                        ResolvedArg::LateBound(::rustc_serialize::Decodable::decode(__decoder),
                            ::rustc_serialize::Decodable::decode(__decoder),
                            ::rustc_serialize::Decodable::decode(__decoder))
                    }
                    3usize => {
                        ResolvedArg::Free(::rustc_serialize::Decodable::decode(__decoder),
                            ::rustc_serialize::Decodable::decode(__decoder))
                    }
                    4usize => {
                        ResolvedArg::Error(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `ResolvedArg`, expected 0..5, actual {0}",
                                n));
                    }
                }
            }
        }
    };TyDecodable, #[automatically_derived]
impl ::core::fmt::Debug for ResolvedArg {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            ResolvedArg::StaticLifetime =>
                ::core::fmt::Formatter::write_str(f, "StaticLifetime"),
            ResolvedArg::EarlyBound(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "EarlyBound", &__self_0),
            ResolvedArg::LateBound(__self_0, __self_1, __self_2) =>
                ::core::fmt::Formatter::debug_tuple_field3_finish(f,
                    "LateBound", __self_0, __self_1, &__self_2),
            ResolvedArg::Free(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f, "Free",
                    __self_0, &__self_1),
            ResolvedArg::Error(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Error",
                    &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for ResolvedArg {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
                match *self {
                    ResolvedArg::StaticLifetime => {}
                    ResolvedArg::EarlyBound(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ResolvedArg::LateBound(ref __binding_0, ref __binding_1,
                        ref __binding_2) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                    ResolvedArg::Free(ref __binding_0, ref __binding_1) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    ResolvedArg::Error(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
12pub enum ResolvedArg {
13    StaticLifetime,
14    EarlyBound(/* decl */ LocalDefId),
15    LateBound(ty::DebruijnIndex, /* late-bound index */ u32, /* decl */ LocalDefId),
16    Free(LocalDefId, /* lifetime decl */ LocalDefId),
17    Error(ErrorGuaranteed),
18}
19
20/// A set containing, at most, one known element.
21/// If two distinct values are inserted into a set, then it
22/// becomes `Many`, which can be used to detect ambiguities.
23#[derive(#[automatically_derived]
impl<T: ::core::marker::Copy> ::core::marker::Copy for Set1<T> { }Copy, #[automatically_derived]
impl<T: ::core::clone::Clone> ::core::clone::Clone for Set1<T> {
    #[inline]
    fn clone(&self) -> Set1<T> {
        match self {
            Set1::Empty => Set1::Empty,
            Set1::One(__self_0) =>
                Set1::One(::core::clone::Clone::clone(__self_0)),
            Set1::Many => Set1::Many,
        }
    }
}Clone, #[automatically_derived]
impl<T: ::core::cmp::PartialEq> ::core::cmp::PartialEq for Set1<T> {
    #[inline]
    fn eq(&self, other: &Set1<T>) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (Set1::One(__self_0), Set1::One(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl<T: ::core::cmp::Eq> ::core::cmp::Eq for Set1<T> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<T>;
    }
}Eq, const _: () =
    {
        impl<'tcx, T, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for Set1<T> where
            T: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        Set1::Empty => { 0usize }
                        Set1::One(ref __binding_0) => { 1usize }
                        Set1::Many => { 2usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    Set1::Empty => {}
                    Set1::One(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    Set1::Many => {}
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, T, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for Set1<T> where
            T: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { Set1::Empty }
                    1usize => {
                        Set1::One(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    2usize => { Set1::Many }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Set1`, expected 0..3, actual {0}",
                                n));
                    }
                }
            }
        }
    };TyDecodable, #[automatically_derived]
impl<T: ::core::fmt::Debug> ::core::fmt::Debug for Set1<T> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Set1::Empty => ::core::fmt::Formatter::write_str(f, "Empty"),
            Set1::One(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "One",
                    &__self_0),
            Set1::Many => ::core::fmt::Formatter::write_str(f, "Many"),
        }
    }
}Debug, const _: () =
    {
        impl<'__ctx, T>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for Set1<T> where
            T: ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
                match *self {
                    Set1::Empty => {}
                    Set1::One(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    Set1::Many => {}
                }
            }
        }
    };HashStable)]
24pub enum Set1<T> {
25    Empty,
26    One(T),
27    Many,
28}
29
30impl<T: PartialEq> Set1<T> {
31    pub fn insert(&mut self, value: T) {
32        *self = match self {
33            Set1::Empty => Set1::One(value),
34            Set1::One(old) if *old == value => return,
35            _ => Set1::Many,
36        };
37    }
38}
39
40#[derive(#[automatically_derived]
impl ::core::marker::Copy for ObjectLifetimeDefault { }Copy, #[automatically_derived]
impl ::core::clone::Clone for ObjectLifetimeDefault {
    #[inline]
    fn clone(&self) -> ObjectLifetimeDefault {
        let _: ::core::clone::AssertParamIsClone<DefId>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for ObjectLifetimeDefault {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            ObjectLifetimeDefault::Empty =>
                ::core::fmt::Formatter::write_str(f, "Empty"),
            ObjectLifetimeDefault::Static =>
                ::core::fmt::Formatter::write_str(f, "Static"),
            ObjectLifetimeDefault::Ambiguous =>
                ::core::fmt::Formatter::write_str(f, "Ambiguous"),
            ObjectLifetimeDefault::Param(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Param",
                    &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for ObjectLifetimeDefault {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
                match *self {
                    ObjectLifetimeDefault::Empty => {}
                    ObjectLifetimeDefault::Static => {}
                    ObjectLifetimeDefault::Ambiguous => {}
                    ObjectLifetimeDefault::Param(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for ObjectLifetimeDefault {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        ObjectLifetimeDefault::Empty => { 0usize }
                        ObjectLifetimeDefault::Static => { 1usize }
                        ObjectLifetimeDefault::Ambiguous => { 2usize }
                        ObjectLifetimeDefault::Param(ref __binding_0) => { 3usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    ObjectLifetimeDefault::Empty => {}
                    ObjectLifetimeDefault::Static => {}
                    ObjectLifetimeDefault::Ambiguous => {}
                    ObjectLifetimeDefault::Param(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for ObjectLifetimeDefault {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { ObjectLifetimeDefault::Empty }
                    1usize => { ObjectLifetimeDefault::Static }
                    2usize => { ObjectLifetimeDefault::Ambiguous }
                    3usize => {
                        ObjectLifetimeDefault::Param(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `ObjectLifetimeDefault`, expected 0..4, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable)]
41pub enum ObjectLifetimeDefault {
42    Empty,
43    Static,
44    Ambiguous,
45    Param(DefId),
46}
47
48/// Maps the id of each bound variable reference to the variable decl
49/// that it corresponds to.
50#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ResolveBoundVars<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "ResolveBoundVars", "defs", &self.defs, "late_bound_vars",
            &self.late_bound_vars, "opaque_captured_lifetimes",
            &&self.opaque_captured_lifetimes)
    }
}Debug, #[automatically_derived]
impl<'tcx> ::core::default::Default for ResolveBoundVars<'tcx> {
    #[inline]
    fn default() -> ResolveBoundVars<'tcx> {
        ResolveBoundVars {
            defs: ::core::default::Default::default(),
            late_bound_vars: ::core::default::Default::default(),
            opaque_captured_lifetimes: ::core::default::Default::default(),
        }
    }
}Default, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for ResolveBoundVars<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    ResolveBoundVars {
                        defs: ref __binding_0,
                        late_bound_vars: ref __binding_1,
                        opaque_captured_lifetimes: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
51pub struct ResolveBoundVars<'tcx> {
52    // Maps from every use of a named (not anonymous) bound var to a
53    // `ResolvedArg` describing how that variable is bound.
54    pub defs: SortedMap<ItemLocalId, ResolvedArg>,
55
56    // Maps relevant hir items to the bound vars on them. These include:
57    // - function defs
58    // - function pointers
59    // - closures
60    // - trait refs
61    // - bound types (like `T` in `for<'a> T<'a>: Foo`)
62    pub late_bound_vars: SortedMap<ItemLocalId, Vec<ty::BoundVariableKind<'tcx>>>,
63
64    // List captured variables for each opaque type.
65    pub opaque_captured_lifetimes: LocalDefIdMap<Vec<(ResolvedArg, LocalDefId)>>,
66}