Skip to content

Commit 98904c2

Browse files
committed
Normalizing associated types when checking borrows in drops.
1 parent 552024a commit 98904c2

File tree

1 file changed

+23
-8
lines changed
  • src/librustc_mir/borrow_check

1 file changed

+23
-8
lines changed

src/librustc_mir/borrow_check/mod.rs

+23-8
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,20 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
463463
target: _,
464464
unwind: _,
465465
} => {
466-
self.visit_terminator_drop(loc, term, flow_state, drop_place, span);
466+
let gcx = self.tcx.global_tcx();
467+
468+
// Compute the type with accurate region information.
469+
let drop_place_ty = drop_place.ty(self.mir, self.tcx);
470+
471+
// Erase the regions.
472+
let drop_place_ty = self.tcx.erase_regions(&drop_place_ty).to_ty(self.tcx);
473+
474+
// "Lift" into the gcx -- once regions are erased, this type should be in the
475+
// global arenas; this "lift" operation basically just asserts that is true, but
476+
// that is useful later.
477+
let drop_place_ty = gcx.lift(&drop_place_ty).unwrap();
478+
479+
self.visit_terminator_drop(loc, term, flow_state, drop_place, drop_place_ty, span);
467480
}
468481
TerminatorKind::DropAndReplace {
469482
location: ref drop_place,
@@ -723,10 +736,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
723736
term: &Terminator<'tcx>,
724737
flow_state: &Flows<'cx, 'gcx, 'tcx>,
725738
drop_place: &Place<'tcx>,
739+
erased_drop_place_ty: ty::Ty<'gcx>,
726740
span: Span,
727741
) {
728-
let ty = drop_place.ty(self.mir, self.tcx).to_ty(self.tcx);
729-
match ty.sty {
742+
match erased_drop_place_ty.sty {
730743
// When a struct is being dropped, we need to check
731744
// whether it has a destructor, if it does, then we can
732745
// call it, if it does not then we need to check the
@@ -735,14 +748,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
735748
// borrows of `x.foo` and not `x.bar`. See #47703.
736749
ty::TyAdt(def, substs) if def.is_struct() && !def.has_dtor(self.tcx) => {
737750
for (index, field) in def.all_fields().enumerate() {
738-
let place = drop_place.clone();
739-
let place = place.field(Field::new(index), field.ty(self.tcx, substs));
751+
let gcx = self.tcx.global_tcx();
752+
let field_ty = field.ty(gcx, substs);
753+
let field_ty = gcx.normalize_associated_type_in_env(&field_ty, self.param_env);
754+
let place = drop_place.clone().field(Field::new(index), field_ty);
740755

741756
self.visit_terminator_drop(
742757
loc,
743758
term,
744759
flow_state,
745760
&place,
761+
field_ty,
746762
span,
747763
);
748764
}
@@ -754,8 +770,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
754770
// "needs drop". If so, we assume that the destructor
755771
// may access any data it likes (i.e., a Deep Write).
756772
let gcx = self.tcx.global_tcx();
757-
let erased_ty = gcx.lift(&self.tcx.erase_regions(&ty)).unwrap();
758-
if erased_ty.needs_drop(gcx, self.param_env) {
773+
if erased_drop_place_ty.needs_drop(gcx, self.param_env) {
759774
self.access_place(
760775
ContextKind::Drop.new(loc),
761776
(drop_place, span),
@@ -2144,7 +2159,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
21442159
while let Some(i) = elems_incoming.next() {
21452160
let borrowed = &data[i.borrow_index()];
21462161

2147-
if self.places_conflict(&borrowed.borrowed_place, &place, access) {
2162+
if self.places_conflict(&borrowed.borrowed_place, place, access) {
21482163
debug!("each_borrow_involving_path: {:?} @ {:?} vs. {:?}/{:?}",
21492164
i, borrowed, place, access);
21502165
let ctrl = op(self, i, borrowed);

0 commit comments

Comments
 (0)