Skip to content

Commit c004f8c

Browse files
committed
Revert "safely transmute<&List<Ty<'tcx>>, &List<GenericArg<'tcx>>>"
This reverts commit a9c1ab8.
1 parent 8756ed2 commit c004f8c

File tree

3 files changed

+6
-100
lines changed

3 files changed

+6
-100
lines changed

compiler/rustc_middle/src/ty/context.rs

+5-32
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ pub struct CtxtInterners<'tcx> {
102102
// Specifically use a speedy hash algorithm for these hash sets, since
103103
// they're accessed quite often.
104104
type_: InternedSet<'tcx, TyS<'tcx>>,
105+
type_list: InternedSet<'tcx, List<Ty<'tcx>>>,
105106
substs: InternedSet<'tcx, InternalSubsts<'tcx>>,
106107
canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
107108
region: InternedSet<'tcx, RegionKind>,
@@ -123,6 +124,7 @@ impl<'tcx> CtxtInterners<'tcx> {
123124
CtxtInterners {
124125
arena,
125126
type_: Default::default(),
127+
type_list: Default::default(),
126128
substs: Default::default(),
127129
region: Default::default(),
128130
poly_existential_predicates: Default::default(),
@@ -1670,25 +1672,6 @@ macro_rules! nop_lift {
16701672
};
16711673
}
16721674

1673-
// Can't use the macros as we have reuse the `substs` here.
1674-
//
1675-
// See `intern_type_list` for more info.
1676-
impl<'a, 'tcx> Lift<'tcx> for &'a List<Ty<'a>> {
1677-
type Lifted = &'tcx List<Ty<'tcx>>;
1678-
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1679-
if self.is_empty() {
1680-
return Some(List::empty());
1681-
}
1682-
if tcx.interners.substs.contains_pointer_to(&InternedInSet(self.as_substs())) {
1683-
// SAFETY: `self` is interned and therefore valid
1684-
// for the entire lifetime of the `TyCtxt`.
1685-
Some(unsafe { mem::transmute::<&'a List<Ty<'a>>, &'tcx List<Ty<'tcx>>>(self) })
1686-
} else {
1687-
None
1688-
}
1689-
}
1690-
}
1691-
16921675
macro_rules! nop_list_lift {
16931676
($set:ident; $ty:ty => $lifted:ty) => {
16941677
impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> {
@@ -1713,6 +1696,7 @@ nop_lift! {const_; Const<'a> => Const<'tcx>}
17131696
nop_lift! {const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx>}
17141697
nop_lift! {predicate; Predicate<'a> => Predicate<'tcx>}
17151698

1699+
nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
17161700
nop_list_lift! {poly_existential_predicates; ty::Binder<'a, ExistentialPredicate<'a>> => ty::Binder<'tcx, ExistentialPredicate<'tcx>>}
17171701
nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>}
17181702
nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>}
@@ -2203,6 +2187,7 @@ macro_rules! slice_interners {
22032187
}
22042188

22052189
slice_interners!(
2190+
type_list: _intern_type_list(Ty<'tcx>),
22062191
substs: _intern_substs(GenericArg<'tcx>),
22072192
canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo<'tcx>),
22082193
poly_existential_predicates:
@@ -2620,19 +2605,7 @@ impl<'tcx> TyCtxt<'tcx> {
26202605
}
26212606

26222607
pub fn intern_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
2623-
if ts.is_empty() {
2624-
List::empty()
2625-
} else {
2626-
// Actually intern type lists as lists of `GenericArg`s.
2627-
//
2628-
// Transmuting from `Ty<'tcx>` to `GenericArg<'tcx>` is sound
2629-
// as explained in ty_slice_as_generic_arg`. With this,
2630-
// we guarantee that even when transmuting between `List<Ty<'tcx>>`
2631-
// and `List<GenericArg<'tcx>>`, the uniqueness requirement for
2632-
// lists is upheld.
2633-
let substs = self._intern_substs(ty::subst::ty_slice_as_generic_args(ts));
2634-
substs.try_as_type_list().unwrap()
2635-
}
2608+
if ts.is_empty() { List::empty() } else { self._intern_type_list(ts) }
26362609
}
26372610

26382611
pub fn intern_substs(self, ts: &[GenericArg<'tcx>]) -> &'tcx List<GenericArg<'tcx>> {

compiler/rustc_middle/src/ty/impls_ty.rs

-30
Original file line numberDiff line numberDiff line change
@@ -61,36 +61,6 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::GenericArg<'t
6161
}
6262
}
6363

64-
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::GenericArgKind<'tcx> {
65-
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
66-
match self {
67-
// WARNING: We dedup cache the `HashStable` results for `List`
68-
// while ignoring types and freely transmute
69-
// between `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>`.
70-
// See `fn intern_type_list` for more details.
71-
//
72-
// We therefore hash types without adding a hash for their discriminant.
73-
//
74-
// In order to make it very unlikely for the sequence of bytes being hashed for
75-
// a `GenericArgKind::Type` to be the same as the sequence of bytes being
76-
// hashed for one of the other variants, we hash a `0xFF` byte before hashing
77-
// their discriminant (since the discriminant of `TyKind` is unlikely to ever start
78-
// with 0xFF).
79-
ty::subst::GenericArgKind::Type(ty) => ty.hash_stable(hcx, hasher),
80-
ty::subst::GenericArgKind::Const(ct) => {
81-
0xFFu8.hash_stable(hcx, hasher);
82-
mem::discriminant(self).hash_stable(hcx, hasher);
83-
ct.hash_stable(hcx, hasher);
84-
}
85-
ty::subst::GenericArgKind::Lifetime(lt) => {
86-
0xFFu8.hash_stable(hcx, hasher);
87-
mem::discriminant(self).hash_stable(hcx, hasher);
88-
lt.hash_stable(hcx, hasher);
89-
}
90-
}
91-
}
92-
}
93-
9464
impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionKind {
9565
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
9666
mem::discriminant(self).hash_stable(hcx, hasher);

compiler/rustc_middle/src/ty/subst.rs

+1-38
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use std::marker::PhantomData;
2020
use std::mem;
2121
use std::num::NonZeroUsize;
2222
use std::ops::ControlFlow;
23-
use std::slice;
2423

2524
/// An entity in the Rust type system, which can be one of
2625
/// several kinds (types, lifetimes, and consts).
@@ -41,38 +40,13 @@ const TYPE_TAG: usize = 0b00;
4140
const REGION_TAG: usize = 0b01;
4241
const CONST_TAG: usize = 0b10;
4342

44-
#[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord)]
43+
#[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord, HashStable)]
4544
pub enum GenericArgKind<'tcx> {
4645
Lifetime(ty::Region<'tcx>),
4746
Type(Ty<'tcx>),
4847
Const(ty::Const<'tcx>),
4948
}
5049

51-
/// This function goes from `&'a [Ty<'tcx>]` to `&'a [GenericArg<'tcx>]`
52-
///
53-
/// This is sound as, for types, `GenericArg` is just
54-
/// `NonZeroUsize::new_unchecked(ty as *const _ as usize)` as
55-
/// long as we use `0` for the `TYPE_TAG`.
56-
pub fn ty_slice_as_generic_args<'a, 'tcx>(ts: &'a [Ty<'tcx>]) -> &'a [GenericArg<'tcx>] {
57-
assert_eq!(TYPE_TAG, 0);
58-
// SAFETY: the whole slice is valid and immutable.
59-
// `Ty` and `GenericArg` is explained above.
60-
unsafe { slice::from_raw_parts(ts.as_ptr().cast(), ts.len()) }
61-
}
62-
63-
impl<'tcx> List<Ty<'tcx>> {
64-
/// Allows to freely switch betwen `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>`.
65-
///
66-
/// As lists are interned, `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>` have
67-
/// be interned together, see `intern_type_list` for more details.
68-
#[inline]
69-
pub fn as_substs(&'tcx self) -> SubstsRef<'tcx> {
70-
assert_eq!(TYPE_TAG, 0);
71-
// SAFETY: `List<T>` is `#[repr(C)]`. `Ty` and `GenericArg` is explained above.
72-
unsafe { &*(self as *const List<Ty<'tcx>> as *const List<GenericArg<'tcx>>) }
73-
}
74-
}
75-
7650
impl<'tcx> GenericArgKind<'tcx> {
7751
#[inline]
7852
fn pack(self) -> GenericArg<'tcx> {
@@ -234,17 +208,6 @@ pub type InternalSubsts<'tcx> = List<GenericArg<'tcx>>;
234208
pub type SubstsRef<'tcx> = &'tcx InternalSubsts<'tcx>;
235209

236210
impl<'a, 'tcx> InternalSubsts<'tcx> {
237-
/// Checks whether all elements of this list are types, if so, transmute.
238-
pub fn try_as_type_list(&'tcx self) -> Option<&'tcx List<Ty<'tcx>>> {
239-
if self.iter().all(|arg| matches!(arg.unpack(), GenericArgKind::Type(_))) {
240-
assert_eq!(TYPE_TAG, 0);
241-
// SAFETY: All elements are types, see `List<Ty<'tcx>>::as_substs`.
242-
Some(unsafe { &*(self as *const List<GenericArg<'tcx>> as *const List<Ty<'tcx>>) })
243-
} else {
244-
None
245-
}
246-
}
247-
248211
/// Interpret these substitutions as the substitutions of a closure type.
249212
/// Closure substitutions have a particular structure controlled by the
250213
/// compiler that encodes information like the signature and closure kind;

0 commit comments

Comments
 (0)