]> git.lizzy.rs Git - rust.git/commitdiff
Move things to rustc_type_ir
authorWilco Kusee <wilcokusee@gmail.com>
Sun, 31 Jan 2021 09:32:34 +0000 (10:32 +0100)
committerMichael Goulet <michael@errs.io>
Sat, 28 May 2022 18:38:22 +0000 (11:38 -0700)
25 files changed:
Cargo.lock
compiler/rustc_const_eval/src/interpret/cast.rs
compiler/rustc_lint/src/builtin.rs
compiler/rustc_macros/src/serialize.rs
compiler/rustc_middle/src/mir/interpret/mod.rs
compiler/rustc_middle/src/mir/mod.rs
compiler/rustc_middle/src/ty/codec.rs
compiler/rustc_middle/src/ty/consts.rs
compiler/rustc_middle/src/ty/context.rs
compiler/rustc_middle/src/ty/diagnostics.rs
compiler/rustc_middle/src/ty/inhabitedness/mod.rs
compiler/rustc_middle/src/ty/mod.rs
compiler/rustc_middle/src/ty/sty.rs
compiler/rustc_middle/src/ty/subst.rs
compiler/rustc_middle/src/ty/util.rs
compiler/rustc_query_impl/Cargo.toml
compiler/rustc_query_impl/src/on_disk_cache.rs
compiler/rustc_query_system/Cargo.toml
compiler/rustc_query_system/src/ich/mod.rs
compiler/rustc_ty_utils/src/ty.rs
compiler/rustc_type_ir/Cargo.toml
compiler/rustc_type_ir/src/codec.rs [new file with mode: 0644]
compiler/rustc_type_ir/src/lib.rs
compiler/rustc_type_ir/src/sty.rs [new file with mode: 0644]
compiler/rustc_typeck/src/coherence/builtin.rs

index 42bf166a71cb2002da876f58427d844f84644fec..871ff8f9cdb4074f1f18ddb7949d7553eabcc802 100644 (file)
@@ -4262,6 +4262,7 @@ dependencies = [
  "rustc_serialize",
  "rustc_session",
  "rustc_span",
+ "rustc_type_ir",
  "tracing",
 ]
 
@@ -4283,6 +4284,7 @@ dependencies = [
  "rustc_session",
  "rustc_span",
  "rustc_target",
+ "rustc_type_ir",
  "smallvec",
  "tracing",
 ]
@@ -4484,6 +4486,7 @@ dependencies = [
  "rustc_index",
  "rustc_macros",
  "rustc_serialize",
+ "smallvec",
 ]
 
 [[package]]
index 7cd2ba34b04a7235795cba1901e374723d103e9f..be34a77bdba966e265ccec946bec6b464ef9ef64 100644 (file)
@@ -8,6 +8,7 @@
 use rustc_middle::ty::layout::{IntegerExt, LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self, FloatTy, Ty, TypeAndMut};
 use rustc_target::abi::{Integer, Variants};
+use rustc_type_ir::sty::TyKind::*;
 
 use super::{
     util::ensure_monomorphic_enough, FnVal, ImmTy, Immediate, InterpCx, Machine, OpTy, PlaceTy,
@@ -102,7 +103,7 @@ pub fn misc_cast(
         src: &ImmTy<'tcx, M::PointerTag>,
         cast_ty: Ty<'tcx>,
     ) -> InterpResult<'tcx, Immediate<M::PointerTag>> {
-        use rustc_middle::ty::TyKind::*;
+        use rustc_type_ir::sty::TyKind::*;
         trace!("Casting {:?}: {:?} to {:?}", *src, src.layout.ty, cast_ty);
 
         match src.layout.ty.kind() {
@@ -205,7 +206,6 @@ pub fn cast_from_int_like(
         let v = scalar.to_bits(src_layout.size)?;
         let v = if signed { self.sign_extend(v, src_layout) } else { v };
         trace!("cast_from_scalar: {}, {} -> {}", v, src_layout.ty, cast_ty);
-        use rustc_middle::ty::TyKind::*;
 
         Ok(match *cast_ty.kind() {
             Int(_) | Uint(_) => {
@@ -247,7 +247,7 @@ fn cast_from_float<F>(&self, f: F, dest_ty: Ty<'tcx>) -> Scalar<M::PointerTag>
     where
         F: Float + Into<Scalar<M::PointerTag>> + FloatConvert<Single> + FloatConvert<Double>,
     {
-        use rustc_middle::ty::TyKind::*;
+        use rustc_type_ir::sty::TyKind::*;
         match *dest_ty.kind() {
             // float -> uint
             Uint(t) => {
index 9317858aed909812b867788927a24d5c748ff9f4..6be78c52f99e3d77932696f6d8199c0532e77662 100644 (file)
@@ -2489,7 +2489,7 @@ fn ty_find_init_error<'tcx>(
             ty: Ty<'tcx>,
             init: InitKind,
         ) -> Option<InitError> {
-            use rustc_middle::ty::TyKind::*;
+            use rustc_type_ir::sty::TyKind::*;
             match ty.kind() {
                 // Primitive types that don't like 0 as a value.
                 Ref(..) => Some(("references must be non-null".to_string(), None)),
@@ -2801,7 +2801,7 @@ fn structurally_same_type_impl<'tcx>(
                 true
             } else {
                 // Do a full, depth-first comparison between the two.
-                use rustc_middle::ty::TyKind::*;
+                use rustc_type_ir::sty::TyKind::*;
                 let a_kind = a.kind();
                 let b_kind = b.kind();
 
index 535158ffd8d844d4461109681c175ef8d0daf627..653c728ee42935c0d6c522813aef6be9db34b009 100644 (file)
@@ -8,7 +8,7 @@ pub fn type_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
     if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
         s.add_impl_generic(parse_quote! { 'tcx });
     }
-    s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_middle::ty::codec::TyDecoder<'tcx>});
+    s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_type_ir::codec::TyDecoder<I = ::rustc_middle::ty::TyInterner<'tcx>>});
     s.add_bounds(synstructure::AddBounds::Generics);
 
     decodable_body(s, decoder_ty)
@@ -95,7 +95,7 @@ pub fn type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
         s.add_impl_generic(parse_quote! {'tcx});
     }
     let encoder_ty = quote! { __E };
-    s.add_impl_generic(parse_quote! {#encoder_ty: ::rustc_middle::ty::codec::TyEncoder<'tcx>});
+    s.add_impl_generic(parse_quote! {#encoder_ty: ::rustc_type_ir::codec::TyEncoder<I = ::rustc_middle::ty::TyInterner<'tcx>>});
     s.add_bounds(synstructure::AddBounds::Generics);
 
     encodable_body(s, encoder_ty, false)
index 16ef8d68be3a3b0fc1339c5ce5f99e3a301baa99..926afa8ccb6bb83e1b4bd42ecbd4977b464d68f3 100644 (file)
@@ -115,7 +115,7 @@ macro_rules! throw_machine_stop {
 use crate::mir;
 use crate::ty::codec::{TyDecoder, TyEncoder};
 use crate::ty::subst::GenericArgKind;
-use crate::ty::{self, Instance, Ty, TyCtxt};
+use crate::ty::{self, Instance, Ty, TyCtxt, TyInterner};
 
 pub use self::error::{
     struct_error, CheckInAllocMsg, ErrorHandled, EvalToAllocationRawResult, EvalToConstValueResult,
@@ -203,7 +203,7 @@ enum AllocDiscriminant {
     Static,
 }
 
-pub fn specialized_encode_alloc_id<'tcx, E: TyEncoder<'tcx>>(
+pub fn specialized_encode_alloc_id<'tcx, E: TyEncoder<I = TyInterner<'tcx>>>(
     encoder: &mut E,
     tcx: TyCtxt<'tcx>,
     alloc_id: AllocId,
@@ -277,7 +277,7 @@ impl<'s> AllocDecodingSession<'s> {
     /// Decodes an `AllocId` in a thread-safe way.
     pub fn decode_alloc_id<'tcx, D>(&self, decoder: &mut D) -> AllocId
     where
-        D: TyDecoder<'tcx>,
+        D: TyDecoder<I = TyInterner<'tcx>>,
     {
         // Read the index of the allocation.
         let idx = usize::try_from(decoder.read_u32()).unwrap();
@@ -305,7 +305,7 @@ pub fn decode_alloc_id<'tcx, D>(&self, decoder: &mut D) -> AllocId
                         AllocDiscriminant::Alloc => {
                             // If this is an allocation, we need to reserve an
                             // `AllocId` so we can decode cyclic graphs.
-                            let alloc_id = decoder.tcx().reserve_alloc_id();
+                            let alloc_id = decoder.interner().tcx.reserve_alloc_id();
                             *entry =
                                 State::InProgress(TinyList::new_single(self.session_id), alloc_id);
                             Some(alloc_id)
@@ -349,7 +349,7 @@ pub fn decode_alloc_id<'tcx, D>(&self, decoder: &mut D) -> AllocId
                     // We already have a reserved `AllocId`.
                     let alloc_id = alloc_id.unwrap();
                     trace!("decoded alloc {:?}: {:#?}", alloc_id, alloc);
-                    decoder.tcx().set_alloc_id_same_memory(alloc_id, alloc);
+                    decoder.interner().tcx.set_alloc_id_same_memory(alloc_id, alloc);
                     alloc_id
                 }
                 AllocDiscriminant::Fn => {
@@ -357,7 +357,7 @@ pub fn decode_alloc_id<'tcx, D>(&self, decoder: &mut D) -> AllocId
                     trace!("creating fn alloc ID");
                     let instance = ty::Instance::decode(decoder);
                     trace!("decoded fn alloc instance: {:?}", instance);
-                    let alloc_id = decoder.tcx().create_fn_alloc(instance);
+                    let alloc_id = decoder.interner().tcx.create_fn_alloc(instance);
                     alloc_id
                 }
                 AllocDiscriminant::Static => {
@@ -365,7 +365,7 @@ pub fn decode_alloc_id<'tcx, D>(&self, decoder: &mut D) -> AllocId
                     trace!("creating extern static alloc ID");
                     let did = <DefId as Decodable<D>>::decode(decoder);
                     trace!("decoded static def-ID: {:?}", did);
-                    let alloc_id = decoder.tcx().create_static_alloc(did);
+                    let alloc_id = decoder.interner().tcx.create_static_alloc(did);
                     alloc_id
                 }
             }
index 9f8b22c8afc4706edc2579f63cfe16e6455c8c27..71cea005cf8583e8b7293602b40ea9fcf13c31d6 100644 (file)
@@ -668,7 +668,7 @@ pub fn assert_crate_local(self) -> T {
 const TAG_CLEAR_CROSS_CRATE_CLEAR: u8 = 0;
 const TAG_CLEAR_CROSS_CRATE_SET: u8 = 1;
 
-impl<'tcx, E: TyEncoder<'tcx>, T: Encodable<E>> Encodable<E> for ClearCrossCrate<T> {
+impl<E: TyEncoder, T: Encodable<E>> Encodable<E> for ClearCrossCrate<T> {
     #[inline]
     fn encode(&self, e: &mut E) -> Result<(), E::Error> {
         if E::CLEAR_CROSS_CRATE {
@@ -684,7 +684,7 @@ fn encode(&self, e: &mut E) -> Result<(), E::Error> {
         }
     }
 }
-impl<'tcx, D: TyDecoder<'tcx>, T: Decodable<D>> Decodable<D> for ClearCrossCrate<T> {
+impl<D: TyDecoder, T: Decodable<D>> Decodable<D> for ClearCrossCrate<T> {
     #[inline]
     fn decode(d: &mut D) -> ClearCrossCrate<T> {
         if D::CLEAR_CROSS_CRATE {
index 2a5191008a9effc9e2906442e1ae7f1bc1687796..234649f1056c71e55a38dac6ce018c4bf9d1fe85 100644 (file)
 use crate::thir;
 use crate::traits;
 use crate::ty::subst::SubstsRef;
-use crate::ty::{self, AdtDef, Ty, TyCtxt};
+use crate::ty::{self, AdtDef, Ty};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
+use rustc_serialize::{Decodable, Encodable};
+use rustc_middle::ty::TyInterner;
 use rustc_span::Span;
+pub use rustc_type_ir::{TyDecoder, TyEncoder};
 use std::hash::Hash;
 use std::intrinsics;
 use std::marker::DiscriminantKind;
 /// This offset is also chosen so that the first byte is never < 0x80.
 pub const SHORTHAND_OFFSET: usize = 0x80;
 
-pub trait EncodableWithShorthand<'tcx, E: TyEncoder<'tcx>>: Copy + Eq + Hash {
+pub trait EncodableWithShorthand<E: TyEncoder>: Copy + Eq + Hash {
     type Variant: Encodable<E>;
     fn variant(&self) -> &Self::Variant;
 }
 
 #[allow(rustc::usage_of_ty_tykind)]
-impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for Ty<'tcx> {
+impl<'tcx, E: TyEncoder<I = TyInterner<'tcx>>> EncodableWithShorthand<E> for Ty<'tcx> {
     type Variant = ty::TyKind<'tcx>;
 
     #[inline]
@@ -43,7 +45,9 @@ fn variant(&self) -> &Self::Variant {
     }
 }
 
-impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for ty::PredicateKind<'tcx> {
+impl<'tcx, E: TyEncoder<I = TyInterner<'tcx>>> EncodableWithShorthand<E>
+    for ty::PredicateKind<'tcx>
+{
     type Variant = ty::PredicateKind<'tcx>;
 
     #[inline]
@@ -52,15 +56,6 @@ fn variant(&self) -> &Self::Variant {
     }
 }
 
-pub trait TyEncoder<'tcx>: Encoder {
-    const CLEAR_CROSS_CRATE: bool;
-
-    fn position(&self) -> usize;
-    fn type_shorthands(&mut self) -> &mut FxHashMap<Ty<'tcx>, usize>;
-    fn predicate_shorthands(&mut self) -> &mut FxHashMap<ty::PredicateKind<'tcx>, usize>;
-    fn encode_alloc_id(&mut self, alloc_id: &AllocId) -> Result<(), Self::Error>;
-}
-
 /// Trait for decoding to a reference.
 ///
 /// This is a separate trait from `Decodable` so that we can implement it for
@@ -71,7 +66,7 @@ pub trait TyEncoder<'tcx>: Encoder {
 ///
 /// `Decodable` can still be implemented in cases where `Decodable` is required
 /// by a trait bound.
-pub trait RefDecodable<'tcx, D: TyDecoder<'tcx>> {
+pub trait RefDecodable<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> {
     fn decode(d: &mut D) -> &'tcx Self;
 }
 
@@ -82,9 +77,9 @@ pub fn encode_with_shorthand<'tcx, E, T, M>(
     cache: M,
 ) -> Result<(), E::Error>
 where
-    E: TyEncoder<'tcx>,
+    E: TyEncoder<I = TyInterner<'tcx>>,
     M: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap<T, usize>,
-    T: EncodableWithShorthand<'tcx, E>,
+    T: EncodableWithShorthand<E>,
     // The discriminant and shorthand must have the same size.
     T::Variant: DiscriminantKind<Discriminant = isize>,
 {
@@ -119,100 +114,105 @@ pub fn encode_with_shorthand<'tcx, E, T, M>(
     Ok(())
 }
 
-impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for Ty<'tcx> {
+impl<'tcx, E: TyEncoder<I = TyInterner<'tcx>>> Encodable<E> for Ty<'tcx> {
     fn encode(&self, e: &mut E) -> Result<(), E::Error> {
         encode_with_shorthand(e, self, TyEncoder::type_shorthands)
     }
 }
 
-impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Binder<'tcx, ty::PredicateKind<'tcx>> {
+impl<'tcx, E: TyEncoder<I = TyInterner<'tcx>>> Encodable<E>
+    for ty::Binder<'tcx, ty::PredicateKind<'tcx>>
+{
     fn encode(&self, e: &mut E) -> Result<(), E::Error> {
         self.bound_vars().encode(e)?;
         encode_with_shorthand(e, &self.skip_binder(), TyEncoder::predicate_shorthands)
     }
 }
 
-impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Predicate<'tcx> {
+impl<'tcx, E: TyEncoder<I = TyInterner<'tcx>>> Encodable<E> for ty::Predicate<'tcx> {
     fn encode(&self, e: &mut E) -> Result<(), E::Error> {
         self.kind().encode(e)
     }
 }
 
-impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Region<'tcx> {
+impl<'tcx, E: TyEncoder<I = TyInterner<'tcx>>> Encodable<E> for ty::Region<'tcx> {
     fn encode(&self, e: &mut E) -> Result<(), E::Error> {
         self.kind().encode(e)
     }
 }
 
-impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Const<'tcx> {
+impl<'tcx, E: TyEncoder<I = TyInterner<'tcx>>> Encodable<E> for ty::Const<'tcx> {
     fn encode(&self, e: &mut E) -> Result<(), E::Error> {
         self.0.0.encode(e)
     }
 }
 
-impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ConstAllocation<'tcx> {
+impl<'tcx, E: TyEncoder<I = TyInterner<'tcx>>> Encodable<E> for ConstAllocation<'tcx> {
     fn encode(&self, e: &mut E) -> Result<(), E::Error> {
         self.inner().encode(e)
     }
 }
 
-impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AdtDef<'tcx> {
+impl<'tcx, E: TyEncoder<I = TyInterner<'tcx>>> Encodable<E> for AdtDef<'tcx> {
     fn encode(&self, e: &mut E) -> Result<(), E::Error> {
         self.0.0.encode(e)
     }
 }
 
-impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AllocId {
+impl<'tcx, E: TyEncoder<I = TyInterner<'tcx>>> Encodable<E> for AllocId {
     fn encode(&self, e: &mut E) -> Result<(), E::Error> {
         e.encode_alloc_id(self)
     }
 }
 
-pub trait TyDecoder<'tcx>: Decoder {
-    const CLEAR_CROSS_CRATE: bool;
-
-    fn tcx(&self) -> TyCtxt<'tcx>;
-
-    fn peek_byte(&self) -> u8;
-
-    fn position(&self) -> usize;
-
-    fn cached_ty_for_shorthand<F>(&mut self, shorthand: usize, or_insert_with: F) -> Ty<'tcx>
-    where
-        F: FnOnce(&mut Self) -> Ty<'tcx>;
-
-    fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
-    where
-        F: FnOnce(&mut Self) -> R;
-
-    fn positioned_at_shorthand(&self) -> bool {
-        (self.peek_byte() & (SHORTHAND_OFFSET as u8)) != 0
+macro_rules! encodable_via_deref {
+    ($($t:ty),+) => {
+        $(impl<'tcx, E: TyEncoder<I = TyInterner<'tcx>>> Encodable<E> for $t {
+            fn encode(&self, e: &mut E) -> Result<(), E::Error> {
+                (**self).encode(e)
+            }
+        })*
     }
+}
 
-    fn decode_alloc_id(&mut self) -> AllocId;
+encodable_via_deref! {
+    &'tcx ty::TypeckResults<'tcx>,
+    &'tcx traits::ImplSource<'tcx, ()>,
+    &'tcx mir::Body<'tcx>,
+    &'tcx mir::UnsafetyCheckResult,
+    &'tcx mir::BorrowCheckResult<'tcx>,
+    &'tcx mir::coverage::CodeRegion
 }
 
 #[inline]
-fn decode_arena_allocable<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable<D>>(
+fn decode_arena_allocable<
+    'tcx,
+    D: TyDecoder<I = TyInterner<'tcx>>,
+    T: ArenaAllocatable<'tcx> + Decodable<D>,
+>(
     decoder: &mut D,
 ) -> &'tcx T
 where
-    D: TyDecoder<'tcx>,
+    D: TyDecoder,
 {
-    decoder.tcx().arena.alloc(Decodable::decode(decoder))
+    decoder.interner().tcx.arena.alloc(Decodable::decode(decoder))
 }
 
 #[inline]
-fn decode_arena_allocable_slice<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable<D>>(
+fn decode_arena_allocable_slice<
+    'tcx,
+    D: TyDecoder<I = TyInterner<'tcx>>,
+    T: ArenaAllocatable<'tcx> + Decodable<D>,
+>(
     decoder: &mut D,
 ) -> &'tcx [T]
 where
-    D: TyDecoder<'tcx>,
+    D: TyDecoder,
 {
-    decoder.tcx().arena.alloc_from_iter(<Vec<T> as Decodable<D>>::decode(decoder))
+    decoder.interner().tcx.arena.alloc_from_iter(<Vec<T> as Decodable<D>>::decode(decoder))
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for Ty<'tcx> {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> Decodable<D> for Ty<'tcx> {
     #[allow(rustc::usage_of_ty_tykind)]
     fn decode(decoder: &mut D) -> Ty<'tcx> {
         // Handle shorthands first, if we have a usize > 0x80.
@@ -225,13 +225,13 @@ fn decode(decoder: &mut D) -> Ty<'tcx> {
                 decoder.with_position(shorthand, Ty::decode)
             })
         } else {
-            let tcx = decoder.tcx();
-            tcx.mk_ty(ty::TyKind::decode(decoder))
+            let tcx = decoder.interner().tcx;
+            tcx.mk_ty(rustc_type_ir::TyKind::decode(decoder))
         }
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Binder<'tcx, ty::PredicateKind<'tcx>> {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> Decodable<D> for ty::Binder<'tcx, ty::PredicateKind<'tcx>> {
     fn decode(decoder: &mut D) -> ty::Binder<'tcx, ty::PredicateKind<'tcx>> {
         let bound_vars = Decodable::decode(decoder);
         // Handle shorthands first, if we have a usize > 0x80.
@@ -250,64 +250,64 @@ fn decode(decoder: &mut D) -> ty::Binder<'tcx, ty::PredicateKind<'tcx>> {
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Predicate<'tcx> {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> Decodable<D> for ty::Predicate<'tcx> {
     fn decode(decoder: &mut D) -> ty::Predicate<'tcx> {
         let predicate_kind = Decodable::decode(decoder);
-        decoder.tcx().mk_predicate(predicate_kind)
+        decoder.interner().tcx.mk_predicate(predicate_kind)
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for SubstsRef<'tcx> {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> Decodable<D> for SubstsRef<'tcx> {
     fn decode(decoder: &mut D) -> Self {
         let len = decoder.read_usize();
-        let tcx = decoder.tcx();
+        let tcx = decoder.interner().tcx;
         tcx.mk_substs(
             (0..len).map::<ty::subst::GenericArg<'tcx>, _>(|_| Decodable::decode(decoder)),
         )
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for mir::Place<'tcx> {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> Decodable<D> for mir::Place<'tcx> {
     fn decode(decoder: &mut D) -> Self {
         let local: mir::Local = Decodable::decode(decoder);
         let len = decoder.read_usize();
-        let projection = decoder.tcx().mk_place_elems(
+        let projection = decoder.interner().tcx.mk_place_elems(
             (0..len).map::<mir::PlaceElem<'tcx>, _>(|_| Decodable::decode(decoder)),
         );
         mir::Place { local, projection }
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Region<'tcx> {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> Decodable<D> for ty::Region<'tcx> {
     fn decode(decoder: &mut D) -> Self {
-        decoder.tcx().mk_region(Decodable::decode(decoder))
+        decoder.interner().tcx.mk_region(Decodable::decode(decoder))
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for CanonicalVarInfos<'tcx> {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> Decodable<D> for CanonicalVarInfos<'tcx> {
     fn decode(decoder: &mut D) -> Self {
         let len = decoder.read_usize();
         let interned: Vec<CanonicalVarInfo<'tcx>> =
             (0..len).map(|_| Decodable::decode(decoder)).collect();
-        decoder.tcx().intern_canonical_var_infos(interned.as_slice())
+        decoder.interner().tcx.intern_canonical_var_infos(interned.as_slice())
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for AllocId {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> Decodable<D> for AllocId {
     fn decode(decoder: &mut D) -> Self {
         decoder.decode_alloc_id()
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::SymbolName<'tcx> {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> Decodable<D> for ty::SymbolName<'tcx> {
     fn decode(decoder: &mut D) -> Self {
-        ty::SymbolName::new(decoder.tcx(), &decoder.read_str())
+        ty::SymbolName::new(decoder.interner().tcx, &decoder.read_str())
     }
 }
 
 macro_rules! impl_decodable_via_ref {
     ($($t:ty),+) => {
-        $(impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for $t {
+        $(impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> Decodable<D> for $t {
             fn decode(decoder: &mut D) -> Self {
                 RefDecodable::decode(decoder)
             }
@@ -315,78 +315,78 @@ fn decode(decoder: &mut D) -> Self {
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<Ty<'tcx>> {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> RefDecodable<'tcx, D> for ty::List<Ty<'tcx>> {
     fn decode(decoder: &mut D) -> &'tcx Self {
         let len = decoder.read_usize();
-        decoder.tcx().mk_type_list((0..len).map::<Ty<'tcx>, _>(|_| Decodable::decode(decoder)))
+        decoder.interner().tcx.mk_type_list((0..len).map::<Ty<'tcx>, _>(|_| Decodable::decode(decoder)))
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D>
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> RefDecodable<'tcx, D>
     for ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>
 {
     fn decode(decoder: &mut D) -> &'tcx Self {
         let len = decoder.read_usize();
-        decoder.tcx().mk_poly_existential_predicates(
+        decoder.interner().tcx.mk_poly_existential_predicates(
             (0..len).map::<ty::Binder<'tcx, _>, _>(|_| Decodable::decode(decoder)),
         )
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Const<'tcx> {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> Decodable<D> for ty::Const<'tcx> {
     fn decode(decoder: &mut D) -> Self {
-        decoder.tcx().mk_const(Decodable::decode(decoder))
+        decoder.interner().tcx.mk_const(Decodable::decode(decoder))
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [ty::ValTree<'tcx>] {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> RefDecodable<'tcx, D> for [ty::ValTree<'tcx>] {
     fn decode(decoder: &mut D) -> &'tcx Self {
-        decoder.tcx().arena.alloc_from_iter(
+        decoder.interner().tcx.arena.alloc_from_iter(
             (0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::<Vec<_>>(),
         )
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ConstAllocation<'tcx> {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> Decodable<D> for ConstAllocation<'tcx> {
     fn decode(decoder: &mut D) -> Self {
-        decoder.tcx().intern_const_alloc(Decodable::decode(decoder))
+        decoder.interner().tcx.intern_const_alloc(Decodable::decode(decoder))
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for AdtDef<'tcx> {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> Decodable<D> for AdtDef<'tcx> {
     fn decode(decoder: &mut D) -> Self {
-        decoder.tcx().intern_adt_def(Decodable::decode(decoder))
+        decoder.interner().tcx.intern_adt_def(Decodable::decode(decoder))
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [(ty::Predicate<'tcx>, Span)] {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> RefDecodable<'tcx, D> for [(ty::Predicate<'tcx>, Span)] {
     fn decode(decoder: &mut D) -> &'tcx Self {
-        decoder.tcx().arena.alloc_from_iter(
+        decoder.interner().tcx.arena.alloc_from_iter(
             (0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::<Vec<_>>(),
         )
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [thir::abstract_const::Node<'tcx>] {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> RefDecodable<'tcx, D> for [thir::abstract_const::Node<'tcx>] {
     fn decode(decoder: &mut D) -> &'tcx Self {
-        decoder.tcx().arena.alloc_from_iter(
+        decoder.interner().tcx.arena.alloc_from_iter(
             (0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::<Vec<_>>(),
         )
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [thir::abstract_const::NodeId] {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> RefDecodable<'tcx, D> for [thir::abstract_const::NodeId] {
     fn decode(decoder: &mut D) -> &'tcx Self {
-        decoder.tcx().arena.alloc_from_iter(
+        decoder.interner().tcx.arena.alloc_from_iter(
             (0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::<Vec<_>>(),
         )
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<ty::BoundVariableKind> {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> RefDecodable<'tcx, D> for ty::List<ty::BoundVariableKind> {
     fn decode(decoder: &mut D) -> &'tcx Self {
         let len = decoder.read_usize();
-        decoder.tcx().mk_bound_variable_kinds(
+        decoder.interner().tcx.mk_bound_variable_kinds(
             (0..len).map::<ty::BoundVariableKind, _>(|_| Decodable::decode(decoder)),
         )
     }
@@ -420,14 +420,14 @@ macro_rules! impl_arena_allocatable_decoder {
     ([]$args:tt) => {};
     ([decode $(, $attrs:ident)*]
      [$name:ident: $ty:ty]) => {
-        impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for $ty {
+        impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> RefDecodable<'tcx, D> for $ty {
             #[inline]
             fn decode(decoder: &mut D) -> &'tcx Self {
                 decode_arena_allocable(decoder)
             }
         }
 
-        impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [$ty] {
+        impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> RefDecodable<'tcx, D> for [$ty] {
             #[inline]
             fn decode(decoder: &mut D) -> &'tcx Self {
                 decode_arena_allocable_slice(decoder)
@@ -518,13 +518,13 @@ fn read_raw_bytes(&mut self, len: usize) -> &[u8] {
 macro_rules! impl_binder_encode_decode {
     ($($t:ty),+ $(,)?) => {
         $(
-            impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Binder<'tcx, $t> {
+            impl<'tcx, E: TyEncoder<I = TyInterner<'tcx>>> Encodable<E> for ty::Binder<'tcx, $t> {
                 fn encode(&self, e: &mut E) -> Result<(), E::Error> {
                     self.bound_vars().encode(e)?;
                     self.as_ref().skip_binder().encode(e)
                 }
             }
-            impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Binder<'tcx, $t> {
+            impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> Decodable<D> for ty::Binder<'tcx, $t> {
                 fn decode(decoder: &mut D) -> Self {
                     let bound_vars = Decodable::decode(decoder);
                     ty::Binder::bind_with_vars(Decodable::decode(decoder), bound_vars)
index 7af7eb4f5ecfd868ebf1408ac90aed3027c08b93..58a237ee6f825824fd0ffcf1f368635f726bd92a 100644 (file)
@@ -2,7 +2,7 @@
 use crate::mir::interpret::{LitToConstInput, Scalar};
 use crate::ty::{
     self, InlineConstSubsts, InlineConstSubstsParts, InternalSubsts, ParamEnv, ParamEnvAnd, Ty,
-    TyCtxt, TypeFoldable,
+    TyCtxt, TyInterner, TypeFoldable,
 };
 use rustc_data_structures::intern::Interned;
 use rustc_errors::ErrorGuaranteed;
@@ -40,6 +40,14 @@ pub struct ConstS<'tcx> {
     pub val: ConstKind<'tcx>,
 }
 
+impl<'tcx, S: rustc_type_ir::TyEncoder<I = TyInterner<'tcx>>> rustc_serialize::Encodable<S>
+    for &'_ Const<'_>
+{
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
+        (*self).encode(s)
+    }
+}
+
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(ConstS<'_>, 48);
 
index 3c08db5dc6814304ec2117d2e435ae7201311a90..efe7a54b5bf1c5fb4a004d0a1523610548a17c2f 100644 (file)
@@ -16,7 +16,6 @@
 use crate::traits;
 use crate::ty::query::{self, TyCtxtAt};
 use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts};
-use crate::ty::TyKind::*;
 use crate::ty::{
     self, AdtDef, AdtDefData, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
     ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, ExistentialPredicate, FloatTy,
@@ -60,9 +59,9 @@
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::abi::{Layout, LayoutS, TargetDataLayout, VariantIdx};
 use rustc_target::spec::abi;
+use rustc_type_ir::sty::TyKind::*;
+use rustc_type_ir::{InternAs, InternIteratorElement, Interner, TypeFlags};
 
-use rustc_type_ir::TypeFlags;
-use smallvec::SmallVec;
 use std::any::Any;
 use std::borrow::Borrow;
 use std::cmp::Ordering;
@@ -91,6 +90,70 @@ fn new_empty(source_map: &'tcx SourceMap) -> Self
     fn serialize(&self, tcx: TyCtxt<'tcx>, encoder: &mut FileEncoder) -> FileEncodeResult;
 }
 
+pub struct TyInterner<'tcx> {
+    pub tcx: TyCtxt<'tcx>,
+}
+
+/// We don't ever actually need this. It's only required for derives.
+impl<'tcx> Hash for TyInterner<'tcx> {
+    fn hash<H: Hasher>(&self, _state: &mut H) {}
+}
+
+/// We don't ever actually need this. It's only required for derives.
+impl<'tcx> Ord for TyInterner<'tcx> {
+    fn cmp(&self, _other: &Self) -> Ordering {
+        Ordering::Equal
+    }
+}
+
+/// We don't ever actually need this. It's only required for derives.
+impl<'tcx> PartialOrd for TyInterner<'tcx> {
+    fn partial_cmp(&self, _other: &Self) -> Option<Ordering> {
+        None
+    }
+}
+
+/// We don't ever actually need this. It's only required for derives.
+impl<'tcx> PartialEq for TyInterner<'tcx> {
+    fn eq(&self, _other: &Self) -> bool {
+        false
+    }
+}
+
+/// We don't ever actually need this. It's only required for derives.
+impl<'tcx> Eq for TyInterner<'tcx> {}
+
+impl fmt::Debug for TyInterner<'_> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "TyInterner")
+    }
+}
+
+#[allow(rustc::usage_of_ty_tykind)]
+impl<'tcx> Interner for TyInterner<'tcx> {
+    type AdtDef = ty::AdtDef<'tcx>;
+    type SubstsRef = ty::SubstsRef<'tcx>;
+    type DefId = DefId;
+    type Ty = Ty<'tcx>;
+    type Const = ty::Const<'tcx>;
+    type Region = Region<'tcx>;
+    type TypeAndMut = TypeAndMut<'tcx>;
+    type Mutability = hir::Mutability;
+    type Movability = hir::Movability;
+    type PolyFnSig = PolyFnSig<'tcx>;
+    type ListBinderExistentialPredicate = &'tcx List<Binder<'tcx, ExistentialPredicate<'tcx>>>;
+    type BinderListTy = Binder<'tcx, &'tcx List<Ty<'tcx>>>;
+    type ListTy = &'tcx List<Ty<'tcx>>;
+    type ProjectionTy = ty::ProjectionTy<'tcx>;
+    type ParamTy = ParamTy;
+    type BoundTy = ty::BoundTy;
+    type PlaceholderType = ty::PlaceholderType;
+    type InferTy = InferTy;
+    type DelaySpanBugEmitted = DelaySpanBugEmitted;
+    type PredicateKind = ty::PredicateKind<'tcx>;
+    type AllocId = crate::mir::interpret::AllocId;
+}
+
 /// A type that is not publicly constructable. This prevents people from making [`TyKind::Error`]s
 /// except through the error-reporting functions on a [`tcx`][TyCtxt].
 #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
@@ -1075,6 +1138,10 @@ pub struct GlobalCtxt<'tcx> {
 }
 
 impl<'tcx> TyCtxt<'tcx> {
+    pub fn interner(self) -> TyInterner<'tcx> {
+        TyInterner { tcx: self }
+    }
+
     /// Expects a body and returns its codegen attributes.
     ///
     /// Unlike `codegen_fn_attrs`, this returns `CodegenFnAttrs::EMPTY` for
@@ -2848,108 +2915,6 @@ pub fn ty_error_with_message(self, msg: &str) -> Ty<'tcx> {
     }
 }
 
-pub trait InternAs<T: ?Sized, R> {
-    type Output;
-    fn intern_with<F>(self, f: F) -> Self::Output
-    where
-        F: FnOnce(&T) -> R;
-}
-
-impl<I, T, R, E> InternAs<[T], R> for I
-where
-    E: InternIteratorElement<T, R>,
-    I: Iterator<Item = E>,
-{
-    type Output = E::Output;
-    fn intern_with<F>(self, f: F) -> Self::Output
-    where
-        F: FnOnce(&[T]) -> R,
-    {
-        E::intern_with(self, f)
-    }
-}
-
-pub trait InternIteratorElement<T, R>: Sized {
-    type Output;
-    fn intern_with<I: Iterator<Item = Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output;
-}
-
-impl<T, R> InternIteratorElement<T, R> for T {
-    type Output = R;
-    fn intern_with<I: Iterator<Item = Self>, F: FnOnce(&[T]) -> R>(
-        mut iter: I,
-        f: F,
-    ) -> Self::Output {
-        // This code is hot enough that it's worth specializing for the most
-        // common length lists, to avoid the overhead of `SmallVec` creation.
-        // Lengths 0, 1, and 2 typically account for ~95% of cases. If
-        // `size_hint` is incorrect a panic will occur via an `unwrap` or an
-        // `assert`.
-        match iter.size_hint() {
-            (0, Some(0)) => {
-                assert!(iter.next().is_none());
-                f(&[])
-            }
-            (1, Some(1)) => {
-                let t0 = iter.next().unwrap();
-                assert!(iter.next().is_none());
-                f(&[t0])
-            }
-            (2, Some(2)) => {
-                let t0 = iter.next().unwrap();
-                let t1 = iter.next().unwrap();
-                assert!(iter.next().is_none());
-                f(&[t0, t1])
-            }
-            _ => f(&iter.collect::<SmallVec<[_; 8]>>()),
-        }
-    }
-}
-
-impl<'a, T, R> InternIteratorElement<T, R> for &'a T
-where
-    T: Clone + 'a,
-{
-    type Output = R;
-    fn intern_with<I: Iterator<Item = Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output {
-        // This code isn't hot.
-        f(&iter.cloned().collect::<SmallVec<[_; 8]>>())
-    }
-}
-
-impl<T, R, E> InternIteratorElement<T, R> for Result<T, E> {
-    type Output = Result<R, E>;
-    fn intern_with<I: Iterator<Item = Self>, F: FnOnce(&[T]) -> R>(
-        mut iter: I,
-        f: F,
-    ) -> Self::Output {
-        // This code is hot enough that it's worth specializing for the most
-        // common length lists, to avoid the overhead of `SmallVec` creation.
-        // Lengths 0, 1, and 2 typically account for ~95% of cases. If
-        // `size_hint` is incorrect a panic will occur via an `unwrap` or an
-        // `assert`, unless a failure happens first, in which case the result
-        // will be an error anyway.
-        Ok(match iter.size_hint() {
-            (0, Some(0)) => {
-                assert!(iter.next().is_none());
-                f(&[])
-            }
-            (1, Some(1)) => {
-                let t0 = iter.next().unwrap()?;
-                assert!(iter.next().is_none());
-                f(&[t0])
-            }
-            (2, Some(2)) => {
-                let t0 = iter.next().unwrap()?;
-                let t1 = iter.next().unwrap()?;
-                assert!(iter.next().is_none());
-                f(&[t0, t1])
-            }
-            _ => f(&iter.collect::<Result<SmallVec<[_; 8]>, _>>()?),
-        })
-    }
-}
-
 // We are comparing types with different invariant lifetimes, so `ptr::eq`
 // won't work for us.
 fn ptr_eq<T, U>(t: *const T, u: *const U) -> bool {
index a6717746979197808da71d385777fb8bb372fbf2..462fc27009de9ce1b9c462519ab6308c1d0c8b33 100644 (file)
@@ -1,7 +1,6 @@
 //! Diagnostics related methods for `Ty`.
 
 use crate::ty::subst::{GenericArg, GenericArgKind};
-use crate::ty::TyKind::*;
 use crate::ty::{
     ConstKind, DefIdTree, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef,
     InferTy, ProjectionTy, Term, Ty, TyCtxt, TypeAndMut,
@@ -13,6 +12,7 @@
 use rustc_hir::def_id::DefId;
 use rustc_hir::WherePredicate;
 use rustc_span::Span;
+use rustc_type_ir::sty::TyKind::*;
 
 impl<'tcx> IntoDiagnosticArg for Ty<'tcx> {
     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
index b8088766cca68674d3d960e5e5b5de565c14da7a..3d22f5a04a2bf1879c22dbd232c8904d95663f93 100644 (file)
@@ -2,11 +2,12 @@
 
 use crate::ty;
 use crate::ty::context::TyCtxt;
-use crate::ty::TyKind::*;
 use crate::ty::{AdtDef, FieldDef, Ty, VariantDef};
 use crate::ty::{AdtKind, Visibility};
 use crate::ty::{DefId, SubstsRef};
 
+use rustc_type_ir::sty::TyKind::*;
+
 mod def_id_forest;
 
 // The methods in this module calculate `DefIdForest`s of modules in which an
index b61a3827602fa08132e1daf5a7c5bf84a98a02c3..2804912c9ab8a111c58a0d805a0948116fa9e311 100644 (file)
@@ -51,6 +51,7 @@
 
 pub use crate::ty::diagnostics::*;
 pub use rustc_type_ir::InferTy::*;
+pub use rustc_type_ir::TyKind::*;
 pub use rustc_type_ir::*;
 
 pub use self::binding::BindingMode;
@@ -67,7 +68,7 @@
 pub use self::context::{
     tls, CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations,
     CtxtInterners, DelaySpanBugEmitted, FreeRegionInfo, GeneratorDiagnosticData,
-    GeneratorInteriorTypeCause, GlobalCtxt, Lift, OnDiskCache, TyCtxt, TypeckResults, UserType,
+    GeneratorInteriorTypeCause, GlobalCtxt, Lift, OnDiskCache, TyCtxt, TyInterner, TypeckResults, UserType,
     UserTypeAnnotationIndex,
 };
 pub use self::instance::{Instance, InstanceDef};
@@ -76,7 +77,6 @@
 pub use self::rvalue_scopes::RvalueScopes;
 pub use self::sty::BoundRegionKind::*;
 pub use self::sty::RegionKind::*;
-pub use self::sty::TyKind::*;
 pub use self::sty::{
     Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar, BoundVariableKind,
     CanonicalPolyFnSig, ClosureSubsts, ClosureSubstsParts, ConstVid, EarlyBinder, EarlyBoundRegion,
@@ -449,13 +449,13 @@ pub(crate) struct TyS<'tcx> {
 }
 
 // `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-static_assert_size!(TyS<'_>, 40);
+//#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+//static_assert_size!(TyS<'_>, 40);
 
 // We are actually storing a stable hash cache next to the type, so let's
 // also check the full size
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-static_assert_size!(WithStableHash<TyS<'_>>, 56);
+//#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+//static_assert_size!(WithStableHash<TyS<'_>>, 56);
 
 /// Use this rather than `TyS`, whenever possible.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
index 2dabc6963884104adcea996ecd02ede90d40d44e..314d0ef277136b0d2e54b79e3be3ecb557d0e97b 100644 (file)
@@ -2,16 +2,14 @@
 
 #![allow(rustc::usage_of_ty_tykind)]
 
-use self::TyKind::*;
-
 use crate::infer::canonical::Canonical;
 use crate::ty::fold::ValidateBoundVars;
 use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
-use crate::ty::InferTy::{self, *};
+use crate::ty::InferTy::*;
 use crate::ty::{
     self, AdtDef, DefIdTree, Discr, Term, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitor,
 };
-use crate::ty::{DelaySpanBugEmitted, List, ParamEnv};
+use crate::ty::{List, ParamEnv};
 use polonius_engine::Atom;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::intern::Interned;
 use std::ops::{ControlFlow, Deref, Range};
 use ty::util::IntTypeExt;
 
+use rustc_type_ir::TyKind as IrTyKind;
+pub type TyKind<'tcx> = IrTyKind<ty::TyInterner<'tcx>>;
+use rustc_type_ir::sty::TyKind::*;
+
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable, Lift)]
 pub struct TypeAndMut<'tcx> {
@@ -78,6 +80,7 @@ pub fn is_named(&self) -> bool {
     }
 }
 
+/*
 /// Defines the kinds of types used by the type system.
 ///
 /// Types written by the user start out as [hir::TyKind](rustc_hir::TyKind) and get
@@ -253,7 +256,9 @@ pub enum TyKind<'tcx> {
     /// propagated to avoid useless error messages.
     Error(DelaySpanBugEmitted),
 }
+*/
 
+/*
 impl<'tcx> TyKind<'tcx> {
     #[inline]
     pub fn is_primitive(&self) -> bool {
@@ -272,6 +277,25 @@ pub fn article(&self) -> &'static str {
         }
     }
 }
+*/
+
+pub trait Article {
+    fn article(&self) -> &'static str;
+}
+
+impl<'tcx> Article for TyKind<'tcx> {
+    /// Get the article ("a" or "an") to use with this type.
+    fn article(&self) -> &'static str {
+        match self {
+            Int(_) | Float(_) | Array(_, _) => "an",
+            Adt(def, _) if def.is_enum() => "an",
+            // This should never happen, but ICEing and causing the user's code
+            // to not compile felt too harsh.
+            Error(_) => "a",
+            _ => "a",
+        }
+    }
+}
 
 // `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
@@ -930,7 +954,9 @@ pub fn projection_bounds<'a>(
     }
 
     #[inline]
-    pub fn auto_traits<'a>(&'a self) -> impl Iterator<Item = DefId> + 'a {
+    pub fn auto_traits<'a>(
+        &'a self,
+    ) -> impl Iterator<Item = DefId> + rustc_data_structures::captures::Captures<'tcx> + 'a {
         self.iter().filter_map(|predicate| match predicate.skip_binder() {
             ExistentialPredicate::AutoTrait(did) => Some(did),
             _ => None,
index 31a318cc68f4432d1d11c97874bdbe9689124875..e50179face0adbc5eea66ed55b419663004f7120 100644 (file)
@@ -4,7 +4,7 @@
 use crate::ty::codec::{TyDecoder, TyEncoder};
 use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeVisitor};
 use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts};
-use crate::ty::{self, EarlyBinder, Lift, List, ParamConst, Ty, TyCtxt};
+use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt, TyInterner};
 
 use rustc_data_structures::intern::{Interned, WithStableHash};
 use rustc_hir::def_id::DefId;
@@ -216,13 +216,13 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow
     }
 }
 
-impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for GenericArg<'tcx> {
+impl<'tcx, E: TyEncoder<I = TyInterner<'tcx>>> Encodable<E> for GenericArg<'tcx> {
     fn encode(&self, e: &mut E) -> Result<(), E::Error> {
         self.unpack().encode(e)
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for GenericArg<'tcx> {
+impl<'tcx, D: TyDecoder<I = TyInterner<'tcx>>> Decodable<D> for GenericArg<'tcx> {
     fn decode(d: &mut D) -> GenericArg<'tcx> {
         GenericArgKind::decode(d).pack()
     }
@@ -506,7 +506,7 @@ pub trait Subst<'tcx>: Sized {
     fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> Self::Inner;
 }
 
-impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for EarlyBinder<T> {
+impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for ty::EarlyBinder<T> {
     type Inner = T;
 
     fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> Self::Inner {
index 809e7ce2e745b39f3e93dd1d29f7205eb22d6784..084c47a1dc4baaa671794a064f79252b45d7a417 100644 (file)
@@ -5,7 +5,9 @@
 use crate::ty::layout::IntegerExt;
 use crate::ty::query::TyCtxtAt;
 use crate::ty::subst::{GenericArgKind, Subst, SubstsRef};
-use crate::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable};
+use crate::ty::{
+    self, Const, DebruijnIndex, DefIdTree, List, ReEarlyBound, Ty, TyCtxt, TypeFoldable,
+};
 use rustc_apfloat::Float as _;
 use rustc_ast as ast;
 use rustc_attr::{self as attr, SignedInt, UnsignedInt};
@@ -20,6 +22,7 @@
 use rustc_span::{sym, DUMMY_SP};
 use rustc_target::abi::{Integer, Size, TargetDataLayout};
 use rustc_target::spec::abi::Abi;
+use rustc_type_ir::TyKind::*;
 use smallvec::SmallVec;
 use std::{fmt, iter};
 
index fa05434e48b1b7eb021e1296c3de7c9f80db9e36..bfc15f0c70b3e500931cfc5f8af42ba80bcede72 100644 (file)
@@ -20,6 +20,7 @@ rustc_query_system = { path = "../rustc_query_system" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
+rustc_type_ir = { path = "../rustc_type_ir" }
 tracing = "0.1"
 
 [features]
index c492040852763c48a630d15c51675eb493aa52be..5282c317fc4bc3519e36dbf7c9759ecdb4c3b3e1 100644 (file)
@@ -547,12 +547,13 @@ fn decode_tagged<D, T, V>(decoder: &mut D, expected_tag: T) -> V
     value
 }
 
-impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
+impl<'a, 'tcx> TyDecoder for CacheDecoder<'a, 'tcx> {
+    type I = TyInterner<'tcx>;
     const CLEAR_CROSS_CRATE: bool = false;
 
     #[inline]
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.tcx
+    fn interner(&self) -> TyInterner<'tcx> {
+        TyInterner { tcx: self.tcx }
     }
 
     #[inline]
@@ -569,7 +570,7 @@ fn cached_ty_for_shorthand<F>(&mut self, shorthand: usize, or_insert_with: F) ->
     where
         F: FnOnce(&mut Self) -> Ty<'tcx>,
     {
-        let tcx = self.tcx();
+        let tcx = self.tcx;
 
         let cache_key = ty::CReaderCacheKey { cnum: None, pos: shorthand };
 
@@ -750,7 +751,7 @@ fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
         // If we get to this point, then all of the query inputs were green,
         // which means that the definition with this hash is guaranteed to
         // still exist in the current compilation session.
-        d.tcx().def_path_hash_to_def_id(def_path_hash, &mut || {
+        d.tcx.def_path_hash_to_def_id(def_path_hash, &mut || {
             panic!("Failed to convert DefPathHash {:?}", def_path_hash)
         })
     }
@@ -927,10 +928,11 @@ fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> {
     }
 }
 
-impl<'a, 'tcx, E> TyEncoder<'tcx> for CacheEncoder<'a, 'tcx, E>
+impl<'a, 'tcx, E> TyEncoder for CacheEncoder<'a, 'tcx, E>
 where
     E: 'a + OpaqueEncoder,
 {
+    type I = TyInterner<'tcx>;
     const CLEAR_CROSS_CRATE: bool = false;
 
     fn position(&self) -> usize {
index 8a35121f90cdbc48ad4beb39f8f4f7c02659f66a..0a80f014ae7927cfa07359cf5f484efd0d52be60 100644 (file)
@@ -21,6 +21,7 @@ rustc_serialize = { path = "../rustc_serialize" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
+rustc_type_ir = { path = "../rustc_type_ir" }
 parking_lot = "0.11"
 smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
 
index 0a1c350b2db13cba843d89b34b5ff62aaf826946..ddaac1c78a129f5002d165275ba48e2d48253869 100644 (file)
@@ -1,6 +1,7 @@
 //! ICH - Incremental Compilation Hash
 
 pub use self::hcx::StableHashingContext;
+use rustc_data_structures::stable_hasher::HashStable;
 use rustc_span::symbol::{sym, Symbol};
 
 mod hcx;
     sym::rustc_partition_codegened,
     sym::rustc_expected_cgu_reuse,
 ];
+
+#[allow(rustc::usage_of_ty_tykind)]
+impl<'__ctx, I: rustc_type_ir::Interner> HashStable<StableHashingContext<'__ctx>>
+    for rustc_type_ir::TyKind<I>
+where
+    I::AdtDef: HashStable<StableHashingContext<'__ctx>>,
+    I::DefId: HashStable<StableHashingContext<'__ctx>>,
+    I::SubstsRef: HashStable<StableHashingContext<'__ctx>>,
+    I::Ty: HashStable<StableHashingContext<'__ctx>>,
+    I::Const: HashStable<StableHashingContext<'__ctx>>,
+    I::TypeAndMut: HashStable<StableHashingContext<'__ctx>>,
+    I::PolyFnSig: HashStable<StableHashingContext<'__ctx>>,
+    I::ListBinderExistentialPredicate: HashStable<StableHashingContext<'__ctx>>,
+    I::Region: HashStable<StableHashingContext<'__ctx>>,
+    I::Movability: HashStable<StableHashingContext<'__ctx>>,
+    I::Mutability: HashStable<StableHashingContext<'__ctx>>,
+    I::BinderListTy: HashStable<StableHashingContext<'__ctx>>,
+    I::ListTy: HashStable<StableHashingContext<'__ctx>>,
+    I::ProjectionTy: HashStable<StableHashingContext<'__ctx>>,
+    I::BoundTy: HashStable<StableHashingContext<'__ctx>>,
+    I::ParamTy: HashStable<StableHashingContext<'__ctx>>,
+    I::PlaceholderType: HashStable<StableHashingContext<'__ctx>>,
+    I::InferTy: HashStable<StableHashingContext<'__ctx>>,
+    I::DelaySpanBugEmitted: HashStable<StableHashingContext<'__ctx>>,
+{
+    #[inline]
+    fn hash_stable(
+        &self,
+        __hcx: &mut crate::ich::StableHashingContext<'__ctx>,
+        __hasher: &mut rustc_data_structures::stable_hasher::StableHasher,
+    ) {
+        std::mem::discriminant(self).hash_stable(__hcx, __hasher);
+        use rustc_type_ir::TyKind::*;
+        match self {
+            Bool => {}
+            Char => {}
+            Int(i) => {
+                i.hash_stable(__hcx, __hasher);
+            }
+            Uint(u) => {
+                u.hash_stable(__hcx, __hasher);
+            }
+            Float(f) => {
+                f.hash_stable(__hcx, __hasher);
+            }
+            Adt(adt, substs) => {
+                adt.hash_stable(__hcx, __hasher);
+                substs.hash_stable(__hcx, __hasher);
+            }
+            Foreign(def_id) => {
+                def_id.hash_stable(__hcx, __hasher);
+            }
+            Str => {}
+            Array(t, c) => {
+                t.hash_stable(__hcx, __hasher);
+                c.hash_stable(__hcx, __hasher);
+            }
+            Slice(t) => {
+                t.hash_stable(__hcx, __hasher);
+            }
+            RawPtr(tam) => {
+                tam.hash_stable(__hcx, __hasher);
+            }
+            Ref(r, t, m) => {
+                r.hash_stable(__hcx, __hasher);
+                t.hash_stable(__hcx, __hasher);
+                m.hash_stable(__hcx, __hasher);
+            }
+            FnDef(def_id, substs) => {
+                def_id.hash_stable(__hcx, __hasher);
+                substs.hash_stable(__hcx, __hasher);
+            }
+            FnPtr(polyfnsig) => {
+                polyfnsig.hash_stable(__hcx, __hasher);
+            }
+            Dynamic(l, r) => {
+                l.hash_stable(__hcx, __hasher);
+                r.hash_stable(__hcx, __hasher);
+            }
+            Closure(def_id, substs) => {
+                def_id.hash_stable(__hcx, __hasher);
+                substs.hash_stable(__hcx, __hasher);
+            }
+            Generator(def_id, substs, m) => {
+                def_id.hash_stable(__hcx, __hasher);
+                substs.hash_stable(__hcx, __hasher);
+                m.hash_stable(__hcx, __hasher);
+            }
+            GeneratorWitness(b) => {
+                b.hash_stable(__hcx, __hasher);
+            }
+            Never => {}
+            Tuple(substs) => {
+                substs.hash_stable(__hcx, __hasher);
+            }
+            Projection(p) => {
+                p.hash_stable(__hcx, __hasher);
+            }
+            Opaque(def_id, substs) => {
+                def_id.hash_stable(__hcx, __hasher);
+                substs.hash_stable(__hcx, __hasher);
+            }
+            Param(p) => {
+                p.hash_stable(__hcx, __hasher);
+            }
+            Bound(d, b) => {
+                d.hash_stable(__hcx, __hasher);
+                b.hash_stable(__hcx, __hasher);
+            }
+            Placeholder(p) => {
+                p.hash_stable(__hcx, __hasher);
+            }
+            Infer(i) => {
+                i.hash_stable(__hcx, __hasher);
+            }
+            Error(d) => {
+                d.hash_stable(__hcx, __hasher);
+            }
+        }
+    }
+}
index 23700e653e36a23359a66ebc382dd11183ec01f6..8d04b8816ffbe59dce69ab985fe1bea9872cd744 100644 (file)
@@ -13,7 +13,7 @@ fn sized_constraint_for_ty<'tcx>(
     adtdef: ty::AdtDef<'tcx>,
     ty: Ty<'tcx>,
 ) -> Vec<Ty<'tcx>> {
-    use ty::TyKind::*;
+    use rustc_type_ir::sty::TyKind::*;
 
     let result = match ty.kind() {
         Bool | Char | Int(..) | Uint(..) | Float(..) | RawPtr(..) | Ref(..) | FnDef(..)
index 439e6cdf70698945a183501613650e651a60454b..b8066f2e5d89186f73191fb623400c1ec3593065 100644 (file)
@@ -12,3 +12,4 @@ rustc_index = { path = "../rustc_index" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_macros = { path = "../rustc_macros" }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/compiler/rustc_type_ir/src/codec.rs b/compiler/rustc_type_ir/src/codec.rs
new file mode 100644 (file)
index 0000000..e0138f8
--- /dev/null
@@ -0,0 +1,63 @@
+use crate::Interner;
+
+use rustc_data_structures::stable_map::FxHashMap;
+use rustc_serialize::{Decoder, Encoder};
+
+/// The shorthand encoding uses an enum's variant index `usize`
+/// and is offset by this value so it never matches a real variant.
+/// This offset is also chosen so that the first byte is never < 0x80.
+pub const SHORTHAND_OFFSET: usize = 0x80;
+
+/// Trait for decoding to a reference.
+///
+/// This is a separate trait from `Decodable` so that we can implement it for
+/// upstream types, such as `FxHashSet`.
+///
+/// The `TyDecodable` derive macro will use this trait for fields that are
+/// references (and don't use a type alias to hide that).
+///
+/// `Decodable` can still be implemented in cases where `Decodable` is required
+/// by a trait bound.
+pub trait RefDecodable<'tcx, D: TyDecoder> {
+    fn decode(d: &mut D) -> &'tcx Self;
+}
+
+pub trait TyEncoder: Encoder {
+    type I: Interner;
+    const CLEAR_CROSS_CRATE: bool;
+
+    fn position(&self) -> usize;
+    fn type_shorthands(&mut self) -> &mut FxHashMap<<Self::I as Interner>::Ty, usize>;
+    fn predicate_shorthands(
+        &mut self,
+    ) -> &mut FxHashMap<<Self::I as Interner>::PredicateKind, usize>;
+    fn encode_alloc_id(
+        &mut self,
+        alloc_id: &<Self::I as Interner>::AllocId,
+    ) -> Result<(), Self::Error>;
+}
+
+pub trait TyDecoder: Decoder {
+    type I: Interner;
+    const CLEAR_CROSS_CRATE: bool;
+
+    fn interner(&self) -> Self::I;
+
+    fn peek_byte(&self) -> u8;
+
+    fn position(&self) -> usize;
+
+    fn cached_ty_for_shorthand<F>(&mut self, shorthand: usize, or_insert_with: F) -> <Self::I as Interner>::Ty
+    where
+        F: FnOnce(&mut Self) -> <Self::I as Interner>::Ty;
+
+    fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
+    where
+        F: FnOnce(&mut Self) -> R;
+
+    fn positioned_at_shorthand(&self) -> bool {
+        (self.peek_byte() & (SHORTHAND_OFFSET as u8)) != 0
+    }
+
+    fn decode_alloc_id(&mut self) -> <Self::I as Interner>::AllocId;
+}
\ No newline at end of file
index c63e9c31d535c44cc62698280f26cf5a61ab7dca..960e42d8006ac77dbafd5ea04e1b81d5c07967ec 100644 (file)
@@ -1,4 +1,5 @@
 #![feature(min_specialization)]
+#![feature(rustc_attrs)]
 
 #[macro_use]
 extern crate bitflags;
@@ -7,9 +8,147 @@
 
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::unify::{EqUnifyValue, UnifyKey};
+//use rustc_serialize::{Decodable, Encodable};
+use smallvec::SmallVec;
 use std::fmt;
+use std::fmt::Debug;
+use std::hash::Hash;
 use std::mem::discriminant;
 
+pub mod codec;
+pub mod sty;
+
+pub use codec::*;
+pub use sty::*;
+
+extern crate self as rustc_type_ir;
+
+pub trait Interner {
+    type AdtDef: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type SubstsRef: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type DefId: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type Ty: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type Const: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type Region: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type TypeAndMut: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type Mutability: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type Movability: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type PolyFnSig: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type ListBinderExistentialPredicate: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type BinderListTy: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type ListTy: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type ProjectionTy: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type ParamTy: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type BoundTy: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type PlaceholderType: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type InferTy: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type DelaySpanBugEmitted: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type PredicateKind: Clone + Debug + Hash + PartialEq + Eq;
+    type AllocId: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+}
+
+pub trait InternAs<T: ?Sized, R> {
+    type Output;
+    fn intern_with<F>(self, f: F) -> Self::Output
+    where
+        F: FnOnce(&T) -> R;
+}
+
+impl<I, T, R, E> InternAs<[T], R> for I
+where
+    E: InternIteratorElement<T, R>,
+    I: Iterator<Item = E>,
+{
+    type Output = E::Output;
+    fn intern_with<F>(self, f: F) -> Self::Output
+    where
+        F: FnOnce(&[T]) -> R,
+    {
+        E::intern_with(self, f)
+    }
+}
+
+pub trait InternIteratorElement<T, R>: Sized {
+    type Output;
+    fn intern_with<I: Iterator<Item = Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output;
+}
+
+impl<T, R> InternIteratorElement<T, R> for T {
+    type Output = R;
+    fn intern_with<I: Iterator<Item = Self>, F: FnOnce(&[T]) -> R>(
+        mut iter: I,
+        f: F,
+    ) -> Self::Output {
+        // This code is hot enough that it's worth specializing for the most
+        // common length lists, to avoid the overhead of `SmallVec` creation.
+        // Lengths 0, 1, and 2 typically account for ~95% of cases. If
+        // `size_hint` is incorrect a panic will occur via an `unwrap` or an
+        // `assert`.
+        match iter.size_hint() {
+            (0, Some(0)) => {
+                assert!(iter.next().is_none());
+                f(&[])
+            }
+            (1, Some(1)) => {
+                let t0 = iter.next().unwrap();
+                assert!(iter.next().is_none());
+                f(&[t0])
+            }
+            (2, Some(2)) => {
+                let t0 = iter.next().unwrap();
+                let t1 = iter.next().unwrap();
+                assert!(iter.next().is_none());
+                f(&[t0, t1])
+            }
+            _ => f(&iter.collect::<SmallVec<[_; 8]>>()),
+        }
+    }
+}
+
+impl<'a, T, R> InternIteratorElement<T, R> for &'a T
+where
+    T: Clone + 'a,
+{
+    type Output = R;
+    fn intern_with<I: Iterator<Item = Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output {
+        // This code isn't hot.
+        f(&iter.cloned().collect::<SmallVec<[_; 8]>>())
+    }
+}
+
+impl<T, R, E> InternIteratorElement<T, R> for Result<T, E> {
+    type Output = Result<R, E>;
+    fn intern_with<I: Iterator<Item = Self>, F: FnOnce(&[T]) -> R>(
+        mut iter: I,
+        f: F,
+    ) -> Self::Output {
+        // This code is hot enough that it's worth specializing for the most
+        // common length lists, to avoid the overhead of `SmallVec` creation.
+        // Lengths 0, 1, and 2 typically account for ~95% of cases. If
+        // `size_hint` is incorrect a panic will occur via an `unwrap` or an
+        // `assert`, unless a failure happens first, in which case the result
+        // will be an error anyway.
+        Ok(match iter.size_hint() {
+            (0, Some(0)) => {
+                assert!(iter.next().is_none());
+                f(&[])
+            }
+            (1, Some(1)) => {
+                let t0 = iter.next().unwrap()?;
+                assert!(iter.next().is_none());
+                f(&[t0])
+            }
+            (2, Some(2)) => {
+                let t0 = iter.next().unwrap()?;
+                let t1 = iter.next().unwrap()?;
+                assert!(iter.next().is_none());
+                f(&[t0, t1])
+            }
+            _ => f(&iter.collect::<Result<SmallVec<[_; 8]>, _>>()?),
+        })
+    }
+}
+
 bitflags! {
     /// Flags that we track on types. These flags are propagated upwards
     /// through the type during type construction, so that we can quickly check
diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs
new file mode 100644 (file)
index 0000000..8f43904
--- /dev/null
@@ -0,0 +1,454 @@
+use crate::DebruijnIndex;
+use crate::FloatTy;
+use crate::IntTy;
+use crate::Interner;
+use crate::TyDecoder;
+use crate::TyEncoder;
+use crate::UintTy;
+
+use rustc_serialize::{Decodable, Encodable};
+
+/// Defines the kinds of types used by the type system.
+///
+/// Types written by the user start out as [hir::TyKind](rustc_hir::TyKind) and get
+/// converted to this representation using `AstConv::ast_ty_to_ty`.
+#[allow(rustc::usage_of_ty_tykind)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+//#[derive(TyEncodable, TyDecodable)]
+//#[derive(HashStable)]
+#[rustc_diagnostic_item = "TyKind"]
+pub enum TyKind<I: Interner> {
+    /// The primitive boolean type. Written as `bool`.
+    Bool,
+
+    /// The primitive character type; holds a Unicode scalar value
+    /// (a non-surrogate code point). Written as `char`.
+    Char,
+
+    /// A primitive signed integer type. For example, `i32`.
+    Int(IntTy),
+
+    /// A primitive unsigned integer type. For example, `u32`.
+    Uint(UintTy),
+
+    /// A primitive floating-point type. For example, `f64`.
+    Float(FloatTy),
+
+    /// Algebraic data types (ADT). For example: structures, enumerations and unions.
+    ///
+    /// For example, the type `List<i32>` would be represented using the `AdtDef`
+    /// for `struct List<T>` and the substs `[i32]`.
+    ///
+    /// Note that generic parameters in fields only get lazily substituted
+    /// by using something like `adt_def.all_fields().map(|field| field.ty(tcx, substs))`.
+    Adt(I::AdtDef, I::SubstsRef),
+
+    /// An unsized FFI type that is opaque to Rust. Written as `extern type T`.
+    Foreign(I::DefId),
+
+    /// The pointee of a string slice. Written as `str`.
+    Str,
+
+    /// An array with the given length. Written as `[T; N]`.
+    Array(I::Ty, I::Const),
+
+    /// The pointee of an array slice. Written as `[T]`.
+    Slice(I::Ty),
+
+    /// A raw pointer. Written as `*mut T` or `*const T`
+    RawPtr(I::TypeAndMut),
+
+    /// A reference; a pointer with an associated lifetime. Written as
+    /// `&'a mut T` or `&'a T`.
+    Ref(I::Region, I::Ty, I::Mutability),
+
+    /// The anonymous type of a function declaration/definition. Each
+    /// function has a unique type.
+    ///
+    /// For the function `fn foo() -> i32 { 3 }` this type would be
+    /// shown to the user as `fn() -> i32 {foo}`.
+    ///
+    /// For example the type of `bar` here:
+    /// ```rust
+    /// fn foo() -> i32 { 1 }
+    /// let bar = foo; // bar: fn() -> i32 {foo}
+    /// ```
+    FnDef(I::DefId, I::SubstsRef),
+
+    /// A pointer to a function. Written as `fn() -> i32`.
+    ///
+    /// Note that both functions and closures start out as either
+    /// [FnDef] or [Closure] which can be then be coerced to this variant.
+    ///
+    /// For example the type of `bar` here:
+    ///
+    /// ```rust
+    /// fn foo() -> i32 { 1 }
+    /// let bar: fn() -> i32 = foo;
+    /// ```
+    FnPtr(I::PolyFnSig),
+
+    /// A trait object. Written as `dyn for<'b> Trait<'b, Assoc = u32> + Send + 'a`.
+    Dynamic(I::ListBinderExistentialPredicate, I::Region),
+
+    /// The anonymous type of a closure. Used to represent the type of `|a| a`.
+    ///
+    /// Closure substs contain both the - potentially substituted - generic parameters
+    /// of its parent and some synthetic parameters. See the documentation for
+    /// [ClosureSubsts] for more details.
+    Closure(I::DefId, I::SubstsRef),
+
+    /// The anonymous type of a generator. Used to represent the type of
+    /// `|a| yield a`.
+    ///
+    /// For more info about generator substs, visit the documentation for
+    /// [GeneratorSubsts].
+    Generator(I::DefId, I::SubstsRef, I::Movability),
+
+    /// A type representing the types stored inside a generator.
+    /// This should only appear as part of the [GeneratorSubsts].
+    ///
+    /// Note that the captured variables for generators are stored separately
+    /// using a tuple in the same way as for closures.
+    ///
+    /// Unlike upvars, the witness can reference lifetimes from
+    /// inside of the generator itself. To deal with them in
+    /// the type of the generator, we convert them to higher ranked
+    /// lifetimes bound by the witness itself.
+    ///
+    /// Looking at the following example, the witness for this generator
+    /// may end up as something like `for<'a> [Vec<i32>, &'a Vec<i32>]`:
+    ///
+    /// ```ignore UNSOLVED (ask @compiler-errors, should this error? can we just swap the yields?)
+    /// #![feature(generators)]
+    /// |a| {
+    ///     let x = &vec![3];
+    ///     yield a;
+    ///     yield x[0];
+    /// }
+    /// # ;
+    /// ```
+    GeneratorWitness(I::BinderListTy),
+
+    /// The never type `!`.
+    Never,
+
+    /// A tuple type. For example, `(i32, bool)`.
+    Tuple(I::ListTy),
+
+    /// The projection of an associated type. For example,
+    /// `<T as Trait<..>>::N`.
+    Projection(I::ProjectionTy),
+
+    /// Opaque (`impl Trait`) type found in a return type.
+    ///
+    /// The `DefId` comes either from
+    /// * the `impl Trait` ast::Ty node,
+    /// * or the `type Foo = impl Trait` declaration
+    ///
+    /// For RPIT the substitutions are for the generics of the function,
+    /// while for TAIT it is used for the generic parameters of the alias.
+    ///
+    /// During codegen, `tcx.type_of(def_id)` can be used to get the underlying type.
+    Opaque(I::DefId, I::SubstsRef),
+
+    /// A type parameter; for example, `T` in `fn f<T>(x: T) {}`.
+    Param(I::ParamTy),
+
+    /// Bound type variable, used to represent the `'a` in `for<'a> fn(&'a ())`.
+    ///
+    /// For canonical queries, we replace inference variables with bound variables,
+    /// so e.g. when checking whether `&'_ (): Trait<_>` holds, we canonicalize that to
+    /// `for<'a, T> &'a (): Trait<T>` and then convert the introduced bound variables
+    /// back to inference variables in a new inference context when inside of the query.
+    ///
+    /// See the `rustc-dev-guide` for more details about
+    /// [higher-ranked trait bounds][1] and [canonical queries][2].
+    ///
+    /// [1]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
+    /// [2]: https://rustc-dev-guide.rust-lang.org/traits/canonical-queries.html
+    Bound(DebruijnIndex, I::BoundTy),
+
+    /// A placeholder type, used during higher ranked subtyping to instantiate
+    /// bound variables.
+    Placeholder(I::PlaceholderType),
+
+    /// A type variable used during type checking.
+    ///
+    /// Similar to placeholders, inference variables also live in a universe to
+    /// correctly deal with higher ranked types. Though unlike placeholders,
+    /// that universe is stored in the `InferCtxt` instead of directly
+    /// inside of the type.
+    Infer(I::InferTy),
+
+    /// A placeholder for a type which could not be computed; this is
+    /// propagated to avoid useless error messages.
+    Error(I::DelaySpanBugEmitted),
+}
+
+#[allow(rustc::usage_of_ty_tykind)]
+impl<I: Interner> TyKind<I> {
+    #[inline]
+    pub fn is_primitive(&self) -> bool {
+        use crate::TyKind::*;
+        matches!(self, Bool | Char | Int(_) | Uint(_) | Float(_))
+    }
+}
+
+#[allow(rustc::usage_of_ty_tykind)]
+impl<__I: Interner, __E: TyEncoder> Encodable<__E> for TyKind<__I>
+where
+    __I::DelaySpanBugEmitted: Encodable<__E>,
+    __I::AdtDef: Encodable<__E>,
+    __I::SubstsRef: Encodable<__E>,
+    __I::DefId: Encodable<__E>,
+    __I::Ty: Encodable<__E>,
+    __I::Const: Encodable<__E>,
+    __I::Region: Encodable<__E>,
+    __I::TypeAndMut: Encodable<__E>,
+    __I::Mutability: Encodable<__E>,
+    __I::Movability: Encodable<__E>,
+    __I::PolyFnSig: Encodable<__E>,
+    __I::ListBinderExistentialPredicate: Encodable<__E>,
+    __I::BinderListTy: Encodable<__E>,
+    __I::ListTy: Encodable<__E>,
+    __I::ProjectionTy: Encodable<__E>,
+    __I::ParamTy: Encodable<__E>,
+    __I::BoundTy: Encodable<__E>,
+    __I::PlaceholderType: Encodable<__E>,
+    __I::InferTy: Encodable<__E>,
+    __I::DelaySpanBugEmitted: Encodable<__E>,
+    __I::PredicateKind: Encodable<__E>,
+    __I::AllocId: Encodable<__E>,
+{
+    fn encode(&self, e: &mut __E) -> Result<(), <__E as rustc_serialize::Encoder>::Error> {
+        rustc_serialize::Encoder::emit_enum(e, |e| {
+            use rustc_type_ir::TyKind::*;
+            match self {
+                Bool => e.emit_enum_variant("Bool", 0, 0, |_| Ok(())),
+                Char => e.emit_enum_variant("Char", 1, 0, |_| Ok(())),
+                Int(i) => e.emit_enum_variant("Int", 2, 1, |e| {
+                    e.emit_enum_variant_arg(true, |e| i.encode(e))?;
+                    Ok(())
+                }),
+                Uint(u) => e.emit_enum_variant("Uint", 3, 1, |e| {
+                    e.emit_enum_variant_arg(true, |e| u.encode(e))?;
+                    Ok(())
+                }),
+                Float(f) => e.emit_enum_variant("Float", 4, 1, |e| {
+                    e.emit_enum_variant_arg(true, |e| f.encode(e))?;
+                    Ok(())
+                }),
+                Adt(adt, substs) => e.emit_enum_variant("Adt", 5, 2, |e| {
+                    e.emit_enum_variant_arg(true, |e| adt.encode(e))?;
+                    e.emit_enum_variant_arg(false, |e| substs.encode(e))?;
+                    Ok(())
+                }),
+                Foreign(def_id) => e.emit_enum_variant("Foreign", 6, 1, |e| {
+                    e.emit_enum_variant_arg(true, |e| def_id.encode(e))?;
+                    Ok(())
+                }),
+                Str => e.emit_enum_variant("Str", 7, 0, |_| Ok(())),
+                Array(t, c) => e.emit_enum_variant("Array", 8, 2, |e| {
+                    e.emit_enum_variant_arg(true, |e| t.encode(e))?;
+                    e.emit_enum_variant_arg(false, |e| c.encode(e))?;
+                    Ok(())
+                }),
+                Slice(t) => e.emit_enum_variant("Slice", 9, 1, |e| {
+                    e.emit_enum_variant_arg(true, |e| t.encode(e))?;
+                    Ok(())
+                }),
+                RawPtr(tam) => e.emit_enum_variant("RawPtr", 10, 1, |e| {
+                    e.emit_enum_variant_arg(true, |e| tam.encode(e))?;
+                    Ok(())
+                }),
+                Ref(r, t, m) => e.emit_enum_variant("Ref", 11, 3, |e| {
+                    e.emit_enum_variant_arg(true, |e| r.encode(e))?;
+                    e.emit_enum_variant_arg(false, |e| t.encode(e))?;
+                    e.emit_enum_variant_arg(false, |e| m.encode(e))?;
+                    Ok(())
+                }),
+                FnDef(def_id, substs) => e.emit_enum_variant("FnDef", 12, 2, |e| {
+                    e.emit_enum_variant_arg(true, |e| def_id.encode(e))?;
+                    e.emit_enum_variant_arg(false, |e| substs.encode(e))?;
+                    Ok(())
+                }),
+                FnPtr(polyfnsig) => e.emit_enum_variant("FnPtr", 13, 1, |e| {
+                    e.emit_enum_variant_arg(true, |e| polyfnsig.encode(e))?;
+                    Ok(())
+                }),
+                Dynamic(l, r) => e.emit_enum_variant("Dynamic", 14, 2, |e| {
+                    e.emit_enum_variant_arg(true, |e| l.encode(e))?;
+                    e.emit_enum_variant_arg(false, |e| r.encode(e))?;
+                    Ok(())
+                }),
+                Closure(def_id, substs) => e.emit_enum_variant("Closure", 15, 2, |e| {
+                    e.emit_enum_variant_arg(true, |e| def_id.encode(e))?;
+                    e.emit_enum_variant_arg(false, |e| substs.encode(e))?;
+                    Ok(())
+                }),
+                Generator(def_id, substs, m) => e.emit_enum_variant("Generator", 16, 3, |e| {
+                    e.emit_enum_variant_arg(true, |e| def_id.encode(e))?;
+                    e.emit_enum_variant_arg(false, |e| substs.encode(e))?;
+                    e.emit_enum_variant_arg(false, |e| m.encode(e))?;
+                    Ok(())
+                }),
+                GeneratorWitness(b) => e.emit_enum_variant("GeneratorWitness", 17, 1, |e| {
+                    e.emit_enum_variant_arg(true, |e| b.encode(e))?;
+                    Ok(())
+                }),
+                Never => e.emit_enum_variant("Never", 18, 0, |_| Ok(())),
+                Tuple(substs) => e.emit_enum_variant("Tuple", 19, 1, |e| {
+                    e.emit_enum_variant_arg(true, |e| substs.encode(e))?;
+                    Ok(())
+                }),
+                Projection(p) => e.emit_enum_variant("Projection", 20, 1, |e| {
+                    e.emit_enum_variant_arg(true, |e| p.encode(e))?;
+                    Ok(())
+                }),
+                Opaque(def_id, substs) => e.emit_enum_variant("Opaque", 21, 2, |e| {
+                    e.emit_enum_variant_arg(true, |e| def_id.encode(e))?;
+                    e.emit_enum_variant_arg(false, |e| substs.encode(e))?;
+                    Ok(())
+                }),
+                Param(p) => e.emit_enum_variant("Param", 22, 1, |e| {
+                    e.emit_enum_variant_arg(true, |e| p.encode(e))?;
+                    Ok(())
+                }),
+                Bound(d, b) => e.emit_enum_variant("Bound", 23, 2, |e| {
+                    e.emit_enum_variant_arg(true, |e| d.encode(e))?;
+                    e.emit_enum_variant_arg(false, |e| b.encode(e))?;
+                    Ok(())
+                }),
+                Placeholder(p) => e.emit_enum_variant("Placeholder", 24, 1, |e| {
+                    e.emit_enum_variant_arg(true, |e| p.encode(e))?;
+                    Ok(())
+                }),
+                Infer(i) => e.emit_enum_variant("Infer", 25, 1, |e| {
+                    e.emit_enum_variant_arg(true, |e| i.encode(e))?;
+                    Ok(())
+                }),
+                Error(d) => e.emit_enum_variant("Error", 26, 1, |e| {
+                    e.emit_enum_variant_arg(true, |e| d.encode(e))?;
+                    Ok(())
+                }),
+            }
+        })
+    }
+}
+
+#[allow(rustc::usage_of_ty_tykind)]
+impl<__I: Interner, __D: TyDecoder<I = __I>> Decodable<__D> for TyKind<__I>
+where
+    __I::DelaySpanBugEmitted: Decodable<__D>,
+    __I::AdtDef: Decodable<__D>,
+    __I::SubstsRef: Decodable<__D>,
+    __I::DefId: Decodable<__D>,
+    __I::Ty: Decodable<__D>,
+    __I::Const: Decodable<__D>,
+    __I::Region: Decodable<__D>,
+    __I::TypeAndMut: Decodable<__D>,
+    __I::Mutability: Decodable<__D>,
+    __I::Movability: Decodable<__D>,
+    __I::PolyFnSig: Decodable<__D>,
+    __I::ListBinderExistentialPredicate: Decodable<__D>,
+    __I::BinderListTy: Decodable<__D>,
+    __I::ListTy: Decodable<__D>,
+    __I::ProjectionTy: Decodable<__D>,
+    __I::ParamTy: Decodable<__D>,
+    __I::BoundTy: Decodable<__D>,
+    __I::PlaceholderType: Decodable<__D>,
+    __I::InferTy: Decodable<__D>,
+    __I::DelaySpanBugEmitted: Decodable<__D>,
+    __I::PredicateKind: Decodable<__D>,
+    __I::AllocId: Decodable<__D>,
+{
+    fn decode(__decoder: &mut __D) -> Self {
+        use TyKind::*;
+
+        match rustc_serialize::Decoder::read_usize(__decoder) {
+            0 => Bool,
+            1 => Char,
+            2 => Int(rustc_serialize::Decodable::decode(__decoder)),
+            3 => Uint(rustc_serialize::Decodable::decode(__decoder)),
+            4 => Float(rustc_serialize::Decodable::decode(__decoder)),
+            5 => Adt(
+                rustc_serialize::Decodable::decode(__decoder),
+                rustc_serialize::Decodable::decode(__decoder),
+            ),
+            6 => Foreign(rustc_serialize::Decodable::decode(__decoder)),
+            7 => Str,
+            8 => Array(
+                rustc_serialize::Decodable::decode(__decoder),
+                rustc_serialize::Decodable::decode(__decoder),
+            ),
+            9 => Slice(rustc_serialize::Decodable::decode(__decoder)),
+            10 => RawPtr(
+                rustc_serialize::Decodable::decode(__decoder),
+            ),
+            11 => Ref(
+                rustc_serialize::Decodable::decode(__decoder),
+                rustc_serialize::Decodable::decode(__decoder),
+                rustc_serialize::Decodable::decode(__decoder),
+            ),
+            12 => FnDef(
+                rustc_serialize::Decodable::decode(__decoder),
+                rustc_serialize::Decodable::decode(__decoder),
+            ),
+            13 => FnPtr(
+                rustc_serialize::Decodable::decode(__decoder),
+            ),
+            14 => Dynamic(
+                rustc_serialize::Decodable::decode(__decoder),
+                rustc_serialize::Decodable::decode(__decoder),
+            ),
+            15 => Closure(
+                rustc_serialize::Decodable::decode(__decoder),
+                rustc_serialize::Decodable::decode(__decoder),
+            ),
+            16 => Generator(
+                rustc_serialize::Decodable::decode(__decoder),
+                rustc_serialize::Decodable::decode(__decoder),
+                rustc_serialize::Decodable::decode(__decoder),
+            ),
+            17 => GeneratorWitness(
+                rustc_serialize::Decodable::decode(__decoder),
+            ),
+            18 => Never,
+            19 => Tuple(
+                rustc_serialize::Decodable::decode(__decoder),
+            ),
+            20 => Projection(
+                rustc_serialize::Decodable::decode(__decoder),
+            ),
+            21 => Opaque(
+                rustc_serialize::Decodable::decode(__decoder),
+                rustc_serialize::Decodable::decode(__decoder),
+            ),
+            22 => Param(
+                rustc_serialize::Decodable::decode(__decoder),
+            ),
+            23 => Bound(
+                rustc_serialize::Decodable::decode(__decoder),
+                rustc_serialize::Decodable::decode(__decoder),
+            ),
+            24 => Placeholder(
+                rustc_serialize::Decodable::decode(__decoder),
+            ),
+            25 => Infer(
+                rustc_serialize::Decodable::decode(__decoder),
+            ),
+            26 => Error(
+                rustc_serialize::Decodable::decode(__decoder),
+            ),
+            _ => 
+                panic!(
+                    "{}",
+                    format!(
+                        "invalid enum variant tag while decoding `{}`, expected 0..{}",
+                        "TyKind", 27,
+                    )
+                ),
+        }
+    }
+}
index 3135e9996ab8b8a7dc798dd604ac8ed09c7bfda3..d08d9938708c914cfab09270c0519c4ef99f970a 100644 (file)
@@ -177,7 +177,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did:
     tcx.infer_ctxt().enter(|infcx| {
         let cause = ObligationCause::misc(span, impl_hir_id);
 
-        use ty::TyKind::*;
+        use rustc_type_ir::sty::TyKind::*;
         match (source.kind(), target.kind()) {
             (&Ref(r_a, _, mutbl_a), Ref(r_b, _, mutbl_b))
                 if infcx.at(&cause, param_env).eq(r_a, *r_b).is_ok() && mutbl_a == *mutbl_b => {}