Auto merge of #60441 - vext01:try-to-kill-projection-params, r=oli-obk
Make place projections concrete.
**I'm not sure if we want this. I'm raising the PR for discussion**
Whilst doing some work on our Rust fork, I noticed the following:
Once upon a time (commit 9bd35c07c2
) there were two kinds of
projection: one for places, and one for constants. It therefore made
sense to share the `Projection` struct for both. Although the different
use-cases used different concrete types, sharing was made possible by
type-parameterisation of `Projection`.
Since then, however, the usage of projections in constants has
disappeared, meaning that (forgetting lifetimes for a moment) the
parameterised type is only every instantiated under one guise. So it may
as well be a concrete type. Right?
What do people think? This is entirely untested, although it does check.
If we *don't* want this, then we should at least update the incorrect comment against `Projection`.
Thanks
This commit is contained in:
commit
5245803120
10 changed files with 55 additions and 67 deletions
|
@ -1914,7 +1914,7 @@ pub enum Place<'tcx> {
|
||||||
Base(PlaceBase<'tcx>),
|
Base(PlaceBase<'tcx>),
|
||||||
|
|
||||||
/// projection out of a place (access a field, deref a pointer, etc)
|
/// projection out of a place (access a field, deref a pointer, etc)
|
||||||
Projection(Box<PlaceProjection<'tcx>>),
|
Projection(Box<Projection<'tcx>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable)]
|
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable)]
|
||||||
|
@ -1944,16 +1944,13 @@ impl_stable_hash_for!(struct Static<'tcx> {
|
||||||
kind
|
kind
|
||||||
});
|
});
|
||||||
|
|
||||||
/// The `Projection` data structure defines things of the form `B.x`
|
/// The `Projection` data structure defines things of the form `base.x`, `*b` or `b[index]`.
|
||||||
/// or `*B` or `B[index]`. Note that it is parameterized because it is
|
|
||||||
/// shared between `Constant` and `Place`. See the aliases
|
|
||||||
/// `PlaceProjection` etc below.
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord,
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord,
|
||||||
Hash, RustcEncodable, RustcDecodable, HashStable)]
|
Hash, RustcEncodable, RustcDecodable, HashStable)]
|
||||||
pub struct Projection<B, V, T> {
|
pub struct Projection<'tcx> {
|
||||||
pub base: B,
|
pub base: Place<'tcx>,
|
||||||
pub elem: ProjectionElem<V, T>,
|
pub elem: PlaceElem<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord,
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord,
|
||||||
Hash, RustcEncodable, RustcDecodable, HashStable)]
|
Hash, RustcEncodable, RustcDecodable, HashStable)]
|
||||||
|
@ -1996,10 +1993,6 @@ pub enum ProjectionElem<V, T> {
|
||||||
Downcast(Option<Symbol>, VariantIdx),
|
Downcast(Option<Symbol>, VariantIdx),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Alias for projections as they appear in places, where the base is a place
|
|
||||||
/// and the index is a local.
|
|
||||||
pub type PlaceProjection<'tcx> = Projection<Place<'tcx>, Local, Ty<'tcx>>;
|
|
||||||
|
|
||||||
/// Alias for projections as they appear in places, where the base is a place
|
/// Alias for projections as they appear in places, where the base is a place
|
||||||
/// and the index is a local.
|
/// and the index is a local.
|
||||||
pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
|
pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
|
||||||
|
@ -2045,7 +2038,7 @@ impl<'tcx> Place<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn elem(self, elem: PlaceElem<'tcx>) -> Place<'tcx> {
|
pub fn elem(self, elem: PlaceElem<'tcx>) -> Place<'tcx> {
|
||||||
Place::Projection(Box::new(PlaceProjection { base: self, elem }))
|
Place::Projection(Box::new(Projection { base: self, elem }))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
|
/// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
|
||||||
|
@ -2076,22 +2069,22 @@ impl<'tcx> Place<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recursively "iterates" over place components, generating a `PlaceBase` and
|
/// Recursively "iterates" over place components, generating a `PlaceBase` and
|
||||||
/// `PlaceProjections` list and invoking `op` with a `PlaceProjectionsIter`.
|
/// `Projections` list and invoking `op` with a `ProjectionsIter`.
|
||||||
pub fn iterate<R>(
|
pub fn iterate<R>(
|
||||||
&self,
|
&self,
|
||||||
op: impl FnOnce(&PlaceBase<'tcx>, PlaceProjectionsIter<'_, 'tcx>) -> R,
|
op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R,
|
||||||
) -> R {
|
) -> R {
|
||||||
self.iterate2(&PlaceProjections::Empty, op)
|
self.iterate2(&Projections::Empty, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iterate2<R>(
|
fn iterate2<R>(
|
||||||
&self,
|
&self,
|
||||||
next: &PlaceProjections<'_, 'tcx>,
|
next: &Projections<'_, 'tcx>,
|
||||||
op: impl FnOnce(&PlaceBase<'tcx>, PlaceProjectionsIter<'_, 'tcx>) -> R,
|
op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R,
|
||||||
) -> R {
|
) -> R {
|
||||||
match self {
|
match self {
|
||||||
Place::Projection(interior) => interior.base.iterate2(
|
Place::Projection(interior) => interior.base.iterate2(
|
||||||
&PlaceProjections::List {
|
&Projections::List {
|
||||||
projection: interior,
|
projection: interior,
|
||||||
next,
|
next,
|
||||||
},
|
},
|
||||||
|
@ -2111,26 +2104,26 @@ impl<'tcx> Place<'tcx> {
|
||||||
/// N.B., this particular impl strategy is not the most obvious. It was
|
/// N.B., this particular impl strategy is not the most obvious. It was
|
||||||
/// chosen because it makes a measurable difference to NLL
|
/// chosen because it makes a measurable difference to NLL
|
||||||
/// performance, as this code (`borrow_conflicts_with_place`) is somewhat hot.
|
/// performance, as this code (`borrow_conflicts_with_place`) is somewhat hot.
|
||||||
pub enum PlaceProjections<'p, 'tcx: 'p> {
|
pub enum Projections<'p, 'tcx: 'p> {
|
||||||
Empty,
|
Empty,
|
||||||
|
|
||||||
List {
|
List {
|
||||||
projection: &'p PlaceProjection<'tcx>,
|
projection: &'p Projection<'tcx>,
|
||||||
next: &'p PlaceProjections<'p, 'tcx>,
|
next: &'p Projections<'p, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'p, 'tcx> PlaceProjections<'p, 'tcx> {
|
impl<'p, 'tcx> Projections<'p, 'tcx> {
|
||||||
fn iter(&self) -> PlaceProjectionsIter<'_, 'tcx> {
|
fn iter(&self) -> ProjectionsIter<'_, 'tcx> {
|
||||||
PlaceProjectionsIter { value: self }
|
ProjectionsIter { value: self }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'p, 'tcx> IntoIterator for &'p PlaceProjections<'p, 'tcx> {
|
impl<'p, 'tcx> IntoIterator for &'p Projections<'p, 'tcx> {
|
||||||
type Item = &'p PlaceProjection<'tcx>;
|
type Item = &'p Projection<'tcx>;
|
||||||
type IntoIter = PlaceProjectionsIter<'p, 'tcx>;
|
type IntoIter = ProjectionsIter<'p, 'tcx>;
|
||||||
|
|
||||||
/// Converts a list of `PlaceProjection` components into an iterator;
|
/// Converts a list of `Projection` components into an iterator;
|
||||||
/// this iterator yields up a never-ending stream of `Option<&Place>`.
|
/// this iterator yields up a never-ending stream of `Option<&Place>`.
|
||||||
/// These begin with the "innermost" projection and then with each
|
/// These begin with the "innermost" projection and then with each
|
||||||
/// projection therefrom. So given a place like `a.b.c` it would
|
/// projection therefrom. So given a place like `a.b.c` it would
|
||||||
|
@ -2144,21 +2137,21 @@ impl<'p, 'tcx> IntoIterator for &'p PlaceProjections<'p, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterator over components; see `PlaceProjections::iter` for more
|
/// Iterator over components; see `Projections::iter` for more
|
||||||
/// information.
|
/// information.
|
||||||
///
|
///
|
||||||
/// N.B., this is not a *true* Rust iterator -- the code above just
|
/// N.B., this is not a *true* Rust iterator -- the code above just
|
||||||
/// manually invokes `next`. This is because we (sometimes) want to
|
/// manually invokes `next`. This is because we (sometimes) want to
|
||||||
/// keep executing even after `None` has been returned.
|
/// keep executing even after `None` has been returned.
|
||||||
pub struct PlaceProjectionsIter<'p, 'tcx: 'p> {
|
pub struct ProjectionsIter<'p, 'tcx: 'p> {
|
||||||
pub value: &'p PlaceProjections<'p, 'tcx>,
|
pub value: &'p Projections<'p, 'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'p, 'tcx> Iterator for PlaceProjectionsIter<'p, 'tcx> {
|
impl<'p, 'tcx> Iterator for ProjectionsIter<'p, 'tcx> {
|
||||||
type Item = &'p PlaceProjection<'tcx>;
|
type Item = &'p Projection<'tcx>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
if let &PlaceProjections::List { projection, next } = self.value {
|
if let &Projections::List { projection, next } = self.value {
|
||||||
self.value = next;
|
self.value = next;
|
||||||
Some(projection)
|
Some(projection)
|
||||||
} else {
|
} else {
|
||||||
|
@ -2167,7 +2160,7 @@ impl<'p, 'tcx> Iterator for PlaceProjectionsIter<'p, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'p, 'tcx> FusedIterator for PlaceProjectionsIter<'p, 'tcx> {}
|
impl<'p, 'tcx> FusedIterator for ProjectionsIter<'p, 'tcx> {}
|
||||||
|
|
||||||
impl<'tcx> Debug for Place<'tcx> {
|
impl<'tcx> Debug for Place<'tcx> {
|
||||||
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
@ -2758,7 +2751,7 @@ impl<'tcx> UserTypeProjections {
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
|
||||||
pub struct UserTypeProjection {
|
pub struct UserTypeProjection {
|
||||||
pub base: UserTypeAnnotationIndex,
|
pub base: UserTypeAnnotationIndex,
|
||||||
pub projs: Vec<ProjectionElem<(), ()>>,
|
pub projs: Vec<ProjectionKind>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Copy for ProjectionKind { }
|
impl Copy for ProjectionKind { }
|
||||||
|
@ -3587,12 +3580,7 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, B, V, T> TypeFoldable<'tcx> for Projection<B, V, T>
|
impl<'tcx> TypeFoldable<'tcx> for Projection<'tcx> {
|
||||||
where
|
|
||||||
B: TypeFoldable<'tcx>,
|
|
||||||
V: TypeFoldable<'tcx>,
|
|
||||||
T: TypeFoldable<'tcx>,
|
|
||||||
{
|
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||||
use crate::mir::ProjectionElem::*;
|
use crate::mir::ProjectionElem::*;
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ macro_rules! make_mir_visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_projection(&mut self,
|
fn visit_projection(&mut self,
|
||||||
place: & $($mutability)? PlaceProjection<'tcx>,
|
place: & $($mutability)? Projection<'tcx>,
|
||||||
context: PlaceContext,
|
context: PlaceContext,
|
||||||
location: Location) {
|
location: Location) {
|
||||||
self.super_projection(place, context, location);
|
self.super_projection(place, context, location);
|
||||||
|
@ -689,7 +689,7 @@ macro_rules! make_mir_visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_projection(&mut self,
|
fn super_projection(&mut self,
|
||||||
proj: & $($mutability)? PlaceProjection<'tcx>,
|
proj: & $($mutability)? Projection<'tcx>,
|
||||||
context: PlaceContext,
|
context: PlaceContext,
|
||||||
location: Location) {
|
location: Location) {
|
||||||
let Projection { base, elem } = proj;
|
let Projection { base, elem } = proj;
|
||||||
|
|
|
@ -2,7 +2,7 @@ use rustc::hir;
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::mir::{
|
use rustc::mir::{
|
||||||
self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory, Local,
|
self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory, Local,
|
||||||
LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, PlaceProjection,
|
LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, Projection,
|
||||||
ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm,
|
ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm,
|
||||||
};
|
};
|
||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
|
@ -619,7 +619,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||||
// union being accessed and the field that was being accessed so we can check the
|
// union being accessed and the field that was being accessed so we can check the
|
||||||
// second borrowed place for the same union and a access to a different field.
|
// second borrowed place for the same union and a access to a different field.
|
||||||
let mut current = first_borrowed_place;
|
let mut current = first_borrowed_place;
|
||||||
while let Place::Projection(box PlaceProjection { base, elem }) = current {
|
while let Place::Projection(box Projection { base, elem }) = current {
|
||||||
match elem {
|
match elem {
|
||||||
ProjectionElem::Field(field, _) if is_union(base) => {
|
ProjectionElem::Field(field, _) if is_union(base) => {
|
||||||
return Some((base, field));
|
return Some((base, field));
|
||||||
|
@ -633,7 +633,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||||
// With the place of a union and a field access into it, we traverse the second
|
// With the place of a union and a field access into it, we traverse the second
|
||||||
// borrowed place and look for a access to a different field of the same union.
|
// borrowed place and look for a access to a different field of the same union.
|
||||||
let mut current = second_borrowed_place;
|
let mut current = second_borrowed_place;
|
||||||
while let Place::Projection(box PlaceProjection { base, elem }) = current {
|
while let Place::Projection(box Projection { base, elem }) = current {
|
||||||
match elem {
|
match elem {
|
||||||
ProjectionElem::Field(field, _) if {
|
ProjectionElem::Field(field, _) if {
|
||||||
is_union(base) && field != target_field && base == target_base
|
is_union(base) && field != target_field && base == target_base
|
||||||
|
@ -1495,7 +1495,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||||
Place::Base(PlaceBase::Static(_)) => {
|
Place::Base(PlaceBase::Static(_)) => {
|
||||||
StorageDeadOrDrop::LocalStorageDead
|
StorageDeadOrDrop::LocalStorageDead
|
||||||
}
|
}
|
||||||
Place::Projection(box PlaceProjection { base, elem }) => {
|
Place::Projection(box Projection { base, elem }) => {
|
||||||
let base_access = self.classify_drop_access_kind(base);
|
let base_access = self.classify_drop_access_kind(base);
|
||||||
match elem {
|
match elem {
|
||||||
ProjectionElem::Deref => match base_access {
|
ProjectionElem::Deref => match base_access {
|
||||||
|
|
|
@ -352,7 +352,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let try_remove_deref = match move_from {
|
let try_remove_deref = match move_from {
|
||||||
Place::Projection(box PlaceProjection {
|
Place::Projection(box Projection {
|
||||||
elem: ProjectionElem::Deref,
|
elem: ProjectionElem::Deref,
|
||||||
..
|
..
|
||||||
}) => true,
|
}) => true,
|
||||||
|
|
|
@ -2370,7 +2370,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||||
"add_reborrow_constraint({:?}, {:?}, {:?})",
|
"add_reborrow_constraint({:?}, {:?}, {:?})",
|
||||||
location, borrow_region, borrowed_place
|
location, borrow_region, borrowed_place
|
||||||
);
|
);
|
||||||
while let Place::Projection(box PlaceProjection { base, elem }) = borrowed_place {
|
while let Place::Projection(box Projection { base, elem }) = borrowed_place {
|
||||||
debug!("add_reborrow_constraint - iteration {:?}", borrowed_place);
|
debug!("add_reborrow_constraint - iteration {:?}", borrowed_place);
|
||||||
|
|
||||||
match *elem {
|
match *elem {
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::borrow_check::Overlap;
|
||||||
use crate::borrow_check::{Deep, Shallow, AccessDepth};
|
use crate::borrow_check::{Deep, Shallow, AccessDepth};
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::mir::{
|
use rustc::mir::{
|
||||||
BorrowKind, Mir, Place, PlaceBase, PlaceProjection, ProjectionElem, PlaceProjectionsIter,
|
BorrowKind, Mir, Place, PlaceBase, Projection, ProjectionElem, ProjectionsIter,
|
||||||
StaticKind
|
StaticKind
|
||||||
};
|
};
|
||||||
use rustc::ty::{self, TyCtxt};
|
use rustc::ty::{self, TyCtxt};
|
||||||
|
@ -86,9 +86,9 @@ pub(super) fn borrow_conflicts_with_place<'gcx, 'tcx>(
|
||||||
fn place_components_conflict<'gcx, 'tcx>(
|
fn place_components_conflict<'gcx, 'tcx>(
|
||||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||||
mir: &Mir<'tcx>,
|
mir: &Mir<'tcx>,
|
||||||
borrow_projections: (&PlaceBase<'tcx>, PlaceProjectionsIter<'_, 'tcx>),
|
borrow_projections: (&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>),
|
||||||
borrow_kind: BorrowKind,
|
borrow_kind: BorrowKind,
|
||||||
access_projections: (&PlaceBase<'tcx>, PlaceProjectionsIter<'_, 'tcx>),
|
access_projections: (&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>),
|
||||||
access: AccessDepth,
|
access: AccessDepth,
|
||||||
bias: PlaceConflictBias,
|
bias: PlaceConflictBias,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
@ -368,8 +368,8 @@ fn place_base_conflict<'a, 'gcx: 'tcx, 'tcx>(
|
||||||
fn place_projection_conflict<'a, 'gcx: 'tcx, 'tcx>(
|
fn place_projection_conflict<'a, 'gcx: 'tcx, 'tcx>(
|
||||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
mir: &Mir<'tcx>,
|
mir: &Mir<'tcx>,
|
||||||
pi1: &PlaceProjection<'tcx>,
|
pi1: &Projection<'tcx>,
|
||||||
pi2: &PlaceProjection<'tcx>,
|
pi2: &Projection<'tcx>,
|
||||||
bias: PlaceConflictBias,
|
bias: PlaceConflictBias,
|
||||||
) -> Overlap {
|
) -> Overlap {
|
||||||
match (&pi1.elem, &pi2.elem) {
|
match (&pi1.elem, &pi2.elem) {
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
|
||||||
path: MovePathIndex,
|
path: MovePathIndex,
|
||||||
mut cond: F)
|
mut cond: F)
|
||||||
-> Option<MovePathIndex>
|
-> Option<MovePathIndex>
|
||||||
where F: FnMut(&mir::PlaceProjection<'tcx>) -> bool
|
where F: FnMut(&mir::Projection<'tcx>) -> bool
|
||||||
{
|
{
|
||||||
let mut next_child = move_data.move_paths[path].first_child;
|
let mut next_child = move_data.move_paths[path].first_child;
|
||||||
while let Some(child_index) = next_child {
|
while let Some(child_index) = next_child {
|
||||||
|
|
|
@ -114,7 +114,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
fn move_path_for_projection(&mut self,
|
fn move_path_for_projection(&mut self,
|
||||||
place: &Place<'tcx>,
|
place: &Place<'tcx>,
|
||||||
proj: &PlaceProjection<'tcx>)
|
proj: &Projection<'tcx>)
|
||||||
-> Result<MovePathIndex, MoveError<'tcx>>
|
-> Result<MovePathIndex, MoveError<'tcx>>
|
||||||
{
|
{
|
||||||
let base = self.move_path_for(&proj.base)?;
|
let base = self.move_path_for(&proj.base)?;
|
||||||
|
|
|
@ -161,7 +161,7 @@ trait Qualif {
|
||||||
|
|
||||||
fn in_projection_structurally(
|
fn in_projection_structurally(
|
||||||
cx: &ConstCx<'_, 'tcx>,
|
cx: &ConstCx<'_, 'tcx>,
|
||||||
proj: &PlaceProjection<'tcx>,
|
proj: &Projection<'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let base_qualif = Self::in_place(cx, &proj.base);
|
let base_qualif = Self::in_place(cx, &proj.base);
|
||||||
let qualif = base_qualif && Self::mask_for_ty(
|
let qualif = base_qualif && Self::mask_for_ty(
|
||||||
|
@ -181,7 +181,7 @@ trait Qualif {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn in_projection(cx: &ConstCx<'_, 'tcx>, proj: &PlaceProjection<'tcx>) -> bool {
|
fn in_projection(cx: &ConstCx<'_, 'tcx>, proj: &Projection<'tcx>) -> bool {
|
||||||
Self::in_projection_structurally(cx, proj)
|
Self::in_projection_structurally(cx, proj)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,7 +387,7 @@ impl Qualif for IsNotPromotable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn in_projection(cx: &ConstCx<'_, 'tcx>, proj: &PlaceProjection<'tcx>) -> bool {
|
fn in_projection(cx: &ConstCx<'_, 'tcx>, proj: &Projection<'tcx>) -> bool {
|
||||||
match proj.elem {
|
match proj.elem {
|
||||||
ProjectionElem::Deref |
|
ProjectionElem::Deref |
|
||||||
ProjectionElem::Downcast(..) => return true,
|
ProjectionElem::Downcast(..) => return true,
|
||||||
|
|
|
@ -89,7 +89,7 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> {
|
||||||
fn uniform(&mut self,
|
fn uniform(&mut self,
|
||||||
location: Location,
|
location: Location,
|
||||||
dst_place: &Place<'tcx>,
|
dst_place: &Place<'tcx>,
|
||||||
proj: &PlaceProjection<'tcx>,
|
proj: &Projection<'tcx>,
|
||||||
item_ty: &'tcx ty::TyS<'tcx>,
|
item_ty: &'tcx ty::TyS<'tcx>,
|
||||||
size: u32) {
|
size: u32) {
|
||||||
match proj.elem {
|
match proj.elem {
|
||||||
|
@ -103,7 +103,7 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> {
|
||||||
Place::Base(PlaceBase::Local(temp)),
|
Place::Base(PlaceBase::Local(temp)),
|
||||||
Rvalue::Use(
|
Rvalue::Use(
|
||||||
Operand::Move(
|
Operand::Move(
|
||||||
Place::Projection(box PlaceProjection{
|
Place::Projection(box Projection{
|
||||||
base: proj.base.clone(),
|
base: proj.base.clone(),
|
||||||
elem: ProjectionElem::ConstantIndex{
|
elem: ProjectionElem::ConstantIndex{
|
||||||
offset: i,
|
offset: i,
|
||||||
|
@ -133,7 +133,7 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> {
|
||||||
dst_place.clone(),
|
dst_place.clone(),
|
||||||
Rvalue::Use(
|
Rvalue::Use(
|
||||||
Operand::Move(
|
Operand::Move(
|
||||||
Place::Projection(box PlaceProjection{
|
Place::Projection(box Projection{
|
||||||
base: proj.base.clone(),
|
base: proj.base.clone(),
|
||||||
elem: ProjectionElem::ConstantIndex{
|
elem: ProjectionElem::ConstantIndex{
|
||||||
offset: size - offset,
|
offset: size - offset,
|
||||||
|
@ -246,7 +246,7 @@ impl RestoreSubsliceArrayMoveOut {
|
||||||
dst_place.clone(),
|
dst_place.clone(),
|
||||||
Rvalue::Use(
|
Rvalue::Use(
|
||||||
Operand::Move(
|
Operand::Move(
|
||||||
Place::Projection(box PlaceProjection{
|
Place::Projection(box Projection{
|
||||||
base: opt_src_place.unwrap().clone(),
|
base: opt_src_place.unwrap().clone(),
|
||||||
elem: ProjectionElem::Subslice{
|
elem: ProjectionElem::Subslice{
|
||||||
from: min, to: size - max - 1}}))));
|
from: min, to: size - max - 1}}))));
|
||||||
|
@ -261,7 +261,7 @@ impl RestoreSubsliceArrayMoveOut {
|
||||||
let statement = &block.statements[location.statement_index];
|
let statement = &block.statements[location.statement_index];
|
||||||
if let StatementKind::Assign(
|
if let StatementKind::Assign(
|
||||||
Place::Base(PlaceBase::Local(_)),
|
Place::Base(PlaceBase::Local(_)),
|
||||||
box Rvalue::Use(Operand::Move(Place::Projection(box PlaceProjection{
|
box Rvalue::Use(Operand::Move(Place::Projection(box Projection{
|
||||||
ref base, elem: ProjectionElem::ConstantIndex{
|
ref base, elem: ProjectionElem::ConstantIndex{
|
||||||
offset, min_length: _, from_end: false}})))) = statement.kind {
|
offset, min_length: _, from_end: false}})))) = statement.kind {
|
||||||
return Some((offset, base))
|
return Some((offset, base))
|
||||||
|
|
Loading…
Reference in a new issue