2022-09-14 23:07:19 +08:00
|
|
|
#![deny(rustc::untranslatable_diagnostic)]
|
|
|
|
#![deny(rustc::diagnostic_outside_of_impl)]
|
2020-12-30 18:48:40 +01:00
|
|
|
use crate::borrow_set::LocalsStateAtExit;
|
2020-03-29 17:19:48 +02:00
|
|
|
use rustc_hir as hir;
|
2020-03-29 16:41:09 +02:00
|
|
|
use rustc_middle::mir::ProjectionElem;
|
|
|
|
use rustc_middle::mir::{Body, Mutability, Place};
|
|
|
|
use rustc_middle::ty::{self, TyCtxt};
|
2018-04-06 15:53:49 -04:00
|
|
|
|
|
|
|
/// Extension methods for the `Place` type.
|
2023-04-29 16:57:50 +02:00
|
|
|
pub trait PlaceExt<'tcx> {
|
2019-02-08 14:53:55 +01:00
|
|
|
/// Returns `true` if we can safely ignore borrows of this place.
|
2018-08-07 18:01:29 -04:00
|
|
|
/// This is true whenever there is no action that the user can do
|
|
|
|
/// to the place `self` that would invalidate the borrow. This is true
|
|
|
|
/// for borrows of raw pointer dereferents as well as shared references.
|
2018-09-05 23:49:58 +01:00
|
|
|
fn ignore_borrow(
|
|
|
|
&self,
|
2019-06-14 00:48:52 +03:00
|
|
|
tcx: TyCtxt<'tcx>,
|
2019-06-03 18:26:48 -04:00
|
|
|
body: &Body<'tcx>,
|
2018-09-05 23:49:58 +01:00
|
|
|
locals_state_at_exit: &LocalsStateAtExit,
|
2019-06-12 00:11:55 +03:00
|
|
|
) -> bool;
|
2018-04-06 15:53:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
|
2018-09-05 23:49:58 +01:00
|
|
|
fn ignore_borrow(
|
|
|
|
&self,
|
2019-06-14 00:48:52 +03:00
|
|
|
tcx: TyCtxt<'tcx>,
|
2019-06-03 18:26:48 -04:00
|
|
|
body: &Body<'tcx>,
|
2018-09-05 23:49:58 +01:00
|
|
|
locals_state_at_exit: &LocalsStateAtExit,
|
|
|
|
) -> bool {
|
2019-12-11 16:50:03 -03:00
|
|
|
// If a local variable is immutable, then we only need to track borrows to guard
|
|
|
|
// against two kinds of errors:
|
|
|
|
// * The variable being dropped while still borrowed (e.g., because the fn returns
|
|
|
|
// a reference to a local variable)
|
|
|
|
// * The variable being moved while still borrowed
|
|
|
|
//
|
|
|
|
// In particular, the variable cannot be mutated -- the "access checks" will fail --
|
|
|
|
// so we don't have to worry about mutation while borrowed.
|
|
|
|
if let LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } =
|
|
|
|
locals_state_at_exit
|
|
|
|
{
|
|
|
|
let ignore = !has_storage_dead_or_moved.contains(self.local)
|
|
|
|
&& body.local_decls[self.local].mutability == Mutability::Not;
|
|
|
|
debug!("ignore_borrow: local {:?} => {:?}", self.local, ignore);
|
|
|
|
if ignore {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2018-08-07 18:01:29 -04:00
|
|
|
|
2023-06-25 20:38:01 -04:00
|
|
|
for (i, (proj_base, elem)) in self.iter_projections().enumerate() {
|
2020-05-23 11:49:24 +02:00
|
|
|
if elem == ProjectionElem::Deref {
|
2023-06-25 20:38:01 -04:00
|
|
|
let ty = proj_base.ty(body, tcx).ty;
|
2020-08-03 00:49:11 +02:00
|
|
|
match ty.kind() {
|
2019-12-16 17:28:40 +01:00
|
|
|
ty::Ref(_, _, hir::Mutability::Not) if i == 0 => {
|
2019-11-18 23:04:06 +00:00
|
|
|
// For references to thread-local statics, we do need
|
|
|
|
// to track the borrow.
|
2019-12-11 16:50:03 -03:00
|
|
|
if body.local_decls[self.local].is_ref_to_thread_local() {
|
2019-11-18 23:04:06 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2019-12-16 17:28:40 +01:00
|
|
|
ty::RawPtr(..) | ty::Ref(_, _, hir::Mutability::Not) => {
|
2019-11-18 23:04:06 +00:00
|
|
|
// For both derefs of raw pointers and `&T`
|
|
|
|
// references, the original path is `Copy` and
|
2022-11-16 20:34:16 +00:00
|
|
|
// therefore not significant. In particular,
|
2019-11-18 23:04:06 +00:00
|
|
|
// there is nothing the user can do to the
|
|
|
|
// original path that would invalidate the
|
|
|
|
// newly created reference -- and if there
|
|
|
|
// were, then the user could have copied the
|
|
|
|
// original path into a new variable and
|
|
|
|
// borrowed *that* one, leaving the original
|
|
|
|
// path unborrowed.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
_ => {}
|
2018-04-06 15:53:49 -04:00
|
|
|
}
|
2019-05-23 21:53:59 +02:00
|
|
|
}
|
2019-07-30 00:07:28 +02:00
|
|
|
}
|
2019-05-23 21:53:59 +02:00
|
|
|
|
2019-11-18 23:04:06 +00:00
|
|
|
false
|
2018-04-06 15:53:49 -04:00
|
|
|
}
|
|
|
|
}
|