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).
2122#![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// NOTE: the outer `cfg_attr` is only there so that r-a doesn't see the nightly-only `bootstrap`
31// in the inner `cfg_attr`. When the latter is removed, the former can be removed as well.
32#![cfg_attr(
33 feature = "nightly",
34 cfg_attr(not(bootstrap), deny(rustc::missing_generic_type_visitable_derive))
35)]
36// tidy-alphabetical-end
3738extern crate self as rustc_type_ir;
3940use std::fmt;
41use std::hash::Hash;
4243use rustc_abi::{FieldIdx, VariantIdx};
44#[cfg(feature = "nightly")]
45use rustc_macros::{Decodable, Encodable, StableHash};
4647// These modules are `pub` since they are not glob-imported.
48pub mod data_structures;
49pub mod elaborate;
50pub mod error;
51pub mod fast_reject;
52#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "type_ir_inherent")]
53pub mod inherent;
54pub mod intern;
55pub mod ir_print;
56pub mod lang_items;
57pub mod lift;
58pub mod outlives;
59pub mod region_constraint;
60pub mod relate;
61pub mod search_graph;
62pub mod solve;
63pub mod sty;
64pub mod transmute;
65pub mod walk;
6667// These modules are not `pub` since they are glob-imported.
68#[macro_use]
69mod macros;
70mod binder;
71mod canonical;
72mod const_kind;
73mod flags;
74mod fold;
75mod generic_arg;
76mod generic_visit;
77mod infer_ctxt;
78mod interner;
79mod opaque_ty;
80mod pattern;
81mod predicate;
82mod predicate_kind;
83mod region_kind;
84#[cfg(feature = "nightly")]
85mod serialize;
86mod term_kind;
87mod ty;
88mod ty_info;
89mod ty_kind;
90mod universe;
91mod unnormalized;
92mod upcast;
93mod visit;
9495pub use AliasTyKind::*;
96pub use InferTy::*;
97pub use RegionKind::*;
98pub use TyKind::*;
99pub use Variance::*;
100pub use binder::{Placeholder, *};
101pub use canonical::*;
102pub use const_kind::*;
103pub use flags::*;
104pub use fold::*;
105pub use generic_arg::*;
106pub use generic_visit::*;
107pub use infer_ctxt::*;
108pub use interner::*;
109pub use opaque_ty::*;
110pub use pattern::*;
111pub use predicate::*;
112pub use predicate_kind::*;
113pub use region_kind::*;
114pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy};
115#[cfg(feature = "nightly")]
116pub use serialize::*;
117pub use sty::*;
118pub use term_kind::*;
119pub use ty::{Alias, *};
120pub use ty_info::*;
121pub use ty_kind::*;
122pub use universe::*;
123pub use unnormalized::Unnormalized;
124pub use upcast::*;
125pub use visit::*;
126127#[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! {
128/// A [De Bruijn index][dbi] is a standard means of representing
129 /// regions (and perhaps later types) in a higher-ranked setting. In
130 /// particular, imagine a type like this:
131 /// ```ignore (illustrative)
132 /// for<'a> fn(for<'b> fn(&'b isize, &'a isize), &'a char)
133 /// // ^ ^ | | |
134 /// // | | | | |
135 /// // | +------------+ 0 | |
136 /// // | | |
137 /// // +----------------------------------+ 1 |
138 /// // | |
139 /// // +----------------------------------------------+ 0
140 /// ```
141 /// In this type, there are two binders (the outer fn and the inner
142 /// fn). We need to be able to determine, for any given region, which
143 /// fn type it is bound by, the inner or the outer one. There are
144 /// various ways you can do this, but a De Bruijn index is one of the
145 /// more convenient and has some nice properties. The basic idea is to
146 /// count the number of binders, inside out. Some examples should help
147 /// clarify what I mean.
148 ///
149 /// Let's start with the reference type `&'b isize` that is the first
150 /// argument to the inner function. This region `'b` is assigned a De
151 /// Bruijn index of 0, meaning "the innermost binder" (in this case, a
152 /// fn). The region `'a` that appears in the second argument type (`&'a
153 /// isize`) would then be assigned a De Bruijn index of 1, meaning "the
154 /// second-innermost binder". (These indices are written on the arrows
155 /// in the diagram).
156 ///
157 /// What is interesting is that De Bruijn index attached to a particular
158 /// variable will vary depending on where it appears. For example,
159 /// the final type `&'a char` also refers to the region `'a` declared on
160 /// the outermost fn. But this time, this reference is not nested within
161 /// any other binders (i.e., it is not an argument to the inner fn, but
162 /// rather the outer one). Therefore, in this case, it is assigned a
163 /// De Bruijn index of 0, because the innermost binder in that location
164 /// is the outer fn.
165 ///
166 /// [dbi]: https://en.wikipedia.org/wiki/De_Bruijn_index
167#[stable_hash]
168 #[encodable]
169 #[orderable]
170 #[debug_format = "DebruijnIndex({})"]
171 #[gate_rustc_only]
172pub struct DebruijnIndex {
173const INNERMOST = 0;
174 }
175}176177impl DebruijnIndex {
178/// Returns the resulting index when this value is moved into
179 /// `amount` number of new binders. So, e.g., if you had
180 ///
181 /// for<'a> fn(&'a x)
182 ///
183 /// and you wanted to change it to
184 ///
185 /// for<'a> fn(for<'b> fn(&'a x))
186 ///
187 /// you would need to shift the index for `'a` into a new binder.
188#[inline]
189 #[must_use]
190pub fn shifted_in(self, amount: u32) -> DebruijnIndex {
191DebruijnIndex::from_u32(self.as_u32() + amount)
192 }
193194/// Update this index in place by shifting it "in" through
195 /// `amount` number of binders.
196#[inline]
197pub fn shift_in(&mut self, amount: u32) {
198*self = self.shifted_in(amount);
199 }
200201/// Returns the resulting index when this value is moved out from
202 /// `amount` number of new binders.
203#[inline]
204 #[must_use]
205pub fn shifted_out(self, amount: u32) -> DebruijnIndex {
206DebruijnIndex::from_u32(self.as_u32() - amount)
207 }
208209/// Update in place by shifting out from `amount` binders.
210#[inline]
211pub fn shift_out(&mut self, amount: u32) {
212*self = self.shifted_out(amount);
213 }
214215/// Adjusts any De Bruijn indices so as to make `to_binder` the
216 /// innermost binder. That is, if we have something bound at `to_binder`,
217 /// it will now be bound at INNERMOST. This is an appropriate thing to do
218 /// when moving a region out from inside binders:
219 ///
220 /// ```ignore (illustrative)
221 /// for<'a> fn(for<'b> for<'c> fn(&'a u32), _)
222 /// // Binder: D3 D2 D1 ^^
223 /// ```
224 ///
225 /// Here, the region `'a` would have the De Bruijn index D3,
226 /// because it is the bound 3 binders out. However, if we wanted
227 /// to refer to that region `'a` in the second argument (the `_`),
228 /// those two binders would not be in scope. In that case, we
229 /// might invoke `shift_out_to_binder(D3)`. This would adjust the
230 /// De Bruijn index of `'a` to D1 (the innermost binder).
231 ///
232 /// If we invoke `shift_out_to_binder` and the region is in fact
233 /// bound by one of the binders we are shifting out of, that is an
234 /// error (and should fail an assertion failure).
235#[inline]
236pub fn shifted_out_to_binder(self, to_binder: DebruijnIndex) -> Self {
237self.shifted_out(to_binder.as_u32() - INNERMOST.as_u32())
238 }
239}
240241pub fn debug_bound_var<T: std::fmt::Write>(
242 fmt: &mut T,
243 bound_index: BoundVarIndexKind,
244 var: impl std::fmt::Debug,
245) -> Result<(), std::fmt::Error> {
246match bound_index {
247 BoundVarIndexKind::Bound(debruijn) => {
248if debruijn == INNERMOST {
249fmt.write_fmt(format_args!("^{0:?}", var))write!(fmt, "^{var:?}")250 } else {
251fmt.write_fmt(format_args!("^{0}_{1:?}", debruijn.index(), var))write!(fmt, "^{}_{:?}", debruijn.index(), var)252 }
253 }
254 BoundVarIndexKind::Canonical => {
255fmt.write_fmt(format_args!("^c_{0:?}", var))write!(fmt, "^c_{:?}", var)256 }
257 }
258}
259260#[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) -> Self { *self }
}Clone, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for Variance { }
#[automatically_derived]
impl ::core::cmp::PartialEq for Variance {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other)
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Variance { }Eq, #[automatically_derived]
impl ::core::hash::Hash for Variance {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&::core::intrinsics::discriminant_value(self),
state)
}
}Hash)]
261#[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))]
262#[cfg_attr(feature = "nightly", rustc_pass_by_value)]
263pub enum Variance {
264 Covariant, // T<A> <: T<B> iff A <: B -- e.g., function return type
265Invariant, // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
266Contravariant, // T<A> <: T<B> iff B <: A -- e.g., function param type
267Bivariant, // T<A> <: T<B> -- e.g., unused type parameter
268}
269270impl Variance {
271/// `a.xform(b)` combines the variance of a context with the
272 /// variance of a type with the following meaning. If we are in a
273 /// context with variance `a`, and we encounter a type argument in
274 /// a position with variance `b`, then `a.xform(b)` is the new
275 /// variance with which the argument appears.
276 ///
277 /// Example 1:
278 /// ```ignore (illustrative)
279 /// *mut Vec<i32>
280 /// ```
281 /// Here, the "ambient" variance starts as covariant. `*mut T` is
282 /// invariant with respect to `T`, so the variance in which the
283 /// `Vec<i32>` appears is `Covariant.xform(Invariant)`, which
284 /// yields `Invariant`. Now, the type `Vec<T>` is covariant with
285 /// respect to its type argument `T`, and hence the variance of
286 /// the `i32` here is `Invariant.xform(Covariant)`, which results
287 /// (again) in `Invariant`.
288 ///
289 /// Example 2:
290 /// ```ignore (illustrative)
291 /// fn(*const Vec<i32>, *mut Vec<i32)
292 /// ```
293 /// The ambient variance is covariant. A `fn` type is
294 /// contravariant with respect to its parameters, so the variance
295 /// within which both pointer types appear is
296 /// `Covariant.xform(Contravariant)`, or `Contravariant`. `*const
297 /// T` is covariant with respect to `T`, so the variance within
298 /// which the first `Vec<i32>` appears is
299 /// `Contravariant.xform(Covariant)` or `Contravariant`. The same
300 /// is true for its `i32` argument. In the `*mut T` case, the
301 /// variance of `Vec<i32>` is `Contravariant.xform(Invariant)`,
302 /// and hence the outermost type is `Invariant` with respect to
303 /// `Vec<i32>` (and its `i32` argument).
304 ///
305 /// Source: Figure 1 of "Taming the Wildcards:
306 /// Combining Definition- and Use-Site Variance" published in PLDI'11.
307pub fn xform(self, v: Variance) -> Variance {
308match (self, v) {
309// Figure 1, column 1.
310(Variance::Covariant, Variance::Covariant) => Variance::Covariant,
311 (Variance::Covariant, Variance::Contravariant) => Variance::Contravariant,
312 (Variance::Covariant, Variance::Invariant) => Variance::Invariant,
313 (Variance::Covariant, Variance::Bivariant) => Variance::Bivariant,
314315// Figure 1, column 2.
316(Variance::Contravariant, Variance::Covariant) => Variance::Contravariant,
317 (Variance::Contravariant, Variance::Contravariant) => Variance::Covariant,
318 (Variance::Contravariant, Variance::Invariant) => Variance::Invariant,
319 (Variance::Contravariant, Variance::Bivariant) => Variance::Bivariant,
320321// Figure 1, column 3.
322(Variance::Invariant, _) => Variance::Invariant,
323324// Figure 1, column 4.
325(Variance::Bivariant, _) => Variance::Bivariant,
326 }
327 }
328}
329330impl fmt::Debugfor Variance {
331fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
332f.write_str(match *self {
333 Variance::Covariant => "+",
334 Variance::Contravariant => "-",
335 Variance::Invariant => "o",
336 Variance::Bivariant => "*",
337 })
338 }
339}
340341#[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! {
342/// "Universes" are used during type- and trait-checking in the
343 /// presence of `for<..>` binders to control what sets of names are
344 /// visible. Universes are arranged into a tree: the root universe
345 /// contains names that are always visible. Each child then adds a new
346 /// set of names that are visible, in addition to those of its parent.
347 /// We say that the child universe "extends" the parent universe with
348 /// new names.
349 ///
350 /// To make this more concrete, consider this program:
351 ///
352 /// ```ignore (illustrative)
353 /// struct Foo { }
354 /// fn bar<T>(x: T) {
355 /// let y: for<'a> fn(&'a u8, Foo) = ...;
356 /// }
357 /// ```
358 ///
359 /// The struct name `Foo` is in the root universe U0. But the type
360 /// parameter `T`, introduced on `bar`, is in an extended universe U1
361 /// -- i.e., within `bar`, we can name both `T` and `Foo`, but outside
362 /// of `bar`, we cannot name `T`. Then, within the type of `y`, the
363 /// region `'a` is in a universe U2 that extends U1, because we can
364 /// name it inside the fn type but not outside.
365 ///
366 /// Universes are used to do type- and trait-checking around these
367 /// "forall" binders (also called **universal quantification**). The
368 /// idea is that when, in the body of `bar`, we refer to `T` as a
369 /// type, we aren't referring to any type in particular, but rather a
370 /// kind of "fresh" type that is distinct from all other types we have
371 /// actually declared. This is called a **placeholder** type, and we
372 /// use universes to talk about this. In other words, a type name in
373 /// universe 0 always corresponds to some "ground" type that the user
374 /// declared, but a type name in a non-zero universe is a placeholder
375 /// type -- an idealized representative of "types in general" that we
376 /// use for checking generic functions.
377#[stable_hash]
378 #[encodable]
379 #[orderable]
380 #[debug_format = "U{}"]
381 #[gate_rustc_only]
382pub struct UniverseIndex {}
383}384385impl UniverseIndex {
386pub const ROOT: UniverseIndex = UniverseIndex::ZERO;
387388/// Returns the "next" universe index in order -- this new index
389 /// is considered to extend all previous universes. This
390 /// corresponds to entering a `forall` quantifier. So, for
391 /// example, suppose we have this type in universe `U`:
392 ///
393 /// ```ignore (illustrative)
394 /// for<'a> fn(&'a u32)
395 /// ```
396 ///
397 /// Once we "enter" into this `for<'a>` quantifier, we are in a
398 /// new universe that extends `U` -- in this new universe, we can
399 /// name the region `'a`, but that region was not nameable from
400 /// `U` because it was not in scope there.
401pub fn next_universe(self) -> UniverseIndex {
402UniverseIndex::from_u32(self.as_u32().checked_add(1).unwrap())
403 }
404405/// Returns `true` if `self` can name a name from `other` -- in other words,
406 /// if the set of names in `self` is a superset of those in
407 /// `other` (`self >= other`).
408pub fn can_name(self, other: UniverseIndex) -> bool {
409self >= other410 }
411412/// Returns `true` if `self` cannot name some names from `other` -- in other
413 /// words, if the set of names in `self` is a strict subset of
414 /// those in `other` (`self < other`).
415pub fn cannot_name(self, other: UniverseIndex) -> bool {
416self < other417 }
418419/// Returns `true` if `self` is the root universe, otherwise false.
420pub fn is_root(self) -> bool {
421self == Self::ROOT422 }
423}
424425impl Defaultfor UniverseIndex {
426fn default() -> Self {
427Self::ROOT428 }
429}
430431#[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! {
432#[stable_hash]
433 #[encodable]
434 #[orderable]
435 #[debug_format = "{}"]
436 #[gate_rustc_only]
437pub struct BoundVar {}
438}439440/// Represents the various closure traits in the language. This
441/// will determine the type of the environment (`self`, in the
442/// desugaring) argument that the closure expects.
443///
444/// You can get the environment type of a closure using
445/// `tcx.closure_env_ty()`.
446#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for ClosureKind { }
#[automatically_derived]
impl ::core::clone::Clone for ClosureKind {
#[inline]
fn clone(&self) -> Self { *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: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other)
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ClosureKind { }Eq, #[automatically_derived]
impl ::core::hash::Hash for ClosureKind {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&::core::intrinsics::discriminant_value(self),
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)]
447#[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))]
448pub enum ClosureKind {
449 Fn,
450 FnMut,
451 FnOnce,
452}
453454impl ClosureKind {
455/// This is the initial value used when doing upvar inference.
456pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn;
457458pub const fn as_str(self) -> &'static str {
459match self {
460 ClosureKind::Fn => "Fn",
461 ClosureKind::FnMut => "FnMut",
462 ClosureKind::FnOnce => "FnOnce",
463 }
464 }
465466/// Returns `true` if a type that impls this closure kind
467 /// must also implement `other`.
468#[rustfmt::skip]
469pub fn extends(self, other: ClosureKind) -> bool {
470use ClosureKind::*;
471match (self, other) {
472 (Fn, Fn | FnMut | FnOnce)
473 | (FnMut, FnMut | FnOnce)
474 | (FnOnce, FnOnce) => true,
475_ => false,
476 }
477 }
478}
479480impl fmt::Displayfor ClosureKind {
481fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
482self.as_str().fmt(f)
483 }
484}
485486pub struct FieldInfo<I: Interner> {
487pub base: I::Ty,
488pub ty: I::Ty,
489pub variant: Option<I::Symbol>,
490pub variant_idx: VariantIdx,
491pub name: I::Symbol,
492pub field_idx: FieldIdx,
493}