diff --git a/Cargo.lock b/Cargo.lock index 2f06506eaa458..f91d388d786a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4467,6 +4467,7 @@ dependencies = [ "rustc_index", "rustc_macros", "rustc_serialize", + "smallvec", ] [[package]] diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index c3e4945c4464c..940023eed8a71 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -713,10 +713,10 @@ macro_rules! declare_arena { self.dropless.alloc_slice(value) } - pub fn alloc_from_iter<'a, T: ArenaAllocatable<'tcx, U>, U>( - &'a self, - iter: impl ::std::iter::IntoIterator, - ) -> &'a mut [T] { + pub fn alloc_from_iter, U, V: IntoIterator>( + &self, + iter: V, + ) -> &mut [T] { T::allocate_from_iter(self, iter) } } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index f6a84966f7a91..23e9c80db01aa 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2476,7 +2476,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { ty: Ty<'tcx>, init: InitKind, ) -> Option { - 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)), @@ -2783,7 +2783,7 @@ impl ClashingExternDeclarations { 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(); diff --git a/compiler/rustc_macros/src/serialize.rs b/compiler/rustc_macros/src/serialize.rs index 7bc669f2b005c..dea0d8cf24f0c 100644 --- a/compiler/rustc_macros/src/serialize.rs +++ b/compiler/rustc_macros/src/serialize.rs @@ -7,7 +7,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>}); s.add_bounds(synstructure::AddBounds::Generics); decodable_body(s, decoder_ty) @@ -136,7 +136,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>}); s.add_bounds(synstructure::AddBounds::Generics); encodable_body(s, encoder_ty, false) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 48900fecd3e1b..1d49ec498a907 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -244,10 +244,6 @@ impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable>> Lazy<[T]> { } impl<'a, 'tcx> DecodeContext<'a, 'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx.expect("missing TyCtxt in DecodeContext") - } - fn cdata(&self) -> CrateMetadataRef<'a> { self.cdata.expect("missing CrateMetadata in DecodeContext") } diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 14bdb0a5a2d50..b8613ff5069a1 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -115,7 +115,7 @@ use rustc_target::abi::Endian; 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, @@ -200,7 +200,7 @@ enum AllocDiscriminant { Static, } -pub fn specialized_encode_alloc_id<'tcx, E: TyEncoder<'tcx>>( +pub fn specialized_encode_alloc_id<'tcx, E: TyEncoder>>( encoder: &mut E, tcx: TyCtxt<'tcx>, alloc_id: AllocId, @@ -270,11 +270,11 @@ pub struct AllocDecodingSession<'s> { session_id: DecodingSessionId, } -impl<'s> AllocDecodingSession<'s> { +impl<'s, 'tcx> AllocDecodingSession<'s> { /// Decodes an `AllocId` in a thread-safe way. pub fn decode_alloc_id(&self, decoder: &mut D) -> Result where - D: TyDecoder<'tcx>, + D: TyDecoder>, { // Read the index of the allocation. let idx = usize::try_from(decoder.read_u32()?).unwrap(); @@ -302,7 +302,7 @@ impl<'s> AllocDecodingSession<'s> { 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) @@ -346,7 +346,7 @@ impl<'s> AllocDecodingSession<'s> { // 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); Ok(alloc_id) } AllocDiscriminant::Fn => { @@ -354,7 +354,7 @@ impl<'s> AllocDecodingSession<'s> { 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); Ok(alloc_id) } AllocDiscriminant::Static => { @@ -362,7 +362,7 @@ impl<'s> AllocDecodingSession<'s> { trace!("creating extern static alloc ID"); let did = >::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); Ok(alloc_id) } } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 7ae7eab6e5a31..526aac8208144 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -381,7 +381,9 @@ impl<'tcx> Body<'tcx> { /// Returns an iterator over all user-declared mutable locals. #[inline] - pub fn mut_vars_iter<'a>(&'a self) -> impl Iterator + 'a { + pub fn mut_vars_iter<'a>( + &'a self, + ) -> impl Iterator + rustc_data_structures::captures::Captures<'tcx> + 'a { (self.arg_count + 1..self.local_decls.len()).filter_map(move |index| { let local = Local::new(index); let decl = &self.local_decls[local]; @@ -395,7 +397,9 @@ impl<'tcx> Body<'tcx> { /// Returns an iterator over all user-declared mutable arguments and locals. #[inline] - pub fn mut_vars_and_args_iter<'a>(&'a self) -> impl Iterator + 'a { + pub fn mut_vars_and_args_iter<'a>( + &'a self, + ) -> impl Iterator + rustc_data_structures::captures::Captures<'tcx> + 'a { (1..self.local_decls.len()).filter_map(move |index| { let local = Local::new(index); let decl = &self.local_decls[local]; @@ -543,7 +547,7 @@ impl ClearCrossCrate { const TAG_CLEAR_CROSS_CRATE_CLEAR: u8 = 0; const TAG_CLEAR_CROSS_CRATE_SET: u8 = 1; -impl<'tcx, E: TyEncoder<'tcx>, T: Encodable> Encodable for ClearCrossCrate { +impl> Encodable for ClearCrossCrate { #[inline] fn encode(&self, e: &mut E) -> Result<(), E::Error> { if E::CLEAR_CROSS_CRATE { @@ -559,7 +563,7 @@ impl<'tcx, E: TyEncoder<'tcx>, T: Encodable> Encodable for ClearCrossCrate } } } -impl<'tcx, D: TyDecoder<'tcx>, T: Decodable> Decodable for ClearCrossCrate { +impl> Decodable for ClearCrossCrate { #[inline] fn decode(d: &mut D) -> Result, D::Error> { if D::CLEAR_CROSS_CRATE { diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 95159ea46aec3..c4780aef05793 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -2,6 +2,7 @@ use crate::ich::StableHashingContext; use crate::mir::interpret::ErrorHandled; use crate::ty; use crate::ty::util::{Discr, IntTypeExt}; +use crate::ty::TyInterner; use rustc_data_structures::captures::Captures; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; @@ -10,10 +11,11 @@ use rustc_errors::ErrorReported; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_index::vec::{Idx, IndexVec}; -use rustc_serialize::{self, Encodable, Encoder}; +use rustc_serialize::{self, Encodable}; use rustc_session::DataTypeKind; use rustc_span::symbol::sym; use rustc_target::abi::VariantIdx; +use rustc_type_ir::codec::TyEncoder; use std::cell::RefCell; use std::cmp::Ordering; @@ -105,7 +107,13 @@ impl Hash for AdtDef { } } -impl Encodable for AdtDef { +impl>> Encodable for AdtDef { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + self.did.encode(s) + } +} + +impl>> Encodable for &AdtDef { fn encode(&self, s: &mut S) -> Result<(), S::Error> { self.did.encode(s) } diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 5ec665e913cc5..0f8faa5a5aa33 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -13,11 +13,13 @@ use crate::mir::{ interpret::{AllocId, Allocation}, }; use crate::ty::subst::SubstsRef; -use crate::ty::{self, List, Ty, TyCtxt}; +use crate::ty::{self, List, Ty}; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefId; -use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; +use rustc_middle::ty::TyInterner; +use rustc_serialize::{Decodable, Encodable}; use rustc_span::Span; +pub use rustc_type_ir::{TyDecoder, TyEncoder}; use std::hash::Hash; use std::intrinsics; use std::marker::DiscriminantKind; @@ -27,13 +29,13 @@ 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: Copy + Eq + Hash { type Variant: Encodable; 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>> EncodableWithShorthand for Ty<'tcx> { type Variant = ty::TyKind<'tcx>; #[inline] @@ -42,7 +44,9 @@ impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for Ty<'tcx> { } } -impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for ty::PredicateKind<'tcx> { +impl<'tcx, E: TyEncoder>> EncodableWithShorthand + for ty::PredicateKind<'tcx> +{ type Variant = ty::PredicateKind<'tcx>; #[inline] @@ -51,15 +55,6 @@ impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for ty::Predicate } } -pub trait TyEncoder<'tcx>: Encoder { - const CLEAR_CROSS_CRATE: bool; - - fn position(&self) -> usize; - fn type_shorthands(&mut self) -> &mut FxHashMap, usize>; - fn predicate_shorthands(&mut self) -> &mut FxHashMap, 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 @@ -70,16 +65,16 @@ 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>> { fn decode(d: &mut D) -> Result<&'tcx Self, D::Error>; } /// Encode the given value or a previously cached shorthand. pub fn encode_with_shorthand(encoder: &mut E, value: &T, cache: M) -> Result<(), E::Error> where - E: TyEncoder<'tcx>, + E: TyEncoder>, M: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap, - T: EncodableWithShorthand<'tcx, E>, + T: EncodableWithShorthand, // The discriminant and shorthand must have the same size. T::Variant: DiscriminantKind, { @@ -114,26 +109,28 @@ where Ok(()) } -impl<'tcx, E: TyEncoder<'tcx>> Encodable for Ty<'tcx> { +impl<'tcx, E: TyEncoder>> Encodable 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 for ty::Binder<'tcx, ty::PredicateKind<'tcx>> { +impl<'tcx, E: TyEncoder>> Encodable + 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 for ty::Predicate<'tcx> { +impl<'tcx, E: TyEncoder>> Encodable for ty::Predicate<'tcx> { fn encode(&self, e: &mut E) -> Result<(), E::Error> { self.kind().encode(e) } } -impl<'tcx, E: TyEncoder<'tcx>> Encodable for AllocId { +impl<'tcx, E: TyEncoder>> Encodable for AllocId { fn encode(&self, e: &mut E) -> Result<(), E::Error> { e.encode_alloc_id(self) } @@ -141,7 +138,7 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable for AllocId { macro_rules! encodable_via_deref { ($($t:ty),+) => { - $(impl<'tcx, E: TyEncoder<'tcx>> Encodable for $t { + $(impl<'tcx, E: TyEncoder>> Encodable for $t { fn encode(&self, e: &mut E) -> Result<(), E::Error> { (**self).encode(e) } @@ -158,55 +155,35 @@ encodable_via_deref! { &'tcx mir::coverage::CodeRegion } -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( - &mut self, - shorthand: usize, - or_insert_with: F, - ) -> Result, Self::Error> - where - F: FnOnce(&mut Self) -> Result, Self::Error>; - - fn with_position(&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) -> Result; -} - #[inline] -fn decode_arena_allocable<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable>( +fn decode_arena_allocable< + 'tcx, + D: TyDecoder>, + T: ArenaAllocatable<'tcx> + Decodable, +>( decoder: &mut D, ) -> Result<&'tcx T, D::Error> where - D: TyDecoder<'tcx>, + D: TyDecoder, { - Ok(decoder.tcx().arena.alloc(Decodable::decode(decoder)?)) + Ok(decoder.interner().tcx.arena.alloc(Decodable::decode(decoder)?)) } #[inline] -fn decode_arena_allocable_slice<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable>( +fn decode_arena_allocable_slice< + 'tcx, + D: TyDecoder>, + T: ArenaAllocatable<'tcx> + Decodable, +>( decoder: &mut D, ) -> Result<&'tcx [T], D::Error> where - D: TyDecoder<'tcx>, + D: TyDecoder, { - Ok(decoder.tcx().arena.alloc_from_iter( as Decodable>::decode(decoder)?)) + Ok(decoder.interner().tcx.arena.alloc_from_iter( as Decodable>::decode(decoder)?)) } -impl<'tcx, D: TyDecoder<'tcx>> Decodable for Ty<'tcx> { +impl<'tcx, D: TyDecoder>> Decodable for Ty<'tcx> { #[allow(rustc::usage_of_ty_tykind)] fn decode(decoder: &mut D) -> Result, D::Error> { // Handle shorthands first, if we have an usize > 0x80. @@ -219,13 +196,15 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable for Ty<'tcx> { decoder.with_position(shorthand, Ty::decode) }) } else { - let tcx = decoder.tcx(); - Ok(tcx.mk_ty(ty::TyKind::decode(decoder)?)) + let tcx = decoder.interner().tcx; + Ok(tcx.mk_ty(rustc_type_ir::TyKind::decode(decoder)?)) } } } -impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::Binder<'tcx, ty::PredicateKind<'tcx>> { +impl<'tcx, D: TyDecoder>> Decodable + for ty::Binder<'tcx, ty::PredicateKind<'tcx>> +{ fn decode(decoder: &mut D) -> Result>, D::Error> { let bound_vars = Decodable::decode(decoder)?; // Handle shorthands first, if we have an usize > 0x80. @@ -244,62 +223,62 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::Binder<'tcx, ty::PredicateKi } } -impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::Predicate<'tcx> { +impl<'tcx, D: TyDecoder>> Decodable for ty::Predicate<'tcx> { fn decode(decoder: &mut D) -> Result, D::Error> { let predicate_kind = Decodable::decode(decoder)?; - let predicate = decoder.tcx().mk_predicate(predicate_kind); + let predicate = decoder.interner().tcx.mk_predicate(predicate_kind); Ok(predicate) } } -impl<'tcx, D: TyDecoder<'tcx>> Decodable for SubstsRef<'tcx> { +impl<'tcx, D: TyDecoder>> Decodable for SubstsRef<'tcx> { fn decode(decoder: &mut D) -> Result { let len = decoder.read_usize()?; - let tcx = decoder.tcx(); + let tcx = decoder.interner().tcx; tcx.mk_substs((0..len).map(|_| Decodable::decode(decoder))) } } -impl<'tcx, D: TyDecoder<'tcx>> Decodable for mir::Place<'tcx> { +impl<'tcx, D: TyDecoder>> Decodable for mir::Place<'tcx> { fn decode(decoder: &mut D) -> Result { let local: mir::Local = Decodable::decode(decoder)?; let len = decoder.read_usize()?; let projection: &'tcx List> = - decoder.tcx().mk_place_elems((0..len).map(|_| Decodable::decode(decoder)))?; + decoder.interner().tcx.mk_place_elems((0..len).map(|_| Decodable::decode(decoder)))?; Ok(mir::Place { local, projection }) } } -impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::Region<'tcx> { +impl<'tcx, D: TyDecoder>> Decodable for ty::Region<'tcx> { fn decode(decoder: &mut D) -> Result { - Ok(decoder.tcx().mk_region(Decodable::decode(decoder)?)) + Ok(decoder.interner().tcx.mk_region(Decodable::decode(decoder)?)) } } -impl<'tcx, D: TyDecoder<'tcx>> Decodable for CanonicalVarInfos<'tcx> { +impl<'tcx, D: TyDecoder>> Decodable for CanonicalVarInfos<'tcx> { fn decode(decoder: &mut D) -> Result { let len = decoder.read_usize()?; let interned: Result>, _> = (0..len).map(|_| Decodable::decode(decoder)).collect(); - Ok(decoder.tcx().intern_canonical_var_infos(interned?.as_slice())) + Ok(decoder.interner().tcx.intern_canonical_var_infos(interned?.as_slice())) } } -impl<'tcx, D: TyDecoder<'tcx>> Decodable for AllocId { +impl>> Decodable for AllocId { fn decode(decoder: &mut D) -> Result { decoder.decode_alloc_id() } } -impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::SymbolName<'tcx> { +impl<'tcx, D: TyDecoder>> Decodable for ty::SymbolName<'tcx> { fn decode(decoder: &mut D) -> Result { - Ok(ty::SymbolName::new(decoder.tcx(), &decoder.read_str()?)) + Ok(ty::SymbolName::new(decoder.interner().tcx, &decoder.read_str()?)) } } macro_rules! impl_decodable_via_ref { ($($t:ty),+) => { - $(impl<'tcx, D: TyDecoder<'tcx>> Decodable for $t { + $(impl<'tcx, D: TyDecoder>> Decodable for $t { fn decode(decoder: &mut D) -> Result { RefDecodable::decode(decoder) } @@ -307,38 +286,53 @@ macro_rules! impl_decodable_via_ref { } } -impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::AdtDef { +impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for ty::AdtDef { fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { let def_id = >::decode(decoder)?; - Ok(decoder.tcx().adt_def(def_id)) + Ok(decoder.interner().tcx.adt_def(def_id)) + } +} + +impl<'tcx, D: TyDecoder>> Decodable for &ty::AdtDef { + fn decode(decoder: &mut D) -> Result { + RefDecodable::decode(decoder) + } +} + +impl<'tcx, D: TyDecoder>> Decodable for &ty::Const<'_> { + fn decode(decoder: &mut D) -> Result { + RefDecodable::decode(decoder) } } -impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List> { +impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for ty::List> { fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { let len = decoder.read_usize()?; - decoder.tcx().mk_type_list((0..len).map(|_| Decodable::decode(decoder))) + decoder.interner().tcx.mk_type_list((0..len).map(|_| Decodable::decode(decoder))) } } -impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> +impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for ty::List>> { fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { let len = decoder.read_usize()?; - decoder.tcx().mk_poly_existential_predicates((0..len).map(|_| Decodable::decode(decoder))) + decoder + .interner() + .tcx + .mk_poly_existential_predicates((0..len).map(|_| Decodable::decode(decoder))) } } -impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::Const<'tcx> { +impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for ty::Const<'tcx> { fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { - Ok(decoder.tcx().mk_const(Decodable::decode(decoder)?)) + Ok(decoder.interner().tcx.mk_const(Decodable::decode(decoder)?)) } } -impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [ty::ValTree<'tcx>] { +impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for [ty::ValTree<'tcx>] { fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { - Ok(decoder.tcx().arena.alloc_from_iter( + Ok(decoder.interner().tcx.arena.alloc_from_iter( (0..decoder.read_usize()?) .map(|_| Decodable::decode(decoder)) .collect::, _>>()?, @@ -346,15 +340,17 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [ty::ValTree<'tcx>] { } } -impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for Allocation { +impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for Allocation { fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { - Ok(decoder.tcx().intern_const_alloc(Decodable::decode(decoder)?)) + Ok(decoder.interner().tcx.intern_const_alloc(Decodable::decode(decoder)?)) } } -impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [(ty::Predicate<'tcx>, Span)] { +impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> + for [(ty::Predicate<'tcx>, Span)] +{ fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { - Ok(decoder.tcx().arena.alloc_from_iter( + Ok(decoder.interner().tcx.arena.alloc_from_iter( (0..decoder.read_usize()?) .map(|_| Decodable::decode(decoder)) .collect::, _>>()?, @@ -362,9 +358,11 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [(ty::Predicate<'tcx>, } } -impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [mir::abstract_const::Node<'tcx>] { +impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> + for [mir::abstract_const::Node<'tcx>] +{ fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { - Ok(decoder.tcx().arena.alloc_from_iter( + Ok(decoder.interner().tcx.arena.alloc_from_iter( (0..decoder.read_usize()?) .map(|_| Decodable::decode(decoder)) .collect::, _>>()?, @@ -372,9 +370,11 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [mir::abstract_const::N } } -impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [mir::abstract_const::NodeId] { +impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> + for [mir::abstract_const::NodeId] +{ fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { - Ok(decoder.tcx().arena.alloc_from_iter( + Ok(decoder.interner().tcx.arena.alloc_from_iter( (0..decoder.read_usize()?) .map(|_| Decodable::decode(decoder)) .collect::, _>>()?, @@ -382,10 +382,15 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [mir::abstract_const::N } } -impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List { +impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> + for ty::List +{ fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { let len = decoder.read_usize()?; - Ok(decoder.tcx().mk_bound_variable_kinds((0..len).map(|_| Decodable::decode(decoder)))?) + Ok(decoder + .interner() + .tcx + .mk_bound_variable_kinds((0..len).map(|_| Decodable::decode(decoder)))?) } } @@ -417,14 +422,14 @@ macro_rules! impl_arena_allocatable_decoder { ([]$args:tt) => {}; ([decode $(, $attrs:ident)*] [[$name:ident: $ty:ty], $tcx:lifetime]) => { - impl<$tcx, D: TyDecoder<$tcx>> RefDecodable<$tcx, D> for $ty { + impl<$tcx, D: TyDecoder>> RefDecodable<$tcx, D> for $ty { #[inline] fn decode(decoder: &mut D) -> Result<&$tcx Self, D::Error> { decode_arena_allocable(decoder) } } - impl<$tcx, D: TyDecoder<$tcx>> RefDecodable<$tcx, D> for [$ty] { + impl<$tcx, D: TyDecoder>> RefDecodable<$tcx, D> for [$ty] { #[inline] fn decode(decoder: &mut D) -> Result<&$tcx Self, D::Error> { decode_arena_allocable_slice(decoder) @@ -499,13 +504,13 @@ macro_rules! implement_ty_decoder { macro_rules! impl_binder_encode_decode { ($($t:ty),+ $(,)?) => { $( - impl<'tcx, E: TyEncoder<'tcx>> Encodable for ty::Binder<'tcx, $t> { + impl<'tcx, E: TyEncoder>> Encodable 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 for ty::Binder<'tcx, $t> { + impl<'tcx, D: TyDecoder>> Decodable for ty::Binder<'tcx, $t> { fn decode(decoder: &mut D) -> Result { let bound_vars = Decodable::decode(decoder)?; Ok(ty::Binder::bind_with_vars(Decodable::decode(decoder)?, bound_vars)) diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index c78151271c171..3165b65935849 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -1,7 +1,7 @@ use crate::mir::interpret::ConstValue; use crate::mir::interpret::{LitToConstInput, Scalar}; use crate::ty::subst::InternalSubsts; -use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{self, Ty, TyCtxt, TyInterner}; use crate::ty::{ParamEnv, ParamEnvAnd}; use rustc_errors::ErrorReported; use rustc_hir as hir; @@ -25,6 +25,14 @@ pub struct Const<'tcx> { pub val: ConstKind<'tcx>, } +impl>> rustc_serialize::Encodable + 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!(Const<'_>, 48); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 73991436b7b6b..6e3656946475c 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -17,7 +17,6 @@ use crate::thir::Thir; use crate::traits; use crate::ty::query::{self, OnDiskCache, TyCtxtAt}; use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts}; -use crate::ty::TyKind::*; use crate::ty::{ self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig, Const, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, FloatVar, FloatVid, GenericParamDefKind, InferConst, @@ -59,8 +58,9 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{Layout, TargetDataLayout, VariantIdx}; use rustc_target::spec::abi; +use rustc_type_ir::sty::TyKind::*; +use rustc_type_ir::{InternAs, InternIteratorElement, Interner}; -use smallvec::SmallVec; use std::any::Any; use std::borrow::Borrow; use std::cmp::Ordering; @@ -72,6 +72,69 @@ use std::mem; use std::ops::{Bound, Deref}; use std::sync::Arc; +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(&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 { + 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 = &'tcx ty::AdtDef; + type SubstsRef = ty::SubstsRef<'tcx>; + type DefId = DefId; + type Ty = Ty<'tcx>; + type Const = &'tcx 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>>; + type BinderListTy = Binder<'tcx, &'tcx List>>; + 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)] @@ -1019,6 +1082,10 @@ pub struct GlobalCtxt<'tcx> { } impl<'tcx> TyCtxt<'tcx> { + pub fn interner(self) -> TyInterner<'tcx> { + TyInterner { tcx: self } + } + pub fn typeck_opt_const_arg( self, def: ty::WithOptConstParam, @@ -2689,81 +2756,6 @@ impl TyCtxtAt<'tcx> { } } -pub trait InternAs { - type Output; - fn intern_with(self, f: F) -> Self::Output - where - F: FnOnce(&T) -> R; -} - -impl InternAs<[T], R> for I -where - E: InternIteratorElement, - I: Iterator, -{ - type Output = E::Output; - fn intern_with(self, f: F) -> Self::Output - where - F: FnOnce(&[T]) -> R, - { - E::intern_with(self, f) - } -} - -pub trait InternIteratorElement: Sized { - type Output; - fn intern_with, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output; -} - -impl InternIteratorElement for T { - type Output = R; - fn intern_with, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output { - f(&iter.collect::>()) - } -} - -impl<'a, T, R> InternIteratorElement for &'a T -where - T: Clone + 'a, -{ - type Output = R; - fn intern_with, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output { - f(&iter.cloned().collect::>()) - } -} - -impl InternIteratorElement for Result { - type Output = Result; - fn intern_with, 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. - // The match arms are in order of frequency. The 1, 2, and 0 cases are - // typically hit in ~95% of cases. We assume that if the upper and - // lower bounds from `size_hint` agree they are correct. - Ok(match iter.size_hint() { - (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]) - } - (0, Some(0)) => { - assert!(iter.next().is_none()); - f(&[]) - } - _ => f(&iter.collect::, _>>()?), - }) - } -} - // We are comparing types with different invariant lifetimes, so `ptr::eq` // won't work for us. fn ptr_eq(t: *const T, u: *const U) -> bool { diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index bfb4c0cb538de..2fe9024358057 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -1,11 +1,11 @@ //! Diagnostics related methods for `TyS`. -use crate::ty::TyKind::*; use crate::ty::{InferTy, TyCtxt, TyS}; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::{QPath, TyKind, WhereBoundPredicate, WherePredicate}; +use rustc_type_ir::sty::TyKind::*; impl<'tcx> TyS<'tcx> { /// Similar to `TyS::is_primitive`, but also considers inferred numeric values to be primitive. diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index 119cb135046db..6bbfe590d00c8 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -2,11 +2,12 @@ pub use self::def_id_forest::DefIdForest; use crate::ty; use crate::ty::context::TyCtxt; -use crate::ty::TyKind::*; use crate::ty::{AdtDef, FieldDef, Ty, TyS, 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 a diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index a2abbec74927c..f8a22c96d56f3 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -50,6 +50,7 @@ use std::{fmt, ptr, str}; 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; @@ -58,13 +59,12 @@ pub use self::consts::{Const, ConstInt, ConstKind, InferConst, ScalarInt, Uneval pub use self::context::{ tls, CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CtxtInterners, DelaySpanBugEmitted, FreeRegionInfo, GeneratorInteriorTypeCause, GlobalCtxt, - Lift, TyCtxt, TypeckResults, UserType, UserTypeAnnotationIndex, + Lift, TyCtxt, TyInterner, TypeckResults, UserType, UserTypeAnnotationIndex, }; pub use self::instance::{Instance, InstanceDef}; pub use self::list::List; 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, EarlyBoundRegion, diff --git a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs index ebaef347f4293..f3364de8d8217 100644 --- a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs @@ -3,7 +3,7 @@ use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState}; use crate::mir::{self, interpret}; use crate::ty::codec::{RefDecodable, TyDecoder, TyEncoder}; use crate::ty::context::TyCtxt; -use crate::ty::{self, Ty}; +use crate::ty::{self, Ty, TyInterner}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, OnceCell}; use rustc_data_structures::thin_vec::ThinVec; @@ -671,12 +671,13 @@ where Ok(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] @@ -697,7 +698,7 @@ impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> { where F: FnOnce(&mut Self) -> Result, Self::Error>, { - let tcx = self.tcx(); + let tcx = self.tcx; let cache_key = ty::CReaderCacheKey { cnum: None, pos: shorthand }; @@ -834,11 +835,11 @@ impl<'a, 'tcx> Decodable> for DefId { // 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. - Ok(d.tcx() + Ok(d.tcx .on_disk_cache .as_ref() .unwrap() - .def_path_hash_to_def_id(d.tcx(), def_path_hash) + .def_path_hash_to_def_id(d.tcx, def_path_hash) .unwrap()) } } @@ -995,10 +996,11 @@ where } } -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 { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 1d9ff512288db..35902f120380c 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2,23 +2,23 @@ #![allow(rustc::usage_of_ty_tykind)] -use self::TyKind::*; - use crate::infer::canonical::Canonical; use crate::ty::fold::BoundVarsCollector; 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, Ty, TyCtxt, TypeFlags, TypeFoldable, WithConstness, }; -use crate::ty::{DelaySpanBugEmitted, List, ParamEnv, TyS}; +use crate::ty::{List, ParamEnv, TyS}; use polonius_engine::Atom; use rustc_data_structures::captures::Captures; +use rustc_data_structures::stable_hasher::HashStable; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_index::vec::Idx; use rustc_macros::HashStable; +use rustc_middle::ich::StableHashingContext; use rustc_span::symbol::{kw, Symbol}; use rustc_target::abi::VariantIdx; use rustc_target::spec::abi; @@ -28,6 +28,10 @@ use std::marker::PhantomData; use std::ops::Range; use ty::util::IntTypeExt; +use rustc_type_ir::TyKind as IrTyKind; +pub type TyKind<'tcx> = IrTyKind>; +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> { @@ -77,6 +81,7 @@ impl BoundRegionKind { } } +/* /// Defines the kinds of types. /// /// N.B., if you change this, you'll probably want to change the corresponding @@ -200,7 +205,9 @@ pub enum TyKind<'tcx> { /// propagated to avoid useless error messages. Error(DelaySpanBugEmitted), } +*/ +/* impl TyKind<'tcx> { #[inline] pub fn is_primitive(&self) -> bool { @@ -219,6 +226,7 @@ impl TyKind<'tcx> { } } } +*/ // `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] @@ -812,7 +820,9 @@ impl<'tcx> List>> { } #[inline] - pub fn auto_traits<'a>(&'a self) -> impl Iterator + 'a { + pub fn auto_traits<'a>( + &'a self, + ) -> impl Iterator + rustc_data_structures::captures::Captures<'tcx> + 'a { self.iter().filter_map(|predicate| match predicate.skip_binder() { ExistentialPredicate::AutoTrait(did) => Some(did), _ => None, @@ -2233,3 +2243,122 @@ impl<'tcx> Default for VarianceDiagInfo<'tcx> { Self::None } } + +impl<'__ctx, I: rustc_type_ir::Interner> HashStable> + for rustc_type_ir::TyKind +where + I::AdtDef: HashStable>, + I::DefId: HashStable>, + I::SubstsRef: HashStable>, + I::Ty: HashStable>, + I::Const: HashStable>, + I::TypeAndMut: HashStable>, + I::PolyFnSig: HashStable>, + I::ListBinderExistentialPredicate: HashStable>, + I::Region: HashStable>, + I::Movability: HashStable>, + I::Mutability: HashStable>, + I::BinderListTy: HashStable>, + I::ProjectionTy: HashStable>, + I::BoundTy: HashStable>, + I::ParamTy: HashStable>, + I::PlaceholderType: HashStable>, + I::InferTy: HashStable>, + I::DelaySpanBugEmitted: HashStable>, +{ + #[inline] + fn hash_stable( + &self, + __hcx: &mut rustc_middle::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); + } + } + } +} diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 9b8d22d8eafce..88a45feeda9e4 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -4,7 +4,7 @@ use crate::mir; use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::sty::{ClosureSubsts, GeneratorSubsts}; -use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt}; +use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt, TyInterner}; use rustc_hir::def_id::DefId; use rustc_macros::HashStable; @@ -170,13 +170,13 @@ impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> { } } -impl<'tcx, E: TyEncoder<'tcx>> Encodable for GenericArg<'tcx> { +impl<'tcx, E: TyEncoder>> Encodable for GenericArg<'tcx> { fn encode(&self, e: &mut E) -> Result<(), E::Error> { self.unpack().encode(e) } } -impl<'tcx, D: TyDecoder<'tcx>> Decodable for GenericArg<'tcx> { +impl<'tcx, D: TyDecoder>> Decodable for GenericArg<'tcx> { fn decode(d: &mut D) -> Result, D::Error> { Ok(GenericArgKind::decode(d)?.pack()) } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 7bf69b9e637e9..5570e224de0a2 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -6,7 +6,6 @@ use crate::ty::fold::TypeFolder; use crate::ty::layout::IntegerExt; use crate::ty::query::TyCtxtAt; use crate::ty::subst::{GenericArgKind, Subst, SubstsRef}; -use crate::ty::TyKind::*; use crate::ty::{self, DefIdTree, List, Ty, TyCtxt, TypeFoldable}; use rustc_apfloat::Float as _; use rustc_ast as ast; @@ -20,6 +19,7 @@ use rustc_hir::def_id::DefId; use rustc_macros::HashStable; use rustc_span::DUMMY_SP; use rustc_target::abi::{Integer, Size, TargetDataLayout}; +use rustc_type_ir::TyKind::*; use smallvec::SmallVec; use std::{fmt, iter}; diff --git a/compiler/rustc_mir/src/interpret/cast.rs b/compiler/rustc_mir/src/interpret/cast.rs index 848b44d13aadf..919acc8f70126 100644 --- a/compiler/rustc_mir/src/interpret/cast.rs +++ b/compiler/rustc_mir/src/interpret/cast.rs @@ -102,7 +102,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { src: &ImmTy<'tcx, M::PointerTag>, cast_ty: Ty<'tcx>, ) -> InterpResult<'tcx, Immediate> { - 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() { @@ -189,7 +189,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let signed = src_layout.abi.is_signed(); // Also asserts that abi is `Scalar`. 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::*; + use rustc_type_ir::sty::TyKind::*; match *cast_ty.kind() { Int(_) | Uint(_) | RawPtr(_) => { let size = match *cast_ty.kind() { @@ -221,7 +221,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { where F: Float + Into> + FloatConvert + FloatConvert, { - use rustc_middle::ty::TyKind::*; + use rustc_type_ir::sty::TyKind::*; match *dest_ty.kind() { // float -> uint Uint(t) => { diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index ebc7b0d0d99cf..5576ea5fa4917 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -15,7 +15,7 @@ fn sized_constraint_for_ty<'tcx>( adtdef: &ty::AdtDef, ty: Ty<'tcx>, ) -> Vec> { - use ty::TyKind::*; + use rustc_type_ir::sty::TyKind::*; let result = match ty.kind() { Bool | Char | Int(..) | Uint(..) | Float(..) | RawPtr(..) | Ref(..) | FnDef(..) diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 3f64bd899979f..b35bac47fdd3e 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -13,3 +13,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 index 0000000000000..92114c3db1ede --- /dev/null +++ b/compiler/rustc_type_ir/src/codec.rs @@ -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) -> Result<&'tcx Self, D::Error>; +} + +pub trait TyEncoder: Encoder { + type I: Interner; + const CLEAR_CROSS_CRATE: bool; + + fn position(&self) -> usize; + fn type_shorthands(&mut self) -> &mut FxHashMap<::Ty, usize>; + fn predicate_shorthands(&mut self) -> &mut FxHashMap<::PredicateKind, usize>; + fn encode_alloc_id(&mut self, alloc_id: &::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( + &mut self, + shorthand: usize, + or_insert_with: F, + ) -> Result<::Ty, Self::Error> + where + F: FnOnce(&mut Self) -> Result<::Ty, Self::Error>; + + fn with_position(&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) -> Result<::AllocId, Self::Error>; +} diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 2d102127dd9d6..cc7dcd9dfe655 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -1,4 +1,5 @@ #![feature(min_specialization)] +#![feature(rustc_attrs)] #[macro_use] extern crate bitflags; @@ -7,9 +8,119 @@ extern crate rustc_macros; 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 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 { + type Output; + fn intern_with(self, f: F) -> Self::Output + where + F: FnOnce(&T) -> R; +} + +impl InternAs<[T], R> for I +where + E: InternIteratorElement, + I: Iterator, +{ + type Output = E::Output; + fn intern_with(self, f: F) -> Self::Output + where + F: FnOnce(&[T]) -> R, + { + E::intern_with(self, f) + } +} + +pub trait InternIteratorElement: Sized { + type Output; + fn intern_with, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output; +} + +impl InternIteratorElement for T { + type Output = R; + fn intern_with, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output { + f(&iter.collect::>()) + } +} + +impl<'a, T, R> InternIteratorElement for &'a T +where + T: Clone + 'a, +{ + type Output = R; + fn intern_with, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output { + f(&iter.cloned().collect::>()) + } +} + +impl InternIteratorElement for Result { + type Output = Result; + fn intern_with, 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. + // The match arms are in order of frequency. The 1, 2, and 0 cases are + // typically hit in ~95% of cases. We assume that if the upper and + // lower bounds from `size_hint` agree they are correct. + Ok(match iter.size_hint() { + (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]) + } + (0, Some(0)) => { + assert!(iter.next().is_none()); + f(&[]) + } + _ => f(&iter.collect::, _>>()?), + }) + } +} + 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 index 0000000000000..d31fa5936a9e6 --- /dev/null +++ b/compiler/rustc_type_ir/src/sty.rs @@ -0,0 +1,437 @@ +use crate::DebruijnIndex; +use crate::FloatTy; +use crate::IntTy; +use crate::UintTy; +use crate::Interner; +use crate::TyDecoder; +use crate::TyEncoder; + +use rustc_serialize::{Decodable, Encodable}; + +/// Defines the kinds of types. +/// +/// N.B., if you change this, you'll probably want to change the corresponding +/// AST structure in `rustc_ast/src/ast.rs` as well. +#[allow(rustc::usage_of_ty_tykind)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +//#[derive(TyEncodable, TyDecodable)] +#[rustc_diagnostic_item = "TyKind"] +pub enum TyKind { + /// 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. + /// + /// InternalSubsts here, possibly against intuition, *may* contain `Param`s. + /// That is, even after substitution it is possible that there are type + /// variables. This happens when the `Adt` corresponds to an ADT + /// definition and not a concrete use of it. + 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, which is output (for a function + /// named `foo` returning an `i32`) 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`. + /// + /// 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(I::DefId, I::SubstsRef), + + /// The anonymous type of a generator. Used to represent the type of + /// `|a| yield a`. + Generator(I::DefId, I::SubstsRef, I::Movability), + + /// A type representing the types stored inside a generator. + /// This should only appear in GeneratorInteriors. + GeneratorWitness(I::BinderListTy), + + /// The never type `!`. + Never, + + /// A tuple type. For example, `(i32, bool)`. + /// Use `TyS::tuple_fields` to iterate over the field types. + Tuple(I::SubstsRef), + + /// The projection of an associated type. For example, + /// `>::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 + /// The substitutions are for the generics of the function in question. + /// After typeck, the concrete type can be found in the `types` map. + Opaque(I::DefId, I::SubstsRef), + + /// A type parameter; for example, `T` in `fn f(x: T) {}`. + Param(I::ParamTy), + + /// Bound type variable, used only when preparing a trait query. + Bound(DebruijnIndex, I::BoundTy), + + /// A placeholder type - universally quantified higher-ranked type. + Placeholder(I::PlaceholderType), + + /// A type variable used during type checking. + 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 TyKind { + #[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::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> 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::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, + ) -> Result::Error> { + __decoder.read_enum( + |__decoder| { + __decoder.read_enum_variant( + &[ + "Bool", + "Char", + "Int", + "Uint", + "Float", + "Adt", + "Foreign", + "Str", + "Array", + "Slice", + "RawPtr", + "Ref", + "FnDef", + "FnPtr", + "Dynamic", + "Closure", + "Generator", + "GeneratorWitness", + "Never", + "Tuple", + "Projection", + "Opaque", + "Param", + "Bound", + "Placeholder", + "Infer", + "Error", + ], + |__decoder, __variant_idx| { + use TyKind::*; + Ok(match __variant_idx { + 0 => Bool, + 1 => Char, + 2 => Int(__decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?), + 3 => Uint(__decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?), + 4 => Float(__decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?), + 5 => Adt( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 6 => Foreign( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 7 => Str, + 8 => Array( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 9 => Slice( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 10 => RawPtr( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 11 => Ref( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 12 => FnDef( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 13 => FnPtr( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 14 => Dynamic( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 15 => Closure( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 16 => Generator( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 17 => GeneratorWitness( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 18 => Never, + 19 => Tuple( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 20 => Projection( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 21 => Opaque( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 22 => Param( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 23 => Bound( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 24 => Placeholder( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 25 => Infer( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + 26 => Error( + __decoder.read_enum_variant_arg(rustc_serialize::Decodable::decode)?, + ), + _ => return Err(rustc_serialize::Decoder::error(__decoder, &format!( + "invalid enum variant tag while decoding `{}`, expected 0..{}", + "TyKind", + 27, + ))), + }) + }) + } + ) + } +} diff --git a/compiler/rustc_typeck/src/coherence/builtin.rs b/compiler/rustc_typeck/src/coherence/builtin.rs index 8cae61e8c22f6..95a32a026bdca 100644 --- a/compiler/rustc_typeck/src/coherence/builtin.rs +++ b/compiler/rustc_typeck/src/coherence/builtin.rs @@ -145,7 +145,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef 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 => {}