Skip to content

Commit 79db32b

Browse files
committed
Pack Term in the same way as GenericArg.
This shrinks the `PredicateS` type, which is instanted frequently.
1 parent d565d51 commit 79db32b

File tree

20 files changed

+192
-109
lines changed

20 files changed

+192
-109
lines changed

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+25-22
Original file line numberDiff line numberDiff line change
@@ -1586,28 +1586,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
15861586
Some(values) => {
15871587
let values = self.resolve_vars_if_possible(values);
15881588
let (is_simple_error, exp_found) = match values {
1589-
ValuePairs::Terms(infer::ExpectedFound {
1590-
expected: ty::Term::Ty(expected),
1591-
found: ty::Term::Ty(found),
1592-
}) => {
1593-
let is_simple_err = expected.is_simple_text() && found.is_simple_text();
1594-
OpaqueTypesVisitor::visit_expected_found(self.tcx, expected, found, span)
1595-
.report(diag);
1596-
1597-
(
1598-
is_simple_err,
1599-
Mismatch::Variable(infer::ExpectedFound { expected, found }),
1600-
)
1589+
ValuePairs::Terms(infer::ExpectedFound { expected, found }) => {
1590+
match (expected.unpack(), found.unpack()) {
1591+
(ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => {
1592+
let is_simple_err =
1593+
expected.is_simple_text() && found.is_simple_text();
1594+
OpaqueTypesVisitor::visit_expected_found(
1595+
self.tcx, expected, found, span,
1596+
)
1597+
.report(diag);
1598+
1599+
(
1600+
is_simple_err,
1601+
Mismatch::Variable(infer::ExpectedFound { expected, found }),
1602+
)
1603+
}
1604+
(ty::TermKind::Const(_), ty::TermKind::Const(_)) => {
1605+
(false, Mismatch::Fixed("constant"))
1606+
}
1607+
_ => (false, Mismatch::Fixed("type")),
1608+
}
16011609
}
1602-
ValuePairs::Terms(infer::ExpectedFound {
1603-
expected: ty::Term::Const(_),
1604-
found: ty::Term::Const(_),
1605-
}) => (false, Mismatch::Fixed("constant")),
16061610
ValuePairs::TraitRefs(_) | ValuePairs::PolyTraitRefs(_) => {
16071611
(false, Mismatch::Fixed("trait"))
16081612
}
16091613
ValuePairs::Regions(_) => (false, Mismatch::Fixed("lifetime")),
1610-
_ => (false, Mismatch::Fixed("type")),
16111614
};
16121615
let vals = match self.values_str(values) {
16131616
Some((expected, found)) => Some((expected, found)),
@@ -2273,11 +2276,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
22732276
return None;
22742277
}
22752278

2276-
Some(match (exp_found.expected, exp_found.found) {
2277-
(ty::Term::Ty(expected), ty::Term::Ty(found)) => self.cmp(expected, found),
2278-
(expected, found) => (
2279-
DiagnosticStyledString::highlighted(expected.to_string()),
2280-
DiagnosticStyledString::highlighted(found.to_string()),
2279+
Some(match (exp_found.expected.unpack(), exp_found.found.unpack()) {
2280+
(ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => self.cmp(expected, found),
2281+
_ => (
2282+
DiagnosticStyledString::highlighted(exp_found.expected.to_string()),
2283+
DiagnosticStyledString::highlighted(exp_found.found.to_string()),
22812284
),
22822285
})
22832286
}

compiler/rustc_infer/src/infer/mod.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -353,12 +353,11 @@ pub enum ValuePairs<'tcx> {
353353

354354
impl<'tcx> ValuePairs<'tcx> {
355355
pub fn ty(&self) -> Option<(Ty<'tcx>, Ty<'tcx>)> {
356-
if let ValuePairs::Terms(ExpectedFound {
357-
expected: ty::Term::Ty(expected),
358-
found: ty::Term::Ty(found),
359-
}) = self
356+
if let ValuePairs::Terms(ExpectedFound { expected, found }) = self
357+
&& let Some(expected) = expected.ty()
358+
&& let Some(found) = found.ty()
360359
{
361-
Some((*expected, *found))
360+
Some((expected, found))
362361
} else {
363362
None
364363
}

compiler/rustc_middle/src/ty/flags.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::ty::subst::{GenericArg, GenericArgKind};
2-
use crate::ty::{self, InferConst, Term, Ty, TypeFlags};
2+
use crate::ty::{self, InferConst, Ty, TypeFlags};
33
use std::slice;
44

55
#[derive(Debug)]
@@ -243,9 +243,9 @@ impl FlagComputation {
243243
}
244244
ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => {
245245
self.add_projection_ty(projection_ty);
246-
match term {
247-
Term::Ty(ty) => self.add_ty(ty),
248-
Term::Const(c) => self.add_const(c),
246+
match term.unpack() {
247+
ty::TermKind::Ty(ty) => self.add_ty(ty),
248+
ty::TermKind::Const(c) => self.add_const(c),
249249
}
250250
}
251251
ty::PredicateKind::WellFormed(arg) => {
@@ -320,9 +320,9 @@ impl FlagComputation {
320320

321321
fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) {
322322
self.add_substs(projection.substs);
323-
match projection.term {
324-
ty::Term::Ty(ty) => self.add_ty(ty),
325-
ty::Term::Const(ct) => self.add_const(ct),
323+
match projection.term.unpack() {
324+
ty::TermKind::Ty(ty) => self.add_ty(ty),
325+
ty::TermKind::Const(ct) => self.add_const(ct),
326326
}
327327
}
328328

compiler/rustc_middle/src/ty/mod.rs

+97-13
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ use rustc_hir::Node;
4040
use rustc_index::vec::IndexVec;
4141
use rustc_macros::HashStable;
4242
use rustc_query_system::ich::StableHashingContext;
43+
use rustc_serialize::{Decodable, Encodable};
4344
use rustc_span::hygiene::MacroKind;
4445
use rustc_span::symbol::{kw, sym, Ident, Symbol};
4546
use rustc_span::{ExpnId, Span};
@@ -49,6 +50,9 @@ pub use vtable::*;
4950

5051
use std::fmt::Debug;
5152
use std::hash::{Hash, Hasher};
53+
use std::marker::PhantomData;
54+
use std::mem;
55+
use std::num::NonZeroUsize;
5256
use std::ops::ControlFlow;
5357
use std::{fmt, str};
5458

@@ -902,42 +906,122 @@ pub struct CoercePredicate<'tcx> {
902906
}
903907
pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
904908

905-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable)]
906-
#[derive(HashStable, TypeFoldable, TypeVisitable)]
907-
pub enum Term<'tcx> {
908-
Ty(Ty<'tcx>),
909-
Const(Const<'tcx>),
909+
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
910+
pub struct Term<'tcx> {
911+
ptr: NonZeroUsize,
912+
marker: PhantomData<(Ty<'tcx>, Const<'tcx>)>,
910913
}
911914

912915
impl<'tcx> From<Ty<'tcx>> for Term<'tcx> {
913916
fn from(ty: Ty<'tcx>) -> Self {
914-
Term::Ty(ty)
917+
TermKind::Ty(ty).pack()
915918
}
916919
}
917920

918921
impl<'tcx> From<Const<'tcx>> for Term<'tcx> {
919922
fn from(c: Const<'tcx>) -> Self {
920-
Term::Const(c)
923+
TermKind::Const(c).pack()
924+
}
925+
}
926+
927+
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Term<'tcx> {
928+
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
929+
self.unpack().hash_stable(hcx, hasher);
930+
}
931+
}
932+
933+
impl<'tcx> TypeFoldable<'tcx> for Term<'tcx> {
934+
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
935+
Ok(self.unpack().try_fold_with(folder)?.pack())
936+
}
937+
}
938+
939+
impl<'tcx> TypeVisitable<'tcx> for Term<'tcx> {
940+
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
941+
self.unpack().visit_with(visitor)
942+
}
943+
}
944+
945+
impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for Term<'tcx> {
946+
fn encode(&self, e: &mut E) {
947+
self.unpack().encode(e)
948+
}
949+
}
950+
951+
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for Term<'tcx> {
952+
fn decode(d: &mut D) -> Self {
953+
let res: TermKind<'tcx> = Decodable::decode(d);
954+
res.pack()
921955
}
922956
}
923957

