]> git.lizzy.rs Git - rust.git/commitdiff
Writeback min_capture map to TypeckResults
authorAman Arora <me@aman-arora.com>
Sat, 21 Nov 2020 09:52:18 +0000 (04:52 -0500)
committerAman Arora <me@aman-arora.com>
Sun, 6 Dec 2020 20:48:19 +0000 (15:48 -0500)
- Derive TypeFoldable on `hir::place::Place` and associated
  structs, to them to be written into typeck results.

Co-authored-by: Jennifer Wills <wills.jenniferg@gmail.com>
Co-authored-by: Logan Mosier <logmosier@gmail.com>
compiler/rustc_middle/src/hir/place.rs
compiler/rustc_middle/src/ty/mod.rs
compiler/rustc_typeck/src/check/writeback.rs
compiler/rustc_typeck/src/expr_use_visitor.rs

index 5da4be4e98279ce7ba7598edfed25037883ba837..143b3867d9fc754ace4cd74ae2fee40b75a6bc1a 100644 (file)
@@ -4,7 +4,18 @@
 use rustc_hir::HirId;
 use rustc_target::abi::VariantIdx;
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
+#[derive(
+    Clone,
+    Copy,
+    Debug,
+    PartialEq,
+    Eq,
+    Hash,
+    TyEncodable,
+    TyDecodable,
+    TypeFoldable,
+    HashStable
+)]
 pub enum PlaceBase {
     /// A temporary variable
     Rvalue,
@@ -16,7 +27,18 @@ pub enum PlaceBase {
     Upvar(ty::UpvarId),
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
+#[derive(
+    Clone,
+    Copy,
+    Debug,
+    PartialEq,
+    Eq,
+    Hash,
+    TyEncodable,
+    TyDecodable,
+    TypeFoldable,
+    HashStable
+)]
 pub enum ProjectionKind {
     /// A dereference of a pointer, reference or `Box<T>` of the given type
     Deref,
@@ -36,7 +58,18 @@ pub enum ProjectionKind {
     Subslice,
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
+#[derive(
+    Clone,
+    Copy,
+    Debug,
+    PartialEq,
+    Eq,
+    Hash,
+    TyEncodable,
+    TyDecodable,
+    TypeFoldable,
+    HashStable
+)]
 pub struct Projection<'tcx> {
     /// Type after the projection is being applied.
     pub ty: Ty<'tcx>,
@@ -48,7 +81,7 @@ pub struct Projection<'tcx> {
 /// A `Place` represents how a value is located in memory.
 ///
 /// This is an HIR version of `mir::Place`
-#[derive(Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, TypeFoldable, HashStable)]
 pub struct Place<'tcx> {
     /// The type of the `PlaceBase`
     pub base_ty: Ty<'tcx>,
@@ -61,7 +94,7 @@ pub struct Place<'tcx> {
 /// A `PlaceWithHirId` represents how a value is located in memory.
 ///
 /// This is an HIR version of `mir::Place`
-#[derive(Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, TypeFoldable, HashStable)]
 pub struct PlaceWithHirId<'tcx> {
     /// `HirId` of the expression or pattern producing this value.
     pub hir_id: HirId,
index 5d8edcf70bfd3329eff91af509afa157cbf3a37a..1a9a6a33fefd40c313834e81ee518a57976f8ade 100644 (file)
@@ -672,7 +672,18 @@ fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHas
 #[rustc_diagnostic_item = "Ty"]
 pub type Ty<'tcx> = &'tcx TyS<'tcx>;
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
+#[derive(
+    Clone,
+    Copy,
+    Debug,
+    PartialEq,
+    Eq,
+    Hash,
+    TyEncodable,
+    TyDecodable,
+    TypeFoldable,
+    HashStable
+)]
 pub struct UpvarPath {
     pub hir_id: hir::HirId,
 }
