From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_middle/src/hir/place.rs | 117 +++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 compiler/rustc_middle/src/hir/place.rs (limited to 'compiler/rustc_middle/src/hir/place.rs') diff --git a/compiler/rustc_middle/src/hir/place.rs b/compiler/rustc_middle/src/hir/place.rs new file mode 100644 index 000000000..83d3b0100 --- /dev/null +++ b/compiler/rustc_middle/src/hir/place.rs @@ -0,0 +1,117 @@ +use crate::ty; +use crate::ty::Ty; + +use rustc_hir::HirId; +use rustc_target::abi::VariantIdx; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] +#[derive(TypeFoldable, TypeVisitable)] +pub enum PlaceBase { + /// A temporary variable. + Rvalue, + /// A named `static` item. + StaticItem, + /// A named local variable. + Local(HirId), + /// An upvar referenced by closure env. + Upvar(ty::UpvarId), +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] +#[derive(TypeFoldable, TypeVisitable)] +pub enum ProjectionKind { + /// A dereference of a pointer, reference or `Box` of the given type. + Deref, + + /// `B.F` where `B` is the base expression and `F` is + /// the field. The field is identified by which variant + /// it appears in along with a field index. The variant + /// is used for enums. + Field(u32, VariantIdx), + + /// Some index like `B[x]`, where `B` is the base + /// expression. We don't preserve the index `x` because + /// we won't need it. + Index, + + /// A subslice covering a range of values like `B[x..y]`. + Subslice, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] +#[derive(TypeFoldable, TypeVisitable)] +pub struct Projection<'tcx> { + /// Type after the projection is applied. + pub ty: Ty<'tcx>, + + /// Defines the kind of access made by the projection. + pub kind: ProjectionKind, +} + +/// A `Place` represents how a value is located in memory. +/// +/// This is an HIR version of [`rustc_middle::mir::Place`]. +#[derive(Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] +#[derive(TypeFoldable, TypeVisitable)] +pub struct Place<'tcx> { + /// The type of the `PlaceBase` + pub base_ty: Ty<'tcx>, + /// The "outermost" place that holds this value. + pub base: PlaceBase, + /// How this place is derived from the base place. + pub projections: Vec>, +} + +/// A `PlaceWithHirId` represents how a value is located in memory. +/// +/// This is an HIR version of [`rustc_middle::mir::Place`]. +#[derive(Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] +#[derive(TypeFoldable, TypeVisitable)] +pub struct PlaceWithHirId<'tcx> { + /// `HirId` of the expression or pattern producing this value. + pub hir_id: HirId, + + /// Information about the `Place`. + pub place: Place<'tcx>, +} + +impl<'tcx> PlaceWithHirId<'tcx> { + pub fn new( + hir_id: HirId, + base_ty: Ty<'tcx>, + base: PlaceBase, + projections: Vec>, + ) -> PlaceWithHirId<'tcx> { + PlaceWithHirId { hir_id, place: Place { base_ty, base, projections } } + } +} + +impl<'tcx> Place<'tcx> { + /// Returns an iterator of the types that have to be dereferenced to access + /// the `Place`. + /// + /// The types are in the reverse order that they are applied. So if + /// `x: &*const u32` and the `Place` is `**x`, then the types returned are + ///`*const u32` then `&*const u32`. + pub fn deref_tys(&self) -> impl Iterator> + '_ { + self.projections.iter().enumerate().rev().filter_map(move |(index, proj)| { + if ProjectionKind::Deref == proj.kind { + Some(self.ty_before_projection(index)) + } else { + None + } + }) + } + + /// Returns the type of this `Place` after all projections have been applied. + pub fn ty(&self) -> Ty<'tcx> { + self.projections.last().map_or(self.base_ty, |proj| proj.ty) + } + + /// Returns the type of this `Place` immediately before `projection_index`th projection + /// is applied. + pub fn ty_before_projection(&self, projection_index: usize) -> Ty<'tcx> { + assert!(projection_index < self.projections.len()); + if projection_index == 0 { self.base_ty } else { self.projections[projection_index - 1].ty } + } +} -- cgit v1.2.3