Skip to main content

rustc_type_ir/
lib.rs

1//! This crate is an abstraction layer, shared between rustc and rust-analyzer, to help with the
2//! overlapping responsibilities (like type inference and trait solving), reduce duplication, and
3//! maintain consistent behavior between the two implementations.
4//!
5//! It defines fundamental interfaces for types, predicates, and the context required by the next
6//! trait solver.
7//!
8//! Both rustc and rust-analyzer immplement these traits for their own concrete implementations, and
9//! `rustc_next_trait_solver` is written to be generic over these abstractions.
10//!
11//! In addition to these interfaces, it also contains components built on top of the abstraction
12//! layer, for example elaboration logic, and the search graph machinery used by the solver, as well
13//! as items that do not need compiler-specific implementations.
14//!
15//! Note that rust-analyzer is built with a stable compiler, while rustc uses unstable features, so
16//! this crate and some of its dependencies need to separate unstable code under the `nightly`
17//! feature.
18//!
19//! There are more details available in a [dedicated dev-guide
20//! chapter](https://rustc-dev-guide.rust-lang.org/solve/sharing-crates-with-rust-analyzer.html).
21
22#![cfg_attr(feature = "nightly", rustc_diagnostic_item = "type_ir")]
23// tidy-alphabetical-start
24#![allow(rustc::direct_use_of_rustc_type_ir)]
25#![allow(rustc::usage_of_ty_tykind)]
26#![allow(rustc::usage_of_type_ir_inherent)]
27#![allow(rustc::usage_of_type_ir_traits)]
28#![cfg_attr(feature = "nightly", allow(internal_features))]
29#![cfg_attr(feature = "nightly", feature(associated_type_defaults, rustc_attrs, negative_impls))]
30// tidy-alphabetical-end
31
32extern crate self as rustc_type_ir;
33
34use std::fmt;
35use std::hash::Hash;
36
37use rustc_abi::{FieldIdx, VariantIdx};
38#[cfg(feature = "nightly")]
39use rustc_macros::{Decodable, Encodable, StableHash};
40
41// These modules are `pub` since they are not glob-imported.
42pub mod data_structures;
43pub mod elaborate;
44pub mod error;
45pub mod fast_reject;
46#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "type_ir_inherent")]
47pub mod inherent;
48pub mod intern;
49pub mod ir_print;
50pub mod lang_items;
51pub mod lift;
52pub mod outlives;
53pub mod region_constraint;
54pub mod relate;
55pub mod search_graph;
56pub mod solve;
57pub mod sty;
58pub mod walk;
59
60// These modules are not `pub` since they are glob-imported.
61#[macro_use]
62mod macros;
63mod binder;
64mod canonical;
65mod const_kind;
66mod flags;
67mod fold;
68mod generic_arg;
69mod generic_visit;
70mod infer_ctxt;
71mod interner;
72mod opaque_ty;
73mod pattern;
74mod predicate;
75mod predicate_kind;
76mod region_kind;
77#[cfg(feature = "nightly")]
78mod serialize;
79mod term_kind;
80mod ty;
81mod ty_info;
82mod ty_kind;
83mod universe;
84mod unnormalized;
85mod upcast;
86mod visit;
87
88pub use AliasTyKind::*;
89pub use InferTy::*;
90pub use RegionKind::*;
91pub use TyKind::*;
92pub use Variance::*;
93pub use binder::{Placeholder, *};
94pub use canonical::*;
95pub use const_kind::*;
96pub use flags::*;
97pub use fold::*;
98pub use generic_arg::*;
99pub use generic_visit::*;
100pub use infer_ctxt::*;
101pub use interner::*;
102pub use opaque_ty::*;
103pub use pattern::*;
104pub use predicate::*;
105pub use predicate_kind::*;
106pub use region_kind::*;
107pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy};
108use rustc_type_ir_macros::GenericTypeVisitable;
109#[cfg(feature = "nightly")]
110pub use serialize::*;
111pub use sty::*;
112pub use term_kind::*;
113pub use ty::{Alias, *};
114pub use ty_info::*;
115pub use ty_kind::*;
116pub use universe::*;
117pub use unnormalized::Unnormalized;
118pub use upcast::*;
119pub use visit::*;
120
121#[automatically_derived]
impl ::core::marker::Copy for DebruijnIndex { }
pub const INNERMOST: DebruijnIndex = DebruijnIndex::from_u32(0);
impl DebruijnIndex {
    #[doc = r" Maximum value the index can take, as a `u32`."]
    pub const MAX_AS_U32: u32 = 0xFFFF_FF00;
    #[doc = r" Maximum value the index can take."]
    pub const MAX: Self = Self::from_u32(0xFFFF_FF00);
    #[doc = r" Zero value of the index."]
    pub const ZERO: Self = Self::from_u32(0);
    #[doc = r" Creates a new index from a given `usize`."]
    #[doc = r""]
    #[doc = r" # Panics"]
    #[doc = r""]
    #[doc = r" Will panic if `value` exceeds `MAX`."]
    #[inline]
    pub const fn from_usize(value: usize) -> Self {
        if !(value <= (0xFFFF_FF00 as usize)) {
            ::core::panicking::panic("assertion failed: value <= (0xFFFF_FF00 as usize)")
        };
        unsafe { Self::from_u32_unchecked(value as u32) }
    }
    #[doc = r" Creates a new index from a given `u32`."]
    #[doc = r""]
    #[doc = r" # Panics"]
    #[doc = r""]
    #[doc = r" Will panic if `value` exceeds `MAX`."]
    #[inline]
    pub const fn from_u32(value: u32) -> Self {
        if !(value <= 0xFFFF_FF00) {
            ::core::panicking::panic("assertion failed: value <= 0xFFFF_FF00")
        };
        unsafe { Self::from_u32_unchecked(value) }
    }
    #[doc = r" Creates a new index from a given `u16`."]
    #[doc = r""]
    #[doc = r" # Panics"]
    #[doc = r""]
    #[doc = r" Will panic if `value` exceeds `MAX`."]
    #[inline]
    pub const fn from_u16(value: u16) -> Self {
        let value = value as u32;
        if !(value <= 0xFFFF_FF00) {
            ::core::panicking::panic("assertion failed: value <= 0xFFFF_FF00")
        };
        unsafe { Self::from_u32_unchecked(value) }
    }
    #[doc = r" Creates a new index from a given `u32`."]
    #[doc = r""]
    #[doc = r" # Safety"]
    #[doc = r""]
    #[doc =
    r" The provided value must be less than or equal to the maximum value for the newtype."]
    #[doc =
    r" Providing a value outside this range is undefined due to layout restrictions."]
    #[doc = r""]
    #[doc = r" Prefer using `from_u32`."]
    #[inline]
    pub const unsafe fn from_u32_unchecked(value: u32) -> Self {
        Self {
            private_use_as_methods_instead: unsafe {
                std::mem::transmute(value)
            },
        }
    }
    #[doc = r" Extracts the value of this index as a `usize`."]
    #[inline]
    pub const fn index(self) -> usize { self.as_usize() }
    #[doc = r" Extracts the value of this index as a `u32`."]
    #[inline]
    pub const fn as_u32(self) -> u32 {
        unsafe { std::mem::transmute(self.private_use_as_methods_instead) }
    }
    #[doc = r" Extracts the value of this index as a `usize`."]
    #[inline]
    pub const fn as_usize(self) -> usize { self.as_u32() as usize }
}
impl std::ops::Add<usize> for DebruijnIndex {
    type Output = Self;
    #[inline]
    fn add(self, other: usize) -> Self {
        Self::from_usize(self.index() + other)
    }
}
impl std::ops::AddAssign<usize> for DebruijnIndex {
    #[inline]
    fn add_assign(&mut self, other: usize) { *self = *self + other; }
}
impl rustc_index::Idx for DebruijnIndex {
    #[inline]
    fn new(value: usize) -> Self { Self::from_usize(value) }
    #[inline]
    fn index(self) -> usize { self.as_usize() }
}
impl ::std::iter::Step for DebruijnIndex {
    #[inline]
    fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
        <usize as
                ::std::iter::Step>::steps_between(&Self::index(*start),
            &Self::index(*end))
    }
    #[inline]
    fn forward_checked(start: Self, u: usize) -> Option<Self> {
        Self::index(start).checked_add(u).map(Self::from_usize)
    }
    #[inline]
    fn backward_checked(start: Self, u: usize) -> Option<Self> {
        Self::index(start).checked_sub(u).map(Self::from_usize)
    }
    #[inline]
    fn forward_overflowing(start: Self, u: usize) -> (Self, bool) {
        let (s, o) = Self::index(start).overflowing_add(u);
        (Self::from_usize(s), o)
    }
    #[inline]
    fn backward_overflowing(start: Self, u: usize) -> (Self, bool) {
        let (s, o) = Self::index(start).overflowing_sub(u);
        (Self::from_usize(s), o)
    }
}
impl ::std::cmp::Ord for DebruijnIndex {
    #[inline]
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.as_u32().cmp(&other.as_u32())
    }
}
impl ::std::cmp::PartialOrd for DebruijnIndex {
    #[inline]
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        Some(self.cmp(other))
    }
}
impl ::rustc_data_structures::stable_hash::StableHash for DebruijnIndex {
    fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
        hcx: &mut __Hcx,
        hasher: &mut ::rustc_data_structures::stable_hash::StableHasher) {
        self.as_u32().stable_hash(hcx, hasher)
    }
}
impl From<DebruijnIndex> for u32 {
    #[inline]
    fn from(v: DebruijnIndex) -> u32 { v.as_u32() }
}
impl From<DebruijnIndex> for usize {
    #[inline]
    fn from(v: DebruijnIndex) -> usize { v.as_usize() }
}
impl From<usize> for DebruijnIndex {
    #[inline]
    fn from(value: usize) -> Self { Self::from_usize(value) }
}
impl From<u32> for DebruijnIndex {
    #[inline]
    fn from(value: u32) -> Self { Self::from_u32(value) }
}
impl ::std::cmp::Eq for DebruijnIndex {}
impl ::std::cmp::PartialEq for DebruijnIndex {
    fn eq(&self, other: &Self) -> bool { self.as_u32().eq(&other.as_u32()) }
}
impl ::std::marker::StructuralPartialEq for DebruijnIndex { }
impl ::std::hash::Hash for DebruijnIndex {
    fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
        self.as_u32().hash(state)
    }
}
impl<D: ::rustc_serialize::Decoder> ::rustc_serialize::Decodable<D> for
    DebruijnIndex {
    fn decode(d: &mut D) -> Self { Self::from_u32(d.read_u32()) }
}
impl<E: ::rustc_serialize::Encoder> ::rustc_serialize::Encodable<E> for
    DebruijnIndex {
    fn encode(&self, e: &mut E) { e.emit_u32(self.as_u32()); }
}
impl ::std::fmt::Debug for DebruijnIndex {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        fmt.write_fmt(format_args!("DebruijnIndex({0})", self.as_u32()))
    }
}rustc_index::newtype_index! {
122    /// A [De Bruijn index][dbi] is a standard means of representing
123    /// regions (and perhaps later types) in a higher-ranked setting. In
124    /// particular, imagine a type like this:
125    /// ```ignore (illustrative)
126    ///    for<'a> fn(for<'b> fn(&'b isize, &'a isize), &'a char)
127    /// // ^          ^            |          |           |
128    /// // |          |            |          |           |
129    /// // |          +------------+ 0        |           |
130    /// // |                                  |           |
131    /// // +----------------------------------+ 1         |
132    /// // |                                              |
133    /// // +----------------------------------------------+ 0
134    /// ```
135    /// In this type, there are two binders (the outer fn and the inner
136    /// fn). We need to be able to determine, for any given region, which
137    /// fn type it is bound by, the inner or the outer one. There are
138    /// various ways you can do this, but a De Bruijn index is one of the
139    /// more convenient and has some nice properties. The basic idea is to
140    /// count the number of binders, inside out. Some examples should help
141    /// clarify what I mean.
142    ///
143    /// Let's start with the reference type `&'b isize` that is the first
144    /// argument to the inner function. This region `'b` is assigned a De
145    /// Bruijn index of 0, meaning "the innermost binder" (in this case, a
146    /// fn). The region `'a` that appears in the second argument type (`&'a
147    /// isize`) would then be assigned a De Bruijn index of 1, meaning "the
148    /// second-innermost binder". (These indices are written on the arrows
149    /// in the diagram).
150    ///
151    /// What is interesting is that De Bruijn index attached to a particular
152    /// variable will vary depending on where it appears. For example,
153    /// the final type `&'a char` also refers to the region `'a` declared on
154    /// the outermost fn. But this time, this reference is not nested within
155    /// any other binders (i.e., it is not an argument to the inner fn, but
156    /// rather the outer one). Therefore, in this case, it is assigned a
157    /// De Bruijn index of 0, because the innermost binder in that location
158    /// is the outer fn.
159    ///
160    /// [dbi]: https://en.wikipedia.org/wiki/De_Bruijn_index
161    #[stable_hash]
162    #[encodable]
163    #[orderable]
164    #[debug_format = "DebruijnIndex({})"]
165    #[gate_rustc_only]
166    pub struct DebruijnIndex {
167        const INNERMOST = 0;
168    }
169}
170
171impl DebruijnIndex {
172    /// Returns the resulting index when this value is moved into
173    /// `amount` number of new binders. So, e.g., if you had
174    ///
175    ///    for<'a> fn(&'a x)
176    ///
177    /// and you wanted to change it to
178    ///
179    ///    for<'a> fn(for<'b> fn(&'a x))
180    ///
181    /// you would need to shift the index for `'a` into a new binder.
182    #[inline]
183    #[must_use]
184    pub fn shifted_in(self, amount: u32) -> DebruijnIndex {
185        DebruijnIndex::from_u32(self.as_u32() + amount)
186    }
187
188    /// Update this index in place by shifting it "in" through
189    /// `amount` number of binders.
190    #[inline]
191    pub fn shift_in(&mut self, amount: u32) {
192        *self = self.shifted_in(amount);
193    }
194
195    /// Returns the resulting index when this value is moved out from
196    /// `amount` number of new binders.
197    #[inline]
198    #[must_use]
199    pub fn shifted_out(self, amount: u32) -> DebruijnIndex {
200        DebruijnIndex::from_u32(self.as_u32() - amount)
201    }
202
203    /// Update in place by shifting out from `amount` binders.
204    #[inline]
205    pub fn shift_out(&mut self, amount: u32) {
206        *self = self.shifted_out(amount);
207    }
208
209    /// Adjusts any De Bruijn indices so as to make `to_binder` the
210    /// innermost binder. That is, if we have something bound at `to_binder`,
211    /// it will now be bound at INNERMOST. This is an appropriate thing to do
212    /// when moving a region out from inside binders:
213    ///
214    /// ```ignore (illustrative)
215    ///             for<'a>   fn(for<'b>   for<'c>   fn(&'a u32), _)
216    /// // Binder:  D3           D2        D1            ^^
217    /// ```
218    ///
219    /// Here, the region `'a` would have the De Bruijn index D3,
220    /// because it is the bound 3 binders out. However, if we wanted
221    /// to refer to that region `'a` in the second argument (the `_`),
222    /// those two binders would not be in scope. In that case, we
223    /// might invoke `shift_out_to_binder(D3)`. This would adjust the
224    /// De Bruijn index of `'a` to D1 (the innermost binder).
225    ///
226    /// If we invoke `shift_out_to_binder` and the region is in fact
227    /// bound by one of the binders we are shifting out of, that is an
228    /// error (and should fail an assertion failure).
229    #[inline]
230    pub fn shifted_out_to_binder(self, to_binder: DebruijnIndex) -> Self {
231        self.shifted_out(to_binder.as_u32() - INNERMOST.as_u32())
232    }
233}
234
235pub fn debug_bound_var<T: std::fmt::Write>(
236    fmt: &mut T,
237    bound_index: BoundVarIndexKind,
238    var: impl std::fmt::Debug,
239) -> Result<(), std::fmt::Error> {
240    match bound_index {
241        BoundVarIndexKind::Bound(debruijn) => {
242            if debruijn == INNERMOST {
243                fmt.write_fmt(format_args!("^{0:?}", var))write!(fmt, "^{var:?}")
244            } else {
245                fmt.write_fmt(format_args!("^{0}_{1:?}", debruijn.index(), var))write!(fmt, "^{}_{:?}", debruijn.index(), var)
246            }
247        }
248        BoundVarIndexKind::Canonical => {
249            fmt.write_fmt(format_args!("^c_{0:?}", var))write!(fmt, "^c_{:?}", var)
250        }
251    }
252}
253
254#[derive(#[automatically_derived]
impl ::core::marker::Copy for Variance { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Variance { }
#[automatically_derived]
impl ::core::clone::Clone for Variance {
    #[inline]
    fn clone(&self) -> Variance { *self }
}Clone, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for Variance { }
#[automatically_derived]
impl ::core::cmp::PartialEq for Variance {
    #[inline]
    fn eq(&self, other: &Variance) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Variance {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for Variance {
    #[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)
    }
}Hash, const _: () =
    {
        unsafe impl<__V> ::rustc_type_ir::GenericTypeVisitable<__V> for
            Variance {
            fn generic_visit_with(&self, __visitor: &mut __V) {
                match *self {
                    Variance::Covariant => {}
                    Variance::Invariant => {}
                    Variance::Contravariant => {}
                    Variance::Bivariant => {}
                }
            }
        }
    };GenericTypeVisitable)]
