Skip to content

Commit a4d0341

Browse files
committed
Auto merge of #101432 - nnethercote:shrink-PredicateS, r=lcnr
Shrink `PredicateS` r? `@ghost`
2 parents e7c7aa7 + 79db32b commit a4d0341

File tree

20 files changed

+202
-121
lines changed

20 files changed

+202
-121
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

+107-25
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ use rustc_hir::Node;
4141
use rustc_index::vec::IndexVec;
4242
use rustc_macros::HashStable;
4343
use rustc_query_system::ich::StableHashingContext;
44+
use rustc_serialize::{Decodable, Encodable};
4445
use rustc_span::hygiene::MacroKind;
4546
use rustc_span::symbol::{kw, sym, Ident, Symbol};
4647
use rustc_span::{ExpnId, Span};
@@ -50,6 +51,9 @@ pub use vtable::*;
5051

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

@@ -459,15 +463,6 @@ pub(crate) struct TyS<'tcx> {
459463
outer_exclusive_binder: ty::DebruijnIndex,
460464
}
461465

462-
// `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
463-
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
464-
static_assert_size!(TyS<'_>, 40);
465-
466-
// We are actually storing a stable hash cache next to the type, so let's
467-
// also check the full size
468-
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
469-
static_assert_size!(WithStableHash<TyS<'_>>, 56);
470-
471466
/// Use this rather than `TyS`, whenever possible.
472467
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
473468
#[rustc_diagnostic_item = "Ty"]
@@ -524,10 +519,6 @@ pub(crate) struct PredicateS<'tcx> {
524519
outer_exclusive_binder: ty::DebruijnIndex,
525520
}
526521

527-
// This type is used a lot. Make sure it doesn't unintentionally get bigger.
528-
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
529-
static_assert_size!(PredicateS<'_>, 56);
530-
531522
/// Use this rather than `PredicateS`, whenever possible.
532523
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
533524
#[rustc_pass_by_value]
@@ -911,42 +902,122 @@ pub struct CoercePredicate<'tcx> {
911902
}
912903
pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
913904

914-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable)]
915-
#[derive(HashStable, TypeFoldable, TypeVisitable)]
916-
pub enum Term<'tcx> {
917-
Ty(Ty<'tcx>),
918-
Const(Const<'tcx>),
905+
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
906+
pub struct Term<'tcx> {
907+
ptr: NonZeroUsize,
908+
marker: PhantomData<(Ty<'tcx>, Const<'tcx>)>,
919909
}
920910

921911
impl<'tcx> From<Ty<'tcx>> for Term<'tcx> {
922912
fn from(ty: Ty<'tcx>) -> Self {
923-
Term::Ty(ty)
913+
TermKind::Ty(ty).pack()
924914
}
925915
}
926916

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

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

938978
pub fn ct(&self) -> Option<Const<'tcx>> {
939-
if let Term::Const(c) = self { Some(*c) } else { None }
979+
if let TermKind::Const(c) = self.unpack() { Some(c) } else { None }
940980
}
941981

942982
pub fn into_arg(self) -> GenericArg<'tcx> {
943-
match self {
944-
Term::Ty(ty) => ty.into(),
945-
Term::Const(c) => c.into(),
983+
match self.unpack() {
984+
TermKind::Ty(ty) => ty.into(),
985+
TermKind::Const(c) => c.into(),
946986
}
947987
}
948988
}
949989

990+
const TAG_MASK: usize = 0b11;
991+
const TYPE_TAG: usize = 0b00;
992+
const CONST_TAG: usize = 0b01;
993+
994+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable)]
995+
#[derive(HashStable, TypeFoldable, TypeVisitable)]
996+
pub enum TermKind<'tcx> {
997+
Ty(Ty<'tcx>),
998+
Const(Const<'tcx>),
999+
}
1000+
1001+
impl<'tcx> TermKind<'tcx> {
1002+
#[inline]
1003+
fn pack(self) -> Term<'tcx> {
1004+
let (tag, ptr) = match self {
1005+
TermKind::Ty(ty) => {
1006+
// Ensure we can use the tag bits.
1007+
assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0);
1008+
(TYPE_TAG, ty.0.0 as *const WithStableHash<ty::TyS<'tcx>> as usize)
1009+
}
1010+
TermKind::Const(ct) => {
1011+
// Ensure we can use the tag bits.
1012+
assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0);
1013+
(CONST_TAG, ct.0.0 as *const ty::ConstS<'tcx> as usize)
1014+
}
1015+
};
1016+
1017+
Term { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData }
1018+
}
1019+
}
1020+
9501021
/// This kind of predicate has no *direct* correspondent in the
9511022
/// syntax, but it roughly corresponds to the syntactic forms:
9521023
///
@@ -2531,3 +2602,14 @@ pub struct DestructuredConst<'tcx> {
25312602
pub variant: Option<VariantIdx>,
25322603
pub fields: &'tcx [ty::Const<'tcx>],
25332604
}
2605+
2606+
// Some types are used a lot. Make sure they don't unintentionally get bigger.
2607+
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
2608+
mod size_asserts {
2609+
use super::*;
2610+
use rustc_data_structures::static_assert_size;
2611+
// These are in alphabetical order, which is easy to maintain.
2612+
static_assert_size!(PredicateS<'_>, 48);
2613+
static_assert_size!(TyS<'_>, 40);
2614+
static_assert_size!(WithStableHash<TyS<'_>>, 56);
2615+
}

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
}

0 commit comments

Comments
 (0)