Skip to content

Commit 904c270

Browse files
committed
More comments and small cleanups
1 parent b39fb9b commit 904c270

File tree

3 files changed

+108
-112
lines changed

3 files changed

+108
-112
lines changed

compiler/rustc_passes/src/region.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
255255
hir::ExprKind::AssignOp(..)
256256
| hir::ExprKind::Index(..)
257257
| hir::ExprKind::Unary(..)
258+
| hir::ExprKind::Call(..)
258259
| hir::ExprKind::MethodCall(..) => {
259260
// FIXME(https://github.com/rust-lang/rfcs/issues/811) Nested method calls
260261
//

compiler/rustc_typeck/src/check/generator_interior.rs

Lines changed: 107 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -182,39 +182,6 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
182182
}
183183
}
184184
}
185-
186-
fn visit_call(
187-
&mut self,
188-
call_expr: &'tcx Expr<'tcx>,
189-
callee: &'tcx Expr<'tcx>,
190-
args: &'tcx [Expr<'tcx>],
191-
) {
192-
match &callee.kind {
193-
ExprKind::Path(qpath) => {
194-
let res = self.fcx.typeck_results.borrow().qpath_res(qpath, callee.hir_id);
195-
match res {
196-
// Direct calls never need to keep the callee `ty::FnDef`
197-
// ZST in a temporary, so skip its type, just in case it
198-
// can significantly complicate the generator type.
199-
Res::Def(
200-
DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn),
201-
_,
202-
) => {
203-
// NOTE(eddyb) this assumes a path expression has
204-
// no nested expressions to keep track of.
205-
self.expr_count += 1;
206-
207-
// Record the rest of the call expression normally.
208-
for arg in args {
209-
self.visit_expr(arg);
210-
}
211-
}
212-
_ => intravisit::walk_expr(self, call_expr),
213-
}
214-
}
215-
_ => intravisit::walk_expr(self, call_expr),
216-
}
217-
}
218185
}
219186

