rustc_borrowck/
prefixes.rs1use rustc_middle::mir::{PlaceRef, ProjectionElem};
8
9use super::MirBorrowckCtxt;
10
11pub(crate) trait IsPrefixOf<'tcx> {
12 fn is_prefix_of(&self, other: PlaceRef<'tcx>) -> bool;
13}
14
15impl<'tcx> IsPrefixOf<'tcx> for PlaceRef<'tcx> {
16 fn is_prefix_of(&self, other: PlaceRef<'tcx>) -> bool {
17 self.local == other.local
18 && self.projection.len() <= other.projection.len()
19 && self.projection == &other.projection[..self.projection.len()]
20 }
21}
22
23pub(super) struct Prefixes<'tcx> {
24 kind: PrefixSet,
25 next: Option<PlaceRef<'tcx>>,
26}
27
28#[derive(#[automatically_derived]
impl ::core::marker::Copy for PrefixSet { }Copy, #[automatically_derived]
impl ::core::clone::Clone for PrefixSet {
#[inline]
fn clone(&self) -> PrefixSet { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for PrefixSet {
#[inline]
fn eq(&self, other: &PrefixSet) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for PrefixSet {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for PrefixSet {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
PrefixSet::All => "All",
PrefixSet::Shallow => "Shallow",
})
}
}Debug)]
29pub(super) enum PrefixSet {
30 All,
33 Shallow,
35}
36
37impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
38 pub(super) fn prefixes(&self, place_ref: PlaceRef<'tcx>, kind: PrefixSet) -> Prefixes<'tcx> {
42 Prefixes { next: Some(place_ref), kind }
43 }
44}
45
46impl<'tcx> Iterator for Prefixes<'tcx> {
47 type Item = PlaceRef<'tcx>;
48 fn next(&mut self) -> Option<Self::Item> {
49 let mut cursor = self.next?;
50
51 loop {
57 match cursor.last_projection() {
58 None => {
59 self.next = None;
60 return Some(cursor);
61 }
62 Some((cursor_base, elem)) => {
63 match elem {
64 ProjectionElem::Field(_ , _ ) => {
65 self.next = Some(cursor_base);
67 return Some(cursor);
68 }
69 ProjectionElem::UnwrapUnsafeBinder(_) => {
70 self.next = Some(cursor_base);
71 return Some(cursor);
72 }
73 ProjectionElem::Downcast(..)
74 | ProjectionElem::Subslice { .. }
75 | ProjectionElem::OpaqueCast { .. }
76 | ProjectionElem::ConstantIndex { .. }
77 | ProjectionElem::Index(_) => {
78 cursor = cursor_base;
79 }
80 ProjectionElem::Deref => {
81 match self.kind {
82 PrefixSet::Shallow => {
83 self.next = None;
87 return Some(cursor);
88 }
89 PrefixSet::All => {
90 self.next = Some(cursor_base);
93 return Some(cursor);
94 }
95 }
96 }
97 }
98 }
99 }
100 }
101 }
102}