@@ -680,7 +691,7 @@ pub struct UpvarPath {
 /// Upvars do not get their own `NodeId`. Instead, we use the pair of
 /// the original var ID (that is, the root variable that is referenced
 /// by the upvar) and the ID of the closure expression.
-#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, TypeFoldable, HashStable)]
 pub struct UpvarId {
     pub var_path: UpvarPath,
     pub closure_expr_id: LocalDefId,
@@ -692,7 +703,7 @@ pub fn new(var_hir_id: hir::HirId, closure_def_id: LocalDefId) -> UpvarId {
     }
 }
 
-#[derive(Clone, PartialEq, Debug, TyEncodable, TyDecodable, Copy, HashStable)]
+#[derive(Clone, PartialEq, Debug, TyEncodable, TyDecodable, TypeFoldable, Copy, HashStable)]
 pub enum BorrowKind {
     /// Data must be immutable and is aliasable.
     ImmBorrow,
@@ -746,7 +757,7 @@ pub enum BorrowKind {
 
 /// Information describing the capture of an upvar. This is computed
 /// during `typeck`, specifically by `regionck`.
-#[derive(PartialEq, Clone, Debug, Copy, TyEncodable, TyDecodable, HashStable)]
+#[derive(PartialEq, Clone, Debug, Copy, TyEncodable, TyDecodable, TypeFoldable, HashStable)]
 pub enum UpvarCapture<'tcx> {
     /// Upvar is captured by value. This is always true when the
     /// closure is labeled `move`, but can also be true in other cases
@@ -763,7 +774,7 @@ pub enum UpvarCapture<'tcx> {
     ByRef(UpvarBorrow<'tcx>),
 }
 
-#[derive(PartialEq, Clone, Copy, TyEncodable, TyDecodable, HashStable)]
+#[derive(PartialEq, Clone, Copy, TyEncodable, TyDecodable, TypeFoldable, HashStable)]
 pub struct UpvarBorrow<'tcx> {
     /// The kind of borrow: by-ref upvars have access to shared
     /// immutable borrows, which are not part of the normal language
@@ -790,7 +801,7 @@ pub struct UpvarBorrow<'tcx> {
 pub type MinCaptureList<'tcx> = Vec<CapturedPlace<'tcx>>;
 
 /// A `Place` and the corresponding `CaptureInfo`.
-#[derive(PartialEq, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
+#[derive(PartialEq, Clone, Debug, TyEncodable, TyDecodable, TypeFoldable, HashStable)]
 pub struct CapturedPlace<'tcx> {
     pub place: HirPlace<'tcx>,
     pub info: CaptureInfo<'tcx>,
@@ -799,7 +810,7 @@ pub struct CapturedPlace<'tcx> {
 /// Part of `MinCaptureInformationMap`; describes the capture kind (&, &mut, move)
 /// for a particular capture as well as identifying the part of the source code
 /// that triggered this capture to occur.
-#[derive(PartialEq, Clone, Debug, Copy, TyEncodable, TyDecodable, HashStable)]
+#[derive(PartialEq, Clone, Debug, Copy, TyEncodable, TyDecodable, TypeFoldable, HashStable)]
 pub struct CaptureInfo<'tcx> {
     /// Expr Id pointing to use that resulted in selecting the current capture kind
     ///
index 68b85a4da34f242ac43cc91a6135afc18baabada..7c9cfe69fc94b4874df12003de13e2224cbe655c 100644 (file)
@@ -55,6 +55,7 @@ pub fn resolve_type_vars_in_body(
             hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::Fn => (),
         }
         wbcx.visit_body(body);
+        wbcx.visit_min_capture_map();
         wbcx.visit_upvar_capture_map();
         wbcx.visit_closures();
         wbcx.visit_liberated_fn_sigs();
@@ -331,6 +332,37 @@ fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) {
 }
 
 impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
+    fn visit_min_capture_map(&mut self) {
+        let mut min_captures_wb = ty::MinCaptureInformationMap::with_capacity_and_hasher(
+            self.fcx.typeck_results.borrow().closure_min_captures.len(),
+            Default::default(),
+        );
+        for (closure_def_id, root_min_captures) in
+            self.fcx.typeck_results.borrow().closure_min_captures.iter()
+        {
+            let mut root_var_map_wb = ty::RootVariableMinCaptureList::with_capacity_and_hasher(
+                root_min_captures.len(),
+                Default::default(),
+            );
+            for (var_hir_id, min_list) in root_min_captures.iter() {
+                let min_list_wb = min_list
+                    .iter()
+                    .map(|captured_place| {
+                        let locatable = captured_place.info.expr_id.unwrap_or(
+                            self.tcx().hir().local_def_id_to_hir_id(closure_def_id.expect_local()),
+                        );
+
+                        self.resolve(captured_place.clone(), &locatable)
+                    })
+                    .collect();
+                root_var_map_wb.insert(*var_hir_id, min_list_wb);
+            }
+            min_captures_wb.insert(*closure_def_id, root_var_map_wb);
+        }
+
+        self.typeck_results.closure_min_captures = min_captures_wb;
+    }
+
     fn visit_upvar_capture_map(&mut self) {
         for (upvar_id, upvar_capture) in self.fcx.typeck_results.borrow().upvar_capture_map.iter() {
             let new_upvar_capture = match *upvar_capture {
index 1b51d5e0182fde51426de0751acd373488cacdd8..8a324807417da0fe5444bf376283d7976bc4e0e7 100644 (file)
@@ -15,7 +15,6 @@
 use rustc_infer::infer::InferCtxt;
 use rustc_middle::hir::place::ProjectionKind;
 use rustc_middle::ty::{self, adjustment, TyCtxt};
-use rustc_span::Span;
 use rustc_target::abi::VariantIdx;
 
 use crate::mem_categorization as mc;
@@ -571,38 +570,6 @@ fn walk_pat(&mut self, discr_place: &PlaceWithHirId<'tcx>, pat: &hir::Pat<'_>) {
         }));
     }
 
-    /// Walk closure captures but using `closure_caputes` instead
-    /// of `closure_min_captures`.
-    ///
-    /// This is needed because clippy uses `ExprUseVisitor` after TypeckResults
-    /// are written back. We don't currently writeback min_captures to
-    /// TypeckResults.
-    fn walk_captures_closure_captures(&mut self, closure_expr: &hir::Expr<'_>) {
-        // FIXME(arora-aman): Remove this function once rust-lang/project-rfc-2229#18
-        // is completed.
-        debug!("walk_captures_closure_captures({:?}), ", closure_expr);
-
-        let closure_def_id = self.tcx().hir().local_def_id(closure_expr.hir_id).to_def_id();
-        let cl_span = self.tcx().hir().span(closure_expr.hir_id);
-
-        let captures = &self.mc.typeck_results.closure_captures[&closure_def_id];
-
-        for (&var_id, &upvar_id) in captures {
-            let upvar_capture = self.mc.typeck_results.upvar_capture(upvar_id);
-            let captured_place =
-                return_if_err!(self.cat_captured_var(closure_expr.hir_id, cl_span, var_id));
-            match upvar_capture {
-                ty::UpvarCapture::ByValue(_) => {
-                    let mode = copy_or_move(&self.mc, &captured_place);
-                    self.delegate.consume(&captured_place, captured_place.hir_id, mode);
-                }
-                ty::UpvarCapture::ByRef(upvar_borrow) => {
-                    self.delegate.borrow(&captured_place, captured_place.hir_id, upvar_borrow.kind);
-                }
-            }
-        }
-    }
-
     /// Handle the case where the current body contains a closure.
     ///
     /// When the current body being handled is a closure, then we must make sure that
@@ -646,16 +613,18 @@ fn walk_captures(&mut self, closure_expr: &hir::Expr<'_>) {
                     let place = &captured_place.place;
                     let capture_info = captured_place.info;
 
-                    let upvar_id = if body_owner_is_closure {
+                    let place_base = if body_owner_is_closure {
                         // Mark the place to be captured by the enclosing closure
-                        ty::UpvarId::new(*var_hir_id, self.body_owner)
+                        PlaceBase::Upvar(ty::UpvarId::new(*var_hir_id, self.body_owner))
                     } else {
-                        ty::UpvarId::new(*var_hir_id, closure_def_id.expect_local())
+                        // If the body owner isn't a closure then the variable must
+                        // be a local variable
+                        PlaceBase::Local(*var_hir_id)
                     };
                     let place_with_id = PlaceWithHirId::new(
                         capture_info.expr_id.unwrap_or(closure_expr.hir_id),
                         place.base_ty,
-                        PlaceBase::Upvar(upvar_id),
+                        place_base,
                         place.projections.clone(),
                     );
 
@@ -674,23 +643,8 @@ fn walk_captures(&mut self, closure_expr: &hir::Expr<'_>) {
                     }
                 }
             }
-        } else if self.mc.typeck_results.closure_captures.contains_key(&closure_def_id) {
-            // Handle the case where clippy calls ExprUseVisitor after
-            self.walk_captures_closure_captures(closure_expr)
         }
     }
-
-    fn cat_captured_var(
-        &mut self,
-        closure_hir_id: hir::HirId,
-        closure_span: Span,
-        var_id: hir::HirId,
-    ) -> mc::McResult<PlaceWithHirId<'tcx>> {
-        // Create the place for the variable being borrowed, from the
-        // perspective of the creator (parent) of the closure.
-        let var_ty = self.mc.node_ty(var_id)?;
-        self.mc.cat_res(closure_hir_id, closure_span, var_ty, Res::Local(var_id))
-    }
 }
 
 fn copy_or_move<'a, 'tcx>(