Skip to content

Commit 3f2088a

Browse files
committed
Auto merge of #79169 - LeSeulArtichaut:ty-lib, r=nikomatsakis
Create `rustc_type_ir` Decided to start small 😄 This PR creates a `rustc_type_ir` crate as part of the WG-Traits plan to create a shared type library. ~~There already exists a `rustc_ty` crate, so I named the new crate `rustc_ty_library`. However I think it would make sense to rename the current `rustc_ty` to something else (e.g. `rustc_ty_passes`) to free the name for this new crate.~~ r? `@jackh726`
2 parents c3ed668 + 0cf5a8a commit 3f2088a

File tree

6 files changed

+234
-194
lines changed

6 files changed

+234
-194
lines changed

Cargo.lock

+11
Original file line numberDiff line numberDiff line change
@@ -3932,6 +3932,7 @@ dependencies = [
39323932
"rustc_session",
39333933
"rustc_span",
39343934
"rustc_target",
3935+
"rustc_type_ir",
39353936
"smallvec 1.4.2",
39363937
"tracing",
39373938
]
@@ -4266,6 +4267,16 @@ dependencies = [
42664267
"tracing",
42674268
]
42684269

4270+
[[package]]
4271+
name = "rustc_type_ir"
4272+
version = "0.0.0"
4273+
dependencies = [
4274+
"bitflags",
4275+
"rustc_data_structures",
4276+
"rustc_index",
4277+
"rustc_serialize",
4278+
]
4279+
42694280
[[package]]
42704281
name = "rustc_typeck"
42714282
version = "0.0.0"

compiler/rustc_middle/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,4 @@ chalk-ir = "0.36.0"
3030
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
3131
measureme = "9.0.0"
3232
rustc_session = { path = "../rustc_session" }
33+
rustc_type_ir = { path = "../rustc_type_ir" }

compiler/rustc_middle/src/ty/mod.rs

+2-86
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub use self::sty::InferTy::*;
5656
pub use self::sty::RegionKind;
5757
pub use self::sty::RegionKind::*;
5858
pub use self::sty::TyKind::*;
59-
pub use self::sty::{Binder, BoundTy, BoundTyKind, BoundVar, DebruijnIndex, INNERMOST};
59+
pub use self::sty::{Binder, BoundTy, BoundTyKind, BoundVar};
6060
pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
6161
pub use self::sty::{CanonicalPolyFnSig, FnSig, GenSig, PolyFnSig, PolyGenSig};
6262
pub use self::sty::{ClosureSubsts, GeneratorSubsts, TypeAndMut, UpvarSubsts};
@@ -67,6 +67,7 @@ pub use self::sty::{ExistentialProjection, PolyExistentialProjection};
6767
pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef};
6868
pub use self::sty::{PolyTraitRef, TraitRef, TyKind};
6969
pub use crate::ty::diagnostics::*;
70+
pub use rustc_type_ir::{DebruijnIndex, TypeFlags, INNERMOST};
7071

7172
pub use self::binding::BindingMode;
7273
pub use self::binding::BindingMode::*;
@@ -497,91 +498,6 @@ pub struct CReaderCacheKey {
497498
pub pos: usize,
498499
}
499500

500-
bitflags! {
501-
/// Flags that we track on types. These flags are propagated upwards
502-
/// through the type during type construction, so that we can quickly check
503-
/// whether the type has various kinds of types in it without recursing
504-
/// over the type itself.
505-
pub struct TypeFlags: u32 {
506-
// Does this have parameters? Used to determine whether substitution is
507-
// required.
508-
/// Does this have [Param]?
509-
const HAS_TY_PARAM = 1 << 0;
510-
/// Does this have [ReEarlyBound]?
511-
const HAS_RE_PARAM = 1 << 1;
512-
/// Does this have [ConstKind::Param]?
513-
const HAS_CT_PARAM = 1 << 2;
514-
515-
const NEEDS_SUBST = TypeFlags::HAS_TY_PARAM.bits
516-
| TypeFlags::HAS_RE_PARAM.bits
517-
| TypeFlags::HAS_CT_PARAM.bits;
518-
519-
/// Does this have [Infer]?
520-
const HAS_TY_INFER = 1 << 3;
521-
/// Does this have [ReVar]?
522-
const HAS_RE_INFER = 1 << 4;
523-
/// Does this have [ConstKind::Infer]?
524-
const HAS_CT_INFER = 1 << 5;
525-
526-
/// Does this have inference variables? Used to determine whether
527-
/// inference is required.
528-
const NEEDS_INFER = TypeFlags::HAS_TY_INFER.bits
529-
| TypeFlags::HAS_RE_INFER.bits
530-
| TypeFlags::HAS_CT_INFER.bits;
531-
532-
/// Does this have [Placeholder]?
533-
const HAS_TY_PLACEHOLDER = 1 << 6;
534-
/// Does this have [RePlaceholder]?
535-
const HAS_RE_PLACEHOLDER = 1 << 7;
536-
/// Does this have [ConstKind::Placeholder]?
537-
const HAS_CT_PLACEHOLDER = 1 << 8;
538-
539-
/// `true` if there are "names" of regions and so forth
540-
/// that are local to a particular fn/inferctxt
541-
const HAS_FREE_LOCAL_REGIONS = 1 << 9;
542-
543-
/// `true` if there are "names" of types and regions and so forth
544-
/// that are local to a particular fn
545-
const HAS_FREE_LOCAL_NAMES = TypeFlags::HAS_TY_PARAM.bits
546-
| TypeFlags::HAS_CT_PARAM.bits
547-
| TypeFlags::HAS_TY_INFER.bits
548-
| TypeFlags::HAS_CT_INFER.bits
549-
| TypeFlags::HAS_TY_PLACEHOLDER.bits
550-
| TypeFlags::HAS_CT_PLACEHOLDER.bits
551-
| TypeFlags::HAS_FREE_LOCAL_REGIONS.bits;
552-
553-
/// Does this have [Projection]?
554-
const HAS_TY_PROJECTION = 1 << 10;
555-
/// Does this have [Opaque]?
556-
const HAS_TY_OPAQUE = 1 << 11;
557-
/// Does this have [ConstKind::Unevaluated]?
558-
const HAS_CT_PROJECTION = 1 << 12;
559-
560-
/// Could this type be normalized further?
561-
const HAS_PROJECTION = TypeFlags::HAS_TY_PROJECTION.bits
562-
| TypeFlags::HAS_TY_OPAQUE.bits
563-
| TypeFlags::HAS_CT_PROJECTION.bits;
564-
565-
/// Is an error type/const reachable?
566-
const HAS_ERROR = 1 << 13;
567-
568-
/// Does this have any region that "appears free" in the type?
569-
/// Basically anything but [ReLateBound] and [ReErased].
570-
const HAS_FREE_REGIONS = 1 << 14;
571-
572-
/// Does this have any [ReLateBound] regions? Used to check
573-
/// if a global bound is safe to evaluate.
574-
const HAS_RE_LATE_BOUND = 1 << 15;
575-
576-
/// Does this have any [ReErased] regions?
577-
const HAS_RE_ERASED = 1 << 16;
578-
579-
/// Does this value have parameters/placeholders/inference variables which could be
580-
/// replaced later, in a way that would change the results of `impl` specialization?
581-
const STILL_FURTHER_SPECIALIZABLE = 1 << 17;
582-
}
583-
}
584-
585501
#[allow(rustc::usage_of_ty_tykind)]
586502
pub struct TyS<'tcx> {
587503
/// This field shouldn't be used directly and may be removed in the future.

compiler/rustc_middle/src/ty/sty.rs

+2-108
Original file line numberDiff line numberDiff line change
@@ -1289,53 +1289,6 @@ impl<'tcx> ParamConst {
12891289
}
12901290
}
12911291

1292-
rustc_index::newtype_index! {
1293-
/// A [De Bruijn index][dbi] is a standard means of representing
1294-
/// regions (and perhaps later types) in a higher-ranked setting. In
1295-
/// particular, imagine a type like this:
1296-
///
1297-
/// for<'a> fn(for<'b> fn(&'b isize, &'a isize), &'a char)
1298-
/// ^ ^ | | |
1299-
/// | | | | |
1300-
/// | +------------+ 0 | |
1301-
/// | | |
1302-
/// +----------------------------------+ 1 |
1303-
/// | |
1304-
/// +----------------------------------------------+ 0
1305-
///
1306-
/// In this type, there are two binders (the outer fn and the inner
1307-
/// fn). We need to be able to determine, for any given region, which
1308-
/// fn type it is bound by, the inner or the outer one. There are
1309-
/// various ways you can do this, but a De Bruijn index is one of the
1310-
/// more convenient and has some nice properties. The basic idea is to
1311-
/// count the number of binders, inside out. Some examples should help
1312-
/// clarify what I mean.
1313-
///
1314-
/// Let's start with the reference type `&'b isize` that is the first
1315-
/// argument to the inner function. This region `'b` is assigned a De
1316-
/// Bruijn index of 0, meaning "the innermost binder" (in this case, a
1317-
/// fn). The region `'a` that appears in the second argument type (`&'a
1318-
/// isize`) would then be assigned a De Bruijn index of 1, meaning "the
1319-
/// second-innermost binder". (These indices are written on the arrays
1320-
/// in the diagram).
1321-
///
1322-
/// What is interesting is that De Bruijn index attached to a particular
1323-
/// variable will vary depending on where it appears. For example,
1324-
/// the final type `&'a char` also refers to the region `'a` declared on
1325-
/// the outermost fn. But this time, this reference is not nested within
1326-
/// any other binders (i.e., it is not an argument to the inner fn, but
1327-
/// rather the outer one). Therefore, in this case, it is assigned a
1328-
/// De Bruijn index of 0, because the innermost binder in that location
1329-
/// is the outer fn.
1330-
///
1331-
/// [dbi]: https://en.wikipedia.org/wiki/De_Bruijn_index
1332-
#[derive(HashStable)]
1333-
pub struct DebruijnIndex {
1334-
DEBUG_FORMAT = "DebruijnIndex({})",
1335-
const INNERMOST = 0,
1336-
}
1337-
}
1338-
13391292
pub type Region<'tcx> = &'tcx RegionKind;
13401293

