"rustc_serialize",
"rustc_session",
"rustc_span",
+ "rustc_type_ir",
"tracing",
]
"rustc_session",
"rustc_span",
"rustc_target",
+ "rustc_type_ir",
"smallvec",
"tracing",
]
"rustc_index",
"rustc_macros",
"rustc_serialize",
+ "smallvec",
]
[[package]]
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,
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() {
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(_) => {
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) => {
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)),
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();
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)
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)
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,
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,
/// 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();
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)
// 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 => {
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 => {
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
}
}
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 {
}
}
}
-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 {
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]
}
}
-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]
}
}
-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
///
/// `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;
}
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>,
{
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.
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.
}
}
-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)
}
}
}
-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)),
)
}
([]$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)
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)
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;
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);
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,
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;
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)]
}
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
}
}
-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 {
//! 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,
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> {
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
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;
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};
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,
}
// `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)]
#![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> {
}
}
+/*
/// 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
/// propagated to avoid useless error messages.
Error(DelaySpanBugEmitted),
}
+*/
+/*
impl<'tcx> TyKind<'tcx> {
#[inline]
pub fn is_primitive(&self) -> bool {
}
}
}
+*/
+
+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"))]
}
#[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,
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;
}
}
-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()
}
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 {
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};
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};
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]
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]
where
F: FnOnce(&mut Self) -> Ty<'tcx>,
{
- let tcx = self.tcx();
+ let tcx = self.tcx;
let cache_key = ty::CReaderCacheKey { cnum: None, pos: shorthand };
// 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)
})
}
}
}
-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 {
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"] }
//! 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);
+ }
+ }
+ }
+}
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(..)
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"] }
--- /dev/null
+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
#![feature(min_specialization)]
+#![feature(rustc_attrs)]
#[macro_use]
extern crate bitflags;
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
--- /dev/null
+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,
+ )
+ ),
+ }
+ }
+}
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 => {}