Skip to content

Commit 8f51bad

Browse files
authored
Unrolled build for rust-lang#119877
Rollup merge of rust-lang#119877 - celinval:smir-visit-projection, r=oli-obk Add more information to `visit_projection_elem` Without the starting place, it's hard to retrieve any useful information from visiting a projection. Note: I still need to add a test.
2 parents 174e73a + efab0dc commit 8f51bad

File tree

2 files changed

+38
-19
lines changed

2 files changed

+38
-19
lines changed

compiler/stable_mir/src/mir/body.rs

+18-15
Original file line numberDiff line numberDiff line change
@@ -963,7 +963,7 @@ pub enum PointerCoercion {
963963
/// Go from a safe fn pointer to an unsafe fn pointer.
964964
UnsafeFnPointer,
965965

966-
/// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.
966+
/// Go from a non-capturing closure to a fn pointer or an unsafe fn pointer.
967967
/// It cannot convert a closure that requires unsafe.
968968
ClosureFnPointer(Safety),
969969

@@ -1037,21 +1037,24 @@ impl Place {
10371037
/// locals from the function body where this place originates from.
10381038
pub fn ty(&self, locals: &[LocalDecl]) -> Result<Ty, Error> {
10391039
let start_ty = locals[self.local].ty;
1040-
self.projection.iter().fold(Ok(start_ty), |place_ty, elem| {
1041-
let ty = place_ty?;
1042-
match elem {
1043-
ProjectionElem::Deref => Self::deref_ty(ty),
1044-
ProjectionElem::Field(_idx, fty) => Ok(*fty),
1045-
ProjectionElem::Index(_) | ProjectionElem::ConstantIndex { .. } => {
1046-
Self::index_ty(ty)
1047-
}
1048-
ProjectionElem::Subslice { from, to, from_end } => {
1049-
Self::subslice_ty(ty, from, to, from_end)
1050-
}
1051-
ProjectionElem::Downcast(_) => Ok(ty),
1052-
ProjectionElem::OpaqueCast(ty) | ProjectionElem::Subtype(ty) => Ok(*ty),
1040+
self.projection.iter().fold(Ok(start_ty), |place_ty, elem| elem.ty(place_ty?))
1041+
}
1042+
}
1043+
1044+
impl ProjectionElem {
1045+
/// Get the expected type after applying this projection to a given place type.
1046+
pub fn ty(&self, place_ty: Ty) -> Result<Ty, Error> {
1047+
let ty = place_ty;
1048+
match &self {
1049+
ProjectionElem::Deref => Self::deref_ty(ty),
1050+
ProjectionElem::Field(_idx, fty) => Ok(*fty),
1051+
ProjectionElem::Index(_) | ProjectionElem::ConstantIndex { .. } => Self::index_ty(ty),
1052+
ProjectionElem::Subslice { from, to, from_end } => {
1053+
Self::subslice_ty(ty, from, to, from_end)
10531054
}
1054-
})
1055+
ProjectionElem::Downcast(_) => Ok(ty),
1056+
ProjectionElem::OpaqueCast(ty) | ProjectionElem::Subtype(ty) => Ok(*ty),
1057+
}
10551058
}
10561059

10571060
fn index_ty(ty: Ty) -> Result<Ty, Error> {

compiler/stable_mir/src/mir/visit.rs

+20-4
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
3838
use crate::mir::*;
3939
use crate::ty::{Const, GenericArgs, Region, Ty};
40-
use crate::{Opaque, Span};
40+
use crate::{Error, Opaque, Span};
4141

4242
pub trait MirVisitor {
4343
fn visit_body(&mut self, body: &Body) {
@@ -76,12 +76,14 @@ pub trait MirVisitor {
7676
self.super_place(place, ptx, location)
7777
}
7878

79-
fn visit_projection_elem(
79+
fn visit_projection_elem<'a>(
8080
&mut self,
81+
place_ref: PlaceRef<'a>,
8182
elem: &ProjectionElem,
8283
ptx: PlaceContext,
8384
location: Location,
8485
) {
86+
let _ = place_ref;
8587
self.super_projection_elem(elem, ptx, location);
8688
}
8789

@@ -284,8 +286,9 @@ pub trait MirVisitor {
284286
let _ = ptx;
285287
self.visit_local(&place.local, ptx, location);
286288

287-
for elem in &place.projection {
288-
self.visit_projection_elem(elem, ptx, location);
289+
for (idx, elem) in place.projection.iter().enumerate() {
290+
let place_ref = PlaceRef { local: place.local, projection: &place.projection[..idx] };
291+
self.visit_projection_elem(place_ref, elem, ptx, location);
289292
}
290293
}
291294

@@ -453,6 +456,19 @@ impl Location {
453456
}
454457
}
455458

459+
/// Reference to a place used to represent a partial projection.
460+
pub struct PlaceRef<'a> {
461+
pub local: Local,
462+
pub projection: &'a [ProjectionElem],
463+
}
464+
465+
impl<'a> PlaceRef<'a> {
466+
/// Get the type of this place.
467+
pub fn ty(&self, locals: &[LocalDecl]) -> Result<Ty, Error> {
468+
self.projection.iter().fold(Ok(locals[self.local].ty), |place_ty, elem| elem.ty(place_ty?))
469+
}
470+
}
471+
456472
/// Information about a place's usage.
457473
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
458474
pub struct PlaceContext {

0 commit comments

Comments
 (0)