924958
impl<'tcx> Term<'tcx> {
959+
#[inline]
960+
pub fn unpack(self) -> TermKind<'tcx> {
961+
let ptr = self.ptr.get();
962+
// SAFETY: use of `Interned::new_unchecked` here is ok because these
963+
// pointers were originally created from `Interned` types in `pack()`,
964+
// and this is just going in the other direction.
965+
unsafe {
966+
match ptr & TAG_MASK {
967+
TYPE_TAG => TermKind::Ty(Ty(Interned::new_unchecked(
968+
&*((ptr & !TAG_MASK) as *const WithStableHash<ty::TyS<'tcx>>),
969+
))),
970+
CONST_TAG => TermKind::Const(ty::Const(Interned::new_unchecked(
971+
&*((ptr & !TAG_MASK) as *const ty::ConstS<'tcx>),
972+
))),
973+
_ => core::intrinsics::unreachable(),
974+
}
975+
}
976+
}
977+
925978
pub fn ty(&self) -> Option<Ty<'tcx>> {
926-
if let Term::Ty(ty) = self { Some(*ty) } else { None }
979+
if let TermKind::Ty(ty) = self.unpack() { Some(ty) } else { None }
927980
}
928981

929982
pub fn ct(&self) -> Option<Const<'tcx>> {
930-
if let Term::Const(c) = self { Some(*c) } else { None }
983+
if let TermKind::Const(c) = self.unpack() { Some(c) } else { None }
931984
}
932985

