Rollup merge of #82091 - henryboisdequin:use-place-ref-more, r=RalfJung
use PlaceRef abstractions more consistently Addresses this [comment](https://github.com/rust-lang/rust/pull/80865/files#r558978715) Associated issue: #80647 r? ```@RalfJung```
This commit is contained in:
commit
cc07061190
@ -199,7 +199,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
|
||||
}
|
||||
|
||||
self.visit_local(&place_ref.local, context, location);
|
||||
self.visit_projection(place_ref.local, place_ref.projection, context, location);
|
||||
self.visit_projection(*place_ref, context, location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -998,12 +998,11 @@ macro_rules! visit_place_fns {
|
||||
() => {
|
||||
fn visit_projection(
|
||||
&mut self,
|
||||
local: Local,
|
||||
projection: &[PlaceElem<'tcx>],
|
||||
place_ref: PlaceRef<'tcx>,
|
||||
context: PlaceContext,
|
||||
location: Location,
|
||||
) {
|
||||
self.super_projection(local, projection, context, location);
|
||||
self.super_projection(place_ref, context, location);
|
||||
}
|
||||
|
||||
fn visit_projection_elem(
|
||||
@ -1033,20 +1032,20 @@ macro_rules! visit_place_fns {
|
||||
|
||||
self.visit_local(&place.local, context, location);
|
||||
|
||||
self.visit_projection(place.local, &place.projection, context, location);
|
||||
self.visit_projection(place.as_ref(), context, location);
|
||||
}
|
||||
|
||||
fn super_projection(
|
||||
&mut self,
|
||||
local: Local,
|
||||
projection: &[PlaceElem<'tcx>],
|
||||
place_ref: PlaceRef<'tcx>,
|
||||
context: PlaceContext,
|
||||
location: Location,
|
||||
) {
|
||||
let mut cursor = projection;
|
||||
// FIXME: Use PlaceRef::iter_projections, once that exists.
|
||||
let mut cursor = place_ref.projection;
|
||||
while let &[ref proj_base @ .., elem] = cursor {
|
||||
cursor = proj_base;
|
||||
self.visit_projection_elem(local, cursor, elem, context, location);
|
||||
self.visit_projection_elem(place_ref.local, cursor, elem, context, location);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ where
|
||||
|
||||
// We purposefully do not call `super_place` here to avoid calling `visit_local` for this
|
||||
// place with one of the `Projection` variants of `PlaceContext`.
|
||||
self.visit_projection(local, projection, context, location);
|
||||
self.visit_projection(place.as_ref(), context, location);
|
||||
|
||||
match DefUse::for_place(context) {
|
||||
// Treat derefs as a use of the base local. `*p = 4` is not a def of `p` but a use.
|
||||
|
@ -515,7 +515,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
|
||||
// Special-case reborrows to be more like a copy of a reference.
|
||||
match *rvalue {
|
||||
Rvalue::Ref(_, kind, place) => {
|
||||
if let Some(reborrowed_proj) = place_as_reborrow(self.tcx, self.body, place) {
|
||||
if let Some(reborrowed_place_ref) = place_as_reborrow(self.tcx, self.body, place) {
|
||||
let ctx = match kind {
|
||||
BorrowKind::Shared => {
|
||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow)
|
||||
@ -530,21 +530,21 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Borrow)
|
||||
}
|
||||
};
|
||||
self.visit_local(&place.local, ctx, location);
|
||||
self.visit_projection(place.local, reborrowed_proj, ctx, location);
|
||||
self.visit_local(&reborrowed_place_ref.local, ctx, location);
|
||||
self.visit_projection(reborrowed_place_ref, ctx, location);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Rvalue::AddressOf(mutbl, place) => {
|
||||
if let Some(reborrowed_proj) = place_as_reborrow(self.tcx, self.body, place) {
|
||||
if let Some(reborrowed_place_ref) = place_as_reborrow(self.tcx, self.body, place) {
|
||||
let ctx = match mutbl {
|
||||
Mutability::Not => {
|
||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf)
|
||||
}
|
||||
Mutability::Mut => PlaceContext::MutatingUse(MutatingUseContext::AddressOf),
|
||||
};
|
||||
self.visit_local(&place.local, ctx, location);
|
||||
self.visit_projection(place.local, reborrowed_proj, ctx, location);
|
||||
self.visit_local(&reborrowed_place_ref.local, ctx, location);
|
||||
self.visit_projection(reborrowed_place_ref, ctx, location);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1039,7 +1039,7 @@ fn place_as_reborrow(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
place: Place<'tcx>,
|
||||
) -> Option<&'a [PlaceElem<'tcx>]> {
|
||||
) -> Option<PlaceRef<'tcx>> {
|
||||
match place.as_ref().last_projection() {
|
||||
Some((place_base, ProjectionElem::Deref)) => {
|
||||
// A borrow of a `static` also looks like `&(*_1)` in the MIR, but `_1` is a `const`
|
||||
@ -1048,13 +1048,14 @@ fn place_as_reborrow(
|
||||
None
|
||||
} else {
|
||||
// Ensure the type being derefed is a reference and not a raw pointer.
|
||||
//
|
||||
// This is sufficient to prevent an access to a `static mut` from being marked as a
|
||||
// reborrow, even if the check above were to disappear.
|
||||
let inner_ty = place_base.ty(body, tcx).ty;
|
||||
match inner_ty.kind() {
|
||||
ty::Ref(..) => Some(place_base.projection),
|
||||
_ => None,
|
||||
|
||||
if let ty::Ref(..) = inner_ty.kind() {
|
||||
return Some(place_base);
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -413,8 +413,7 @@ impl UsedLocals {
|
||||
} else {
|
||||
// A definition. Although, it still might use other locals for indexing.
|
||||
self.super_projection(
|
||||
place.local,
|
||||
&place.projection,
|
||||
place.as_ref(),
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Projection),
|
||||
location,
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user