-
Notifications
You must be signed in to change notification settings - Fork 12.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Begin to abstract rustc_type_ir for rust-analyzer
- Loading branch information
1 parent
49691b1
commit 6f43680
Showing
9 changed files
with
337 additions
and
152 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd, Debug)] | ||
pub struct DebruijnIndex { | ||
pub(crate) private: u32, | ||
} | ||
|
||
impl DebruijnIndex { | ||
pub const fn from_u32(u: u32) -> Self { | ||
Self { private: u } | ||
} | ||
|
||
pub const fn as_u32(self) -> u32 { | ||
self.private | ||
} | ||
} | ||
|
||
pub const INNERMOST: DebruijnIndex = DebruijnIndex { private: 0 }; | ||
|
||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd, Debug)] | ||
pub struct UniverseIndex { | ||
pub(crate) private: u32, | ||
} | ||
|
||
impl UniverseIndex { | ||
pub const fn from_u32(u: u32) -> Self { | ||
Self { private: u } | ||
} | ||
|
||
pub const fn as_u32(self) -> u32 { | ||
self.private | ||
} | ||
} | ||
|
||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd, Debug)] | ||
pub struct TyVid { | ||
pub(crate) private: u32, | ||
} | ||
|
||
impl TyVid { | ||
pub const fn from_u32(u: u32) -> Self { | ||
Self { private: u } | ||
} | ||
|
||
pub const fn as_u32(self) -> u32 { | ||
self.private | ||
} | ||
} | ||
|
||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd, Debug)] | ||
pub struct FloatVid { | ||
pub(crate) private: u32, | ||
} | ||
|
||
impl FloatVid { | ||
pub const fn from_u32(u: u32) -> Self { | ||
Self { private: u } | ||
} | ||
|
||
pub const fn as_u32(self) -> u32 { | ||
self.private | ||
} | ||
} | ||
|
||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd, Debug)] | ||
pub struct IntVid { | ||
pub(crate) private: u32, | ||
} | ||
|
||
impl IntVid { | ||
pub const fn from_u32(u: u32) -> Self { | ||
Self { private: u } | ||
} | ||
|
||
pub const fn as_u32(self) -> u32 { | ||
self.private | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
rustc_index::newtype_index! { | ||
/// A [De Bruijn index][dbi] is a standard means of representing | ||
/// regions (and perhaps later types) in a higher-ranked setting. In | ||
/// particular, imagine a type like this: | ||
/// ```ignore (illustrative) | ||
/// for<'a> fn(for<'b> fn(&'b isize, &'a isize), &'a char) | ||
/// // ^ ^ | | | | ||
/// // | | | | | | ||
/// // | +------------+ 0 | | | ||
/// // | | | | ||
/// // +----------------------------------+ 1 | | ||
/// // | | | ||
/// // +----------------------------------------------+ 0 | ||
/// ``` | ||
/// In this type, there are two binders (the outer fn and the inner | ||
/// fn). We need to be able to determine, for any given region, which | ||
/// fn type it is bound by, the inner or the outer one. There are | ||
/// various ways you can do this, but a De Bruijn index is one of the | ||
/// more convenient and has some nice properties. The basic idea is to | ||
/// count the number of binders, inside out. Some examples should help | ||
/// clarify what I mean. | ||
/// | ||
/// Let's start with the reference type `&'b isize` that is the first | ||
/// argument to the inner function. This region `'b` is assigned a De | ||
/// Bruijn index of 0, meaning "the innermost binder" (in this case, a | ||
/// fn). The region `'a` that appears in the second argument type (`&'a | ||
/// isize`) would then be assigned a De Bruijn index of 1, meaning "the | ||
/// second-innermost binder". (These indices are written on the arrows | ||
/// in the diagram). | ||
/// | ||
/// What is interesting is that De Bruijn index attached to a particular | ||
/// variable will vary depending on where it appears. For example, | ||
/// the final type `&'a char` also refers to the region `'a` declared on | ||
/// the outermost fn. But this time, this reference is not nested within | ||
/// any other binders (i.e., it is not an argument to the inner fn, but | ||
/// rather the outer one). Therefore, in this case, it is assigned a | ||
/// De Bruijn index of 0, because the innermost binder in that location | ||
/// is the outer fn. | ||
/// | ||
/// [dbi]: https://en.wikipedia.org/wiki/De_Bruijn_index | ||
#[derive(HashStable_Generic)] | ||
#[debug_format = "DebruijnIndex({})"] | ||
pub struct DebruijnIndex { | ||
const INNERMOST = 0; | ||
} | ||
} | ||
|
||
rustc_index::newtype_index! { | ||
/// A **ty**pe **v**ariable **ID**. | ||
#[debug_format = "?{}t"] | ||
pub struct TyVid {} | ||
} | ||
|
||
rustc_index::newtype_index! { | ||
/// An **int**egral (`u32`, `i32`, `usize`, etc.) type **v**ariable **ID**. | ||
#[debug_format = "?{}i"] | ||
pub struct IntVid {} | ||
} | ||
|
||
rustc_index::newtype_index! { | ||
/// A **float**ing-point (`f32` or `f64`) type **v**ariable **ID**. | ||
#[debug_format = "?{}f"] | ||
pub struct FloatVid {} | ||
} | ||
|
||
rustc_index::newtype_index! { | ||
/// "Universes" are used during type- and trait-checking in the | ||
/// presence of `for<..>` binders to control what sets of names are | ||
/// visible. Universes are arranged into a tree: the root universe | ||
/// contains names that are always visible. Each child then adds a new | ||
/// set of names that are visible, in addition to those of its parent. | ||
/// We say that the child universe "extends" the parent universe with | ||
/// new names. | ||
/// | ||
/// To make this more concrete, consider this program: | ||
/// | ||
/// ```ignore (illustrative) | ||
/// struct Foo { } | ||
/// fn bar<T>(x: T) { | ||
/// let y: for<'a> fn(&'a u8, Foo) = ...; | ||
/// } | ||
/// ``` | ||
/// | ||
/// The struct name `Foo` is in the root universe U0. But the type | ||
/// parameter `T`, introduced on `bar`, is in an extended universe U1 | ||
/// -- i.e., within `bar`, we can name both `T` and `Foo`, but outside | ||
/// of `bar`, we cannot name `T`. Then, within the type of `y`, the | ||
/// region `'a` is in a universe U2 that extends U1, because we can | ||
/// name it inside the fn type but not outside. | ||
/// | ||
/// Universes are used to do type- and trait-checking around these | ||
/// "forall" binders (also called **universal quantification**). The | ||
/// idea is that when, in the body of `bar`, we refer to `T` as a | ||
/// type, we aren't referring to any type in particular, but rather a | ||
/// kind of "fresh" type that is distinct from all other types we have | ||
/// actually declared. This is called a **placeholder** type, and we | ||
/// use universes to talk about this. In other words, a type name in | ||
/// universe 0 always corresponds to some "ground" type that the user | ||
/// declared, but a type name in a non-zero universe is a placeholder | ||
/// type -- an idealized representative of "types in general" that we | ||
/// use for checking generic functions. | ||
#[derive(HashStable_Generic)] | ||
#[debug_format = "U{}"] | ||
pub struct UniverseIndex {} | ||
} |
Oops, something went wrong.