From a7015fe8169ebfcd6707f34bf190cb4c4ae302f7 Mon Sep 17 00:00:00 2001 From: Wilco Kusee Date: Sun, 31 Jan 2021 10:32:34 +0100 Subject: [PATCH] Move things to rustc_type_ir --- Cargo.lock | 3 + .../rustc_const_eval/src/interpret/cast.rs | 6 +- compiler/rustc_lint/src/builtin.rs | 4 +- compiler/rustc_macros/src/serialize.rs | 4 +- .../rustc_middle/src/mir/interpret/mod.rs | 14 +- compiler/rustc_middle/src/mir/mod.rs | 4 +- compiler/rustc_middle/src/ty/codec.rs | 186 +++---- compiler/rustc_middle/src/ty/consts.rs | 10 +- compiler/rustc_middle/src/ty/context.rs | 175 +++---- compiler/rustc_middle/src/ty/diagnostics.rs | 2 +- .../rustc_middle/src/ty/inhabitedness/mod.rs | 3 +- compiler/rustc_middle/src/ty/mod.rs | 12 +- compiler/rustc_middle/src/ty/sty.rs | 36 +- compiler/rustc_middle/src/ty/subst.rs | 8 +- compiler/rustc_middle/src/ty/util.rs | 5 +- compiler/rustc_query_impl/Cargo.toml | 1 + .../rustc_query_impl/src/on_disk_cache.rs | 14 +- compiler/rustc_query_system/Cargo.toml | 1 + compiler/rustc_query_system/src/ich/mod.rs | 122 +++++ compiler/rustc_ty_utils/src/ty.rs | 2 +- compiler/rustc_type_ir/Cargo.toml | 1 + compiler/rustc_type_ir/src/codec.rs | 63 +++ compiler/rustc_type_ir/src/lib.rs | 139 ++++++ compiler/rustc_type_ir/src/sty.rs | 454 ++++++++++++++++++ .../rustc_typeck/src/coherence/builtin.rs | 2 +- 25 files changed, 1030 insertions(+), 241 deletions(-) create mode 100644 compiler/rustc_type_ir/src/codec.rs create mode 100644 compiler/rustc_type_ir/src/sty.rs diff --git a/Cargo.lock b/Cargo.lock index 42bf166a71c..871ff8f9cdb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4262,6 +4262,7 @@ dependencies = [ "rustc_serialize", "rustc_session", "rustc_span", + "rustc_type_ir", "tracing", ] @@ -4283,6 +4284,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", + "rustc_type_ir", "smallvec", "tracing", ] @@ -4484,6 +4486,7 @@ dependencies = [ "rustc_index", "rustc_macros", "rustc_serialize", + "smallvec", ] [[package]] diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 7cd2ba34b04..be34a77bdba 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -8,6 +8,7 @@ use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::layout::{IntegerExt, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, FloatTy, Ty, TypeAndMut}; use rustc_target::abi::{Integer, Variants}; +use rustc_type_ir::sty::TyKind::*; use super::{ util::ensure_monomorphic_enough, FnVal, ImmTy, Immediate, InterpCx, Machine, OpTy, PlaceTy, @@ -102,7 +103,7 @@ 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() { @@ -205,7 +206,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let v = scalar.to_bits(src_layout.size)?; let v = if signed { self.sign_extend(v, src_layout) } else { v }; trace!("cast_from_scalar: {}, {} -> {}", v, src_layout.ty, cast_ty); - use rustc_middle::ty::TyKind::*; Ok(match *cast_ty.kind() { Int(_) | Uint(_) => { @@ -247,7 +247,7 @@ 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_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 9317858aed9..6be78c52f99 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2489,7 +2489,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)), @@ -2801,7 +2801,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 535158ffd8d..653c728ee42 100644 --- a/compiler/rustc_macros/src/serialize.rs +++ b/compiler/rustc_macros/src/serialize.rs @@ -8,7 +8,7 @@ pub fn type_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2: if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") { s.add_impl_generic(parse_quote! { 'tcx }); } - s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_middle::ty::codec::TyDecoder<'tcx>}); + s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_type_ir::codec::TyDecoder>}); s.add_bounds(synstructure::AddBounds::Generics); decodable_body(s, decoder_ty) @@ -95,7 +95,7 @@ pub fn type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2: s.add_impl_generic(parse_quote! {'tcx}); } let encoder_ty = quote! { __E }; - s.add_impl_generic(parse_quote! {#encoder_ty: ::rustc_middle::ty::codec::TyEncoder<'tcx>}); + s.add_impl_generic(parse_quote! {#encoder_ty: ::rustc_type_ir::codec::TyEncoder>}); s.add_bounds(synstructure::AddBounds::Generics); encodable_body(s, encoder_ty, false) diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 16ef8d68be3..926afa8ccb6 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, @@ -203,7 +203,7 @@ enum AllocDiscriminant { Static, } -pub fn specialized_encode_alloc_id<'tcx, E: TyEncoder<'tcx>>( +pub fn specialized_encode_alloc_id<'tcx, E: TyEncoder>>( encoder: &mut E, tcx: TyCtxt<'tcx>, alloc_id: AllocId, @@ -277,7 +277,7 @@ impl<'s> AllocDecodingSession<'s> { /// Decodes an `AllocId` in a thread-safe way. pub fn decode_alloc_id<'tcx, D>(&self, decoder: &mut D) -> AllocId where - D: TyDecoder<'tcx>, + D: TyDecoder>, { // Read the index of the allocation. let idx = usize::try_from(decoder.read_u32()).unwrap(); @@ -305,7 +305,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) @@ -349,7 +349,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); alloc_id } AllocDiscriminant::Fn => { @@ -357,7 +357,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); alloc_id } AllocDiscriminant::Static => { @@ -365,7 +365,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); alloc_id } } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 9f8b22c8afc..71cea005cf8 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -668,7 +668,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 { @@ -684,7 +684,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) -> ClearCrossCrate { if D::CLEAR_CROSS_CRATE { diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 2a5191008a9..234649f1056 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -15,10 +15,12 @@ use crate::mir::{ 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; @@ -28,13 +30,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] @@ -43,7 +45,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] @@ -52,15 +56,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 @@ -71,7 +66,7 @@ pub trait TyEncoder<'tcx>: Encoder { /// /// `Decodable` can still be implemented in cases where `Decodable` is required /// by a trait bound. -pub trait RefDecodable<'tcx, D: TyDecoder<'tcx>> { +pub trait RefDecodable<'tcx, D: TyDecoder>> { fn decode(d: &mut D) -> &'tcx Self; } @@ -82,9 +77,9 @@ pub fn encode_with_shorthand<'tcx, E, T, M>( cache: M, ) -> Result<(), E::Error> where - E: TyEncoder<'tcx>, + E: TyEncoder>, 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, { @@ -119,100 +114,105 @@ 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 ty::Region<'tcx> { +impl<'tcx, E: TyEncoder>> Encodable for ty::Region<'tcx> { fn encode(&self, e: &mut E) -> Result<(), E::Error> { self.kind().encode(e) } } -impl<'tcx, E: TyEncoder<'tcx>> Encodable for ty::Const<'tcx> { +impl<'tcx, E: TyEncoder>> Encodable for ty::Const<'tcx> { fn encode(&self, e: &mut E) -> Result<(), E::Error> { self.0.0.encode(e) } } -impl<'tcx, E: TyEncoder<'tcx>> Encodable for ConstAllocation<'tcx> { +impl<'tcx, E: TyEncoder>> Encodable for ConstAllocation<'tcx> { fn encode(&self, e: &mut E) -> Result<(), E::Error> { self.inner().encode(e) } } -impl<'tcx, E: TyEncoder<'tcx>> Encodable for AdtDef<'tcx> { +impl<'tcx, E: TyEncoder>> Encodable for AdtDef<'tcx> { fn encode(&self, e: &mut E) -> Result<(), E::Error> { self.0.0.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) } } -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) -> Ty<'tcx> - where - F: FnOnce(&mut Self) -> Ty<'tcx>; - - 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 +macro_rules! encodable_via_deref { + ($($t:ty),+) => { + $(impl<'tcx, E: TyEncoder>> Encodable 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>( +fn decode_arena_allocable< + 'tcx, + D: TyDecoder>, + T: ArenaAllocatable<'tcx> + Decodable, +>( 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>( +fn decode_arena_allocable_slice< + 'tcx, + D: TyDecoder>, + T: ArenaAllocatable<'tcx> + Decodable, +>( decoder: &mut D, ) -> &'tcx [T] where - D: TyDecoder<'tcx>, + D: TyDecoder, { - decoder.tcx().arena.alloc_from_iter( as Decodable>::decode(decoder)) + 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) -> Ty<'tcx> { // Handle shorthands first, if we have a usize > 0x80. @@ -225,13 +225,13 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable for Ty<'tcx> { decoder.with_position(shorthand, Ty::decode) }) } else { - let tcx = decoder.tcx(); - tcx.mk_ty(ty::TyKind::decode(decoder)) + let tcx = decoder.interner().tcx; + tcx.mk_ty(rustc_type_ir::TyKind::decode(decoder)) } } } -impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::Binder<'tcx, ty::PredicateKind<'tcx>> { +impl<'tcx, D: TyDecoder>> Decodable for ty::Binder<'tcx, ty::PredicateKind<'tcx>> { fn decode(decoder: &mut D) -> ty::Binder<'tcx, ty::PredicateKind<'tcx>> { let bound_vars = Decodable::decode(decoder); // Handle shorthands first, if we have a usize > 0x80. @@ -250,64 +250,64 @@ 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) -> 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 for SubstsRef<'tcx> { +impl<'tcx, D: TyDecoder>> Decodable 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::, _>(|_| 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) -> 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::, _>(|_| Decodable::decode(decoder)), ); 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) -> Self { - decoder.tcx().mk_region(Decodable::decode(decoder)) + 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) -> Self { let len = decoder.read_usize(); let interned: Vec> = (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 for AllocId { +impl<'tcx, D: TyDecoder>> Decodable for AllocId { fn decode(decoder: &mut D) -> Self { 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) -> 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 for $t { + $(impl<'tcx, D: TyDecoder>> Decodable for $t { fn decode(decoder: &mut D) -> Self { RefDecodable::decode(decoder) } @@ -315,78 +315,78 @@ macro_rules! impl_decodable_via_ref { } } -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) -> &'tcx Self { 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) -> &'tcx Self { let len = decoder.read_usize(); - decoder.tcx().mk_poly_existential_predicates( + decoder.interner().tcx.mk_poly_existential_predicates( (0..len).map::, _>(|_| Decodable::decode(decoder)), ) } } -impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::Const<'tcx> { +impl<'tcx, D: TyDecoder>> Decodable 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>> 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::>(), ) } } -impl<'tcx, D: TyDecoder<'tcx>> Decodable for ConstAllocation<'tcx> { +impl<'tcx, D: TyDecoder>> Decodable 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 for AdtDef<'tcx> { +impl<'tcx, D: TyDecoder>> Decodable 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>> 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::>(), ) } } -impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [thir::abstract_const::Node<'tcx>] { +impl<'tcx, D: TyDecoder>> 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::>(), ) } } -impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [thir::abstract_const::NodeId] { +impl<'tcx, D: TyDecoder>> 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::>(), ) } } -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) -> &'tcx Self { let len = decoder.read_usize(); - decoder.tcx().mk_bound_variable_kinds( + decoder.interner().tcx.mk_bound_variable_kinds( (0..len).map::(|_| Decodable::decode(decoder)), ) } @@ -420,14 +420,14 @@ macro_rules! impl_arena_allocatable_decoder { ([]$args:tt) => {}; ([decode $(, $attrs:ident)*] [$name:ident: $ty:ty]) => { - impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for $ty { + impl<'tcx, D: TyDecoder>> 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>> RefDecodable<'tcx, D> for [$ty] { #[inline] fn decode(decoder: &mut D) -> &'tcx Self { decode_arena_allocable_slice(decoder) @@ -518,13 +518,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) -> Self { let bound_vars = Decodable::decode(decoder); 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 7af7eb4f5ec..58a237ee6f8 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -2,7 +2,7 @@ use crate::mir::interpret::ConstValue; use crate::mir::interpret::{LitToConstInput, Scalar}; use crate::ty::{ self, InlineConstSubsts, InlineConstSubstsParts, InternalSubsts, ParamEnv, ParamEnvAnd, Ty, - TyCtxt, TypeFoldable, + TyCtxt, TyInterner, TypeFoldable, }; use rustc_data_structures::intern::Interned; use rustc_errors::ErrorGuaranteed; @@ -40,6 +40,14 @@ pub struct ConstS<'tcx> { pub val: ConstKind<'tcx>, } +impl<'tcx, S: rustc_type_ir::TyEncoder>> 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!(ConstS<'_>, 48); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 3c08db5dc68..efe7a54b5bf 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -16,7 +16,6 @@ use crate::thir::Thir; use crate::traits; use crate::ty::query::{self, TyCtxtAt}; use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts}; -use crate::ty::TyKind::*; use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig, ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, @@ -60,9 +59,9 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{Layout, LayoutS, TargetDataLayout, VariantIdx}; use rustc_target::spec::abi; +use rustc_type_ir::sty::TyKind::*; +use rustc_type_ir::{InternAs, InternIteratorElement, Interner, TypeFlags}; -use rustc_type_ir::TypeFlags; -use smallvec::SmallVec; use std::any::Any; use std::borrow::Borrow; use std::cmp::Ordering; @@ -91,6 +90,70 @@ pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync { 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(&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 = 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>>; + type BinderListTy = Binder<'tcx, &'tcx List>>; + type ListTy = &'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)] @@ -1075,6 +1138,10 @@ pub struct GlobalCtxt<'tcx> { } impl<'tcx> TyCtxt<'tcx> { + pub fn interner(self) -> TyInterner<'tcx> { + TyInterner { tcx: self } + } + /// Expects a body and returns its codegen attributes. /// /// Unlike `codegen_fn_attrs`, this returns `CodegenFnAttrs::EMPTY` for @@ -2848,108 +2915,6 @@ impl<'tcx> 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>( - 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::>()), - } - } -} - -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 { - // This code isn't hot. - 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. - // 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::, _>>()?), - }) - } -} - // 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 a6717746979..462fc27009d 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -1,7 +1,6 @@ //! Diagnostics related methods for `Ty`. use crate::ty::subst::{GenericArg, GenericArgKind}; -use crate::ty::TyKind::*; use crate::ty::{ ConstKind, DefIdTree, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, InferTy, ProjectionTy, Term, Ty, TyCtxt, TypeAndMut, @@ -13,6 +12,7 @@ use rustc_hir as hir; 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> { diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index b8088766cca..3d22f5a04a2 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, 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 diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b61a3827602..2804912c9ab 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -51,6 +51,7 @@ use std::{fmt, 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; @@ -67,7 +68,7 @@ pub use self::consts::{ pub use self::context::{ tls, CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CtxtInterners, DelaySpanBugEmitted, FreeRegionInfo, GeneratorDiagnosticData, - GeneratorInteriorTypeCause, GlobalCtxt, Lift, OnDiskCache, TyCtxt, TypeckResults, UserType, + GeneratorInteriorTypeCause, GlobalCtxt, Lift, OnDiskCache, TyCtxt, TyInterner, TypeckResults, UserType, UserTypeAnnotationIndex, }; pub use self::instance::{Instance, InstanceDef}; @@ -76,7 +77,6 @@ pub use self::parameterized::ParameterizedOverTcx; pub use self::rvalue_scopes::RvalueScopes; pub use self::sty::BoundRegionKind::*; pub use self::sty::RegionKind::*; -pub use self::sty::TyKind::*; pub use self::sty::{ Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar, BoundVariableKind, CanonicalPolyFnSig, ClosureSubsts, ClosureSubstsParts, ConstVid, EarlyBinder, EarlyBoundRegion, @@ -449,13 +449,13 @@ pub(crate) struct TyS<'tcx> { } // `TyS` is used a lot. Make sure it doesn't unintentionally get bigger. -#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(TyS<'_>, 40); +//#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] +//static_assert_size!(TyS<'_>, 40); // We are actually storing a stable hash cache next to the type, so let's // also check the full size -#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(WithStableHash>, 56); +//#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] +//static_assert_size!(WithStableHash>, 56); /// Use this rather than `TyS`, whenever possible. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)] diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 2dabc696388..314d0ef2771 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2,16 +2,14 @@ #![allow(rustc::usage_of_ty_tykind)] -use self::TyKind::*; - use crate::infer::canonical::Canonical; use crate::ty::fold::ValidateBoundVars; use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; -use crate::ty::InferTy::{self, *}; +use crate::ty::InferTy::*; use crate::ty::{ self, AdtDef, DefIdTree, Discr, Term, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitor, }; -use crate::ty::{DelaySpanBugEmitted, List, ParamEnv}; +use crate::ty::{List, ParamEnv}; use polonius_engine::Atom; use rustc_data_structures::captures::Captures; use rustc_data_structures::intern::Interned; @@ -29,6 +27,10 @@ use std::marker::PhantomData; use std::ops::{ControlFlow, Deref, 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> { @@ -78,6 +80,7 @@ impl BoundRegionKind { } } +/* /// Defines the kinds of types used by the type system. /// /// Types written by the user start out as [hir::TyKind](rustc_hir::TyKind) and get @@ -253,7 +256,9 @@ pub enum TyKind<'tcx> { /// propagated to avoid useless error messages. Error(DelaySpanBugEmitted), } +*/ +/* impl<'tcx> TyKind<'tcx> { #[inline] pub fn is_primitive(&self) -> bool { @@ -272,6 +277,25 @@ impl<'tcx> TyKind<'tcx> { } } } +*/ + +pub trait Article { + fn article(&self) -> &'static str; +} + +impl<'tcx> Article for TyKind<'tcx> { + /// Get the article ("a" or "an") to use with this type. + fn article(&self) -> &'static str { + match self { + Int(_) | Float(_) | Array(_, _) => "an", + Adt(def, _) if def.is_enum() => "an", + // This should never happen, but ICEing and causing the user's code + // to not compile felt too harsh. + Error(_) => "a", + _ => "a", + } + } +} // `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] @@ -930,7 +954,9 @@ 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, diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 31a318cc68f..e50179face0 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::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts}; -use crate::ty::{self, EarlyBinder, Lift, List, ParamConst, Ty, TyCtxt}; +use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt, TyInterner}; use rustc_data_structures::intern::{Interned, WithStableHash}; use rustc_hir::def_id::DefId; @@ -216,13 +216,13 @@ 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) -> GenericArg<'tcx> { GenericArgKind::decode(d).pack() } @@ -506,7 +506,7 @@ pub trait Subst<'tcx>: Sized { fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> Self::Inner; } -impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for EarlyBinder { +impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for ty::EarlyBinder { type Inner = T; fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> Self::Inner { diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 809e7ce2e74..084c47a1dc4 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -5,7 +5,9 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFolder}; use crate::ty::layout::IntegerExt; use crate::ty::query::TyCtxtAt; use crate::ty::subst::{GenericArgKind, Subst, SubstsRef}; -use crate::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{ + self, Const, DebruijnIndex, DefIdTree, List, ReEarlyBound, Ty, TyCtxt, TypeFoldable, +}; use rustc_apfloat::Float as _; use rustc_ast as ast; use rustc_attr::{self as attr, SignedInt, UnsignedInt}; @@ -20,6 +22,7 @@ use rustc_macros::HashStable; 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}; diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index fa05434e48b..bfc15f0c70b 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -20,6 +20,7 @@ rustc_query_system = { path = "../rustc_query_system" } rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } +rustc_type_ir = { path = "../rustc_type_ir" } tracing = "0.1" [features] diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index c4920408527..5282c317fc4 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -547,12 +547,13 @@ where value } -impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> { +impl<'a, 'tcx> TyDecoder for CacheDecoder<'a, 'tcx> { + type I = TyInterner<'tcx>; const CLEAR_CROSS_CRATE: bool = false; #[inline] - fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx + fn interner(&self) -> TyInterner<'tcx> { + TyInterner { tcx: self.tcx } } #[inline] @@ -569,7 +570,7 @@ impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> { where F: FnOnce(&mut Self) -> Ty<'tcx>, { - let tcx = self.tcx(); + let tcx = self.tcx; let cache_key = ty::CReaderCacheKey { cnum: None, pos: shorthand }; @@ -750,7 +751,7 @@ 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. - d.tcx().def_path_hash_to_def_id(def_path_hash, &mut || { + d.tcx.def_path_hash_to_def_id(def_path_hash, &mut || { panic!("Failed to convert DefPathHash {:?}", def_path_hash) }) } @@ -927,10 +928,11 @@ 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_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index 8a35121f90c..0a80f014ae7 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -21,6 +21,7 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } +rustc_type_ir = { path = "../rustc_type_ir" } parking_lot = "0.11" smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_query_system/src/ich/mod.rs b/compiler/rustc_query_system/src/ich/mod.rs index 0a1c350b2db..ddaac1c78a1 100644 --- a/compiler/rustc_query_system/src/ich/mod.rs +++ b/compiler/rustc_query_system/src/ich/mod.rs @@ -1,6 +1,7 @@ //! ICH - Incremental Compilation Hash pub use self::hcx::StableHashingContext; +use rustc_data_structures::stable_hasher::HashStable; use rustc_span::symbol::{sym, Symbol}; mod hcx; @@ -17,3 +18,124 @@ pub const IGNORED_ATTRIBUTES: &[Symbol] = &[ sym::rustc_partition_codegened, sym::rustc_expected_cgu_reuse, ]; + +#[allow(rustc::usage_of_ty_tykind)] +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::ListTy: 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 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); + } + } + } +} diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 23700e653e3..8d04b8816ff 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -13,7 +13,7 @@ fn sized_constraint_for_ty<'tcx>( adtdef: ty::AdtDef<'tcx>, 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 439e6cdf706..b8066f2e5d8 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -12,3 +12,4 @@ rustc_index = { path = "../rustc_index" } rustc_serialize = { path = "../rustc_serialize" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_macros = { path = "../rustc_macros" } +smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_type_ir/src/codec.rs b/compiler/rustc_type_ir/src/codec.rs new file mode 100644 index 00000000000..e0138f8aad9 --- /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) -> &'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<::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) -> ::Ty + where + F: FnOnce(&mut Self) -> ::Ty; + + 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) -> ::AllocId; +} \ No newline at end of file diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index c63e9c31d53..960e42d8006 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,147 @@ 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 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 { + 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>( + 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::>()), + } + } +} + +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 { + // This code isn't hot. + 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. + // 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::, _>>()?), + }) + } +} + 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 00000000000..8f43904d96a --- /dev/null +++ b/compiler/rustc_type_ir/src/sty.rs @@ -0,0 +1,454 @@ +use crate::DebruijnIndex; +use crate::FloatTy; +use crate::IntTy; +use crate::Interner; +use crate::TyDecoder; +use crate::TyEncoder; +use crate::UintTy; + +use rustc_serialize::{Decodable, Encodable}; + +/// Defines the kinds of types used by the type system. +/// +/// Types written by the user start out as [hir::TyKind](rustc_hir::TyKind) and get +/// converted to this representation using `AstConv::ast_ty_to_ty`. +#[allow(rustc::usage_of_ty_tykind)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +//#[derive(TyEncodable, TyDecodable)] +//#[derive(HashStable)] +#[rustc_diagnostic_item = "TyKind"] +pub enum TyKind { + /// 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` would be represented using the `AdtDef` + /// for `struct List` 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, &'a Vec]`: + /// + /// ```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, + /// `>::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(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` 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 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::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> 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, + ) + ), + } + } +} diff --git a/compiler/rustc_typeck/src/coherence/builtin.rs b/compiler/rustc_typeck/src/coherence/builtin.rs index 3135e9996ab..d08d9938708 100644 --- a/compiler/rustc_typeck/src/coherence/builtin.rs +++ b/compiler/rustc_typeck/src/coherence/builtin.rs @@ -177,7 +177,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did: tcx.infer_ctxt().enter(|infcx| { let cause = ObligationCause::misc(span, impl_hir_id); - use ty::TyKind::*; + use rustc_type_ir::sty::TyKind::*; match (source.kind(), target.kind()) { (&Ref(r_a, _, mutbl_a), Ref(r_b, _, mutbl_b)) if infcx.at(&cause, param_env).eq(r_a, *r_b).is_ok() && mutbl_a == *mutbl_b => {}