use crate::borrow_check::ArtificialField;
use crate::borrow_check::Overlap;
-use crate::borrow_check::{Deep, Shallow, AccessDepth};
-use rustc::hir;
-use rustc::mir::{
- Body, BorrowKind, Place, PlaceBase, PlaceElem, PlaceRef, ProjectionElem, StaticKind,
-};
+use crate::borrow_check::{AccessDepth, Deep, Shallow};
+use rustc::mir::{Body, BorrowKind, Place, PlaceBase, PlaceElem, PlaceRef, ProjectionElem};
use rustc::ty::{self, TyCtxt};
+use rustc_hir as hir;
use std::cmp::max;
/// When checking if a place conflicts with another place, this enum is used to influence decisions
debug!("borrow_conflicts_with_place: shallow access behind ptr");
return false;
}
- (ProjectionElem::Deref, ty::Ref(_, _, hir::Mutability::Immutable), _) => {
+ (ProjectionElem::Deref, ty::Ref(_, _, hir::Mutability::Not), _) => {
// Shouldn't be tracked
bug!("Tracking borrow behind shared reference.");
}
- (ProjectionElem::Deref,
- ty::Ref(_, _, hir::Mutability::Mutable),
- AccessDepth::Drop) => {
+ (ProjectionElem::Deref, ty::Ref(_, _, hir::Mutability::Mut), AccessDepth::Drop) => {
// Values behind a mutable reference are not access either by dropping a
// value, or by StorageDead
debug!("borrow_conflicts_with_place: drop access behind ptr");
// between `elem1` and `elem2`.
fn place_base_conflict<'tcx>(
tcx: TyCtxt<'tcx>,
- param_env: ty::ParamEnv<'tcx>,
+ _param_env: ty::ParamEnv<'tcx>,
elem1: &PlaceBase<'tcx>,
elem2: &PlaceBase<'tcx>,
) -> Overlap {
}
}
(PlaceBase::Static(s1), PlaceBase::Static(s2)) => {
- match (&s1.kind, &s2.kind) {
- (StaticKind::Static, StaticKind::Static) => {
- if s1.def_id != s2.def_id {
- debug!("place_element_conflict: DISJOINT-STATIC");
- Overlap::Disjoint
- } else if tcx.is_mutable_static(s1.def_id) {
- // We ignore mutable statics - they can only be unsafe code.
- debug!("place_element_conflict: IGNORE-STATIC-MUT");
- Overlap::Disjoint
- } else {
- debug!("place_element_conflict: DISJOINT-OR-EQ-STATIC");
- Overlap::EqualOrDisjoint
- }
- },
- (StaticKind::Promoted(promoted_1, _), StaticKind::Promoted(promoted_2, _)) => {
- if promoted_1 == promoted_2 {
- if let ty::Array(_, len) = s1.ty.kind {
- if let Some(0) = len.try_eval_usize(tcx, param_env) {
- // Ignore conflicts with promoted [T; 0].
- debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED");
- return Overlap::Disjoint;
- }
- }
- // the same promoted - base case, equal
- debug!("place_element_conflict: DISJOINT-OR-EQ-PROMOTED");
- Overlap::EqualOrDisjoint
- } else {
- // different promoteds - base case, disjoint
- debug!("place_element_conflict: DISJOINT-PROMOTED");
- Overlap::Disjoint
- }
- },
- (_, _) => {
- debug!("place_element_conflict: DISJOINT-STATIC-PROMOTED");
- Overlap::Disjoint
- }
+ if s1.def_id != s2.def_id {
+ debug!("place_element_conflict: DISJOINT-STATIC");
+ Overlap::Disjoint
+ } else if tcx.is_mutable_static(s1.def_id) {
+ // We ignore mutable statics - they can only be unsafe code.
+ debug!("place_element_conflict: IGNORE-STATIC-MUT");
+ Overlap::Disjoint
+ } else {
+ debug!("place_element_conflict: DISJOINT-OR-EQ-STATIC");
+ Overlap::EqualOrDisjoint
}
}
- (PlaceBase::Local(_), PlaceBase::Static(_)) |
- (PlaceBase::Static(_), PlaceBase::Local(_)) => {
+ (PlaceBase::Local(_), PlaceBase::Static(_))
+ | (PlaceBase::Static(_), PlaceBase::Local(_)) => {
debug!("place_element_conflict: DISJOINT-STATIC-LOCAL-PROMOTED");
Overlap::Disjoint
}
}
}
}
- (ProjectionElem::ConstantIndex { offset: o1, min_length: _, from_end: false },
- ProjectionElem::ConstantIndex { offset: o2, min_length: _, from_end: false })
- | (ProjectionElem::ConstantIndex { offset: o1, min_length: _, from_end: true },
- ProjectionElem::ConstantIndex {
- offset: o2, min_length: _, from_end: true }) => {
+ (
+ ProjectionElem::ConstantIndex { offset: o1, min_length: _, from_end: false },
+ ProjectionElem::ConstantIndex { offset: o2, min_length: _, from_end: false },
+ )
+ | (
+ ProjectionElem::ConstantIndex { offset: o1, min_length: _, from_end: true },
+ ProjectionElem::ConstantIndex { offset: o2, min_length: _, from_end: true },
+ ) => {
if o1 == o2 {
debug!("place_element_conflict: DISJOINT-OR-EQ-ARRAY-CONSTANT-INDEX");
Overlap::EqualOrDisjoint
Overlap::Disjoint
}
}
- (ProjectionElem::ConstantIndex {
- offset: offset_from_begin, min_length: min_length1, from_end: false },
+ (
ProjectionElem::ConstantIndex {
- offset: offset_from_end, min_length: min_length2, from_end: true })
- | (ProjectionElem::ConstantIndex {
- offset: offset_from_end, min_length: min_length1, from_end: true },
- ProjectionElem::ConstantIndex {
- offset: offset_from_begin, min_length: min_length2, from_end: false }) => {
+ offset: offset_from_begin,
+ min_length: min_length1,
+ from_end: false,
+ },
+ ProjectionElem::ConstantIndex {
+ offset: offset_from_end,
+ min_length: min_length2,
+ from_end: true,
+ },
+ )
+ | (
+ ProjectionElem::ConstantIndex {
+ offset: offset_from_end,
+ min_length: min_length1,
+ from_end: true,
+ },
+ ProjectionElem::ConstantIndex {
+ offset: offset_from_begin,
+ min_length: min_length2,
+ from_end: false,
+ },
+ ) => {
// both patterns matched so it must be at least the greater of the two
let min_length = max(min_length1, min_length2);
// `offset_from_end` can be in range `[1..min_length]`, 1 indicates the last
}
(
ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false },
- ProjectionElem::Subslice { from, to, from_end: false }
+ ProjectionElem::Subslice { from, to, from_end: false },
)
| (
ProjectionElem::Subslice { from, to, from_end: false },
- ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false }
+ ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false },
) => {
if (from..to).contains(&offset) {
debug!("place_element_conflict: DISJOINT-OR-EQ-ARRAY-CONSTANT-INDEX-SUBSLICE");
Overlap::Disjoint
}
}
- (ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false },
- ProjectionElem::Subslice {from, .. })
- | (ProjectionElem::Subslice {from, .. },
- ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false }) => {
+ (
+ ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false },
+ ProjectionElem::Subslice { from, .. },
+ )
+ | (
+ ProjectionElem::Subslice { from, .. },
+ ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false },
+ ) => {
if offset >= from {
- debug!(
- "place_element_conflict: DISJOINT-OR-EQ-SLICE-CONSTANT-INDEX-SUBSLICE");
+ debug!("place_element_conflict: DISJOINT-OR-EQ-SLICE-CONSTANT-INDEX-SUBSLICE");
Overlap::EqualOrDisjoint
} else {
debug!("place_element_conflict: DISJOINT-SLICE-CONSTANT-INDEX-SUBSLICE");
Overlap::Disjoint
}
}
- (ProjectionElem::ConstantIndex { offset, min_length: _, from_end: true },
- ProjectionElem::Subslice { to, from_end: true, .. })
- | (ProjectionElem::Subslice { to, from_end: true, .. },
- ProjectionElem::ConstantIndex { offset, min_length: _, from_end: true }) => {
+ (
+ ProjectionElem::ConstantIndex { offset, min_length: _, from_end: true },
+ ProjectionElem::Subslice { to, from_end: true, .. },
+ )
+ | (
+ ProjectionElem::Subslice { to, from_end: true, .. },
+ ProjectionElem::ConstantIndex { offset, min_length: _, from_end: true },
+ ) => {
if offset > to {
- debug!("place_element_conflict: \
- DISJOINT-OR-EQ-SLICE-CONSTANT-INDEX-SUBSLICE-FE");
+ debug!(
+ "place_element_conflict: \
+ DISJOINT-OR-EQ-SLICE-CONSTANT-INDEX-SUBSLICE-FE"
+ );
Overlap::EqualOrDisjoint
} else {
debug!("place_element_conflict: DISJOINT-SLICE-CONSTANT-INDEX-SUBSLICE-FE");
}
(
ProjectionElem::Subslice { from: f1, to: t1, from_end: false },
- ProjectionElem::Subslice { from: f2, to: t2, from_end: false }
+ ProjectionElem::Subslice { from: f2, to: t2, from_end: false },
) => {
if f2 >= t1 || f1 >= t2 {
debug!("place_element_conflict: DISJOINT-ARRAY-SUBSLICES");
}
(ProjectionElem::Subslice { .. }, ProjectionElem::Subslice { .. }) => {
debug!("place_element_conflict: DISJOINT-OR-EQ-SLICE-SUBSLICES");
- Overlap::EqualOrDisjoint
+ Overlap::EqualOrDisjoint
}
(ProjectionElem::Deref, _)
| (ProjectionElem::Field(..), _)