Skip to main content

rustc_type_ir/
flags.rs

1use crate::inherent::*;
2use crate::visit::Flags;
3use crate::{self as ty, Interner};
4
5#[doc = r" Flags that we track on types. These flags are propagated upwards"]
#[doc =
r" through the type during type construction, so that we can quickly check"]
#[doc =
r" whether the type has various kinds of types in it without recursing"]
#[doc = r" over the type itself."]
pub struct TypeFlags(<TypeFlags as
    ::bitflags::__private::PublicFlags>::Internal);
#[automatically_derived]
impl ::core::fmt::Debug for TypeFlags {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "TypeFlags",
            &&self.0)
    }
}
#[automatically_derived]
impl ::core::marker::StructuralPartialEq for TypeFlags { }
#[automatically_derived]
impl ::core::cmp::PartialEq for TypeFlags {
    #[inline]
    fn eq(&self, other: &TypeFlags) -> bool { self.0 == other.0 }
}
#[automatically_derived]
impl ::core::cmp::Eq for TypeFlags {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _:
                ::core::cmp::AssertParamIsEq<<TypeFlags as
                ::bitflags::__private::PublicFlags>::Internal>;
    }
}
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for TypeFlags { }
#[automatically_derived]
impl ::core::clone::Clone for TypeFlags {
    #[inline]
    fn clone(&self) -> TypeFlags {
        let _:
                ::core::clone::AssertParamIsClone<<TypeFlags as
                ::bitflags::__private::PublicFlags>::Internal>;
        *self
    }
}
#[automatically_derived]
impl ::core::marker::Copy for TypeFlags { }
impl TypeFlags {
    #[doc = r" Does this have `Param`?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_TY_PARAM: Self = Self::from_bits_retain(1 << 0);
    #[doc = r" Does this have `ReEarlyParam`?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_RE_PARAM: Self = Self::from_bits_retain(1 << 1);
    #[doc = r" Does this have `ConstKind::Param`?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_CT_PARAM: Self = Self::from_bits_retain(1 << 2);
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_PARAM: Self =
        Self::from_bits_retain(TypeFlags::HAS_TY_PARAM.bits() |
                    TypeFlags::HAS_RE_PARAM.bits() |
                TypeFlags::HAS_CT_PARAM.bits());
    #[doc = r" Does this have `Infer`?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_TY_INFER: Self = Self::from_bits_retain(1 << 3);
    #[doc = r" Does this have `ReVar`?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_RE_INFER: Self = Self::from_bits_retain(1 << 4);
    #[doc = r" Does this have `ConstKind::Infer`?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_CT_INFER: Self = Self::from_bits_retain(1 << 5);
    #[doc = r" Does this have inference variables? Used to determine whether"]
    #[doc = r" inference is required."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_INFER: Self =
        Self::from_bits_retain(TypeFlags::HAS_TY_INFER.bits() |
                    TypeFlags::HAS_RE_INFER.bits() |
                TypeFlags::HAS_CT_INFER.bits());
    #[doc = r" Does this have `Placeholder`?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_TY_PLACEHOLDER: Self = Self::from_bits_retain(1 << 6);
    #[doc = r" Does this have `RePlaceholder`?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_RE_PLACEHOLDER: Self = Self::from_bits_retain(1 << 7);
    #[doc = r" Does this have `ConstKind::Placeholder`?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_CT_PLACEHOLDER: Self = Self::from_bits_retain(1 << 8);
    #[doc = r" Does this have placeholders?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_PLACEHOLDER: Self =
        Self::from_bits_retain(TypeFlags::HAS_TY_PLACEHOLDER.bits() |
                    TypeFlags::HAS_RE_PLACEHOLDER.bits() |
                TypeFlags::HAS_CT_PLACEHOLDER.bits());
    #[doc = r#" `true` if there are "names" of regions and so forth"#]
    #[doc = r" that are local to a particular fn/inferctxt"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_FREE_LOCAL_REGIONS: Self = Self::from_bits_retain(1 << 9);
    #[doc =
    r#" `true` if there are "names" of types and regions and so forth"#]
    #[doc = r" that are local to a particular fn"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_FREE_LOCAL_NAMES: Self =
        Self::from_bits_retain(TypeFlags::HAS_TY_PARAM.bits() |
                                                TypeFlags::HAS_CT_PARAM.bits() |
                                            TypeFlags::HAS_TY_INFER.bits() |
                                        TypeFlags::HAS_CT_INFER.bits() |
                                    TypeFlags::HAS_TY_PLACEHOLDER.bits() |
                                TypeFlags::HAS_CT_PLACEHOLDER.bits() |
                            TypeFlags::HAS_TY_FRESH.bits() |
                        TypeFlags::HAS_CT_FRESH.bits() |
                    TypeFlags::HAS_FREE_LOCAL_REGIONS.bits() |
                TypeFlags::HAS_RE_ERASED.bits());
    #[doc = r" Does this have `Projection`?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_TY_PROJECTION: Self = Self::from_bits_retain(1 << 10);
    #[doc = r" Does this have `Free` aliases?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_TY_FREE_ALIAS: Self = Self::from_bits_retain(1 << 11);
    #[doc = r" Does this have `Opaque`?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_TY_OPAQUE: Self = Self::from_bits_retain(1 << 12);
    #[doc = r" Does this have `Inherent`?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_TY_INHERENT: Self = Self::from_bits_retain(1 << 13);
    #[doc = r" Does this have `ConstKind::Unevaluated`?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_CT_PROJECTION: Self = Self::from_bits_retain(1 << 14);
    #[doc = r" Does this have `Alias` or `ConstKind::Unevaluated`?"]
    #[doc = r""]
    #[doc = r" Rephrased, could this term be normalized further?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_ALIAS: Self =
        Self::from_bits_retain(TypeFlags::HAS_TY_PROJECTION.bits() |
                            TypeFlags::HAS_TY_FREE_ALIAS.bits() |
                        TypeFlags::HAS_TY_OPAQUE.bits() |
                    TypeFlags::HAS_TY_INHERENT.bits() |
                TypeFlags::HAS_CT_PROJECTION.bits());
    #[doc = r" Is a type or const error reachable?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_NON_REGION_ERROR: Self = Self::from_bits_retain(1 << 15);
    #[doc = r" Is a region error reachable?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_RE_ERROR: Self = Self::from_bits_retain(1 << 16);
    #[doc = r" Is an error type/lifetime/const reachable?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_ERROR: Self =
        Self::from_bits_retain(TypeFlags::HAS_NON_REGION_ERROR.bits() |
                TypeFlags::HAS_RE_ERROR.bits());
    #[doc = r#" Does this have any region that "appears free" in the type?"#]
    #[doc = r" Basically anything but `ReBound` and `ReErased`."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_FREE_REGIONS: Self = Self::from_bits_retain(1 << 17);
    #[doc = r" Does this have any `ReBound` regions?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_RE_BOUND: Self = Self::from_bits_retain(1 << 18);
    #[doc = r" Does this have any `Bound` types?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_TY_BOUND: Self = Self::from_bits_retain(1 << 19);
    #[doc = r" Does this have any `ConstKind::Bound` consts?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_CT_BOUND: Self = Self::from_bits_retain(1 << 20);
    #[doc = r" Does this have any bound variables?"]
    #[doc = r" Used to check if a global bound is safe to evaluate."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_BOUND_VARS: Self =
        Self::from_bits_retain(TypeFlags::HAS_RE_BOUND.bits() |
                    TypeFlags::HAS_TY_BOUND.bits() |
                TypeFlags::HAS_CT_BOUND.bits());
    #[doc = r" Does this have any `ReErased` regions?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_RE_ERASED: Self = Self::from_bits_retain(1 << 21);
    #[doc =
    r" Does this value have parameters/placeholders/inference variables which could be"]
    #[doc =
    r" replaced later, in a way that would change the results of `impl` specialization?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const STILL_FURTHER_SPECIALIZABLE: Self =
        Self::from_bits_retain(TypeFlags::HAS_TY_PARAM.bits() |
                                TypeFlags::HAS_TY_PLACEHOLDER.bits() |
                            TypeFlags::HAS_TY_INFER.bits() |
                        TypeFlags::HAS_CT_PARAM.bits() |
                    TypeFlags::HAS_CT_PLACEHOLDER.bits() |
                TypeFlags::HAS_CT_INFER.bits());
    #[doc =
    r" Does this value have `InferTy::FreshTy/FreshIntTy/FreshFloatTy`?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_TY_FRESH: Self = Self::from_bits_retain(1 << 22);
    #[doc = r" Does this value have `InferConst::Fresh`?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_CT_FRESH: Self = Self::from_bits_retain(1 << 23);
    #[doc =
    r" Does this have any binders with bound vars (e.g. that need to be anonymized)?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_BINDER_VARS: Self = Self::from_bits_retain(1 << 24);
    #[doc = r" Does this type have any coroutines in it?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_TY_CORO: Self = Self::from_bits_retain(1 << 25);
    #[doc =
    r" Does this have have a `Bound(BoundVarIndexKind::Canonical, _)`?"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HAS_CANONICAL_BOUND: Self = Self::from_bits_retain(1 << 26);
}
impl ::bitflags::Flags for TypeFlags {
    const FLAGS: &'static [::bitflags::Flag<TypeFlags>] =
        &[{

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_TY_PARAM",
                            TypeFlags::HAS_TY_PARAM)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_RE_PARAM",
                            TypeFlags::HAS_RE_PARAM)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_CT_PARAM",
                            TypeFlags::HAS_CT_PARAM)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_PARAM", TypeFlags::HAS_PARAM)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_TY_INFER",
                            TypeFlags::HAS_TY_INFER)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_RE_INFER",
                            TypeFlags::HAS_RE_INFER)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_CT_INFER",
                            TypeFlags::HAS_CT_INFER)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_INFER", TypeFlags::HAS_INFER)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_TY_PLACEHOLDER",
                            TypeFlags::HAS_TY_PLACEHOLDER)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_RE_PLACEHOLDER",
                            TypeFlags::HAS_RE_PLACEHOLDER)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_CT_PLACEHOLDER",
                            TypeFlags::HAS_CT_PLACEHOLDER)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_PLACEHOLDER",
                            TypeFlags::HAS_PLACEHOLDER)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_FREE_LOCAL_REGIONS",
                            TypeFlags::HAS_FREE_LOCAL_REGIONS)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_FREE_LOCAL_NAMES",
                            TypeFlags::HAS_FREE_LOCAL_NAMES)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_TY_PROJECTION",
                            TypeFlags::HAS_TY_PROJECTION)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_TY_FREE_ALIAS",
                            TypeFlags::HAS_TY_FREE_ALIAS)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_TY_OPAQUE",
                            TypeFlags::HAS_TY_OPAQUE)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_TY_INHERENT",
                            TypeFlags::HAS_TY_INHERENT)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_CT_PROJECTION",
                            TypeFlags::HAS_CT_PROJECTION)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_ALIAS", TypeFlags::HAS_ALIAS)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_NON_REGION_ERROR",
                            TypeFlags::HAS_NON_REGION_ERROR)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_RE_ERROR",
                            TypeFlags::HAS_RE_ERROR)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_ERROR", TypeFlags::HAS_ERROR)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_FREE_REGIONS",
                            TypeFlags::HAS_FREE_REGIONS)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_RE_BOUND",
                            TypeFlags::HAS_RE_BOUND)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_TY_BOUND",
                            TypeFlags::HAS_TY_BOUND)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_CT_BOUND",
                            TypeFlags::HAS_CT_BOUND)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_BOUND_VARS",
                            TypeFlags::HAS_BOUND_VARS)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_RE_ERASED",
                            TypeFlags::HAS_RE_ERASED)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("STILL_FURTHER_SPECIALIZABLE",
                            TypeFlags::STILL_FURTHER_SPECIALIZABLE)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_TY_FRESH",
                            TypeFlags::HAS_TY_FRESH)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_CT_FRESH",
                            TypeFlags::HAS_CT_FRESH)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_BINDER_VARS",
                            TypeFlags::HAS_BINDER_VARS)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_TY_CORO", TypeFlags::HAS_TY_CORO)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HAS_CANONICAL_BOUND",
                            TypeFlags::HAS_CANONICAL_BOUND)
                    }];
    type Bits = u32;
    fn bits(&self) -> u32 { TypeFlags::bits(self) }
    fn from_bits_retain(bits: u32) -> TypeFlags {
        TypeFlags::from_bits_retain(bits)
    }
}
#[allow(dead_code, deprecated, unused_doc_comments, unused_attributes,
unused_mut, unused_imports, non_upper_case_globals, clippy ::
assign_op_pattern, clippy :: indexing_slicing, clippy :: same_name_method,
clippy :: iter_without_into_iter,)]
const _: () =
    {
        #[repr(transparent)]
        pub struct InternalBitFlags(u32);
        #[automatically_derived]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone for InternalBitFlags { }
        #[automatically_derived]
        impl ::core::clone::Clone for InternalBitFlags {
            #[inline]
            fn clone(&self) -> InternalBitFlags {
                let _: ::core::clone::AssertParamIsClone<u32>;
                *self
            }
        }
        #[automatically_derived]
        impl ::core::marker::Copy for InternalBitFlags { }
        #[automatically_derived]
        impl ::core::marker::StructuralPartialEq for InternalBitFlags { }
        #[automatically_derived]
        impl ::core::cmp::PartialEq for InternalBitFlags {
            #[inline]
            fn eq(&self, other: &InternalBitFlags) -> bool {
                self.0 == other.0
            }
        }
        #[automatically_derived]
        impl ::core::cmp::Eq for InternalBitFlags {
            #[inline]
            #[doc(hidden)]
            #[coverage(off)]
            fn assert_fields_are_eq(&self) {
                let _: ::core::cmp::AssertParamIsEq<u32>;
            }
        }
        #[automatically_derived]
        impl ::core::cmp::PartialOrd for InternalBitFlags {
            #[inline]
            fn partial_cmp(&self, other: &InternalBitFlags)
                -> ::core::option::Option<::core::cmp::Ordering> {
                ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
            }
        }
        #[automatically_derived]
        impl ::core::cmp::Ord for InternalBitFlags {
            #[inline]
            fn cmp(&self, other: &InternalBitFlags) -> ::core::cmp::Ordering {
                ::core::cmp::Ord::cmp(&self.0, &other.0)
            }
        }
        #[automatically_derived]
        impl ::core::hash::Hash for InternalBitFlags {
            #[inline]
            fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
                ::core::hash::Hash::hash(&self.0, state)
            }
        }
        impl ::bitflags::__private::PublicFlags for TypeFlags {
            type Primitive = u32;
            type Internal = InternalBitFlags;
        }
        impl ::bitflags::__private::core::default::Default for
            InternalBitFlags {
            #[inline]
            fn default() -> Self { InternalBitFlags::empty() }
        }
        impl ::bitflags::__private::core::fmt::Debug for InternalBitFlags {
            fn fmt(&self,
                f: &mut ::bitflags::__private::core::fmt::Formatter<'_>)
                -> ::bitflags::__private::core::fmt::Result {
                if self.is_empty() {
                    f.write_fmt(format_args!("{0:#x}",
                            <u32 as ::bitflags::Bits>::EMPTY))
                } else {
                    ::bitflags::__private::core::fmt::Display::fmt(self, f)
                }
            }
        }
        impl ::bitflags::__private::core::fmt::Display for InternalBitFlags {
            fn fmt(&self,
                f: &mut ::bitflags::__private::core::fmt::Formatter<'_>)
                -> ::bitflags::__private::core::fmt::Result {
                ::bitflags::parser::to_writer(&TypeFlags(*self), f)
            }
        }
        impl ::bitflags::__private::core::str::FromStr for InternalBitFlags {
            type Err = ::bitflags::parser::ParseError;
            fn from_str(s: &str)
                ->
                    ::bitflags::__private::core::result::Result<Self,
                    Self::Err> {
                ::bitflags::parser::from_str::<TypeFlags>(s).map(|flags|
                        flags.0)
            }
        }
        impl ::bitflags::__private::core::convert::AsRef<u32> for
            InternalBitFlags {
            fn as_ref(&self) -> &u32 { &self.0 }
        }
        impl ::bitflags::__private::core::convert::From<u32> for
            InternalBitFlags {
            fn from(bits: u32) -> Self { Self::from_bits_retain(bits) }
        }
        #[allow(dead_code, deprecated, unused_attributes)]
        impl InternalBitFlags {
            /// Get a flags value with all bits unset.
            #[inline]
            pub const fn empty() -> Self {
                Self(<u32 as ::bitflags::Bits>::EMPTY)
            }
            /// Get a flags value with all known bits set.
            #[inline]
            pub const fn all() -> Self {
                let mut truncated = <u32 as ::bitflags::Bits>::EMPTY;
                let mut i = 0;
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <TypeFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                let _ = i;
                Self(truncated)
            }
            /// Get the underlying bits value.
            ///
            /// The returned value is exactly the bits set in this flags value.
            #[inline]
            pub const fn bits(&self) -> u32 { self.0 }
            /// Convert from a bits value.
            ///
            /// This method will return `None` if any unknown bits are set.
            #[inline]
            pub const fn from_bits(bits: u32)
                -> ::bitflags::__private::core::option::Option<Self> {
                let truncated = Self::from_bits_truncate(bits).0;
                if truncated == bits {
                    ::bitflags::__private::core::option::Option::Some(Self(bits))
                } else { ::bitflags::__private::core::option::Option::None }
            }
            /// Convert from a bits value, unsetting any unknown bits.
            #[inline]
            pub const fn from_bits_truncate(bits: u32) -> Self {
                Self(bits & Self::all().0)
            }
            /// Convert from a bits value exactly.
            #[inline]
            pub const fn from_bits_retain(bits: u32) -> Self { Self(bits) }
            /// Get a flags value with the bits of a flag with the given name set.
            ///
            /// This method will return `None` if `name` is empty or doesn't
            /// correspond to any named flag.
            #[inline]
            pub fn from_name(name: &str)
                -> ::bitflags::__private::core::option::Option<Self> {
                {
                    if name == "HAS_TY_PARAM" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_TY_PARAM.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_RE_PARAM" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_RE_PARAM.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_CT_PARAM" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_CT_PARAM.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_PARAM" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_PARAM.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_TY_INFER" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_TY_INFER.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_RE_INFER" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_RE_INFER.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_CT_INFER" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_CT_INFER.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_INFER" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_INFER.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_TY_PLACEHOLDER" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_TY_PLACEHOLDER.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_RE_PLACEHOLDER" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_RE_PLACEHOLDER.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_CT_PLACEHOLDER" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_CT_PLACEHOLDER.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_PLACEHOLDER" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_PLACEHOLDER.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_FREE_LOCAL_REGIONS" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_FREE_LOCAL_REGIONS.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_FREE_LOCAL_NAMES" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_FREE_LOCAL_NAMES.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_TY_PROJECTION" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_TY_PROJECTION.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_TY_FREE_ALIAS" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_TY_FREE_ALIAS.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_TY_OPAQUE" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_TY_OPAQUE.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_TY_INHERENT" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_TY_INHERENT.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_CT_PROJECTION" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_CT_PROJECTION.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_ALIAS" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_ALIAS.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_NON_REGION_ERROR" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_NON_REGION_ERROR.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_RE_ERROR" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_RE_ERROR.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_ERROR" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_ERROR.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_FREE_REGIONS" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_FREE_REGIONS.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_RE_BOUND" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_RE_BOUND.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_TY_BOUND" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_TY_BOUND.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_CT_BOUND" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_CT_BOUND.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_BOUND_VARS" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_BOUND_VARS.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_RE_ERASED" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_RE_ERASED.bits()));
                    }
                };
                ;
                {
                    if name == "STILL_FURTHER_SPECIALIZABLE" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::STILL_FURTHER_SPECIALIZABLE.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_TY_FRESH" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_TY_FRESH.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_CT_FRESH" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_CT_FRESH.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_BINDER_VARS" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_BINDER_VARS.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_TY_CORO" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_TY_CORO.bits()));
                    }
                };
                ;
                {
                    if name == "HAS_CANONICAL_BOUND" {
                        return ::bitflags::__private::core::option::Option::Some(Self(TypeFlags::HAS_CANONICAL_BOUND.bits()));
                    }
                };
                ;
                let _ = name;
                ::bitflags::__private::core::option::Option::None
            }
            /// Whether all bits in this flags value are unset.
            #[inline]
            pub const fn is_empty(&self) -> bool {
                self.0 == <u32 as ::bitflags::Bits>::EMPTY
            }
            /// Whether all known bits in this flags value are set.
            #[inline]
            pub const fn is_all(&self) -> bool {
                Self::all().0 | self.0 == self.0
            }
            /// Whether any set bits in a source flags value are also set in a target flags value.
            #[inline]
            pub const fn intersects(&self, other: Self) -> bool {
                self.0 & other.0 != <u32 as ::bitflags::Bits>::EMPTY
            }
            /// Whether all set bits in a source flags value are also set in a target flags value.
            #[inline]
            pub const fn contains(&self, other: Self) -> bool {
                self.0 & other.0 == other.0
            }
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            pub fn insert(&mut self, other: Self) {
                *self = Self(self.0).union(other);
            }
            /// The intersection of a source flags value with the complement of a target flags
            /// value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `remove` won't truncate `other`, but the `!` operator will.
            #[inline]
            pub fn remove(&mut self, other: Self) {
                *self = Self(self.0).difference(other);
            }
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            pub fn toggle(&mut self, other: Self) {
                *self = Self(self.0).symmetric_difference(other);
            }
            /// Call `insert` when `value` is `true` or `remove` when `value` is `false`.
            #[inline]
            pub fn set(&mut self, other: Self, value: bool) {
                if value { self.insert(other); } else { self.remove(other); }
            }
            /// The bitwise and (`&`) of the bits in two flags values.
            #[inline]
            #[must_use]
            pub const fn intersection(self, other: Self) -> Self {
                Self(self.0 & other.0)
            }
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            #[must_use]
            pub const fn union(self, other: Self) -> Self {
                Self(self.0 | other.0)
            }
            /// The intersection of a source flags value with the complement of a target flags
            /// value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            #[must_use]
            pub const fn difference(self, other: Self) -> Self {
                Self(self.0 & !other.0)
            }
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            #[must_use]
            pub const fn symmetric_difference(self, other: Self) -> Self {
                Self(self.0 ^ other.0)
            }
            /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
            #[inline]
            #[must_use]
            pub const fn complement(self) -> Self {
                Self::from_bits_truncate(!self.0)
            }
        }
        impl ::bitflags::__private::core::fmt::Binary for InternalBitFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::Binary::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::Octal for InternalBitFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::Octal::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::LowerHex for InternalBitFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::LowerHex::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::UpperHex for InternalBitFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::UpperHex::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::ops::BitOr for InternalBitFlags {
            type Output = Self;
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            fn bitor(self, other: InternalBitFlags) -> Self {
                self.union(other)
            }
        }
        impl ::bitflags::__private::core::ops::BitOrAssign for
            InternalBitFlags {
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            fn bitor_assign(&mut self, other: Self) { self.insert(other); }
        }
        impl ::bitflags::__private::core::ops::BitXor for InternalBitFlags {
            type Output = Self;
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            fn bitxor(self, other: Self) -> Self {
                self.symmetric_difference(other)
            }
        }
        impl ::bitflags::__private::core::ops::BitXorAssign for
            InternalBitFlags {
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            fn bitxor_assign(&mut self, other: Self) { self.toggle(other); }
        }
        impl ::bitflags::__private::core::ops::BitAnd for InternalBitFlags {
            type Output = Self;
            /// The bitwise and (`&`) of the bits in two flags values.
            #[inline]
            fn bitand(self, other: Self) -> Self { self.intersection(other) }
        }
        impl ::bitflags::__private::core::ops::BitAndAssign for
            InternalBitFlags {
            /// The bitwise and (`&`) of the bits in two flags values.
            #[inline]
            fn bitand_assign(&mut self, other: Self) {
                *self =
                    Self::from_bits_retain(self.bits()).intersection(other);
            }
        }
        impl ::bitflags::__private::core::ops::Sub for InternalBitFlags {
            type Output = Self;
            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            fn sub(self, other: Self) -> Self { self.difference(other) }
        }
        impl ::bitflags::__private::core::ops::SubAssign for InternalBitFlags
            {
            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            fn sub_assign(&mut self, other: Self) { self.remove(other); }
        }
        impl ::bitflags::__private::core::ops::Not for InternalBitFlags {
            type Output = Self;
            /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
            #[inline]
            fn not(self) -> Self { self.complement() }
        }
        impl ::bitflags::__private::core::iter::Extend<InternalBitFlags> for
            InternalBitFlags {
            /// The bitwise or (`|`) of the bits in each flags value.
            fn extend<T: ::bitflags::__private::core::iter::IntoIterator<Item
                = Self>>(&mut self, iterator: T) {
                for item in iterator { self.insert(item) }
            }
        }
        impl ::bitflags::__private::core::iter::FromIterator<InternalBitFlags>
            for InternalBitFlags {
            /// The bitwise or (`|`) of the bits in each flags value.
            fn from_iter<T: ::bitflags::__private::core::iter::IntoIterator<Item
                = Self>>(iterator: T) -> Self {
                use ::bitflags::__private::core::iter::Extend;
                let mut result = Self::empty();
                result.extend(iterator);
                result
            }
        }
        impl InternalBitFlags {
            /// Yield a set of contained flags values.
            ///
            /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
            /// will be yielded together as a final flags value.
            #[inline]
            pub const fn iter(&self) -> ::bitflags::iter::Iter<TypeFlags> {
                ::bitflags::iter::Iter::__private_const_new(<TypeFlags as
                        ::bitflags::Flags>::FLAGS,
                    TypeFlags::from_bits_retain(self.bits()),
                    TypeFlags::from_bits_retain(self.bits()))
            }
            /// Yield a set of contained named flags values.
            ///
            /// This method is like [`iter`](#method.iter), except only yields bits in contained named flags.
            /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
            #[inline]
            pub const fn iter_names(&self)
                -> ::bitflags::iter::IterNames<TypeFlags> {
                ::bitflags::iter::IterNames::__private_const_new(<TypeFlags as
                        ::bitflags::Flags>::FLAGS,
                    TypeFlags::from_bits_retain(self.bits()),
                    TypeFlags::from_bits_retain(self.bits()))
            }
        }
        impl ::bitflags::__private::core::iter::IntoIterator for
            InternalBitFlags {
            type Item = TypeFlags;
            type IntoIter = ::bitflags::iter::Iter<TypeFlags>;
            fn into_iter(self) -> Self::IntoIter { self.iter() }
        }
        impl InternalBitFlags {
            /// Returns a mutable reference to the raw value of the flags currently stored.
            #[inline]
            pub fn bits_mut(&mut self) -> &mut u32 { &mut self.0 }
        }
        #[allow(dead_code, deprecated, unused_attributes)]
        impl TypeFlags {
            /// Get a flags value with all bits unset.
            #[inline]
            pub const fn empty() -> Self { Self(InternalBitFlags::empty()) }
            /// Get a flags value with all known bits set.
            #[inline]
            pub const fn all() -> Self { Self(InternalBitFlags::all()) }
            /// Get the underlying bits value.
            ///
            /// The returned value is exactly the bits set in this flags value.
            #[inline]
            pub const fn bits(&self) -> u32 { self.0.bits() }
            /// Convert from a bits value.
            ///
            /// This method will return `None` if any unknown bits are set.
            #[inline]
            pub const fn from_bits(bits: u32)
                -> ::bitflags::__private::core::option::Option<Self> {
                match InternalBitFlags::from_bits(bits) {
                    ::bitflags::__private::core::option::Option::Some(bits) =>
                        ::bitflags::__private::core::option::Option::Some(Self(bits)),
                    ::bitflags::__private::core::option::Option::None =>
                        ::bitflags::__private::core::option::Option::None,
                }
            }
            /// Convert from a bits value, unsetting any unknown bits.
            #[inline]
            pub const fn from_bits_truncate(bits: u32) -> Self {
                Self(InternalBitFlags::from_bits_truncate(bits))
            }
            /// Convert from a bits value exactly.
            #[inline]
            pub const fn from_bits_retain(bits: u32) -> Self {
                Self(InternalBitFlags::from_bits_retain(bits))
            }
            /// Get a flags value with the bits of a flag with the given name set.
            ///
            /// This method will return `None` if `name` is empty or doesn't
            /// correspond to any named flag.
            #[inline]
            pub fn from_name(name: &str)
                -> ::bitflags::__private::core::option::Option<Self> {
                match InternalBitFlags::from_name(name) {
                    ::bitflags::__private::core::option::Option::Some(bits) =>
                        ::bitflags::__private::core::option::Option::Some(Self(bits)),
                    ::bitflags::__private::core::option::Option::None =>
                        ::bitflags::__private::core::option::Option::None,
                }
            }
            /// Whether all bits in this flags value are unset.
            #[inline]
            pub const fn is_empty(&self) -> bool { self.0.is_empty() }
            /// Whether all known bits in this flags value are set.
            #[inline]
            pub const fn is_all(&self) -> bool { self.0.is_all() }
            /// Whether any set bits in a source flags value are also set in a target flags value.
            #[inline]
            pub const fn intersects(&self, other: Self) -> bool {
                self.0.intersects(other.0)
            }
            /// Whether all set bits in a source flags value are also set in a target flags value.
            #[inline]
            pub const fn contains(&self, other: Self) -> bool {
                self.0.contains(other.0)
            }
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            pub fn insert(&mut self, other: Self) { self.0.insert(other.0) }
            /// The intersection of a source flags value with the complement of a target flags
            /// value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `remove` won't truncate `other`, but the `!` operator will.
            #[inline]
            pub fn remove(&mut self, other: Self) { self.0.remove(other.0) }
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            pub fn toggle(&mut self, other: Self) { self.0.toggle(other.0) }
            /// Call `insert` when `value` is `true` or `remove` when `value` is `false`.
            #[inline]
            pub fn set(&mut self, other: Self, value: bool) {
                self.0.set(other.0, value)
            }
            /// The bitwise and (`&`) of the bits in two flags values.
            #[inline]
            #[must_use]
            pub const fn intersection(self, other: Self) -> Self {
                Self(self.0.intersection(other.0))
            }
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            #[must_use]
            pub const fn union(self, other: Self) -> Self {
                Self(self.0.union(other.0))
            }
            /// The intersection of a source flags value with the complement of a target flags
            /// value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            #[must_use]
            pub const fn difference(self, other: Self) -> Self {
                Self(self.0.difference(other.0))
            }
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            #[must_use]
            pub const fn symmetric_difference(self, other: Self) -> Self {
                Self(self.0.symmetric_difference(other.0))
            }
            /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
            #[inline]
            #[must_use]
            pub const fn complement(self) -> Self {
                Self(self.0.complement())
            }
        }
        impl ::bitflags::__private::core::fmt::Binary for TypeFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::Binary::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::Octal for TypeFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::Octal::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::LowerHex for TypeFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::LowerHex::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::UpperHex for TypeFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::UpperHex::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::ops::BitOr for TypeFlags {
            type Output = Self;
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            fn bitor(self, other: TypeFlags) -> Self { self.union(other) }
        }
        impl ::bitflags::__private::core::ops::BitOrAssign for TypeFlags {
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            fn bitor_assign(&mut self, other: Self) { self.insert(other); }
        }
        impl ::bitflags::__private::core::ops::BitXor for TypeFlags {
            type Output = Self;
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            fn bitxor(self, other: Self) -> Self {
                self.symmetric_difference(other)
            }
        }
        impl ::bitflags::__private::core::ops::BitXorAssign for TypeFlags {
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            fn bitxor_assign(&mut self, other: Self) { self.toggle(other); }
        }
        impl ::bitflags::__private::core::ops::BitAnd for TypeFlags {
            type Output = Self;
            /// The bitwise and (`&`) of the bits in two flags values.
            #[inline]
            fn bitand(self, other: Self) -> Self { self.intersection(other) }
        }
        impl ::bitflags::__private::core::ops::BitAndAssign for TypeFlags {
            /// The bitwise and (`&`) of the bits in two flags values.
            #[inline]
            fn bitand_assign(&mut self, other: Self) {
                *self =
                    Self::from_bits_retain(self.bits()).intersection(other);
            }
        }
        impl ::bitflags::__private::core::ops::Sub for TypeFlags {
            type Output = Self;
            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            fn sub(self, other: Self) -> Self { self.difference(other) }
        }
        impl ::bitflags::__private::core::ops::SubAssign for TypeFlags {
            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            fn sub_assign(&mut self, other: Self) { self.remove(other); }
        }
        impl ::bitflags::__private::core::ops::Not for TypeFlags {
            type Output = Self;
            /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
            #[inline]
            fn not(self) -> Self { self.complement() }
        }
        impl ::bitflags::__private::core::iter::Extend<TypeFlags> for
            TypeFlags {
            /// The bitwise or (`|`) of the bits in each flags value.
            fn extend<T: ::bitflags::__private::core::iter::IntoIterator<Item
                = Self>>(&mut self, iterator: T) {
                for item in iterator { self.insert(item) }
            }
        }
        impl ::bitflags::__private::core::iter::FromIterator<TypeFlags> for
            TypeFlags {
            /// The bitwise or (`|`) of the bits in each flags value.
            fn from_iter<T: ::bitflags::__private::core::iter::IntoIterator<Item
                = Self>>(iterator: T) -> Self {
                use ::bitflags::__private::core::iter::Extend;
                let mut result = Self::empty();
                result.extend(iterator);
                result
            }
        }
        impl TypeFlags {
            /// Yield a set of contained flags values.
            ///
            /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
            /// will be yielded together as a final flags value.
            #[inline]
            pub const fn iter(&self) -> ::bitflags::iter::Iter<TypeFlags> {
                ::bitflags::iter::Iter::__private_const_new(<TypeFlags as
                        ::bitflags::Flags>::FLAGS,
                    TypeFlags::from_bits_retain(self.bits()),
                    TypeFlags::from_bits_retain(self.bits()))
            }
            /// Yield a set of contained named flags values.
            ///
            /// This method is like [`iter`](#method.iter), except only yields bits in contained named flags.
            /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
            #[inline]
            pub const fn iter_names(&self)
                -> ::bitflags::iter::IterNames<TypeFlags> {
                ::bitflags::iter::IterNames::__private_const_new(<TypeFlags as
                        ::bitflags::Flags>::FLAGS,
                    TypeFlags::from_bits_retain(self.bits()),
                    TypeFlags::from_bits_retain(self.bits()))
            }
        }
        impl ::bitflags::__private::core::iter::IntoIterator for TypeFlags {
            type Item = TypeFlags;
            type IntoIter = ::bitflags::iter::Iter<TypeFlags>;
            fn into_iter(self) -> Self::IntoIter { self.iter() }
        }
    };bitflags::bitflags! {
6    /// Flags that we track on types. These flags are propagated upwards
7    /// through the type during type construction, so that we can quickly check
8    /// whether the type has various kinds of types in it without recursing
9    /// over the type itself.
10    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
11    pub struct TypeFlags: u32 {
12        // Does this have parameters? Used to determine whether instantiation is
13        // required.
14        /// Does this have `Param`?
15        const HAS_TY_PARAM                = 1 << 0;
16        /// Does this have `ReEarlyParam`?
17        const HAS_RE_PARAM                = 1 << 1;
18        /// Does this have `ConstKind::Param`?
19        const HAS_CT_PARAM                = 1 << 2;
20
21        const HAS_PARAM                   = TypeFlags::HAS_TY_PARAM.bits()
22                                          | TypeFlags::HAS_RE_PARAM.bits()
23                                          | TypeFlags::HAS_CT_PARAM.bits();
24
25        /// Does this have `Infer`?
26        const HAS_TY_INFER                = 1 << 3;
27        /// Does this have `ReVar`?
28        const HAS_RE_INFER                = 1 << 4;
29        /// Does this have `ConstKind::Infer`?
30        const HAS_CT_INFER                = 1 << 5;
31
32        /// Does this have inference variables? Used to determine whether
33        /// inference is required.
34        const HAS_INFER                   = TypeFlags::HAS_TY_INFER.bits()
35                                          | TypeFlags::HAS_RE_INFER.bits()
36                                          | TypeFlags::HAS_CT_INFER.bits();
37
38        /// Does this have `Placeholder`?
39        const HAS_TY_PLACEHOLDER          = 1 << 6;
40        /// Does this have `RePlaceholder`?
41        const HAS_RE_PLACEHOLDER          = 1 << 7;
42        /// Does this have `ConstKind::Placeholder`?
43        const HAS_CT_PLACEHOLDER          = 1 << 8;
44
45        /// Does this have placeholders?
46        const HAS_PLACEHOLDER             = TypeFlags::HAS_TY_PLACEHOLDER.bits()
47                                          | TypeFlags::HAS_RE_PLACEHOLDER.bits()
48                                          | TypeFlags::HAS_CT_PLACEHOLDER.bits();
49
50        /// `true` if there are "names" of regions and so forth
51        /// that are local to a particular fn/inferctxt
52        const HAS_FREE_LOCAL_REGIONS      = 1 << 9;
53
54        /// `true` if there are "names" of types and regions and so forth
55        /// that are local to a particular fn
56        const HAS_FREE_LOCAL_NAMES        = TypeFlags::HAS_TY_PARAM.bits()
57                                          | TypeFlags::HAS_CT_PARAM.bits()
58                                          | TypeFlags::HAS_TY_INFER.bits()
59                                          | TypeFlags::HAS_CT_INFER.bits()
60                                          | TypeFlags::HAS_TY_PLACEHOLDER.bits()
61                                          | TypeFlags::HAS_CT_PLACEHOLDER.bits()
62                                          // We consider 'freshened' types and constants
63                                          // to depend on a particular fn.
64                                          // The freshening process throws away information,
65                                          // which can make things unsuitable for use in a global
66                                          // cache. Note that there is no 'fresh lifetime' flag -
67                                          // freshening replaces all lifetimes with `ReErased`,
68                                          // which is different from how types/const are freshened.
69                                          | TypeFlags::HAS_TY_FRESH.bits()
70                                          | TypeFlags::HAS_CT_FRESH.bits()
71                                          | TypeFlags::HAS_FREE_LOCAL_REGIONS.bits()
72                                          | TypeFlags::HAS_RE_ERASED.bits();
73
74        /// Does this have `Projection`?
75        const HAS_TY_PROJECTION           = 1 << 10;
76        /// Does this have `Free` aliases?
77        const HAS_TY_FREE_ALIAS           = 1 << 11;
78        /// Does this have `Opaque`?
79        const HAS_TY_OPAQUE               = 1 << 12;
80        /// Does this have `Inherent`?
81        const HAS_TY_INHERENT             = 1 << 13;
82        /// Does this have `ConstKind::Unevaluated`?
83        const HAS_CT_PROJECTION           = 1 << 14;
84
85        /// Does this have `Alias` or `ConstKind::Unevaluated`?
86        ///
87        /// Rephrased, could this term be normalized further?
88        const HAS_ALIAS                   = TypeFlags::HAS_TY_PROJECTION.bits()
89                                          | TypeFlags::HAS_TY_FREE_ALIAS.bits()
90                                          | TypeFlags::HAS_TY_OPAQUE.bits()
91                                          | TypeFlags::HAS_TY_INHERENT.bits()
92                                          | TypeFlags::HAS_CT_PROJECTION.bits();
93
94        /// Is a type or const error reachable?
95        const HAS_NON_REGION_ERROR          = 1 << 15;
96        /// Is a region error reachable?
97        const HAS_RE_ERROR                = 1 << 16;
98        /// Is an error type/lifetime/const reachable?
99        const HAS_ERROR                   = TypeFlags::HAS_NON_REGION_ERROR.bits()
100                                          | TypeFlags::HAS_RE_ERROR.bits();
101
102        /// Does this have any region that "appears free" in the type?
103        /// Basically anything but `ReBound` and `ReErased`.
104        const HAS_FREE_REGIONS            = 1 << 17;
105
106        /// Does this have any `ReBound` regions?
107        const HAS_RE_BOUND                = 1 << 18;
108        /// Does this have any `Bound` types?
109        const HAS_TY_BOUND                = 1 << 19;
110        /// Does this have any `ConstKind::Bound` consts?
111        const HAS_CT_BOUND                = 1 << 20;
112        /// Does this have any bound variables?
113        /// Used to check if a global bound is safe to evaluate.
114        const HAS_BOUND_VARS              = TypeFlags::HAS_RE_BOUND.bits()
115                                          | TypeFlags::HAS_TY_BOUND.bits()
116                                          | TypeFlags::HAS_CT_BOUND.bits();
117
118        /// Does this have any `ReErased` regions?
119        const HAS_RE_ERASED               = 1 << 21;
120
121        /// Does this value have parameters/placeholders/inference variables which could be
122        /// replaced later, in a way that would change the results of `impl` specialization?
123        const STILL_FURTHER_SPECIALIZABLE = TypeFlags::HAS_TY_PARAM.bits()
124                                          | TypeFlags::HAS_TY_PLACEHOLDER.bits()
125                                          | TypeFlags::HAS_TY_INFER.bits()
126                                          | TypeFlags::HAS_CT_PARAM.bits()
127                                          | TypeFlags::HAS_CT_PLACEHOLDER.bits()
128                                          | TypeFlags::HAS_CT_INFER.bits();
129
130        /// Does this value have `InferTy::FreshTy/FreshIntTy/FreshFloatTy`?
131        const HAS_TY_FRESH                = 1 << 22;
132
133        /// Does this value have `InferConst::Fresh`?
134        const HAS_CT_FRESH                = 1 << 23;
135
136        /// Does this have any binders with bound vars (e.g. that need to be anonymized)?
137        const HAS_BINDER_VARS             = 1 << 24;
138
139        /// Does this type have any coroutines in it?
140        const HAS_TY_CORO                 = 1 << 25;
141
142        /// Does this have have a `Bound(BoundVarIndexKind::Canonical, _)`?
143        const HAS_CANONICAL_BOUND         = 1 << 26;
144    }
145}
146
147#[derive(#[automatically_derived]
impl<I: ::core::fmt::Debug> ::core::fmt::Debug for FlagComputation<I> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "FlagComputation", "flags", &self.flags, "outer_exclusive_binder",
            &self.outer_exclusive_binder, "interner", &&self.interner)
    }
}Debug)]
148pub struct FlagComputation<I> {
149    pub flags: TypeFlags,
150
151    /// see `Ty::outer_exclusive_binder` for details
152    pub outer_exclusive_binder: ty::DebruijnIndex,
153
154    interner: std::marker::PhantomData<I>,
155}
156
157impl<I: Interner> FlagComputation<I> {
158    fn new() -> FlagComputation<I> {
159        FlagComputation {
160            flags: TypeFlags::empty(),
161            outer_exclusive_binder: ty::INNERMOST,
162            interner: std::marker::PhantomData,
163        }
164    }
165
166    #[allow(rustc::usage_of_ty_tykind)]
167    pub fn for_kind(kind: &ty::TyKind<I>) -> FlagComputation<I> {
168        let mut result = FlagComputation::new();
169        result.add_kind(kind);
170        result
171    }
172
173    pub fn for_predicate(binder: ty::Binder<I, ty::PredicateKind<I>>) -> FlagComputation<I> {
174        let mut result = FlagComputation::new();
175        result.add_predicate(binder);
176        result
177    }
178
179    pub fn for_const_kind(kind: &ty::ConstKind<I>) -> FlagComputation<I> {
180        let mut result = FlagComputation::new();
181        result.add_const_kind(kind);
182        result
183    }
184
185    pub fn for_clauses(clauses: &[I::Clause]) -> FlagComputation<I> {
186        let mut result = FlagComputation::new();
187        for c in clauses {
188            result.add_flags(c.as_predicate().flags());
189            result.add_exclusive_binder(c.as_predicate().outer_exclusive_binder());
190        }
191        result
192    }
193
194    fn add_flags(&mut self, flags: TypeFlags) {
195        self.flags = self.flags | flags;
196    }
197
198    /// indicates that `self` refers to something at binding level `binder`
199    fn add_bound_var(&mut self, binder: ty::DebruijnIndex) {
200        let exclusive_binder = binder.shifted_in(1);
201        self.add_exclusive_binder(exclusive_binder);
202    }
203
204    /// indicates that `self` refers to something *inside* binding
205    /// level `binder` -- not bound by `binder`, but bound by the next
206    /// binder internal to it
207    fn add_exclusive_binder(&mut self, exclusive_binder: ty::DebruijnIndex) {
208        self.outer_exclusive_binder = self.outer_exclusive_binder.max(exclusive_binder);
209    }
210
211    /// Adds the flags/depth from a set of types that appear within the current type, but within a
212    /// region binder.
213    fn bound_computation<T, F>(&mut self, value: ty::Binder<I, T>, f: F)
214    where
215        F: FnOnce(&mut Self, T),
216    {
217        let mut computation = FlagComputation::new();
218
219        if !value.bound_vars().is_empty() {
220            computation.add_flags(TypeFlags::HAS_BINDER_VARS);
221        }
222
223        f(&mut computation, value.skip_binder());
224
225        self.add_flags(computation.flags);
226
227        // The types that contributed to `computation` occurred within
228        // a region binder, so subtract one from the region depth
229        // within when adding the depth to `self`.
230        let outer_exclusive_binder = computation.outer_exclusive_binder;
231        if outer_exclusive_binder > ty::INNERMOST {
232            self.add_exclusive_binder(outer_exclusive_binder.shifted_out(1));
233        } // otherwise, this binder captures nothing
234    }
235
236    #[allow(rustc::usage_of_ty_tykind)]
237    fn add_kind(&mut self, kind: &ty::TyKind<I>) {
238        match *kind {
239            ty::Bool
240            | ty::Char
241            | ty::Int(_)
242            | ty::Float(_)
243            | ty::Uint(_)
244            | ty::Never
245            | ty::Str
246            | ty::Foreign(..) => {}
247
248            ty::Error(_) => self.add_flags(TypeFlags::HAS_NON_REGION_ERROR),
249
250            ty::Param(_) => {
251                self.add_flags(TypeFlags::HAS_TY_PARAM);
252            }
253
254            ty::Closure(_, args)
255            | ty::CoroutineClosure(_, args)
256            | ty::CoroutineWitness(_, args) => {
257                self.add_args(args.as_slice());
258            }
259
260            ty::Coroutine(_, args) => {
261                self.add_flags(TypeFlags::HAS_TY_CORO);
262                self.add_args(args.as_slice());
263            }
264
265            ty::Bound(ty::BoundVarIndexKind::Canonical, _) => {
266                self.add_flags(TypeFlags::HAS_TY_BOUND);
267                self.add_flags(TypeFlags::HAS_CANONICAL_BOUND);
268            }
269
270            ty::Bound(ty::BoundVarIndexKind::Bound(debruijn), _) => {
271                self.add_bound_var(debruijn);
272                self.add_flags(TypeFlags::HAS_TY_BOUND);
273            }
274
275            ty::Placeholder(..) => {
276                self.add_flags(TypeFlags::HAS_TY_PLACEHOLDER);
277            }
278
279            ty::Infer(infer) => match infer {
280                ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => {
281                    self.add_flags(TypeFlags::HAS_TY_FRESH)
282                }
283
284                ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => {
285                    self.add_flags(TypeFlags::HAS_TY_INFER)
286                }
287            },
288
289            ty::Adt(_, args) => {
290                self.add_args(args.as_slice());
291            }
292
293            ty::Alias(alias) => {
294                self.add_flags(match alias.kind {
295                    ty::Projection { .. } => TypeFlags::HAS_TY_PROJECTION,
296                    ty::Free { .. } => TypeFlags::HAS_TY_FREE_ALIAS,
297                    ty::Opaque { .. } => TypeFlags::HAS_TY_OPAQUE,
298                    ty::Inherent { .. } => TypeFlags::HAS_TY_INHERENT,
299                });
300
301                self.add_alias_ty(alias);
302            }
303
304            ty::Dynamic(obj, r) => {
305                for predicate in obj.iter() {
306                    self.bound_computation(predicate, |computation, predicate| match predicate {
307                        ty::ExistentialPredicate::Trait(tr) => {
308                            computation.add_args(tr.args.as_slice())
309                        }
310                        ty::ExistentialPredicate::Projection(p) => {
311                            computation.add_existential_projection(&p);
312                        }
313                        ty::ExistentialPredicate::AutoTrait(_) => {}
314                    });
315                }
316
317                self.add_region(r);
318            }
319
320            ty::Array(tt, len) => {
321                self.add_ty(tt);
322                self.add_const(len);
323            }
324
325            ty::Pat(ty, pat) => {
326                self.add_ty(ty);
327                self.add_ty_pat(pat);
328            }
329
330            ty::Slice(tt) => self.add_ty(tt),
331
332            ty::RawPtr(ty, _) => {
333                self.add_ty(ty);
334            }
335
336            ty::Ref(r, ty, _) => {
337                self.add_region(r);
338                self.add_ty(ty);
339            }
340
341            ty::Tuple(types) => {
342                self.add_tys(types);
343            }
344
345            ty::FnDef(_, args) => {
346                self.add_args(args.as_slice());
347            }
348
349            ty::FnPtr(sig_tys, _) => self.bound_computation(sig_tys, |computation, sig_tys| {
350                computation.add_tys(sig_tys.inputs_and_output);
351            }),
352
353            ty::UnsafeBinder(bound_ty) => {
354                self.bound_computation(bound_ty.into(), |computation, ty| {
355                    computation.add_ty(ty);
356                })
357            }
358        }
359    }
360
361    fn add_ty_pat(&mut self, pat: <I as Interner>::Pat) {
362        self.add_flags(pat.flags());
363        self.add_exclusive_binder(pat.outer_exclusive_binder());
364    }
365
366    fn add_predicate(&mut self, binder: ty::Binder<I, ty::PredicateKind<I>>) {
367        self.bound_computation(binder, |computation, atom| computation.add_predicate_atom(atom));
368    }
369
370    fn add_predicate_atom(&mut self, atom: ty::PredicateKind<I>) {
371        match atom {
372            ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => {
373                self.add_args(trait_pred.trait_ref.args.as_slice());
374            }
375            ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
376                trait_ref,
377                constness: _,
378            })) => {
379                self.add_args(trait_ref.args.as_slice());
380            }
381            ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
382                a,
383                b,
384            ))) => {
385                self.add_region(a);
386                self.add_region(b);
387            }
388            ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
389                ty,
390                region,
391            ))) => {
392                self.add_ty(ty);
393                self.add_region(region);
394            }
395            ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
396                self.add_const(ct);
397                self.add_ty(ty);
398            }
399            ty::PredicateKind::Subtype(ty::SubtypePredicate { a_is_expected: _, a, b }) => {
400                self.add_ty(a);
401                self.add_ty(b);
402            }
403            ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => {
404                self.add_ty(a);
405                self.add_ty(b);
406            }
407            ty::PredicateKind::Clause(ty::ClauseKind::Projection(ty::ProjectionPredicate {
408                projection_term,
409                term,
410            })) => {
411                self.add_alias_term(projection_term);
412                self.add_term(term);
413            }
414            ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) => {
415                self.add_term(term);
416            }
417            ty::PredicateKind::DynCompatible(_def_id) => {}
418            ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(uv)) => {
419                self.add_const(uv);
420            }
421            ty::PredicateKind::ConstEquate(expected, found) => {
422                self.add_const(expected);
423                self.add_const(found);
424            }
425            ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term }) => {
426                self.add_alias_term(alias);
427                self.add_term(term);
428            }
429            ty::PredicateKind::AliasRelate(t1, t2, _) => {
430                self.add_term(t1);
431                self.add_term(t2);
432            }
433            ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(_sym)) => {}
434            ty::PredicateKind::Ambiguous => {}
435        }
436    }
437
438    fn add_ty(&mut self, ty: I::Ty) {
439        self.add_flags(ty.flags());
440        self.add_exclusive_binder(ty.outer_exclusive_binder());
441    }
442
443    fn add_tys(&mut self, tys: I::Tys) {
444        for ty in tys.iter() {
445            self.add_ty(ty);
446        }
447    }
448
449    fn add_region(&mut self, r: I::Region) {
450        self.add_flags(r.flags());
451        if let ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _) = r.kind() {
452            self.add_bound_var(debruijn);
453        }
454    }
455
456    fn add_const(&mut self, c: I::Const) {
457        self.add_flags(c.flags());
458        self.add_exclusive_binder(c.outer_exclusive_binder());
459    }
460
461    fn add_const_kind(&mut self, c: &ty::ConstKind<I>) {
462        match *c {
463            ty::ConstKind::Unevaluated(uv) => {
464                self.add_args(uv.args.as_slice());
465                self.add_flags(TypeFlags::HAS_CT_PROJECTION);
466            }
467            ty::ConstKind::Infer(infer) => match infer {
468                ty::InferConst::Fresh(_) => self.add_flags(TypeFlags::HAS_CT_FRESH),
469                ty::InferConst::Var(_) => self.add_flags(TypeFlags::HAS_CT_INFER),
470            },
471            ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(debruijn), _) => {
472                self.add_bound_var(debruijn);
473                self.add_flags(TypeFlags::HAS_CT_BOUND);
474            }
475            ty::ConstKind::Bound(ty::BoundVarIndexKind::Canonical, _) => {
476                self.add_flags(TypeFlags::HAS_CT_BOUND);
477                self.add_flags(TypeFlags::HAS_CANONICAL_BOUND);
478            }
479            ty::ConstKind::Param(_) => {
480                self.add_flags(TypeFlags::HAS_CT_PARAM);
481            }
482            ty::ConstKind::Placeholder(_) => {
483                self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER);
484            }
485            ty::ConstKind::Value(cv) => {
486                self.add_ty(cv.ty());
487                match cv.valtree().kind() {
488                    ty::ValTreeKind::Leaf(_) => (),
489                    ty::ValTreeKind::Branch(cts) => {
490                        for ct in cts.iter() {
491                            self.add_const(ct);
492                        }
493                    }
494                }
495            }
496            ty::ConstKind::Expr(e) => self.add_args(e.args().as_slice()),
497            ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_NON_REGION_ERROR),
498        }
499    }
500
501    fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<I>) {
502        self.add_args(projection.args.as_slice());
503        match projection.term.kind() {
504            ty::TermKind::Ty(ty) => self.add_ty(ty),
505            ty::TermKind::Const(ct) => self.add_const(ct),
506        }
507    }
508
509    fn add_alias_ty(&mut self, alias_ty: ty::AliasTy<I>) {
510        self.add_args(alias_ty.args.as_slice());
511    }
512
513    fn add_alias_term(&mut self, alias_term: ty::AliasTerm<I>) {
514        self.add_args(alias_term.args.as_slice());
515    }
516
517    fn add_args(&mut self, args: &[I::GenericArg]) {
518        for arg in args {
519            match arg.kind() {
520                ty::GenericArgKind::Type(ty) => self.add_ty(ty),
521                ty::GenericArgKind::Lifetime(lt) => self.add_region(lt),
522                ty::GenericArgKind::Const(ct) => self.add_const(ct),
523            }
524        }
525    }
526
527    fn add_term(&mut self, term: I::Term) {
528        match term.kind() {
529            ty::TermKind::Ty(ty) => self.add_ty(ty),
530            ty::TermKind::Const(ct) => self.add_const(ct),
531        }
532    }
533}