Skip to content

Commit 96f07a7

Browse files
committed
Erase query return types
1 parent 65f0ce0 commit 96f07a7

File tree

22 files changed

+712
-214
lines changed

22 files changed

+712
-214
lines changed

Cargo.lock

+6
Original file line numberDiff line numberDiff line change
@@ -3983,6 +3983,10 @@ dependencies = [
39833983
"winapi",
39843984
]
39853985

3986+
[[package]]
3987+
name = "rustc_erase"
3988+
version = "0.0.0"
3989+
39863990
[[package]]
39873991
name = "rustc_error_codes"
39883992
version = "0.0.0"
@@ -4373,6 +4377,7 @@ dependencies = [
43734377
"rustc_ast",
43744378
"rustc_attr",
43754379
"rustc_data_structures",
4380+
"rustc_erase",
43764381
"rustc_error_messages",
43774382
"rustc_errors",
43784383
"rustc_feature",
@@ -4571,6 +4576,7 @@ dependencies = [
45714576
"rustc-rayon-core",
45724577
"rustc_ast",
45734578
"rustc_data_structures",
4579+
"rustc_erase",
45744580
"rustc_errors",
45754581
"rustc_hir",
45764582
"rustc_index",

compiler/rustc_data_structures/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub mod stable_hasher;
7272
mod atomic_ref;
7373
pub mod fingerprint;
7474
pub mod profiling;
75+
pub mod remap;
7576
pub mod sharded;
7677
pub mod stack;
7778
pub mod sync;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/// Remaps the type with a different lifetime for 'tcx if applicable.
2+
pub trait Remap {
3+
type Remap<'a>;
4+
}
5+
6+
impl Remap for u32 {
7+
type Remap<'a> = u32;
8+
}
9+
10+
impl<T: Remap> Remap for Option<T> {
11+
type Remap<'a> = Option<T::Remap<'a>>;
12+
}
13+
14+
impl Remap for () {
15+
type Remap<'a> = ();
16+
}
17+
18+
impl<T0: Remap, T1: Remap> Remap for (T0, T1) {
19+
type Remap<'a> = (T0::Remap<'a>, T1::Remap<'a>);
20+
}
21+
22+
impl<T0: Remap, T1: Remap, T2: Remap> Remap for (T0, T1, T2) {
23+
type Remap<'a> = (T0::Remap<'a>, T1::Remap<'a>, T2::Remap<'a>);
24+
}
25+
26+
impl<T0: Remap, T1: Remap, T2: Remap, T3: Remap> Remap for (T0, T1, T2, T3) {
27+
type Remap<'a> = (T0::Remap<'a>, T1::Remap<'a>, T2::Remap<'a>, T3::Remap<'a>);
28+
}

compiler/rustc_erase/Cargo.toml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "rustc_erase"
3+
version = "0.0.0"
4+
edition = "2021"
5+
6+
[lib]

compiler/rustc_erase/src/lib.rs

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// This is a separate crate so that we can `allow(incomplete_features)` for just `generic_const_exprs`
2+
#![feature(generic_const_exprs)]
3+
#![allow(incomplete_features)]
4+
5+
#[cfg(debug_assertions)]
6+
use std::intrinsics::type_name;
7+
use std::{
8+
fmt,
9+
mem::{size_of, transmute_copy, MaybeUninit},
10+
};
11+
12+
#[derive(Copy, Clone)]
13+
pub struct Erased<const N: usize> {
14+
data: MaybeUninit<[u8; N]>,
15+
#[cfg(debug_assertions)]
16+
type_id: &'static str,
17+
}
18+
19+
impl<const N: usize> fmt::Debug for Erased<N> {
20+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21+
write!(f, "Erased<{}>", N)
22+
}
23+
}
24+
25+
pub type Erase<T> = Erased<{ size_of::<T>() }>;
26+
27+
#[inline(always)]
28+
pub fn erase<T: Copy>(src: T) -> Erased<{ size_of::<T>() }> {
29+
Erased {
30+
// SAFETY:: Is it safe to transmute to MaybeUninit
31+
data: unsafe { transmute_copy(&src) },
32+
#[cfg(debug_assertions)]
33+
type_id: type_name::<T>(),
34+
}
35+
}
36+
37+
/// Restores an erased value.
38+
///
39+
/// This is only safe if `value` is a valid instance of `T`.
40+
/// For example if `T` was erased with `erase` previously.
41+
#[inline(always)]
42+
pub unsafe fn restore<T: Copy>(value: Erased<{ size_of::<T>() }>) -> T {
43+
#[cfg(debug_assertions)]
44+
assert_eq!(value.type_id, type_name::<T>());
45+
unsafe { transmute_copy(&value.data) }
46+
}

