Skip to content

Commit

Permalink
Remove rich UserTypeProjection projections in SMIR
Browse files Browse the repository at this point in the history
It's not clear to me (klinvill) that UserTypeProjections are produced
anymore with the removal of type ascriptions as per
rust-lang/rfcs#3307. Furthermore, it's not clear
to me which variants of ProjectionElem could appear in such projections.
For these reasons, I'm reverting projections in UserTypeProjections to
simple strings until I can get more clarity on UserTypeProjections.
  • Loading branch information
klinvill committed Nov 10, 2023
1 parent 30d6733 commit 2e70d95
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 49 deletions.
38 changes: 3 additions & 35 deletions compiler/rustc_smir/src/rustc_smir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ impl<'tcx> Stable<'tcx> for mir::Place<'tcx> {
}

impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> {
type T = stable_mir::mir::ProjectionElem<stable_mir::mir::Local, stable_mir::ty::Ty>;
type T = stable_mir::mir::ProjectionElem;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
use mir::ProjectionElem::*;
match self {
Expand Down Expand Up @@ -722,40 +722,8 @@ impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> {
impl<'tcx> Stable<'tcx> for mir::UserTypeProjection {
type T = stable_mir::mir::UserTypeProjection;

fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
UserTypeProjection {
base: self.base.as_usize(),
projection: self.projs.iter().map(|e| e.stable(tables)).collect(),
}
}
}

// ProjectionKind is nearly identical to PlaceElem, except its generic arguments are units. We
// therefore don't need to resolve any arguments with the generic types.
impl<'tcx> Stable<'tcx> for mir::ProjectionKind {
type T = stable_mir::mir::ProjectionElem<(), ()>;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
use mir::ProjectionElem::*;
match self {
Deref => stable_mir::mir::ProjectionElem::Deref,
Field(idx, ty) => stable_mir::mir::ProjectionElem::Field(idx.stable(tables), *ty),
Index(local) => stable_mir::mir::ProjectionElem::Index(*local),
ConstantIndex { offset, min_length, from_end } => {
stable_mir::mir::ProjectionElem::ConstantIndex {
offset: *offset,
min_length: *min_length,
from_end: *from_end,
}
}
Subslice { from, to, from_end } => stable_mir::mir::ProjectionElem::Subslice {
from: *from,
to: *to,
from_end: *from_end,
},
Downcast(_, idx) => stable_mir::mir::ProjectionElem::Downcast(idx.stable(tables)),
OpaqueCast(ty) => stable_mir::mir::ProjectionElem::OpaqueCast(*ty),
Subtype(ty) => stable_mir::mir::ProjectionElem::Subtype(*ty),
}
fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
UserTypeProjection { base: self.base.as_usize(), projection: format!("{:?}", self.projs) }
}
}

Expand Down
25 changes: 12 additions & 13 deletions compiler/stable_mir/src/mir/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,22 +398,23 @@ pub enum Operand {
pub struct Place {
pub local: Local,
/// projection out of a place (access a field, deref a pointer, etc)
pub projection: Vec<ProjectionElem<Local, Ty>>,
pub projection: Vec<ProjectionElem>,
}

// TODO(klinvill): in MIR ProjectionElem is parameterized on the second Field argument and the Index
// argument. This is so it can be used for both the rust provided Places (for which the projection
// elements are of type ProjectionElem<Local, Ty>) and user-provided type annotations (for which the
// projection elements are of type ProjectionElem<(), ()>). Should we do the same thing in Stable MIR?
// In MIR ProjectionElem is parameterized on the second Field argument and the Index argument. This
// is so it can be used for both Places (for which the projection elements are of type
// ProjectionElem<Local, Ty>) and user-provided type annotations (for which the projection elements
// are of type ProjectionElem<(), ()>). In SMIR we don't need this generality, so we just use
// ProjectionElem for Places.
#[derive(Clone, Debug)]
pub enum ProjectionElem<V, T> {
pub enum ProjectionElem {
/// Dereference projections (e.g. `*_1`) project to the address referenced by the base place.
Deref,

/// A field projection (e.g., `f` in `_1.f`) project to a field in the base place. The field is
/// referenced by source-order index rather than the name of the field. The fields type is also
/// given.
Field(FieldIdx, T),
Field(FieldIdx, Ty),

/// Index into a slice/array. The value of the index is computed at runtime using the `V`
/// argument.
Expand All @@ -429,7 +430,7 @@ pub enum ProjectionElem<V, T> {
///
/// The `x[i]` is turned into a `Deref` followed by an `Index`, not just an `Index`. The same
/// thing is true of the `ConstantIndex` and `Subslice` projections below.
Index(V),
Index(Local),

/// Index into a slice/array given by offsets.
///
Expand Down Expand Up @@ -472,24 +473,22 @@ pub enum ProjectionElem<V, T> {

/// Like an explicit cast from an opaque type to a concrete type, but without
/// requiring an intermediate variable.
OpaqueCast(T),
OpaqueCast(Ty),

/// A `Subtype(T)` projection is applied to any `StatementKind::Assign` where
/// type of lvalue doesn't match the type of rvalue, the primary goal is making subtyping
/// explicit during optimizations and codegen.
///
/// This projection doesn't impact the runtime behavior of the program except for potentially changing
/// some type metadata of the interpreter or codegen backend.
Subtype(T),
Subtype(Ty),
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct UserTypeProjection {
pub base: UserTypeAnnotationIndex,

/// `UserTypeProjection` projections need neither the `V` parameter for `Index` nor the `T` for
/// `Field`.
pub projection: Vec<ProjectionElem<(), ()>>,
pub projection: String,
}

pub type Local = usize;
Expand Down
2 changes: 1 addition & 1 deletion tests/ui-fulldeps/stable-mir/projections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ fn main() {
CRATE_NAME.to_string(),
path.to_string(),
];
run!(args, tcx, test_projections(tcx)).unwrap();
run!(args, tcx, test_place_projections(tcx)).unwrap();
}

fn generate_input(path: &str) -> std::io::Result<()> {
Expand Down

0 comments on commit 2e70d95

Please sign in to comment.