255#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for Variance {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { Variance::Covariant }
                    1usize => { Variance::Invariant }
                    2usize => { Variance::Contravariant }
                    3usize => { Variance::Bivariant }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Variance`, expected 0..4, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for Variance {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        Variance::Covariant => { 0usize }
                        Variance::Invariant => { 1usize }
                        Variance::Contravariant => { 2usize }
                        Variance::Bivariant => { 3usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
            }
        }
    };Encodable, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for Variance {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    Variance::Covariant => {}
                    Variance::Invariant => {}
                    Variance::Contravariant => {}
                    Variance::Bivariant => {}
                }
            }
        }
    };StableHash))]
256#[cfg_attr(feature = "nightly", rustc_pass_by_value)]
257pub enum Variance {
258    Covariant,     // T<A> <: T<B> iff A <: B -- e.g., function return type
259    Invariant,     // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
260    Contravariant, // T<A> <: T<B> iff B <: A -- e.g., function param type
261    Bivariant,     // T<A> <: T<B>            -- e.g., unused type parameter
262}
263
264impl Variance {
265    /// `a.xform(b)` combines the variance of a context with the
266    /// variance of a type with the following meaning. If we are in a
267    /// context with variance `a`, and we encounter a type argument in
268    /// a position with variance `b`, then `a.xform(b)` is the new
269    /// variance with which the argument appears.
270    ///
271    /// Example 1:
272    /// ```ignore (illustrative)
273    /// *mut Vec<i32>
274    /// ```
275    /// Here, the "ambient" variance starts as covariant. `*mut T` is
276    /// invariant with respect to `T`, so the variance in which the
277    /// `Vec<i32>` appears is `Covariant.xform(Invariant)`, which
278    /// yields `Invariant`. Now, the type `Vec<T>` is covariant with
279    /// respect to its type argument `T`, and hence the variance of
280    /// the `i32` here is `Invariant.xform(Covariant)`, which results
281    /// (again) in `Invariant`.
282    ///
283    /// Example 2:
284    /// ```ignore (illustrative)
285    /// fn(*const Vec<i32>, *mut Vec<i32)
286    /// ```
287    /// The ambient variance is covariant. A `fn` type is
288    /// contravariant with respect to its parameters, so the variance
289    /// within which both pointer types appear is
290    /// `Covariant.xform(Contravariant)`, or `Contravariant`. `*const
291    /// T` is covariant with respect to `T`, so the variance within
292    /// which the first `Vec<i32>` appears is
293    /// `Contravariant.xform(Covariant)` or `Contravariant`. The same
294    /// is true for its `i32` argument. In the `*mut T` case, the
295    /// variance of `Vec<i32>` is `Contravariant.xform(Invariant)`,
296    /// and hence the outermost type is `Invariant` with respect to
297    /// `Vec<i32>` (and its `i32` argument).
298    ///
299    /// Source: Figure 1 of "Taming the Wildcards:
300    /// Combining Definition- and Use-Site Variance" published in PLDI'11.
301    pub fn xform(self, v: Variance) -> Variance {
302        match (self, v) {
303            // Figure 1, column 1.
304            (Variance::Covariant, Variance::Covariant) => Variance::Covariant,
305            (Variance::Covariant, Variance::Contravariant) => Variance::Contravariant,
306            (Variance::Covariant, Variance::Invariant) => Variance::Invariant,
307            (Variance::Covariant, Variance::Bivariant) => Variance::Bivariant,
308
309            // Figure 1, column 2.
310            (Variance::Contravariant, Variance::Covariant) => Variance::Contravariant,
311            (Variance::Contravariant, Variance::Contravariant) => Variance::Covariant,
312            (Variance::Contravariant, Variance::Invariant) => Variance::Invariant,
313            (Variance::Contravariant, Variance::Bivariant) => Variance::Bivariant,
314
315            // Figure 1, column 3.
316            (Variance::Invariant, _) => Variance::Invariant,
317
318            // Figure 1, column 4.
319            (Variance::Bivariant, _) => Variance::Bivariant,
320        }
321    }
322}
323
324impl fmt::Debug for Variance {
325    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
326        f.write_str(match *self {
327            Variance::Covariant => "+",
328            Variance::Contravariant => "-",
329            Variance::Invariant => "o",
330            Variance::Bivariant => "*",
331        })
332    }
333}
334
335#[automatically_derived]
impl ::core::marker::Copy for UniverseIndex { }
impl UniverseIndex {
    #[doc = r" Maximum value the index can take, as a `u32`."]
    pub const MAX_AS_U32: u32 = 0xFFFF_FF00;
    #[doc = r" Maximum value the index can take."]
    pub const MAX: Self = Self::from_u32(0xFFFF_FF00);
    #[doc = r" Zero value of the index."]
    pub const ZERO: Self = Self::from_u32(0);
    #[doc = r" Creates a new index from a given `usize`."]
    #[doc = r""]
    #[doc = r" # Panics"]
    #[doc = r""]
    #[doc = r" Will panic if `value` exceeds `MAX`."]
    #[inline]
    pub const fn from_usize(value: usize) -> Self {
        if !(value <= (0xFFFF_FF00 as usize)) {
            ::core::panicking::panic("assertion failed: value <= (0xFFFF_FF00 as usize)")
        };
        unsafe { Self::from_u32_unchecked(value as u32) }
    }
    #[doc = r" Creates a new index from a given `u32`."]
    #[doc = r""]
    #[doc = r" # Panics"]
    #[doc = r""]
    #[doc = r" Will panic if `value` exceeds `MAX`."]
    #[inline]
    pub const fn from_u32(value: u32) -> Self {
        if !(value <= 0xFFFF_FF00) {
            ::core::panicking::panic("assertion failed: value <= 0xFFFF_FF00")
        };
        unsafe { Self::from_u32_unchecked(value) }
    }
    #[doc = r" Creates a new index from a given `u16`."]
    #[doc = r""]
    #[doc = r" # Panics"]
    #[doc = r""]
    #[doc = r" Will panic if `value` exceeds `MAX`."]
    #[inline]
    pub const fn from_u16(value: u16) -> Self {
        let value = value as u32;
        if !(value <= 0xFFFF_FF00) {
            ::core::panicking::panic("assertion failed: value <= 0xFFFF_FF00")
        };
        unsafe { Self::from_u32_unchecked(value) }
    }
    #[doc = r" Creates a new index from a given `u32`."]
    #[doc = r""]
    #[doc = r" # Safety"]
    #[doc = r""]
    #[doc =
    r" The provided value must be less than or equal to the maximum value for the newtype."]
    #[doc =
    r" Providing a value outside this range is undefined due to layout restrictions."]
    #[doc = r""]
    #[doc = r" Prefer using `from_u32`."]
    #[inline]
    pub const unsafe fn from_u32_unchecked(value: u32) -> Self {
        Self {
            private_use_as_methods_instead: unsafe {
                std::mem::transmute(value)
            },
        }
    }
    #[doc = r" Extracts the value of this index as a `usize`."]
    #[inline]
    pub const fn index(self) -> usize { self.as_usize() }
    #[doc = r" Extracts the value of this index as a `u32`."]
    #[inline]
    pub const fn as_u32(self) -> u32 {
        unsafe { std::mem::transmute(self.private_use_as_methods_instead) }
    }
    #[doc = r" Extracts the value of this index as a `usize`."]
    #[inline]
    pub const fn as_usize(self) -> usize { self.as_u32() as usize }
}
impl std::ops::Add<usize> for UniverseIndex {
    type Output = Self;
    #[inline]
    fn add(self, other: usize) -> Self {
        Self::from_usize(self.index() + other)
    }
}
impl std::ops::AddAssign<usize> for UniverseIndex {
    #[inline]
    fn add_assign(&mut self, other: usize) { *self = *self + other; }
}
impl rustc_index::Idx for UniverseIndex {
    #[inline]
    fn new(value: usize) -> Self { Self::from_usize(value) }
    #[inline]
    fn index(self) -> usize { self.as_usize() }
}
impl ::std::iter::Step for UniverseIndex {
    #[inline]
    fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
        <usize as
                ::std::iter::Step>::steps_between(&Self::index(*start),
            &Self::index(*end))
    }
    #[inline]
    fn forward_checked(start: Self, u: usize) -> Option<Self> {
        Self::index(start).checked_add(u).map(Self::from_usize)
    }
    #[inline]
    fn backward_checked(start: Self, u: usize) -> Option<Self> {
        Self::index(start).checked_sub(u).map(Self::from_usize)
    }
    #[inline]
    fn forward_overflowing(start: Self, u: usize) -> (Self, bool) {
        let (s, o) = Self::index(start).overflowing_add(u);
        (Self::from_usize(s), o)
    }
    #[inline]
    fn backward_overflowing(start: Self, u: usize) -> (Self, bool) {
        let (s, o) = Self::index(start).overflowing_sub(u);
        (Self::from_usize(s), o)
    }
}
impl ::std::cmp::Ord for UniverseIndex {
    #[inline]
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.as_u32().cmp(&other.as_u32())
    }
}
impl ::std::cmp::PartialOrd for UniverseIndex {
    #[inline]
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        Some(self.cmp(other))
    }
}
impl ::rustc_data_structures::stable_hash::StableHash for UniverseIndex {
    fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
        hcx: &mut __Hcx,
        hasher: &mut ::rustc_data_structures::stable_hash::StableHasher) {
        self.as_u32().stable_hash(hcx, hasher)
    }
}
impl From<UniverseIndex> for u32 {
    #[inline]
    fn from(v: UniverseIndex) -> u32 { v.as_u32() }
}
impl From<UniverseIndex> for usize {
    #[inline]
    fn from(v: UniverseIndex) -> usize { v.as_usize() }
}
impl From<usize> for UniverseIndex {
    #[inline]
    fn from(value: usize) -> Self { Self::from_usize(value) }
}
impl From<u32> for UniverseIndex {
    #[inline]
    fn from(value: u32) -> Self { Self::from_u32(value) }
}
impl ::std::cmp::Eq for UniverseIndex {}
impl ::std::cmp::PartialEq for UniverseIndex {
    fn eq(&self, other: &Self) -> bool { self.as_u32().eq(&other.as_u32()) }
}
impl ::std::marker::StructuralPartialEq for UniverseIndex { }
impl ::std::hash::Hash for UniverseIndex {
    fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
        self.as_u32().hash(state)
    }
}
impl<D: ::rustc_serialize::Decoder> ::rustc_serialize::Decodable<D> for
    UniverseIndex {
    fn decode(d: &mut D) -> Self { Self::from_u32(d.read_u32()) }
}
impl<E: ::rustc_serialize::Encoder> ::rustc_serialize::Encodable<E> for
    UniverseIndex {
    fn encode(&self, e: &mut E) { e.emit_u32(self.as_u32()); }
}
impl ::std::fmt::Debug for UniverseIndex {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        fmt.write_fmt(format_args!("U{0}", self.as_u32()))
    }
}rustc_index::newtype_index! {
336    /// "Universes" are used during type- and trait-checking in the
337    /// presence of `for<..>` binders to control what sets of names are
338    /// visible. Universes are arranged into a tree: the root universe
339    /// contains names that are always visible. Each child then adds a new
340    /// set of names that are visible, in addition to those of its parent.
341    /// We say that the child universe "extends" the parent universe with
342    /// new names.
343    ///
344    /// To make this more concrete, consider this program:
345    ///
346    /// ```ignore (illustrative)
347    /// struct Foo { }
348    /// fn bar<T>(x: T) {
349    ///   let y: for<'a> fn(&'a u8, Foo) = ...;
350    /// }
351    /// ```
352    ///
353    /// The struct name `Foo` is in the root universe U0. But the type
354    /// parameter `T`, introduced on `bar`, is in an extended universe U1
355    /// -- i.e., within `bar`, we can name both `T` and `Foo`, but outside
356    /// of `bar`, we cannot name `T`. Then, within the type of `y`, the
357    /// region `'a` is in a universe U2 that extends U1, because we can
358    /// name it inside the fn type but not outside.
359    ///
360    /// Universes are used to do type- and trait-checking around these
361    /// "forall" binders (also called **universal quantification**). The
362    /// idea is that when, in the body of `bar`, we refer to `T` as a
363    /// type, we aren't referring to any type in particular, but rather a
364    /// kind of "fresh" type that is distinct from all other types we have
365    /// actually declared. This is called a **placeholder** type, and we
366    /// use universes to talk about this. In other words, a type name in
367    /// universe 0 always corresponds to some "ground" type that the user
368    /// declared, but a type name in a non-zero universe is a placeholder
369    /// type -- an idealized representative of "types in general" that we
370    /// use for checking generic functions.
371    #[stable_hash]
372    #[encodable]
373    #[orderable]
374    #[debug_format = "U{}"]
375    #[gate_rustc_only]
376    pub struct UniverseIndex {}
377}
378
379impl UniverseIndex {
380    pub const ROOT: UniverseIndex = UniverseIndex::ZERO;
381
382    /// Returns the "next" universe index in order -- this new index
383    /// is considered to extend all previous universes. This
384    /// corresponds to entering a `forall` quantifier. So, for
385    /// example, suppose we have this type in universe `U`:
386    ///
387    /// ```ignore (illustrative)
388    /// for<'a> fn(&'a u32)
389    /// ```
390    ///
391    /// Once we "enter" into this `for<'a>` quantifier, we are in a
392    /// new universe that extends `U` -- in this new universe, we can
393    /// name the region `'a`, but that region was not nameable from
394    /// `U` because it was not in scope there.
395    pub fn next_universe(self) -> UniverseIndex {
396        UniverseIndex::from_u32(self.as_u32().checked_add(1).unwrap())
397    }
398
399    /// Returns `true` if `self` can name a name from `other` -- in other words,
400    /// if the set of names in `self` is a superset of those in
401    /// `other` (`self >= other`).
402    pub fn can_name(self, other: UniverseIndex) -> bool {
403        self >= other
404    }
405
406    /// Returns `true` if `self` cannot name some names from `other` -- in other
407    /// words, if the set of names in `self` is a strict subset of
408    /// those in `other` (`self < other`).
409    pub fn cannot_name(self, other: UniverseIndex) -> bool {
410        self < other
411    }
412
413    /// Returns `true` if `self` is the root universe, otherwise false.
414    pub fn is_root(self) -> bool {
415        self == Self::ROOT
416    }
417}
418
419impl Default for UniverseIndex {
420    fn default() -> Self {
421        Self::ROOT
422    }
423}
424
425#[automatically_derived]
impl ::core::marker::Copy for BoundVar { }
impl BoundVar {
    #[doc = r" Maximum value the index can take, as a `u32`."]
    pub const MAX_AS_U32: u32 = 0xFFFF_FF00;
    #[doc = r" Maximum value the index can take."]
    pub const MAX: Self = Self::from_u32(0xFFFF_FF00);
    #[doc = r" Zero value of the index."]
    pub const ZERO: Self = Self::from_u32(0);
    #[doc = r" Creates a new index from a given `usize`."]
    #[doc = r""]
    #[doc = r" # Panics"]
    #[doc = r""]
    #[doc = r" Will panic if `value` exceeds `MAX`."]
    #[inline]
    pub const fn from_usize(value: usize) -> Self {
        if !(value <= (0xFFFF_FF00 as usize)) {
            ::core::panicking::panic("assertion failed: value <= (0xFFFF_FF00 as usize)")
        };
        unsafe { Self::from_u32_unchecked(value as u32) }
    }
    #[doc = r" Creates a new index from a given `u32`."]
    #[doc = r""]
    #[doc = r" # Panics"]
    #[doc = r""]
    #[doc = r" Will panic if `value` exceeds `MAX`."]
    #[inline]
    pub const fn from_u32(value: u32) -> Self {
        if !(value <= 0xFFFF_FF00) {
            ::core::panicking::panic("assertion failed: value <= 0xFFFF_FF00")
        };
        unsafe { Self::from_u32_unchecked(value) }
    }
    #[doc = r" Creates a new index from a given `u16`."]
    #[doc = r""]
    #[doc = r" # Panics"]
    #[doc = r""]
    #[doc = r" Will panic if `value` exceeds `MAX`."]
    #[inline]
    pub const fn from_u16(value: u16) -> Self {
        let value = value as u32;
        if !(value <= 0xFFFF_FF00) {
            ::core::panicking::panic("assertion failed: value <= 0xFFFF_FF00")
        };
        unsafe { Self::from_u32_unchecked(value) }
    }
    #[doc = r" Creates a new index from a given `u32`."]
    #[doc = r""]
    #[doc = r" # Safety"]
    #[doc = r""]
    #[doc =
    r" The provided value must be less than or equal to the maximum value for the newtype."]
    #[doc =
    r" Providing a value outside this range is undefined due to layout restrictions."]
    #[doc = r""]
    #[doc = r" Prefer using `from_u32`."]
    #[inline]
    pub const unsafe fn from_u32_unchecked(value: u32) -> Self {
        Self {
            private_use_as_methods_instead: unsafe {
                std::mem::transmute(value)
            },
        }
    }
    #[doc = r" Extracts the value of this index as a `usize`."]
    #[inline]
    pub const fn index(self) -> usize { self.as_usize() }
    #[doc = r" Extracts the value of this index as a `u32`."]
    #[inline]
    pub const fn as_u32(self) -> u32 {
        unsafe { std::mem::transmute(self.private_use_as_methods_instead) }
    }
    #[doc = r" Extracts the value of this index as a `usize`."]
    #[inline]
    pub const fn as_usize(self) -> usize { self.as_u32() as usize }
}
impl std::ops::Add<usize> for BoundVar {
    type Output = Self;
    #[inline]
    fn add(self, other: usize) -> Self {
        Self::from_usize(self.index() + other)
    }
}
impl std::ops::AddAssign<usize> for BoundVar {
    #[inline]
    fn add_assign(&mut self, other: usize) { *self = *self + other; }
}
impl rustc_index::Idx for BoundVar {
    #[inline]
    fn new(value: usize) -> Self { Self::from_usize(value) }
    #[inline]
    fn index(self) -> usize { self.as_usize() }
}
impl ::std::iter::Step for BoundVar {
    #[inline]
    fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
        <usize as
                ::std::iter::Step>::steps_between(&Self::index(*start),
            &Self::index(*end))
    }
    #[inline]
    fn forward_checked(start: Self, u: usize) -> Option<Self> {
        Self::index(start).checked_add(u).map(Self::from_usize)
    }
    #[inline]
    fn backward_checked(start: Self, u: usize) -> Option<Self> {
        Self::index(start).checked_sub(u).map(Self::from_usize)
    }
    #[inline]
    fn forward_overflowing(start: Self, u: usize) -> (Self, bool) {
        let (s, o) = Self::index(start).overflowing_add(u);
        (Self::from_usize(s), o)
    }
    #[inline]
    fn backward_overflowing(start: Self, u: usize) -> (Self, bool) {
        let (s, o) = Self::index(start).overflowing_sub(u);
        (Self::from_usize(s), o)
    }
}
impl ::std::cmp::Ord for BoundVar {
    #[inline]
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.as_u32().cmp(&other.as_u32())
    }
}
impl ::std::cmp::PartialOrd for BoundVar {
    #[inline]
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        Some(self.cmp(other))
    }
}
impl ::rustc_data_structures::stable_hash::StableHash for BoundVar {
    fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
        hcx: &mut __Hcx,
        hasher: &mut ::rustc_data_structures::stable_hash::StableHasher) {
        self.as_u32().stable_hash(hcx, hasher)
    }
}
impl From<BoundVar> for u32 {
    #[inline]
    fn from(v: BoundVar) -> u32 { v.as_u32() }
}
impl From<BoundVar> for usize {
    #[inline]
    fn from(v: BoundVar) -> usize { v.as_usize() }
}
impl From<usize> for BoundVar {
    #[inline]
    fn from(value: usize) -> Self { Self::from_usize(value) }
}
impl From<u32> for BoundVar {
    #[inline]
    fn from(value: u32) -> Self { Self::from_u32(value) }
}
impl ::std::cmp::Eq for BoundVar {}
impl ::std::cmp::PartialEq for BoundVar {
    fn eq(&self, other: &Self) -> bool { self.as_u32().eq(&other.as_u32()) }
}
impl ::std::marker::StructuralPartialEq for BoundVar { }
impl ::std::hash::Hash for BoundVar {
    fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
        self.as_u32().hash(state)
    }
}
impl<D: ::rustc_serialize::Decoder> ::rustc_serialize::Decodable<D> for
    BoundVar {
    fn decode(d: &mut D) -> Self { Self::from_u32(d.read_u32()) }
}
impl<E: ::rustc_serialize::Encoder> ::rustc_serialize::Encodable<E> for
    BoundVar {
    fn encode(&self, e: &mut E) { e.emit_u32(self.as_u32()); }
}
impl ::std::fmt::Debug for BoundVar {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        fmt.write_fmt(format_args!("{0}", self.as_u32()))
    }
}rustc_index::newtype_index! {
426    #[stable_hash]
427    #[encodable]
428    #[orderable]
429    #[debug_format = "{}"]
430    #[gate_rustc_only]
431    pub struct BoundVar {}
432}
433
434/// Represents the various closure traits in the language. This
435/// will determine the type of the environment (`self`, in the
436/// desugaring) argument that the closure expects.
437///
438/// You can get the environment type of a closure using
439/// `tcx.closure_env_ty()`.
440#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for ClosureKind { }
#[automatically_derived]
impl ::core::clone::Clone for ClosureKind {
    #[inline]
    fn clone(&self) -> ClosureKind { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for ClosureKind { }Copy, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for ClosureKind { }
#[automatically_derived]
impl ::core::cmp::PartialEq for ClosureKind {
    #[inline]
    fn eq(&self, other: &ClosureKind) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ClosureKind {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for ClosureKind {
    #[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)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for ClosureKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                ClosureKind::Fn => "Fn",
                ClosureKind::FnMut => "FnMut",
                ClosureKind::FnOnce => "FnOnce",
            })
    }
}Debug)]
441#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for ClosureKind {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        ClosureKind::Fn => { 0usize }
                        ClosureKind::FnMut => { 1usize }
                        ClosureKind::FnOnce => { 2usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for ClosureKind {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { ClosureKind::Fn }
                    1usize => { ClosureKind::FnMut }
                    2usize => { ClosureKind::FnOnce }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `ClosureKind`, expected 0..3, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for ClosureKind
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    ClosureKind::Fn => {}
                    ClosureKind::FnMut => {}
                    ClosureKind::FnOnce => {}
                }
            }
        }
    };StableHash))]
442pub enum ClosureKind {
443    Fn,
444    FnMut,
445    FnOnce,
446}
447
448impl ClosureKind {
449    /// This is the initial value used when doing upvar inference.
450    pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn;
451
452    pub const fn as_str(self) -> &'static str {
453        match self {
454            ClosureKind::Fn => "Fn",
455            ClosureKind::FnMut => "FnMut",
456            ClosureKind::FnOnce => "FnOnce",
457        }
458    }
459
460    /// Returns `true` if a type that impls this closure kind
461    /// must also implement `other`.
462    #[rustfmt::skip]
463    pub fn extends(self, other: ClosureKind) -> bool {
464        use ClosureKind::*;
465        match (self, other) {
466              (Fn, Fn | FnMut | FnOnce)
467            | (FnMut,   FnMut | FnOnce)
468            | (FnOnce,          FnOnce) => true,
469            _ => false,
470        }
471    }
472}
473
474impl fmt::Display for ClosureKind {
475    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
476        self.as_str().fmt(f)
477    }
478}
479
480pub struct FieldInfo<I: Interner> {
481    pub base: I::Ty,
482    pub ty: I::Ty,
483    pub variant: Option<I::Symbol>,
484    pub variant_idx: VariantIdx,
485    pub name: I::Symbol,
486    pub field_idx: FieldIdx,
487}