intern offsetof fields
This commit is contained in:
parent
511e457c4b
commit
61f23e0003
8 changed files with 33 additions and 11 deletions
|
@ -719,7 +719,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
|
||||
let mut current_ty = *container;
|
||||
|
||||
for &field in fields {
|
||||
for field in fields.iter() {
|
||||
match current_ty.kind() {
|
||||
ty::Tuple(fields) => {
|
||||
let Some(&f_ty) = fields.get(field.as_usize()) else {
|
||||
|
|
|
@ -1115,7 +1115,7 @@ pub enum Rvalue<'tcx> {
|
|||
CheckedBinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>),
|
||||
|
||||
/// Computes a value as described by the operation.
|
||||
NullaryOp(NullOp, Ty<'tcx>),
|
||||
NullaryOp(NullOp<'tcx>, Ty<'tcx>),
|
||||
|
||||
/// Exactly like `BinaryOp`, but less operands.
|
||||
///
|
||||
|
@ -1212,13 +1212,13 @@ pub enum AggregateKind<'tcx> {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
|
||||
pub enum NullOp {
|
||||
pub enum NullOp<'tcx> {
|
||||
/// Returns the size of a value of that type
|
||||
SizeOf,
|
||||
/// Returns the minimum alignment of a type
|
||||
AlignOf,
|
||||
/// Returns the offset of a field
|
||||
OffsetOf(Vec<FieldIdx>),
|
||||
OffsetOf(&'tcx List<FieldIdx>),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
|
@ -1288,6 +1288,6 @@ mod size_asserts {
|
|||
static_assert_size!(Operand<'_>, 24);
|
||||
static_assert_size!(Place<'_>, 16);
|
||||
static_assert_size!(PlaceElem<'_>, 24);
|
||||
static_assert_size!(Rvalue<'_>, 48);
|
||||
static_assert_size!(Rvalue<'_>, 40);
|
||||
// tidy-alphabetical-end
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ TrivialTypeTraversalAndLiftImpls! {
|
|||
UserTypeAnnotationIndex,
|
||||
BorrowKind,
|
||||
CastKind,
|
||||
NullOp,
|
||||
hir::Movability,
|
||||
BasicBlock,
|
||||
SwitchTargets,
|
||||
|
@ -26,6 +25,7 @@ TrivialTypeTraversalAndLiftImpls! {
|
|||
|
||||
TrivialTypeTraversalImpls! {
|
||||
ConstValue<'tcx>,
|
||||
NullOp<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx [InlineAsmTemplatePiece] {
|
||||
|
|
|
@ -20,7 +20,7 @@ use rustc_middle::mir::interpret::AllocId;
|
|||
use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, Mutability, UnOp};
|
||||
use rustc_middle::ty::adjustment::PointerCast;
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::{self, AdtDef, FnSig, Ty, UpvarSubsts};
|
||||
use rustc_middle::ty::{self, AdtDef, FnSig, List, Ty, UpvarSubsts};
|
||||
use rustc_middle::ty::{CanonicalUserType, CanonicalUserTypeAnnotation};
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::{sym, Span, Symbol, DUMMY_SP};
|
||||
|
@ -484,7 +484,7 @@ pub enum ExprKind<'tcx> {
|
|||
/// Field offset (`offset_of!`)
|
||||
OffsetOf {
|
||||
container: Ty<'tcx>,
|
||||
fields: Vec<FieldIdx>,
|
||||
fields: &'tcx List<FieldIdx>,
|
||||
},
|
||||
/// An expression taking a reference to a thread local.
|
||||
ThreadLocalRef(DefId),
|
||||
|
|
|
@ -19,6 +19,7 @@ use rustc_data_structures::fx::FxHashMap;
|
|||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::abi::FieldIdx;
|
||||
pub use rustc_type_ir::{TyDecoder, TyEncoder};
|
||||
use std::hash::Hash;
|
||||
use std::intrinsics;
|
||||
|
@ -401,6 +402,15 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<ty
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<FieldIdx> {
|
||||
fn decode(decoder: &mut D) -> &'tcx Self {
|
||||
let len = decoder.read_usize();
|
||||
decoder
|
||||
.interner()
|
||||
.mk_fields_from_iter((0..len).map::<FieldIdx, _>(|_| Decodable::decode(decoder)))
|
||||
}
|
||||
}
|
||||
|
||||
impl_decodable_via_ref! {
|
||||
&'tcx ty::TypeckResults<'tcx>,
|
||||
&'tcx ty::List<Ty<'tcx>>,
|
||||
|
@ -412,6 +422,7 @@ impl_decodable_via_ref! {
|
|||
&'tcx mir::coverage::CodeRegion,
|
||||
&'tcx ty::List<ty::BoundVariableKind>,
|
||||
&'tcx ty::List<ty::Predicate<'tcx>>,
|
||||
&'tcx ty::List<FieldIdx>,
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
|
|
|
@ -155,6 +155,7 @@ pub struct CtxtInterners<'tcx> {
|
|||
layout: InternedSet<'tcx, LayoutS>,
|
||||
adt_def: InternedSet<'tcx, AdtDefData>,
|
||||
external_constraints: InternedSet<'tcx, ExternalConstraintsData<'tcx>>,
|
||||
fields: InternedSet<'tcx, List<FieldIdx>>,
|
||||
}
|
||||
|
||||
impl<'tcx> CtxtInterners<'tcx> {
|
||||
|
@ -178,6 +179,7 @@ impl<'tcx> CtxtInterners<'tcx> {
|
|||
layout: Default::default(),
|
||||
adt_def: Default::default(),
|
||||
external_constraints: Default::default(),
|
||||
fields: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1585,6 +1587,7 @@ slice_interners!(
|
|||
projs: pub mk_projs(ProjectionKind),
|
||||
place_elems: pub mk_place_elems(PlaceElem<'tcx>),
|
||||
bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
|
||||
fields: pub mk_fields(FieldIdx),
|
||||
);
|
||||
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
|
@ -2253,6 +2256,14 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
|
||||
}
|
||||
|
||||
pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
|
||||
{
|
||||
T::collect_and_apply(iter, |xs| self.mk_fields(xs))
|
||||
}
|
||||
|
||||
pub fn mk_substs_trait(
|
||||
self,
|
||||
self_ty: Ty<'tcx>,
|
||||
|
|
|
@ -481,8 +481,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
}))))
|
||||
}
|
||||
|
||||
ExprKind::OffsetOf { container, ref fields } => {
|
||||
block.and(Rvalue::NullaryOp(NullOp::OffsetOf(fields.clone()), container))
|
||||
ExprKind::OffsetOf { container, fields } => {
|
||||
block.and(Rvalue::NullaryOp(NullOp::OffsetOf(fields), container))
|
||||
}
|
||||
|
||||
ExprKind::Literal { .. }
|
||||
|
|
|
@ -667,7 +667,7 @@ impl<'tcx> Cx<'tcx> {
|
|||
hir::ExprKind::OffsetOf(_, _) => {
|
||||
let data = self.typeck_results.offset_of_data();
|
||||
let &(container, ref indices) = data.get(expr.hir_id).unwrap();
|
||||
let fields = indices.iter().copied().collect();
|
||||
let fields = tcx.mk_fields_from_iter(indices.iter().copied());
|
||||
|
||||
ExprKind::OffsetOf { container, fields }
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue