Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#![feature(try_trait_v2_residual)]
#![feature(try_trait_v2_yeet)]
#![feature(type_alias_impl_trait)]
#![feature(unwrap_infallible)]
#![feature(yeet_expr)]
#![recursion_limit = "256"]
// tidy-alphabetical-end
Expand Down
36 changes: 35 additions & 1 deletion compiler/rustc_middle/src/mir/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,11 @@ impl<'tcx> PlaceTy<'tcx> {
/// Convenience wrapper around `projection_ty_core` for `PlaceElem`,
/// where we can just use the `Ty` that is already stored inline on
/// field projection elems.
pub fn projection_ty(self, tcx: TyCtxt<'tcx>, elem: PlaceElem<'tcx>) -> PlaceTy<'tcx> {
pub fn projection_ty<V: ::std::fmt::Debug>(
self,
tcx: TyCtxt<'tcx>,
elem: ProjectionElem<V, Ty<'tcx>>,
) -> PlaceTy<'tcx> {
self.projection_ty_core(tcx, &elem, |ty| ty, |_, _, _, ty| ty, |ty| ty)
}

Expand Down Expand Up @@ -290,6 +294,36 @@ impl<V, T> ProjectionElem<V, T> {
Self::UnwrapUnsafeBinder(..) => false,
}
}

/// Returns the `ProjectionKind` associated to this projection.
pub fn kind(self) -> ProjectionKind {
self.try_map(|_| Some(()), |_| ()).unwrap()
}

/// Apply functions to types and values in this projection and return the result.
pub fn try_map<V2, T2>(
self,
v: impl FnOnce(V) -> Option<V2>,
t: impl FnOnce(T) -> T2,
) -> Option<ProjectionElem<V2, T2>> {
Some(match self {
ProjectionElem::Deref => ProjectionElem::Deref,
ProjectionElem::Downcast(name, read_variant) => {
ProjectionElem::Downcast(name, read_variant)
}
ProjectionElem::Field(f, ty) => ProjectionElem::Field(f, t(ty)),
ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
ProjectionElem::ConstantIndex { offset, min_length, from_end }
}
ProjectionElem::Subslice { from, to, from_end } => {
ProjectionElem::Subslice { from, to, from_end }
}
ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(t(ty)),
ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(t(ty)),
ProjectionElem::UnwrapUnsafeBinder(ty) => ProjectionElem::UnwrapUnsafeBinder(t(ty)),
ProjectionElem::Index(val) => ProjectionElem::Index(v(val)?),
})
}
}

/// Alias for projections as they appear in `UserTypeProjection`, where we
Expand Down
38 changes: 0 additions & 38 deletions compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs

This file was deleted.

5 changes: 2 additions & 3 deletions compiler/rustc_mir_dataflow/src/move_paths/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use rustc_middle::{bug, span_bug};
use smallvec::{SmallVec, smallvec};
use tracing::debug;

