Skip to content

Commit 88c5679

Browse files
committed
rustc_metadata: remove ty{en,de}code and move to auto-derived serialization.
1 parent bcbb410 commit 88c5679

File tree

12 files changed

+235
-1113
lines changed

12 files changed

+235
-1113
lines changed

src/librustc/ty/context.rs

Lines changed: 70 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use middle::stability;
2525
use ty::subst::Substs;
2626
use traits;
2727
use ty::{self, TraitRef, Ty, TypeAndMut};
28-
use ty::{TyS, TypeVariants};
28+
use ty::{TyS, TypeVariants, Slice};
2929
use ty::{AdtKind, AdtDef, ClosureSubsts, Region};
3030
use hir::FreevarMap;
3131
use ty::{BareFnTy, InferTy, ParamTy, ProjectionTy, TraitObject};
@@ -92,7 +92,7 @@ pub struct CtxtInterners<'tcx> {
9292
/// Specifically use a speedy hash algorithm for these hash sets,
9393
/// they're accessed quite often.
9494
type_: RefCell<FnvHashSet<Interned<'tcx, TyS<'tcx>>>>,
95-
type_list: RefCell<FnvHashSet<Interned<'tcx, [Ty<'tcx>]>>>,
95+
type_list: RefCell<FnvHashSet<Interned<'tcx, Slice<Ty<'tcx>>>>>,
9696
substs: RefCell<FnvHashSet<Interned<'tcx, Substs<'tcx>>>>,
9797
bare_fn: RefCell<FnvHashSet<Interned<'tcx, BareFnTy<'tcx>>>>,
9898
region: RefCell<FnvHashSet<Interned<'tcx, Region>>>,
@@ -847,10 +847,11 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Region {
847847
}
848848
}
849849

850-
impl<'a, 'tcx> Lift<'tcx> for &'a [Ty<'a>] {
851-
type Lifted = &'tcx [Ty<'tcx>];
852-
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx [Ty<'tcx>]> {
853-
if let Some(&Interned(list)) = tcx.interners.type_list.borrow().get(*self) {
850+
impl<'a, 'tcx> Lift<'tcx> for &'a Slice<Ty<'a>> {
851+
type Lifted = &'tcx Slice<Ty<'tcx>>;
852+
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
853+
-> Option<&'tcx Slice<Ty<'tcx>>> {
854+
if let Some(&Interned(list)) = tcx.interners.type_list.borrow().get(&self[..]) {
854855
if *self as *const _ == list as *const _ {
855856
return Some(list);
856857
}
@@ -1067,9 +1068,24 @@ impl<'tcx: 'lcx, 'lcx> Borrow<TypeVariants<'lcx>> for Interned<'tcx, TyS<'tcx>>
10671068
}
10681069
}
10691070

1070-
impl<'tcx: 'lcx, 'lcx> Borrow<[Ty<'lcx>]> for Interned<'tcx, [Ty<'tcx>]> {
1071+
// NB: An Interned<Slice<T>> compares and hashes as its elements.
1072+
impl<'tcx, T: PartialEq> PartialEq for Interned<'tcx, Slice<T>> {
1073+
fn eq(&self, other: &Interned<'tcx, Slice<T>>) -> bool {
1074+
self.0[..] == other.0[..]
1075+
}
1076+
}
1077+
1078+
impl<'tcx, T: Eq> Eq for Interned<'tcx, Slice<T>> {}
1079+
1080+
impl<'tcx, T: Hash> Hash for Interned<'tcx, Slice<T>> {
1081+
fn hash<H: Hasher>(&self, s: &mut H) {
1082+
self.0[..].hash(s)
1083+
}
1084+
}
1085+
1086+
impl<'tcx: 'lcx, 'lcx> Borrow<[Ty<'lcx>]> for Interned<'tcx, Slice<Ty<'tcx>>> {
10711087
fn borrow<'a>(&'a self) -> &'a [Ty<'lcx>] {
1072-
self.0
1088+
&self.0[..]
10731089
}
10741090
}
10751091

@@ -1091,32 +1107,23 @@ impl<'tcx> Borrow<Region> for Interned<'tcx, Region> {
10911107
}
10921108
}
10931109