220187
pub fn resolve_interior<'a, 'tcx>(
@@ -252,7 +219,6 @@ pub fn resolve_interior<'a, 'tcx>(
252219
intravisit::walk_body(&mut drop_range_visitor, body);
253220

254221
drop_range_visitor.drop_ranges.propagate_to_fixpoint();
255-
// drop_range_visitor.drop_ranges.save_graph("drop_ranges.dot");
256222

257223
InteriorVisitor {
258224
fcx,
@@ -395,7 +361,31 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
395361
let mut guard_borrowing_from_pattern = false;
396362

397363
match &expr.kind {
398-
ExprKind::Call(callee, args) => self.visit_call(expr, callee, args),
364+
ExprKind::Call(callee, args) => match &callee.kind {
365+
ExprKind::Path(qpath) => {
366+
let res = self.fcx.typeck_results.borrow().qpath_res(qpath, callee.hir_id);
367+
match res {
368+
// Direct calls never need to keep the callee `ty::FnDef`
369+
// ZST in a temporary, so skip its type, just in case it
370+
// can significantly complicate the generator type.
371+
Res::Def(
372+
DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn),
373+
_,
374+
) => {
375+
// NOTE(eddyb) this assumes a path expression has
376+
// no nested expressions to keep track of.
377+
self.expr_count += 1;
378+
379+
// Record the rest of the call expression normally.
380+
for arg in args.iter() {
381+
self.visit_expr(arg);
382+
}
383+
}
384+
_ => intravisit::walk_expr(self, expr),
385+
}
386+
}
387+
_ => intravisit::walk_expr(self, expr),
388+
},
399389
ExprKind::Path(qpath) => {
400390
intravisit::walk_expr(self, expr);
401391
let res = self.fcx.typeck_results.borrow().qpath_res(qpath, expr.hir_id);
@@ -675,6 +665,26 @@ fn check_must_not_suspend_def(
675665
false
676666
}
677667

668+
// The following structs and impls are used for drop range analysis.
669+
//
670+
// Drop range analysis finds the portions of the tree where a value is guaranteed to be dropped
671+
// (i.e. moved, uninitialized, etc.). This is used to exclude the types of those values from the
672+
// generator type. See `InteriorVisitor::record` for where the results of this analysis are used.
673+
//
674+
// There are three phases to this analysis:
675+
// 1. Use `ExprUseVisitor` to identify the interesting values that are consumed and borrowed.
676+
// 2. Use `DropRangeVisitor` to find where the interesting values are dropped or reinitialized,
677+
// and also build a control flow graph.
678+
// 3. Use `DropRanges::propagate_to_fixpoint` to flow the dropped/reinitialized information through
679+
// the CFG and find the exact points where we know a value is definitely dropped.
680+
//
681+
// The end result is a data structure that maps the post-order index of each node in the HIR tree
682+
// to a set of values that are known to be dropped at that location.
683+
684+
/// Works with ExprUseVisitor to find interesting values for the drop range analysis.
685+
///
686+
/// Interesting values are those that are either dropped or borrowed. For dropped values, we also
687+
/// record the parent expression, which is the point where the drop actually takes place.
678688
struct ExprUseDelegate<'tcx> {
679689
hir: Map<'tcx>,
680690
/// Maps a HirId to a set of HirIds that are dropped by that node.
@@ -691,7 +701,65 @@ impl<'tcx> ExprUseDelegate<'tcx> {
691701
}
692702
}
693703

694-
/// This struct facilitates computing the ranges for which a place is uninitialized.
704+
impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> {
705+
fn consume(
706+
&mut self,
707+
place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
708+
diag_expr_id: hir::HirId,
709+
) {
710+
let parent = match self.hir.find_parent_node(place_with_id.hir_id) {
711+
Some(parent) => parent,
712+
None => place_with_id.hir_id,
713+
};
714+
debug!(
715+
"consume {:?}; diag_expr_id={:?}, using parent {:?}",
716+
place_with_id, diag_expr_id, parent
717+
);
718+
self.mark_consumed(parent, place_with_id.hir_id);
719+
place_hir_id(&place_with_id.place).map(|place| self.mark_consumed(parent, place));
720+
}
721+
722+
fn borrow(
723+
&mut self,
724+
place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
725+
_diag_expr_id: hir::HirId,
726+
_bk: rustc_middle::ty::BorrowKind,
727+
) {
728+
place_hir_id(&place_with_id.place).map(|place| self.borrowed_places.insert(place));
729+
}
730+
731+
fn mutate(
732+
&mut self,
733+
_assignee_place: &expr_use_visitor::PlaceWithHirId<'tcx>,
734+
_diag_expr_id: hir::HirId,
735+
) {
736+
}
737+
738+
fn fake_read(
739+
&mut self,
740+
_place: expr_use_visitor::Place<'tcx>,
741+
_cause: rustc_middle::mir::FakeReadCause,
742+
_diag_expr_id: hir::HirId,
743+
) {
744+
}
745+
}
746+
747+
/// Gives the hir_id associated with a place if one exists. This is the hir_id that we want to
748+
/// track for a value in the drop range analysis.
749+
fn place_hir_id(place: &Place<'_>) -> Option<HirId> {
750+
match place.base {
751+
PlaceBase::Rvalue | PlaceBase::StaticItem => None,
752+
PlaceBase::Local(hir_id)
753+
| PlaceBase::Upvar(ty::UpvarId { var_path: ty::UpvarPath { hir_id }, .. }) => Some(hir_id),
754+
}
755+
}
756+
757+
/// This struct is used to gather the information for `DropRanges` to determine the regions of the
758+
/// HIR tree for which a value is dropped.
759+
///
760+
/// We are interested in points where a variables is dropped or initialized, and the control flow
761+
/// of the code. We identify locations in code by their post-order traversal index, so it is
762+
/// important for this traversal to match that in `RegionResolutionVisitor` and `InteriorVisitor`.
695763
struct DropRangeVisitor<'tcx> {
696764
hir: Map<'tcx>,
697765
/// Maps a HirId to a set of HirIds that are dropped by that node.
@@ -756,6 +824,9 @@ impl<'tcx> DropRangeVisitor<'tcx> {
756824
}
757825
}
758826

827+
/// Applies `f` to consumable portion of a HIR node.
828+
///
829+
/// The `node` parameter should be the result of calling `Map::find(place)`.
759830
fn for_each_consumable(place: HirId, node: Option<Node<'_>>, mut f: impl FnMut(HirId)) {
760831
f(place);
761832
if let Some(Node::Expr(expr)) = node {
@@ -771,57 +842,6 @@ fn for_each_consumable(place: HirId, node: Option<Node<'_>>, mut f: impl FnMut(H
771842
}
772843
}
773844

774-
fn place_hir_id(place: &Place<'_>) -> Option<HirId> {
775-
match place.base {
776-
PlaceBase::Rvalue | PlaceBase::StaticItem => None,
777-
PlaceBase::Local(hir_id)
778-
| PlaceBase::Upvar(ty::UpvarId { var_path: ty::UpvarPath { hir_id }, .. }) => Some(hir_id),
779-
}
780-
}
781-
782-
impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> {
783-
fn consume(
784-
&mut self,
785-
place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
786-
diag_expr_id: hir::HirId,
787-
) {
788-
let parent = match self.hir.find_parent_node(place_with_id.hir_id) {
789-
Some(parent) => parent,
790-
None => place_with_id.hir_id,
791-
};
792-
debug!(
793-
"consume {:?}; diag_expr_id={:?}, using parent {:?}",
794-
place_with_id, diag_expr_id, parent
795-
);
796-
self.mark_consumed(parent, place_with_id.hir_id);
797-
place_hir_id(&place_with_id.place).map(|place| self.mark_consumed(parent, place));
798-
}
799-
800-
fn borrow(
801-
&mut self,
802-
place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
803-
_diag_expr_id: hir::HirId,
804-
_bk: rustc_middle::ty::BorrowKind,
805-
) {
806-
place_hir_id(&place_with_id.place).map(|place| self.borrowed_places.insert(place));
807-
}
808-
809-
fn mutate(
810-
&mut self,
811-
_assignee_place: &expr_use_visitor::PlaceWithHirId<'tcx>,
812-
_diag_expr_id: hir::HirId,
813-
) {
814-
}
815-
816-
fn fake_read(
817-
&mut self,
818-
_place: expr_use_visitor::Place<'tcx>,
819-
_cause: rustc_middle::mir::FakeReadCause,
820-
_diag_expr_id: hir::HirId,
821-
) {
822-
}
823-
}
824-
825845
impl<'tcx> Visitor<'tcx> for DropRangeVisitor<'tcx> {
826846
type Map = intravisit::ErasedMap<'tcx>;
827847

@@ -832,26 +852,6 @@ impl<'tcx> Visitor<'tcx> for DropRangeVisitor<'tcx> {
832852
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
833853
let mut reinit = None;
834854
match expr.kind {
835-
// ExprKind::AssignOp(_op, lhs, rhs) => {
836-
// // These operations are weird because their order of evaluation depends on whether
837-
// // the operator is overloaded. In a perfect world, we'd just ask the type checker
838-
// // whether this is a method call, but we also need to match the expression IDs
839-
// // from RegionResolutionVisitor. RegionResolutionVisitor doesn't know the order,
840-
// // so it runs both orders and picks the most conservative. We'll mirror that here.
841-
// let mut old_count = self.expr_count;
842-
// self.visit_expr(lhs);
843-
// self.visit_expr(rhs);
844-
845-
// let old_drops = self.swap_drop_ranges(<_>::default());
846-
// std::mem::swap(&mut old_count, &mut self.expr_count);
847-
// self.visit_expr(rhs);
848-
// self.visit_expr(lhs);
849-
850-
// // We should have visited the same number of expressions in either order.
851-
// assert_eq!(old_count, self.expr_count);
852-
853-
// self.intersect_drop_ranges(old_drops);
854-
// }
855855
ExprKind::If(test, if_true, if_false) => {
856856
self.visit_expr(test);
857857

compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,6 @@ impl DropRanges {
203203
}
204204
preds
205205
}
206-
207-
// pub fn save_graph(&self, filename: &str) {
208-
// use std::fs::File;
209-
// dot::render(self, &mut File::create(filename).unwrap()).unwrap();
210-
// }
211206
}
212207

213208
impl<'a> dot::GraphWalk<'a> for DropRanges {

0 commit comments

Comments
 (0)