933986
pub fn into_arg(self) -> GenericArg<'tcx> {
934-
match self {
935-
Term::Ty(ty) => ty.into(),
936-
Term::Const(c) => c.into(),
987+
match self.unpack() {
988+
TermKind::Ty(ty) => ty.into(),
989+
TermKind::Const(c) => c.into(),
937990
}
938991
}
939992
}
940993

994+
const TAG_MASK: usize = 0b11;
995+
const TYPE_TAG: usize = 0b00;
996+
const CONST_TAG: usize = 0b01;
997+
998+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable)]
999+
#[derive(HashStable, TypeFoldable, TypeVisitable)]
1000+
pub enum TermKind<'tcx> {
1001+
Ty(Ty<'tcx>),
1002+
Const(Const<'tcx>),
1003+
}
1004+
1005+
impl<'tcx> TermKind<'tcx> {
1006+
#[inline]
1007+
fn pack(self) -> Term<'tcx> {
1008+
let (tag, ptr) = match self {
1009+
TermKind::Ty(ty) => {
1010+
// Ensure we can use the tag bits.
1011+
assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0);
1012+
(TYPE_TAG, ty.0.0 as *const WithStableHash<ty::TyS<'tcx>> as usize)
1013+
}
1014+
TermKind::Const(ct) => {
1015+
// Ensure we can use the tag bits.
1016+
assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0);
1017+
(CONST_TAG, ct.0.0 as *const ty::ConstS<'tcx> as usize)
1018+
}
1019+
};
1020+
1021+
Term { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData }
1022+
}
1023+
}
1024+
9411025
/// This kind of predicate has no *direct* correspondent in the
9421026
/// syntax, but it roughly corresponds to the syntactic forms:
9431027
///
@@ -2528,7 +2612,7 @@ mod size_asserts {
25282612
use super::*;
25292613
use rustc_data_structures::static_assert_size;
25302614
// These are in alphabetical order, which is easy to maintain.
2531-
static_assert_size!(PredicateS<'_>, 56);
2615+
static_assert_size!(PredicateS<'_>, 48);
25322616
static_assert_size!(TyS<'_>, 40);
25332617
static_assert_size!(WithStableHash<TyS<'_>>, 56);
25342618
}

compiler/rustc_middle/src/ty/print/pretty.rs

+8-12
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar};
22
use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
33
use crate::ty::{
4-
self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable,
4+
self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable,
55
TypeSuperFoldable, TypeSuperVisitable, TypeVisitable,
66
};
77
use rustc_apfloat::ieee::{Double, Single};
@@ -855,7 +855,7 @@ pub trait PrettyPrinter<'tcx>:
855855
}
856856

857857
p!(")");
858-
if let Term::Ty(ty) = return_ty.skip_binder() {
858+
if let Some(ty) = return_ty.skip_binder().ty() {
859859
if !ty.is_unit() {
860860
p!(" -> ", print(return_ty));
861861
}
@@ -942,13 +942,9 @@ pub trait PrettyPrinter<'tcx>:
942942

943943
p!(write("{} = ", tcx.associated_item(assoc_item_def_id).name));
944944

945-
match term {
946-
Term::Ty(ty) => {
947-
p!(print(ty))
948-
}
949-
Term::Const(c) => {
950-
p!(print(c));
951-
}
945+
match term.unpack() {
946+
TermKind::Ty(ty) => p!(print(ty)),
947+
TermKind::Const(c) => p!(print(c)),
952948
};
953949
}
954950

@@ -2608,9 +2604,9 @@ define_print_and_forward_display! {
26082604
}
26092605

26102606
ty::Term<'tcx> {
2611-
match self {
2612-
ty::Term::Ty(ty) => p!(print(ty)),
2613-
ty::Term::Const(c) => p!(print(c)),
2607+
match self.unpack() {
2608+
ty::TermKind::Ty(ty) => p!(print(ty)),
2609+
ty::TermKind::Const(c) => p!(print(c)),
26142610
}
26152611
}
26162612

compiler/rustc_middle/src/ty/relate.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
use crate::ty::error::{ExpectedFound, TypeError};
88
use crate::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef};
9-
use crate::ty::{self, ImplSubject, Term, Ty, TyCtxt, TypeFoldable};
9+
use crate::ty::{self, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable};
1010
use rustc_hir as ast;
1111
use rustc_hir::def_id::DefId;
1212
use rustc_span::DUMMY_SP;
@@ -803,15 +803,15 @@ impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> {
803803
}
804804
}
805805

806-
impl<'tcx> Relate<'tcx> for ty::Term<'tcx> {
806+
impl<'tcx> Relate<'tcx> for Term<'tcx> {
807807
fn relate<R: TypeRelation<'tcx>>(
808808
relation: &mut R,
809809
a: Self,
810810
b: Self,
811811
) -> RelateResult<'tcx, Self> {
812-
Ok(match (a, b) {
813-
(Term::Ty(a), Term::Ty(b)) => relation.relate(a, b)?.into(),
814-
(Term::Const(a), Term::Const(b)) => relation.relate(a, b)?.into(),
812+
Ok(match (a.unpack(), b.unpack()) {
813+
(TermKind::Ty(a), TermKind::Ty(b)) => relation.relate(a, b)?.into(),
814+
(TermKind::Const(a), TermKind::Const(b)) => relation.relate(a, b)?.into(),
815815
_ => return Err(TypeError::Mismatch),
816816
})
817817
}

compiler/rustc_middle/src/ty/structural_impls.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::mir::ProjectionKind;
77
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
88
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
99
use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
10-
use crate::ty::{self, InferConst, Lift, Term, Ty, TyCtxt};
10+
use crate::ty::{self, InferConst, Lift, Term, TermKind, Ty, TyCtxt};
1111
use rustc_data_structures::functor::IdFunctor;
1212
use rustc_hir as hir;
1313
use rustc_hir::def::Namespace;
@@ -344,10 +344,13 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> {
344344
impl<'a, 'tcx> Lift<'tcx> for Term<'a> {
345345
type Lifted = ty::Term<'tcx>;
346346
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
347-
Some(match self {
348-
Term::Ty(ty) => Term::Ty(tcx.lift(ty)?),
349-
Term::Const(c) => Term::Const(tcx.lift(c)?),
350-
})
347+
Some(
348+
match self.unpack() {
349+
TermKind::Ty(ty) => TermKind::Ty(tcx.lift(ty)?),
350+
TermKind::Const(c) => TermKind::Const(tcx.lift(c)?),
351+
}
352+
.pack(),
353+
)
351354
}
352355
}
353356

compiler/rustc_middle/src/ty/walk.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,9 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
165165
}
166166
};
167167

168-
substs.iter().rev().chain(opt_ty.map(|term| match term {
169-
ty::Term::Ty(ty) => ty.into(),
170-
ty::Term::Const(ct) => ct.into(),
168+
substs.iter().rev().chain(opt_ty.map(|term| match term.unpack() {
169+
ty::TermKind::Ty(ty) => ty.into(),
170+
ty::TermKind::Const(ct) => ct.into(),
171171
}))
172172
}));
173173
}

0 commit comments

Comments
 (0)