13411294
/// Representation of regions. Note that the NLL checker uses a distinct
@@ -1450,7 +1403,7 @@ pub enum RegionKind {
14501403

14511404
/// Region bound in a function scope, which will be substituted when the
14521405
/// function is called.
1453-
ReLateBound(DebruijnIndex, BoundRegion),
1406+
ReLateBound(ty::DebruijnIndex, BoundRegion),
14541407

14551408
/// When checking a function body, the types of all arguments and so forth
14561409
/// that refer to bound region parameters are modified to refer to free
@@ -1614,65 +1567,6 @@ impl<'tcx> PolyExistentialProjection<'tcx> {
16141567
}
16151568
}
16161569

1617-
impl DebruijnIndex {
1618-
/// Returns the resulting index when this value is moved into
1619-
/// `amount` number of new binders. So, e.g., if you had
1620-
///
1621-
/// for<'a> fn(&'a x)
1622-
///
1623-
/// and you wanted to change it to
1624-
///
1625-
/// for<'a> fn(for<'b> fn(&'a x))
1626-
///
1627-
/// you would need to shift the index for `'a` into a new binder.
1628-
#[must_use]
1629-
pub fn shifted_in(self, amount: u32) -> DebruijnIndex {
1630-
DebruijnIndex::from_u32(self.as_u32() + amount)
1631-
}
1632-
1633-
/// Update this index in place by shifting it "in" through
1634-
/// `amount` number of binders.
1635-
pub fn shift_in(&mut self, amount: u32) {
1636-
*self = self.shifted_in(amount);
1637-
}
1638-
1639-
/// Returns the resulting index when this value is moved out from
1640-
/// `amount` number of new binders.
1641-
#[must_use]
1642-
pub fn shifted_out(self, amount: u32) -> DebruijnIndex {
1643-
DebruijnIndex::from_u32(self.as_u32() - amount)
1644-
}
1645-
1646-
/// Update in place by shifting out from `amount` binders.
1647-
pub fn shift_out(&mut self, amount: u32) {
1648-
*self = self.shifted_out(amount);
1649-
}
1650-
1651-
/// Adjusts any De Bruijn indices so as to make `to_binder` the
1652-
/// innermost binder. That is, if we have something bound at `to_binder`,
1653-
/// it will now be bound at INNERMOST. This is an appropriate thing to do
1654-
/// when moving a region out from inside binders:
1655-
///
1656-
/// ```
1657-
/// for<'a> fn(for<'b> for<'c> fn(&'a u32), _)
1658-
/// // Binder: D3 D2 D1 ^^
1659-
/// ```
1660-
///
1661-
/// Here, the region `'a` would have the De Bruijn index D3,
1662-
/// because it is the bound 3 binders out. However, if we wanted
1663-
/// to refer to that region `'a` in the second argument (the `_`),
1664-
/// those two binders would not be in scope. In that case, we
1665-
/// might invoke `shift_out_to_binder(D3)`. This would adjust the
1666-
/// De Bruijn index of `'a` to D1 (the innermost binder).
1667-
///
1668-
/// If we invoke `shift_out_to_binder` and the region is in fact
1669-
/// bound by one of the binders we are shifting out of, that is an
1670-
/// error (and should fail an assertion failure).
1671-
pub fn shifted_out_to_binder(self, to_binder: DebruijnIndex) -> Self {
1672-
self.shifted_out(to_binder.as_u32() - INNERMOST.as_u32())
1673-
}
1674-
}
1675-
16761570
/// Region utilities
16771571
impl RegionKind {
16781572
/// Is this region named by the user?
@@ -1703,7 +1597,7 @@ impl RegionKind {
17031597
}
17041598
}
17051599

1706-
pub fn bound_at_or_above_binder(&self, index: DebruijnIndex) -> bool {
1600+
pub fn bound_at_or_above_binder(&self, index: ty::DebruijnIndex) -> bool {
17071601
match *self {
17081602
ty::ReLateBound(debruijn, _) => debruijn >= index,
17091603
_ => false,

compiler/rustc_type_ir/Cargo.toml

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[package]
2+
name = "rustc_type_ir"
3+
version = "0.0.0"
4+
authors = ["The Rust Project Developers"]
5+
edition = "2018"
6+
7+
[lib]
8+
doctest = false
9+
10+
[dependencies]
11+
bitflags = "1.2.1"
12+
rustc_index = { path = "../rustc_index" }
13+
rustc_serialize = { path = "../rustc_serialize" }
14+
rustc_data_structures = { path = "../rustc_data_structures" }

0 commit comments

Comments
 (0)