compiler/rustc_hir/src/hir_id.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use crate::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_ID};
2-
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey};
2+
use rustc_data_structures::{
3+
remap::Remap,
4+
stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey},
5+
};
36
use rustc_span::{def_id::DefPathHash, HashStableContext};
47
use std::fmt::{self, Debug};
58

@@ -9,6 +12,10 @@ pub struct OwnerId {
912
pub def_id: LocalDefId,
1013
}
1114

15+
impl Remap for OwnerId {
16+
type Remap<'a> = OwnerId;
17+
}
18+
1219
impl Debug for OwnerId {
1320
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1421
// Example: DefId(0:1 ~ aa[7697]::{use#0})
@@ -75,6 +82,10 @@ pub struct HirId {
7582
pub local_id: ItemLocalId,
7683
}
7784

85+
impl Remap for HirId {
86+
type Remap<'a> = HirId;
87+
}
88+
7889
impl Debug for HirId {
7990
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8091
// Example: HirId(DefId(0:1 ~ aa[7697]::{use#0}).10)

compiler/rustc_middle/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ rustc_arena = { path = "../rustc_arena" }
1717
rustc_ast = { path = "../rustc_ast" }
1818
rustc_attr = { path = "../rustc_attr" }
1919
rustc_data_structures = { path = "../rustc_data_structures" }
20+
rustc_erase = { path = "../rustc_erase" }
2021
rustc_errors = { path = "../rustc_errors" }
2122
# Used for intra-doc links
2223
rustc_error_messages = { path = "../rustc_error_messages" }

compiler/rustc_middle/src/query/keys.rs

+134-2
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,21 @@
33
use crate::infer::canonical::Canonical;
44
use crate::mir;
55
use crate::traits;
6+
use crate::traits::ChalkEnvironmentAndGoal;
67
use crate::ty::fast_reject::SimplifiedType;
78
use crate::ty::subst::{GenericArg, SubstsRef};
89
use crate::ty::{self, layout::TyAndLayout, Ty, TyCtxt};
10+
use rustc_data_structures::remap::Remap;
911
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
1012
use rustc_hir::hir_id::{HirId, OwnerId};
13+
pub use rustc_middle::traits::query::type_op;
1114
use rustc_query_system::query::{DefaultCacheSelector, VecCacheSelector};
1215
use rustc_span::symbol::{Ident, Symbol};
1316
use rustc_span::{Span, DUMMY_SP};
1417

1518
/// The `Key` trait controls what types can legally be used as the key
1619
/// for a query.
17-
pub trait Key: Sized {
20+
pub trait Key: Sized + Remap {
1821
// N.B. Most of the keys down below have `type CacheSelector = DefaultCacheSelector<Self>;`,
1922
// it would be reasonable to use associated type defaults, to remove the duplication...
2023
//
@@ -588,7 +591,7 @@ impl Key for Option<Symbol> {
588591

589592
/// Canonical query goals correspond to abstract trait operations that
590593
/// are not tied to any crate in particular.
591-
impl<'tcx, T> Key for Canonical<'tcx, T> {
594+
impl<'tcx, T: Remap> Key for Canonical<'tcx, T> {
592595
type CacheSelector = DefaultCacheSelector<Self>;
593596

594597
#[inline(always)]
@@ -696,3 +699,132 @@ impl Key for HirId {
696699
None
697700
}
698701
}
702+
703+
// Remap implementations
704+
705+
impl<'tcx, T: Remap> Remap for ty::ParamEnvAnd<'tcx, T> {
706+
type Remap<'a> = ty::ParamEnvAnd<'a, T::Remap<'a>>;
707+
}
708+
709+
impl<'tcx, T: Remap> Remap for ty::Binder<'tcx, T> {
710+
type Remap<'a> = ty::Binder<'a, T::Remap<'a>>;
711+
}
712+
713+
impl<'tcx, T: Remap> Remap for Canonical<'tcx, T> {
714+
type Remap<'a> = Canonical<'a, T::Remap<'a>>;
715+
}
716+
717+
impl<T: Remap> Remap for type_op::Normalize<T> {
718+
type Remap<'a> = type_op::Normalize<T::Remap<'a>>;
719+
}
720+
721+
impl<'tcx> Remap for type_op::AscribeUserType<'tcx> {
722+
type Remap<'a> = type_op::AscribeUserType<'a>;
723+
}
724+
725+
impl<'tcx> Remap for type_op::Subtype<'tcx> {
726+
type Remap<'a> = type_op::Subtype<'a>;
727+
}
728+
729+
impl<'tcx> Remap for type_op::Eq<'tcx> {
730+
type Remap<'a> = type_op::Eq<'a>;
731+
}
732+
733+
impl<'tcx> Remap for type_op::ProvePredicate<'tcx> {
734+
type Remap<'a> = type_op::ProvePredicate<'a>;
735+
}
736+
737+
impl<'tcx> Remap for ty::FnSig<'tcx> {
738+
type Remap<'a> = ty::FnSig<'a>;
739+
}
740+
741+
impl<'tcx> Remap for ty::AliasTy<'tcx> {
742+
type Remap<'a> = ty::AliasTy<'a>;
743+
}
744+
745+
impl<'tcx> Remap for Ty<'tcx> {
746+
type Remap<'a> = Ty<'a>;
747+
}
748+
749+
impl<'tcx> Remap for ty::Predicate<'tcx> {
750+
type Remap<'a> = ty::Predicate<'a>;
751+
}
752+
753+
impl<'tcx> Remap for ChalkEnvironmentAndGoal<'tcx> {
754+
type Remap<'a> = ChalkEnvironmentAndGoal<'a>;
755+
}
756+
757+
impl<'tcx> Remap for ty::Instance<'tcx> {
758+
type Remap<'a> = ty::Instance<'a>;
759+
}
760+
761+
impl<'tcx> Remap for ty::InstanceDef<'tcx> {
762+
type Remap<'a> = ty::InstanceDef<'a>;
763+
}
764+
765+
impl<T: Remap> Remap for ty::WithOptConstParam<T> {
766+
type Remap<'a> = ty::WithOptConstParam<T::Remap<'a>>;
767+
}
768+
769+
impl Remap for SimplifiedType {
770+
type Remap<'a> = SimplifiedType;
771+
}
772+
773+
impl<'tcx> Remap for mir::interpret::GlobalId<'tcx> {
774+
type Remap<'a> = mir::interpret::GlobalId<'a>;
775+
}
776+
777+
impl<'tcx> Remap for mir::interpret::LitToConstInput<'tcx> {
778+
type Remap<'a> = mir::interpret::LitToConstInput<'a>;
779+
}
780+
781+
impl<'tcx> Remap for mir::interpret::ConstAlloc<'tcx> {
782+
type Remap<'a> = mir::interpret::ConstAlloc<'a>;
783+
}
784+
785+
impl<'tcx> Remap for mir::ConstantKind<'tcx> {
786+
type Remap<'a> = mir::ConstantKind<'a>;
787+
}
788+
789+
impl Remap for mir::Field {
790+
type Remap<'a> = mir::Field;
791+
}
792+
793+
impl<'tcx> Remap for ty::ValTree<'tcx> {
794+
type Remap<'a> = ty::ValTree<'a>;
795+
}
796+
797+
impl<'tcx> Remap for ty::ParamEnv<'tcx> {
798+
type Remap<'a> = ty::ParamEnv<'a>;
799+
}
800+
801+
impl<'tcx> Remap for ty::GenericArg<'tcx> {
802+
type Remap<'a> = ty::GenericArg<'a>;
803+
}
804+
805+
impl<'tcx, T: Remap> Remap for &'tcx ty::List<T>
806+
where
807+
for<'a> <T as Remap>::Remap<'a>: 'a,
808+
{
809+
type Remap<'a> = &'a ty::List<T::Remap<'a>>;
810+
}
811+
812+
impl<'tcx> Remap for ty::ExistentialTraitRef<'tcx> {
813+
type Remap<'a> = ty::ExistentialTraitRef<'a>;
814+
}
815+
816+
impl<'tcx> Remap for ty::Const<'tcx> {
817+
type Remap<'a> = ty::Const<'a>;
818+
}
819+
820+
impl<'tcx> Remap for ty::TraitRef<'tcx> {
821+
type Remap<'a> = ty::TraitRef<'a>;
822+
}
823+
824+
impl<'tcx> Remap for ty::UnevaluatedConst<'tcx> {
825+
type Remap<'a> = ty::UnevaluatedConst<'a>;
826+
}
827+
828+
impl Remap for traits::WellFormedLoc {
829+
type Remap<'a> = traits::WellFormedLoc;
830+
}

0 commit comments

Comments
 (0)