]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_borrowck/src/place_ext.rs
bump version to 1.80.1+dfsg1-1~bpo12+pve1
[rustc.git] / compiler / rustc_borrowck / src / place_ext.rs
CommitLineData
c295e0f8 1use crate::borrow_set::LocalsStateAtExit;
dfeec247 2use rustc_hir as hir;
c620b35d 3use rustc_macros::extension;
ba9703b0
XL
4use rustc_middle::mir::ProjectionElem;
5use rustc_middle::mir::{Body, Mutability, Place};
6use rustc_middle::ty::{self, TyCtxt};
83c7162d 7
c620b35d
FG
8#[extension(pub trait PlaceExt<'tcx>)]
9impl<'tcx> Place<'tcx> {
9fa01778 10 /// Returns `true` if we can safely ignore borrows of this place.
b7449926
XL
11 /// This is true whenever there is no action that the user can do
12 /// to the place `self` that would invalidate the borrow. This is true
13 /// for borrows of raw pointer dereferents as well as shared references.
b7449926
XL
14 fn ignore_borrow(
15 &self,
dc9dc135
XL
16 tcx: TyCtxt<'tcx>,
17 body: &Body<'tcx>,
b7449926
XL
18 locals_state_at_exit: &LocalsStateAtExit,
19 ) -> bool {
dfeec247
XL
20 // If a local variable is immutable, then we only need to track borrows to guard
21 // against two kinds of errors:
22 // * The variable being dropped while still borrowed (e.g., because the fn returns
23 // a reference to a local variable)
24 // * The variable being moved while still borrowed
25 //
26 // In particular, the variable cannot be mutated -- the "access checks" will fail --
27 // so we don't have to worry about mutation while borrowed.
28 if let LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } =
29 locals_state_at_exit
30 {
31 let ignore = !has_storage_dead_or_moved.contains(self.local)
32 && body.local_decls[self.local].mutability == Mutability::Not;
33 debug!("ignore_borrow: local {:?} => {:?}", self.local, ignore);
34 if ignore {
35 return true;
e1599b0c 36 }
dfeec247 37 }
b7449926 38
fe692bf9 39 for (i, (proj_base, elem)) in self.iter_projections().enumerate() {
f9f354fc 40 if elem == ProjectionElem::Deref {
fe692bf9 41 let ty = proj_base.ty(body, tcx).ty;
1b1a35ee 42 match ty.kind() {
dfeec247 43 ty::Ref(_, _, hir::Mutability::Not) if i == 0 => {
60c5eb7d
XL
44 // For references to thread-local statics, we do need
45 // to track the borrow.
dfeec247 46 if body.local_decls[self.local].is_ref_to_thread_local() {
60c5eb7d
XL
47 continue;
48 }
49 return true;
50 }
dfeec247 51 ty::RawPtr(..) | ty::Ref(_, _, hir::Mutability::Not) => {
60c5eb7d
XL
52 // For both derefs of raw pointers and `&T`
53 // references, the original path is `Copy` and
9c376795 54 // therefore not significant. In particular,
60c5eb7d
XL
55 // there is nothing the user can do to the
56 // original path that would invalidate the
57 // newly created reference -- and if there
58 // were, then the user could have copied the
59 // original path into a new variable and
60 // borrowed *that* one, leaving the original
61 // path unborrowed.
62 return true;
63 }
64 _ => {}
83c7162d 65 }
dc9dc135 66 }
e1599b0c 67 }
dc9dc135 68
60c5eb7d 69 false
83c7162d 70 }
83c7162d 71}