use super::abs_domain::Lift;
use super::{
Init, InitIndex, InitKind, InitLocation, LocationMap, LookupResult, MoveData, MoveOut,
MoveOutIndex, MovePath, MovePathIndex, MovePathLookup,
Expand Down Expand Up @@ -241,7 +240,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
if union_path.is_none() {
// inlined from add_move_path because of a borrowck conflict with the iterator
base =
*data.rev_lookup.projections.entry((base, elem.lift())).or_insert_with(|| {
*data.rev_lookup.projections.entry((base, elem.kind())).or_insert_with(|| {
new_move_path(
&mut data.move_paths,
&mut data.path_map,
Expand Down Expand Up @@ -272,7 +271,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
tcx,
..
} = self;
*rev_lookup.projections.entry((base, elem.lift())).or_insert_with(move || {
*rev_lookup.projections.entry((base, elem.kind())).or_insert_with(move || {
new_move_path(move_paths, path_map, init_path_map, Some(base), mk_place(*tcx))
})
}
Expand Down
18 changes: 14 additions & 4 deletions compiler/rustc_mir_dataflow/src/move_paths/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
//! The move-analysis portion of borrowck needs to work in an abstract
//! domain of lifted `Place`s. Most of the `Place` variants fall into a
//! one-to-one mapping between the concrete and abstract (e.g., a
//! field-deref on a local variable, `x.field`, has the same meaning
//! in both domains). Indexed projections are the exception: `a[x]`
//! needs to be treated as mapping to the same move path as `a[y]` as
//! well as `a[13]`, etc. So we map these `x`/`y` values to `()`.
//!
//! (In theory, the analysis could be extended to work with sets of
//! paths, so that `a[0]` and `a[13]` could be kept distinct, while
//! `a[x]` would still overlap them both. But that is not this
//! representation does today.)

use std::fmt;
use std::ops::{Index, IndexMut};

Expand All @@ -8,11 +21,8 @@ use rustc_middle::ty::{Ty, TyCtxt};
use rustc_span::Span;
use smallvec::SmallVec;

use self::abs_domain::Lift;
use crate::un_derefer::UnDerefer;

mod abs_domain;

rustc_index::newtype_index! {
#[orderable]
#[debug_format = "mp{}"]
Expand Down Expand Up @@ -324,7 +334,7 @@ impl<'tcx> MovePathLookup<'tcx> {
};

for (_, elem) in self.un_derefer.iter_projections(place) {
if let Some(&subpath) = self.projections.get(&(result, elem.lift())) {
if let Some(&subpath) = self.projections.get(&(result, elem.kind())) {
result = subpath;
} else {
return LookupResult::Parent(Some(result));
Expand Down
62 changes: 15 additions & 47 deletions compiler/rustc_mir_transform/src/gvn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,26 +447,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {

Projection(base, elem) => {
let base = self.evaluated[base].as_ref()?;
let elem = match elem {
ProjectionElem::Deref => ProjectionElem::Deref,
ProjectionElem::Downcast(name, read_variant) => {
ProjectionElem::Downcast(name, read_variant)
}
ProjectionElem::Field(f, ()) => ProjectionElem::Field(f, ty.ty),
ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
ProjectionElem::ConstantIndex { offset, min_length, from_end }
}
ProjectionElem::Subslice { from, to, from_end } => {
ProjectionElem::Subslice { from, to, from_end }
}
ProjectionElem::OpaqueCast(()) => ProjectionElem::OpaqueCast(ty.ty),
ProjectionElem::Subtype(()) => ProjectionElem::Subtype(ty.ty),
ProjectionElem::UnwrapUnsafeBinder(()) => {
ProjectionElem::UnwrapUnsafeBinder(ty.ty)
}
// This should have been replaced by a `ConstantIndex` earlier.
ProjectionElem::Index(_) => return None,
};
// `Index` by constants should have been replaces by `ConstantIndex` by
// `simplify_place_projection`.
let elem = elem.try_map(|_| None, |()| ty.ty)?;
self.ecx.project(base, elem).discard_err()?
}
Address { place, kind: _, provenance: _ } => {
Expand All @@ -476,13 +459,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
let local = self.locals[place.local]?;
let pointer = self.evaluated[local].as_ref()?;
let mut mplace = self.ecx.deref_pointer(pointer).discard_err()?;
for proj in place.projection.iter().skip(1) {
// We have no call stack to associate a local with a value, so we cannot
// interpret indexing.
if matches!(proj, ProjectionElem::Index(_)) {
return None;
}
mplace = self.ecx.project(&mplace, proj).discard_err()?;
for elem in place.projection.iter().skip(1) {
// `Index` by constants should have been replaces by `ConstantIndex` by
// `simplify_place_projection`.
let elem = elem.try_map(|_| None, |ty| ty)?;
mplace = self.ecx.project(&mplace, elem).discard_err()?;
}
let pointer = mplace.to_ref(&self.ecx);
ImmTy::from_immediate(pointer, ty).into()
Expand Down Expand Up @@ -902,27 +883,14 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
proj: ProjectionElem<VnIndex, ()>,
loc: Location,
) -> Option<PlaceElem<'tcx>> {
Some(match proj {
ProjectionElem::Deref => ProjectionElem::Deref,
ProjectionElem::Field(idx, ()) => ProjectionElem::Field(idx, ty),
ProjectionElem::Index(idx) => {
let Some(local) = self.try_as_local(idx, loc) else {
return None;
};
proj.try_map(
|value| {
let local = self.try_as_local(value, loc)?;
self.reused_locals.insert(local);
ProjectionElem::Index(local)
}
ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
ProjectionElem::ConstantIndex { offset, min_length, from_end }
}
ProjectionElem::Subslice { from, to, from_end } => {
ProjectionElem::Subslice { from, to, from_end }
}
ProjectionElem::Downcast(symbol, idx) => ProjectionElem::Downcast(symbol, idx),
ProjectionElem::OpaqueCast(()) => ProjectionElem::OpaqueCast(ty),
ProjectionElem::Subtype(()) => ProjectionElem::Subtype(ty),
ProjectionElem::UnwrapUnsafeBinder(()) => ProjectionElem::UnwrapUnsafeBinder(ty),
})
Some(local)
},
|()| ty,
)
}

fn simplify_aggregate_to_copy(
Expand Down
Loading