diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index ee2e190e7cd..a936852f4e7 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -9,7 +9,7 @@ macro_rules! arena_types { [] layout: rustc_target::abi::Layout, [] fn_abi: rustc_target::abi::call::FnAbi<'tcx, rustc_middle::ty::Ty<'tcx>>, // AdtDef are interned and compared by address - [] adt_def: rustc_middle::ty::AdtDef, + [decode] adt_def: rustc_middle::ty::AdtDef, [] steal_thir: rustc_data_structures::steal::Steal>, [] steal_mir: rustc_data_structures::steal::Steal>, [decode] mir: rustc_middle::mir::Body<'tcx>, diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 771ce2eb884..5cde54c9328 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -11,7 +11,6 @@ use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_index::vec::{Idx, IndexVec}; use rustc_query_system::ich::StableHashingContext; -use rustc_serialize::{self, Encodable, Encoder}; use rustc_session::DataTypeKind; use rustc_span::symbol::sym; use rustc_target::abi::VariantIdx; @@ -20,7 +19,7 @@ use std::cell::RefCell; use std::cmp::Ordering; use std::hash::{Hash, Hasher}; use std::ops::Range; -use std::{ptr, str}; +use std::str; use super::{ Destructor, FieldDef, GenericPredicates, ReprOptions, Ty, TyCtxt, VariantDef, VariantDiscr, @@ -30,7 +29,7 @@ use super::{ pub struct AdtSizedConstraint<'tcx>(pub &'tcx [Ty<'tcx>]); bitflags! { - #[derive(HashStable)] + #[derive(HashStable, TyEncodable, TyDecodable)] pub struct AdtFlags: u32 { const NO_ADT_FLAGS = 0; /// Indicates whether the ADT is an enum. @@ -88,6 +87,7 @@ bitflags! { /// /// where `x` here represents the `DefId` of `S.x`. Then, the `DefId` /// can be used with [`TyCtxt::type_of()`] to get the type of the field. +#[derive(TyEncodable, TyDecodable)] pub struct AdtDef { /// The `DefId` of the struct, enum or union item. pub did: DefId, @@ -113,26 +113,23 @@ impl Ord for AdtDef { } } +/// There should be only one AdtDef for each `did`, therefore +/// it is fine to implement `PartialEq` only based on `did`. impl PartialEq for AdtDef { - // `AdtDef`s are always interned, and this is part of `TyS` equality. #[inline] fn eq(&self, other: &Self) -> bool { - ptr::eq(self, other) + self.did == other.did } } impl Eq for AdtDef {} +/// There should be only one AdtDef for each `did`, therefore +/// it is fine to implement `Hash` only based on `did`. impl Hash for AdtDef { #[inline] fn hash(&self, s: &mut H) { - (self as *const AdtDef).hash(s) - } -} - -impl Encodable for AdtDef { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - self.did.encode(s) + self.did.hash(s) } } @@ -161,7 +158,7 @@ impl<'a> HashStable> for AdtDef { } } -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, TyEncodable, TyDecodable)] pub enum AdtKind { Struct, Union, diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 3f2b987b1e6..2032f32ed8c 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -16,7 +16,6 @@ use crate::thir; use crate::ty::subst::SubstsRef; use crate::ty::{self, List, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; -use rustc_hir::def_id::DefId; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_span::Span; use std::hash::Hash; @@ -308,13 +307,6 @@ macro_rules! impl_decodable_via_ref { } } -impl<'tcx, D: TyDecoder<'tcx>> 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)) - } -} - impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List> { fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { let len = decoder.read_usize()?; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 0bf457ca8a8..119120b57be 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -112,6 +112,7 @@ pub struct CtxtInterners<'tcx> { const_allocation: InternedSet<'tcx, Allocation>, bound_variable_kinds: InternedSet<'tcx, List>, layout: InternedSet<'tcx, Layout>, + adt_def: InternedSet<'tcx, AdtDef>, } impl<'tcx> CtxtInterners<'tcx> { @@ -132,6 +133,7 @@ impl<'tcx> CtxtInterners<'tcx> { const_allocation: Default::default(), bound_variable_kinds: Default::default(), layout: Default::default(), + adt_def: Default::default(), } } @@ -1078,7 +1080,7 @@ impl<'tcx> TyCtxt<'tcx> { variants: IndexVec, repr: ReprOptions, ) -> &'tcx ty::AdtDef { - self.arena.alloc(ty::AdtDef::new(self, did, kind, variants, repr)) + self.intern_adt_def(ty::AdtDef::new(self, did, kind, variants, repr)) } /// Allocates a read-only byte or string literal for `mir::interpret`. @@ -2057,6 +2059,7 @@ direct_interners! { const_: mk_const(Const<'tcx>), const_allocation: intern_const_alloc(Allocation), layout: intern_layout(Layout), + adt_def: intern_adt_def(AdtDef), } macro_rules! slice_interners { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index d0d2a46fc4c..642ec514130 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1472,7 +1472,7 @@ pub struct Destructor { } bitflags! { - #[derive(HashStable)] + #[derive(HashStable, TyEncodable, TyDecodable)] pub struct VariantFlags: u32 { const NO_VARIANT_FLAGS = 0; /// Indicates whether the field list of this variant is `#[non_exhaustive]`. @@ -1484,7 +1484,7 @@ bitflags! { } /// Definition of a variant -- a struct's fields or an enum variant. -#[derive(Debug, HashStable)] +#[derive(Debug, HashStable, TyEncodable, TyDecodable)] pub struct VariantDef { /// `DefId` that identifies the variant itself. /// If this variant belongs to a struct or union, then this is a copy of its `DefId`. @@ -1586,7 +1586,7 @@ pub enum VariantDiscr { Relative(u32), } -#[derive(Debug, HashStable)] +#[derive(Debug, HashStable, TyEncodable, TyDecodable)] pub struct FieldDef { pub did: DefId, #[stable_hasher(project(name))]