1094-
macro_rules! items { ($($item:item)+) => ($($item)+) }
1095-
macro_rules! impl_interners {
1096-
($lt_tcx:tt, $($name:ident: $method:ident($alloc:ty, $needs_infer:expr)-> $ty:ty),+) => {
1097-
items!($(impl<$lt_tcx> PartialEq for Interned<$lt_tcx, $ty> {
1098-
fn eq(&self, other: &Self) -> bool {
1099-
self.0 == other.0
1100-
}
1101-
}
1102-
1103-
impl<$lt_tcx> Eq for Interned<$lt_tcx, $ty> {}
1104-
1105-
impl<$lt_tcx> Hash for Interned<$lt_tcx, $ty> {
1106-
fn hash<H: Hasher>(&self, s: &mut H) {
1107-
self.0.hash(s)
1108-
}
1109-
}
1110-
1110+
macro_rules! intern_method {
1111+
($lt_tcx:tt, $name:ident: $method:ident($alloc:ty,
1112+
$alloc_to_key:expr,
1113+
$alloc_to_ret:expr,
1114+
$needs_infer:expr) -> $ty:ty) => {
11111115
impl<'a, 'gcx, $lt_tcx> TyCtxt<'a, 'gcx, $lt_tcx> {
11121116
pub fn $method(self, v: $alloc) -> &$lt_tcx $ty {
1113-
if let Some(i) = self.interners.$name.borrow().get::<$ty>(&v) {
1114-
return i.0;
1115-
}
1116-
if !self.is_global() {
1117-
if let Some(i) = self.global_interners.$name.borrow().get::<$ty>(&v) {
1117+
{
1118+
let key = ($alloc_to_key)(&v);
1119+
if let Some(i) = self.interners.$name.borrow().get(key) {
11181120
return i.0;
11191121
}
1122+
if !self.is_global() {
1123+
if let Some(i) = self.global_interners.$name.borrow().get(key) {
1124+
return i.0;
1125+
}
1126+
}
11201127
}
11211128

11221129
// HACK(eddyb) Depend on flags being accurate to
@@ -1127,7 +1134,7 @@ macro_rules! impl_interners {
11271134
let v = unsafe {
11281135
mem::transmute(v)
11291136
};
1130-
let i = self.global_interners.arenas.$name.alloc(v);
1137+
let i = ($alloc_to_ret)(self.global_interners.arenas.$name.alloc(v));
11311138
self.global_interners.$name.borrow_mut().insert(Interned(i));
11321139
return i;
11331140
}
@@ -1141,34 +1148,59 @@ macro_rules! impl_interners {
11411148
}
11421149
}
11431150

1144-
let i = self.interners.arenas.$name.alloc(v);
1151+
let i = ($alloc_to_ret)(self.interners.arenas.$name.alloc(v));
11451152
self.interners.$name.borrow_mut().insert(Interned(i));
11461153
i
11471154
}
1148-
})+);
1155+
}
1156+
}
1157+
}
1158+
1159+
macro_rules! direct_interners {
1160+
($lt_tcx:tt, $($name:ident: $method:ident($needs_infer:expr) -> $ty:ty),+) => {
1161+
$(impl<$lt_tcx> PartialEq for Interned<$lt_tcx, $ty> {
1162+
fn eq(&self, other: &Self) -> bool {
1163+
self.0 == other.0
1164+
}
1165+
}
1166+
1167+
impl<$lt_tcx> Eq for Interned<$lt_tcx, $ty> {}
1168+
1169+
impl<$lt_tcx> Hash for Interned<$lt_tcx, $ty> {
1170+
fn hash<H: Hasher>(&self, s: &mut H) {
1171+
self.0.hash(s)
1172+
}
1173+
}
1174+
1175+
intern_method!($lt_tcx, $name: $method($ty, |x| x, |x| x, $needs_infer) -> $ty);)+
11491176
}
11501177
}
11511178

11521179
fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool {
11531180
x.has_type_flags(ty::TypeFlags::KEEP_IN_LOCAL_TCX)
11541181
}
11551182

1156-
impl_interners!('tcx,
1157-
type_list: mk_type_list(Vec<Ty<'tcx>>, keep_local) -> [Ty<'tcx>],
1158-
substs: mk_substs(Substs<'tcx>, |substs: &Substs| {
1183+
direct_interners!('tcx,
1184+
substs: mk_substs(|substs: &Substs| {
11591185
substs.params().iter().any(keep_local)
11601186
}) -> Substs<'tcx>,
1161-
bare_fn: mk_bare_fn(BareFnTy<'tcx>, |fty: &BareFnTy| {
1187+
bare_fn: mk_bare_fn(|fty: &BareFnTy| {
11621188
keep_local(&fty.sig)
11631189
}) -> BareFnTy<'tcx>,
1164-
region: mk_region(Region, |r| {
1190+
region: mk_region(|r| {
11651191
match r {
11661192
&ty::ReVar(_) | &ty::ReSkolemized(..) => true,
11671193
_ => false
11681194
}
11691195
}) -> Region
11701196
);
11711197

1198+
intern_method!('tcx,
1199+
type_list: mk_type_list(Vec<Ty<'tcx>>, Deref::deref, |xs: &[Ty]| -> &Slice<Ty> {
1200+
unsafe { mem::transmute(xs) }
1201+
}, keep_local) -> Slice<Ty<'tcx>>
1202+
);
1203+
11721204
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
11731205
/// Create an unsafe fn ty based on a safe fn ty.
11741206
pub fn safe_to_unsafe_fn_ty(self, bare_fn: &BareFnTy<'tcx>) -> Ty<'tcx> {

src/librustc/ty/mod.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use std::borrow::Cow;
3838
use std::cell::Cell;
3939
use std::hash::{Hash, Hasher};
4040
use std::iter;
41+
use std::ops::Deref;
4142
use std::rc::Rc;
4243
use std::slice;
4344
use std::vec::IntoIter;
@@ -569,6 +570,45 @@ pub type Ty<'tcx> = &'tcx TyS<'tcx>;
569570
impl<'tcx> serialize::UseSpecializedEncodable for Ty<'tcx> {}
570571
impl<'tcx> serialize::UseSpecializedDecodable for Ty<'tcx> {}
571572

573+
/// A wrapper for slices with the additioanl invariant
574+
/// that the slice is interned and no other slice with
575+
/// the same contents can exist in the same context.
576+
/// This means we can use pointer + length for both
577+
/// equality comparisons and hashing.
578+
#[derive(Debug, RustcEncodable)]
579+
pub struct Slice<T>([T]);
580+
581+
impl<T> PartialEq for Slice<T> {
582+
#[inline]
583+
fn eq(&self, other: &Slice<T>) -> bool {
584+
(&self.0 as *const [T]) == (&other.0 as *const [T])
585+
}
586+
}
587+
impl<T> Eq for Slice<T> {}
588+
589+
impl<T> Hash for Slice<T> {
590+
fn hash<H: Hasher>(&self, s: &mut H) {
591+
(self.as_ptr(), self.len()).hash(s)
592+
}
593+
}
594+
595+
impl<T> Deref for Slice<T> {
596+
type Target = [T];
597+
fn deref(&self) -> &[T] {
598+
&self.0
599+
}
600+
}
601+
602+
impl<'a, T> IntoIterator for &'a Slice<T> {
603+
type Item = &'a T;
604+
type IntoIter = <&'a [T] as IntoIterator>::IntoIter;
605+
fn into_iter(self) -> Self::IntoIter {
606+
self[..].iter()
607+
}
608+
}
609+
610+
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Slice<Ty<'tcx>> {}
611+
572612
/// Upvars do not get their own node-id. Instead, we use the pair of
573613
/// the original var id (that is, the root variable that is referenced
574614
/// by the upvar) and the id of the closure expression.

src/librustc/ty/structural_impls.rs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
1414

1515
use std::rc::Rc;
1616
use syntax::abi;
17-
use syntax::ptr::P;
1817

1918
use hir;
2019

@@ -437,16 +436,6 @@ impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
437436
}
438437
}
439438

440-
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for P<[T]> {
441-
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
442-
self.iter().map(|t| t.fold_with(folder)).collect()
443-
}
444-
445-
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
446-
self.iter().any(|t| t.visit_with(visitor))
447-
}
448-
}
449-
450439
impl<'tcx> TypeFoldable<'tcx> for ty::TraitObject<'tcx> {
451440
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
452441
ty::TraitObject {
@@ -464,7 +453,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TraitObject<'tcx> {
464453
}
465454
}
466455

467-
impl<'tcx> TypeFoldable<'tcx> for &'tcx [Ty<'tcx>] {
456+
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice<Ty<'tcx>> {
468457
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
469458
let tys = self.iter().map(|t| t.fold_with(folder)).collect();
470459
folder.tcx().mk_type_list(tys)

0 commit comments

Comments
 (0)