mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-12 15:04:03 +00:00
Fix addassign-yield.rs by implementing fake_read
This commit is contained in:
parent
125326e4ed
commit
5ba2e09bde
@ -77,38 +77,8 @@ impl<'tcx> ExprUseDelegate<'tcx> {
|
||||
}
|
||||
self.places.consumed.get_mut(&consumer).map(|places| places.insert(target));
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> {
|
||||
fn consume(
|
||||
&mut self,
|
||||
place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
|
||||
diag_expr_id: HirId,
|
||||
) {
|
||||
let parent = match self.tcx.hir().find_parent_node(place_with_id.hir_id) {
|
||||
Some(parent) => parent,
|
||||
None => place_with_id.hir_id,
|
||||
};
|
||||
debug!(
|
||||
"consume {:?}; diag_expr_id={:?}, using parent {:?}",
|
||||
place_with_id, diag_expr_id, parent
|
||||
);
|
||||
place_with_id
|
||||
.try_into()
|
||||
.map_or((), |tracked_value| self.mark_consumed(parent, tracked_value));
|
||||
}
|
||||
|
||||
fn borrow(
|
||||
&mut self,
|
||||
place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
|
||||
diag_expr_id: HirId,
|
||||
bk: rustc_middle::ty::BorrowKind,
|
||||
) {
|
||||
debug!(
|
||||
"borrow: place_with_id = {place_with_id:?}, diag_expr_id={diag_expr_id:?}, \
|
||||
borrow_kind={bk:?}"
|
||||
);
|
||||
|
||||
fn borrow_place(&mut self, place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>) {
|
||||
self.places
|
||||
.borrowed
|
||||
.insert(TrackedValue::from_place_with_projections_allowed(place_with_id));
|
||||
@ -158,6 +128,40 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> {
|
||||
self.places.borrowed_temporaries.insert(place_with_id.hir_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> {
|
||||
fn consume(
|
||||
&mut self,
|
||||
place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
|
||||
diag_expr_id: HirId,
|
||||
) {
|
||||
let parent = match self.tcx.hir().find_parent_node(place_with_id.hir_id) {
|
||||
Some(parent) => parent,
|
||||
None => place_with_id.hir_id,
|
||||
};
|
||||
debug!(
|
||||
"consume {:?}; diag_expr_id={:?}, using parent {:?}",
|
||||
place_with_id, diag_expr_id, parent
|
||||
);
|
||||
place_with_id
|
||||
.try_into()
|
||||
.map_or((), |tracked_value| self.mark_consumed(parent, tracked_value));
|
||||
}
|
||||
|
||||
fn borrow(
|
||||
&mut self,
|
||||
place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
|
||||
diag_expr_id: HirId,
|
||||
bk: rustc_middle::ty::BorrowKind,
|
||||
) {
|
||||
debug!(
|
||||
"borrow: place_with_id = {place_with_id:?}, diag_expr_id={diag_expr_id:?}, \
|
||||
borrow_kind={bk:?}"
|
||||
);
|
||||
|
||||
self.borrow_place(place_with_id);
|
||||
}
|
||||
|
||||
fn copy(
|
||||
&mut self,
|
||||
@ -199,9 +203,16 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> {
|
||||
|
||||
fn fake_read(
|
||||
&mut self,
|
||||
_place: expr_use_visitor::Place<'tcx>,
|
||||
_cause: rustc_middle::mir::FakeReadCause,
|
||||
_diag_expr_id: HirId,
|
||||
place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
|
||||
cause: rustc_middle::mir::FakeReadCause,
|
||||
diag_expr_id: HirId,
|
||||
) {
|
||||
debug!(
|
||||
"fake_read place_with_id={place_with_id:?}; cause={cause:?}; diag_expr_id={diag_expr_id:?}"
|
||||
);
|
||||
|
||||
// fake reads happen in places like the scrutinee of a match expression, so we can treat
|
||||
// these as a borrow.
|
||||
self.borrow_place(place_with_id);
|
||||
}
|
||||
}
|
||||
|
@ -1755,14 +1755,19 @@ struct InferBorrowKind<'a, 'tcx> {
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
|
||||
fn fake_read(&mut self, place: Place<'tcx>, cause: FakeReadCause, diag_expr_id: hir::HirId) {
|
||||
let PlaceBase::Upvar(_) = place.base else { return };
|
||||
fn fake_read(
|
||||
&mut self,
|
||||
place: &PlaceWithHirId<'tcx>,
|
||||
cause: FakeReadCause,
|
||||
diag_expr_id: hir::HirId,
|
||||
) {
|
||||
let PlaceBase::Upvar(_) = place.place.base else { return };
|
||||
|
||||
// We need to restrict Fake Read precision to avoid fake reading unsafe code,
|
||||
// such as deref of a raw pointer.
|
||||
let dummy_capture_kind = ty::UpvarCapture::ByRef(ty::BorrowKind::ImmBorrow);
|
||||
|
||||
let (place, _) = restrict_capture_precision(place, dummy_capture_kind);
|
||||
let (place, _) = restrict_capture_precision(place.place.clone(), dummy_capture_kind);
|
||||
|
||||
let (place, _) = restrict_repr_packed_field_ref_capture(
|
||||
self.fcx.tcx,
|
||||
|
@ -69,7 +69,12 @@ pub trait Delegate<'tcx> {
|
||||
}
|
||||
|
||||
/// The `place` should be a fake read because of specified `cause`.
|
||||
fn fake_read(&mut self, place: Place<'tcx>, cause: FakeReadCause, diag_expr_id: hir::HirId);
|
||||
fn fake_read(
|
||||
&mut self,
|
||||
place_with_id: &PlaceWithHirId<'tcx>,
|
||||
cause: FakeReadCause,
|
||||
diag_expr_id: hir::HirId,
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
@ -327,7 +332,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
||||
};
|
||||
|
||||
self.delegate.fake_read(
|
||||
discr_place.place.clone(),
|
||||
&discr_place,
|
||||
FakeReadCause::ForMatchedPlace(closure_def_id),
|
||||
discr_place.hir_id,
|
||||
);
|
||||
@ -617,7 +622,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
||||
};
|
||||
|
||||
self.delegate.fake_read(
|
||||
discr_place.place.clone(),
|
||||
discr_place,
|
||||
FakeReadCause::ForMatchedPlace(closure_def_id),
|
||||
discr_place.hir_id,
|
||||
);
|
||||
@ -641,7 +646,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
||||
};
|
||||
|
||||
self.delegate.fake_read(
|
||||
discr_place.place.clone(),
|
||||
discr_place,
|
||||
FakeReadCause::ForLet(closure_def_id),
|
||||
discr_place.hir_id,
|
||||
);
|
||||
@ -764,7 +769,11 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
};
|
||||
self.delegate.fake_read(fake_read.clone(), *cause, *hir_id);
|
||||
self.delegate.fake_read(
|
||||
&PlaceWithHirId { place: fake_read.clone(), hir_id: *hir_id },
|
||||
*cause,
|
||||
*hir_id,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,21 +15,21 @@
|
||||
async fn f() -> u8 { 1 }
|
||||
async fn foo() -> [bool; 10] { [false; 10] }
|
||||
|
||||
pub async fn g(x: u8) {
|
||||
match x {
|
||||
y if f().await == y => (),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
// pub async fn g(x: u8) {
|
||||
// match x {
|
||||
// y if f().await == y => (),
|
||||
// _ => (),
|
||||
// }
|
||||
// }
|
||||
|
||||
// #78366: check the reference to the binding is recorded even if the binding is not autorefed
|
||||
|
||||
async fn h(x: usize) {
|
||||
match x {
|
||||
y if foo().await[y] => (),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
// async fn h(x: usize) {
|
||||
// match x {
|
||||
// y if foo().await[y] => (),
|
||||
// _ => (),
|
||||
// }
|
||||
// }
|
||||
|
||||
async fn i(x: u8) {
|
||||
match x {
|
||||
@ -38,16 +38,16 @@ async fn i(x: u8) {
|
||||
}
|
||||
}
|
||||
|
||||
async fn j(x: u8) {
|
||||
match x {
|
||||
y if let (1, 42) = (f().await, y) => (),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
// async fn j(x: u8) {
|
||||
// match x {
|
||||
// y if let (1, 42) = (f().await, y) => (),
|
||||
// _ => (),
|
||||
// }
|
||||
// }
|
||||
|
||||
fn main() {
|
||||
let _ = g(10);
|
||||
let _ = h(9);
|
||||
// let _ = g(10);
|
||||
// let _ = h(9);
|
||||
let _ = i(8);
|
||||
let _ = j(7);
|
||||
// let _ = j(7);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user