Rollup merge of #122598 - Nadrieril:full-derefpats, r=matthewjasper
deref patterns: lower deref patterns to MIR This lowers deref patterns to MIR. This is a bit tricky because this is the first kind of pattern that requires storing a value in a temporary. Thanks to https://github.com/rust-lang/rust/pull/123324 false edges are no longer a problem. The thing I'm not confident about is the handling of fake borrows. This PR ignores any fake borrows inside a deref pattern. We are guaranteed to at least fake borrow the place of the first pointer value, which could be enough, but I'm not certain.
This commit is contained in:
commit
332cac2c6d
51 changed files with 764 additions and 301 deletions
|
@ -414,7 +414,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
BorrowKind::Shared => {
|
||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow)
|
||||
}
|
||||
BorrowKind::Fake => {
|
||||
BorrowKind::Fake(_) => {
|
||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::FakeBorrow)
|
||||
}
|
||||
BorrowKind::Mut { .. } => {
|
||||
|
@ -487,7 +487,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Fake, place)
|
||||
Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Fake(_), place)
|
||||
| Rvalue::AddressOf(Mutability::Not, place) => {
|
||||
let borrowed_place_has_mut_interior = qualifs::in_place::<HasMutInterior, _>(
|
||||
self.ccx,
|
||||
|
|
|
@ -105,7 +105,7 @@ where
|
|||
fn ref_allows_mutation(&self, kind: mir::BorrowKind, place: mir::Place<'tcx>) -> bool {
|
||||
match kind {
|
||||
mir::BorrowKind::Mut { .. } => true,
|
||||
mir::BorrowKind::Shared | mir::BorrowKind::Fake => {
|
||||
mir::BorrowKind::Shared | mir::BorrowKind::Fake(_) => {
|
||||
self.shared_borrow_allows_mutation(place)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -965,7 +965,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
},
|
||||
Rvalue::Ref(_, BorrowKind::Fake, _) => {
|
||||
Rvalue::Ref(_, BorrowKind::Fake(_), _) => {
|
||||
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
|
||||
self.fail(
|
||||
location,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue