diff --git a/compiler/rustc_macros/src/hash_stable.rs b/compiler/rustc_macros/src/hash_stable.rs index 63bdcea87f817..fd1ffe775d1d3 100644 --- a/compiler/rustc_macros/src/hash_stable.rs +++ b/compiler/rustc_macros/src/hash_stable.rs @@ -43,7 +43,7 @@ fn parse_attributes(field: &syn::Field) -> Attributes { pub fn hash_stable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { let generic: syn::GenericParam = parse_quote!(__CTX); - s.add_bounds(synstructure::AddBounds::Generics); + s.add_bounds(synstructure::AddBounds::Fields); s.add_impl_generic(generic); s.add_where_predicate(parse_quote! { __CTX: crate::HashStableContext }); let body = s.each(|bi| { @@ -86,7 +86,7 @@ pub fn hash_stable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_ma pub fn hash_stable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { let generic: syn::GenericParam = parse_quote!('__ctx); - s.add_bounds(synstructure::AddBounds::Generics); + s.add_bounds(synstructure::AddBounds::Fields); s.add_impl_generic(generic); let body = s.each(|bi| { let attrs = parse_attributes(bi.ast()); diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 36bda3e0f6bb2..10b6a84bb1ea9 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -120,6 +120,8 @@ decl_derive!([Decodable] => serialize::decodable_derive); decl_derive!([Encodable] => serialize::encodable_derive); decl_derive!([TyDecodable] => serialize::type_decodable_derive); decl_derive!([TyEncodable] => serialize::type_encodable_derive); +decl_derive!([IrTyDecodable] => serialize::ir_type_decodable_derive); +decl_derive!([IrTyEncodable] => serialize::ir_type_encodable_derive); decl_derive!([MetadataDecodable] => serialize::meta_decodable_derive); decl_derive!([MetadataEncodable] => serialize::meta_encodable_derive); decl_derive!([TypeFoldable, attributes(type_foldable)] => type_foldable::type_foldable_derive); diff --git a/compiler/rustc_macros/src/serialize.rs b/compiler/rustc_macros/src/serialize.rs index 82e6972d0270c..854871364e3c5 100644 --- a/compiler/rustc_macros/src/serialize.rs +++ b/compiler/rustc_macros/src/serialize.rs @@ -3,13 +3,21 @@ use quote::{quote, quote_spanned}; use syn::parse_quote; use syn::spanned::Spanned; +pub fn ir_type_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + let decoder_ty = quote! { __D }; + s.add_impl_generic(parse_quote! {#decoder_ty: crate::codec::TyDecoder}); + s.add_bounds(synstructure::AddBounds::Fields); + + decodable_body(s, decoder_ty) +} + pub fn type_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { let decoder_ty = quote! { __D }; 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_type_ir::codec::TyDecoder>}); - s.add_bounds(synstructure::AddBounds::Generics); + s.add_bounds(synstructure::AddBounds::Fields); decodable_body(s, decoder_ty) } @@ -20,7 +28,7 @@ pub fn meta_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2: } s.add_impl_generic(parse_quote! { '__a }); let decoder_ty = quote! { DecodeContext<'__a, 'tcx> }; - s.add_bounds(synstructure::AddBounds::Generics); + s.add_bounds(synstructure::AddBounds::Fields); decodable_body(s, decoder_ty) } @@ -28,7 +36,7 @@ pub fn meta_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2: pub fn decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { let decoder_ty = quote! { __D }; s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_serialize::Decoder}); - s.add_bounds(synstructure::AddBounds::Generics); + s.add_bounds(synstructure::AddBounds::Fields); decodable_body(s, decoder_ty) } @@ -90,13 +98,21 @@ fn decode_field(field: &syn::Field) -> proc_macro2::TokenStream { quote_spanned! {field_span=> #decode_inner_method(#__decoder) } } +pub fn ir_type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + let encoder_ty = quote! { __E }; + s.add_impl_generic(parse_quote! {#encoder_ty: crate::codec::TyEncoder}); + s.add_bounds(synstructure::AddBounds::Fields); + + encodable_body(s, encoder_ty, false) +} + pub fn type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") { s.add_impl_generic(parse_quote! {'tcx}); } let encoder_ty = quote! { __E }; s.add_impl_generic(parse_quote! {#encoder_ty: ::rustc_type_ir::codec::TyEncoder>}); - s.add_bounds(synstructure::AddBounds::Generics); + s.add_bounds(synstructure::AddBounds::Fields); encodable_body(s, encoder_ty, false) } @@ -107,7 +123,7 @@ pub fn meta_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2: } s.add_impl_generic(parse_quote! { '__a }); let encoder_ty = quote! { EncodeContext<'__a, 'tcx> }; - s.add_bounds(synstructure::AddBounds::Generics); + s.add_bounds(synstructure::AddBounds::Fields); encodable_body(s, encoder_ty, true) } @@ -115,7 +131,7 @@ pub fn meta_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2: pub fn encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { let encoder_ty = quote! { __E }; s.add_impl_generic(parse_quote! { #encoder_ty: ::rustc_serialize::Encoder}); - s.add_bounds(synstructure::AddBounds::Generics); + s.add_bounds(synstructure::AddBounds::Fields); encodable_body(s, encoder_ty, false) } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index cf420bafeb12f..ee4eed92a2ae8 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -15,6 +15,7 @@ use hir::def::DefKind; use polonius_engine::Atom; use rustc_data_structures::captures::Captures; use rustc_data_structures::intern::Interned; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_index::vec::Idx; @@ -1337,20 +1338,31 @@ impl fmt::Debug for EarlyBoundRegion { /// A **`const`** **v**ariable **ID**. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[derive(HashStable, TyEncodable, TyDecodable)] +#[derive(TyEncodable, TyDecodable)] pub struct ConstVid<'tcx> { pub index: u32, pub phantom: PhantomData<&'tcx ()>, } +impl HashStable for ConstVid<'_> { + fn hash_stable(&self, _: &mut CTX, _: &mut StableHasher) { + panic!("const variables should not be hashed: {self:?}") + } +} + rustc_index::newtype_index! { /// A **region** (lifetime) **v**ariable **ID**. - #[derive(HashStable)] pub struct RegionVid { DEBUG_FORMAT = custom, } } +impl HashStable for RegionVid { + fn hash_stable(&self, _: &mut CTX, _: &mut StableHasher) { + panic!("region variables should not be hashed: {self:?}") + } +} + impl Atom for RegionVid { fn index(self) -> usize { Idx::index(self) diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 7fbe78aa52353..f6b1c26907cf0 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -502,6 +502,12 @@ rustc_index::newtype_index! { } } +impl HashStable for TyVid { + fn hash_stable(&self, _: &mut CTX, _: &mut StableHasher) { + panic!("type variables should not be hashed: {self:?}") + } +} + /// An **int**egral (`u32`, `i32`, `usize`, etc.) type **v**ariable **ID**. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)] pub struct IntVid { diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index a4fb1480fa448..5873de3a270ee 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -5,19 +5,13 @@ use std::{fmt, hash}; use crate::DebruijnIndex; use crate::FloatTy; -use crate::HashStableContext; use crate::IntTy; use crate::Interner; -use crate::TyDecoder; -use crate::TyEncoder; use crate::UintTy; use self::RegionKind::*; use self::TyKind::*; -use rustc_data_structures::stable_hasher::HashStable; -use rustc_serialize::{Decodable, Decoder, Encodable}; - /// Specifies how a trait object is represented. #[derive( Clone, @@ -51,6 +45,7 @@ pub enum DynKind { /// Types written by the user start out as `hir::TyKind` and get /// converted to this representation using `AstConv::ast_ty_to_ty`. #[rustc_diagnostic_item = "IrTyKind"] +#[derive(IrTyEncodable, IrTyDecodable, HashStable_Generic)] pub enum TyKind { /// The primitive boolean type. Written as `bool`. Bool, @@ -623,311 +618,6 @@ impl fmt::Debug for TyKind { } } -// This is manually implemented because a derive would require `I: Encodable` -impl Encodable for TyKind -where - I::DelaySpanBugEmitted: Encodable, - I::AdtDef: Encodable, - I::SubstsRef: Encodable, - I::DefId: Encodable, - I::Ty: Encodable, - I::Const: Encodable, - I::Region: Encodable, - I::TypeAndMut: Encodable, - I::Mutability: Encodable, - I::Movability: Encodable, - I::PolyFnSig: Encodable, - I::ListBinderExistentialPredicate: Encodable, - I::BinderListTy: Encodable, - I::ListTy: Encodable, - I::ProjectionTy: Encodable, - I::ParamTy: Encodable, - I::BoundTy: Encodable, - I::PlaceholderType: Encodable, - I::InferTy: Encodable, - I::DelaySpanBugEmitted: Encodable, - I::PredicateKind: Encodable, - I::AllocId: Encodable, -{ - fn encode(&self, e: &mut E) { - let disc = tykind_discriminant(self); - match self { - Bool => e.emit_enum_variant(disc, |_| {}), - Char => e.emit_enum_variant(disc, |_| {}), - Int(i) => e.emit_enum_variant(disc, |e| { - i.encode(e); - }), - Uint(u) => e.emit_enum_variant(disc, |e| { - u.encode(e); - }), - Float(f) => e.emit_enum_variant(disc, |e| { - f.encode(e); - }), - Adt(adt, substs) => e.emit_enum_variant(disc, |e| { - adt.encode(e); - substs.encode(e); - }), - Foreign(def_id) => e.emit_enum_variant(disc, |e| { - def_id.encode(e); - }), - Str => e.emit_enum_variant(disc, |_| {}), - Array(t, c) => e.emit_enum_variant(disc, |e| { - t.encode(e); - c.encode(e); - }), - Slice(t) => e.emit_enum_variant(disc, |e| { - t.encode(e); - }), - RawPtr(tam) => e.emit_enum_variant(disc, |e| { - tam.encode(e); - }), - Ref(r, t, m) => e.emit_enum_variant(disc, |e| { - r.encode(e); - t.encode(e); - m.encode(e); - }), - FnDef(def_id, substs) => e.emit_enum_variant(disc, |e| { - def_id.encode(e); - substs.encode(e); - }), - FnPtr(polyfnsig) => e.emit_enum_variant(disc, |e| { - polyfnsig.encode(e); - }), - Dynamic(l, r, repr) => e.emit_enum_variant(disc, |e| { - l.encode(e); - r.encode(e); - repr.encode(e); - }), - Closure(def_id, substs) => e.emit_enum_variant(disc, |e| { - def_id.encode(e); - substs.encode(e); - }), - Generator(def_id, substs, m) => e.emit_enum_variant(disc, |e| { - def_id.encode(e); - substs.encode(e); - m.encode(e); - }), - GeneratorWitness(b) => e.emit_enum_variant(disc, |e| { - b.encode(e); - }), - Never => e.emit_enum_variant(disc, |_| {}), - Tuple(substs) => e.emit_enum_variant(disc, |e| { - substs.encode(e); - }), - Projection(p) => e.emit_enum_variant(disc, |e| { - p.encode(e); - }), - Opaque(def_id, substs) => e.emit_enum_variant(disc, |e| { - def_id.encode(e); - substs.encode(e); - }), - Param(p) => e.emit_enum_variant(disc, |e| { - p.encode(e); - }), - Bound(d, b) => e.emit_enum_variant(disc, |e| { - d.encode(e); - b.encode(e); - }), - Placeholder(p) => e.emit_enum_variant(disc, |e| { - p.encode(e); - }), - Infer(i) => e.emit_enum_variant(disc, |e| { - i.encode(e); - }), - Error(d) => e.emit_enum_variant(disc, |e| { - d.encode(e); - }), - } - } -} - -// This is manually implemented because a derive would require `I: Decodable` -impl> Decodable for TyKind -where - I::DelaySpanBugEmitted: Decodable, - I::AdtDef: Decodable, - I::SubstsRef: Decodable, - I::DefId: Decodable, - I::Ty: Decodable, - I::Const: Decodable, - I::Region: Decodable, - I::TypeAndMut: Decodable, - I::Mutability: Decodable, - I::Movability: Decodable, - I::PolyFnSig: Decodable, - I::ListBinderExistentialPredicate: Decodable, - I::BinderListTy: Decodable, - I::ListTy: Decodable, - I::ProjectionTy: Decodable, - I::ParamTy: Decodable, - I::BoundTy: Decodable, - I::PlaceholderType: Decodable, - I::InferTy: Decodable, - I::DelaySpanBugEmitted: Decodable, - I::PredicateKind: Decodable, - I::AllocId: Decodable, -{ - fn decode(d: &mut D) -> Self { - match Decoder::read_usize(d) { - 0 => Bool, - 1 => Char, - 2 => Int(Decodable::decode(d)), - 3 => Uint(Decodable::decode(d)), - 4 => Float(Decodable::decode(d)), - 5 => Adt(Decodable::decode(d), Decodable::decode(d)), - 6 => Foreign(Decodable::decode(d)), - 7 => Str, - 8 => Array(Decodable::decode(d), Decodable::decode(d)), - 9 => Slice(Decodable::decode(d)), - 10 => RawPtr(Decodable::decode(d)), - 11 => Ref(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)), - 12 => FnDef(Decodable::decode(d), Decodable::decode(d)), - 13 => FnPtr(Decodable::decode(d)), - 14 => Dynamic(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)), - 15 => Closure(Decodable::decode(d), Decodable::decode(d)), - 16 => Generator(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)), - 17 => GeneratorWitness(Decodable::decode(d)), - 18 => Never, - 19 => Tuple(Decodable::decode(d)), - 20 => Projection(Decodable::decode(d)), - 21 => Opaque(Decodable::decode(d), Decodable::decode(d)), - 22 => Param(Decodable::decode(d)), - 23 => Bound(Decodable::decode(d), Decodable::decode(d)), - 24 => Placeholder(Decodable::decode(d)), - 25 => Infer(Decodable::decode(d)), - 26 => Error(Decodable::decode(d)), - _ => panic!( - "{}", - format!( - "invalid enum variant tag while decoding `{}`, expected 0..{}", - "TyKind", 27, - ) - ), - } - } -} - -// This is not a derived impl because a derive would require `I: HashStable` -#[allow(rustc::usage_of_ty_tykind)] -impl HashStable for 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 CTX, - __hasher: &mut rustc_data_structures::stable_hasher::StableHasher, - ) { - std::mem::discriminant(self).hash_stable(__hcx, __hasher); - 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, repr) => { - l.hash_stable(__hcx, __hasher); - r.hash_stable(__hcx, __hasher); - repr.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); - } - } - } -} - /// Representation of regions. Note that the NLL checker uses a distinct /// representation of regions. For this reason, it internally replaces all the /// regions with inference variables -- the index of the variable is then used @@ -1034,6 +724,7 @@ where /// [1]: https://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/ /// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/ /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html +#[derive(IrTyEncodable, IrTyDecodable, HashStable_Generic)] pub enum RegionKind { /// Region bound in a type or fn declaration which will be /// substituted 'early' -- that is, at the same time when type @@ -1235,106 +926,3 @@ impl fmt::Debug for RegionKind { } } } - -// This is manually implemented because a derive would require `I: Encodable` -impl Encodable for RegionKind -where - I::EarlyBoundRegion: Encodable, - I::BoundRegion: Encodable, - I::FreeRegion: Encodable, - I::RegionVid: Encodable, - I::PlaceholderRegion: Encodable, -{ - fn encode(&self, e: &mut E) { - let disc = regionkind_discriminant(self); - match self { - ReEarlyBound(a) => e.emit_enum_variant(disc, |e| { - a.encode(e); - }), - ReLateBound(a, b) => e.emit_enum_variant(disc, |e| { - a.encode(e); - b.encode(e); - }), - ReFree(a) => e.emit_enum_variant(disc, |e| { - a.encode(e); - }), - ReStatic => e.emit_enum_variant(disc, |_| {}), - ReVar(a) => e.emit_enum_variant(disc, |e| { - a.encode(e); - }), - RePlaceholder(a) => e.emit_enum_variant(disc, |e| { - a.encode(e); - }), - ReErased => e.emit_enum_variant(disc, |_| {}), - } - } -} - -// This is manually implemented because a derive would require `I: Decodable` -impl> Decodable for RegionKind -where - I::EarlyBoundRegion: Decodable, - I::BoundRegion: Decodable, - I::FreeRegion: Decodable, - I::RegionVid: Decodable, - I::PlaceholderRegion: Decodable, -{ - fn decode(d: &mut D) -> Self { - match Decoder::read_usize(d) { - 0 => ReEarlyBound(Decodable::decode(d)), - 1 => ReLateBound(Decodable::decode(d), Decodable::decode(d)), - 2 => ReFree(Decodable::decode(d)), - 3 => ReStatic, - 4 => ReVar(Decodable::decode(d)), - 5 => RePlaceholder(Decodable::decode(d)), - 6 => ReErased, - _ => panic!( - "{}", - format!( - "invalid enum variant tag while decoding `{}`, expected 0..{}", - "RegionKind", 8, - ) - ), - } - } -} - -// This is not a derived impl because a derive would require `I: HashStable` -impl HashStable for RegionKind -where - I::EarlyBoundRegion: HashStable, - I::BoundRegion: HashStable, - I::FreeRegion: HashStable, - I::RegionVid: HashStable, - I::PlaceholderRegion: HashStable, -{ - #[inline] - fn hash_stable( - &self, - hcx: &mut CTX, - hasher: &mut rustc_data_structures::stable_hasher::StableHasher, - ) { - std::mem::discriminant(self).hash_stable(hcx, hasher); - match self { - ReErased | ReStatic => { - // No variant fields to hash for these ... - } - ReLateBound(db, br) => { - db.hash_stable(hcx, hasher); - br.hash_stable(hcx, hasher); - } - ReEarlyBound(eb) => { - eb.hash_stable(hcx, hasher); - } - ReFree(ref free_region) => { - free_region.hash_stable(hcx, hasher); - } - RePlaceholder(p) => { - p.hash_stable(hcx, hasher); - } - ReVar(_) => { - panic!("region variables should not be hashed: {self:?}") - } - } - } -}