]> git.lizzy.rs Git - rust.git/commitdiff
add a new RegionKind variant: ReClosureBound
authorNiko Matsakis <niko@alum.mit.edu>
Tue, 5 Dec 2017 10:18:58 +0000 (05:18 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Fri, 15 Dec 2017 15:27:52 +0000 (10:27 -0500)
This is needed to allow the `ClosureRegionRequirements` to capture
types that include regions.

13 files changed:
src/librustc/ich/impls_ty.rs
src/librustc/infer/combine.rs
src/librustc/infer/error_reporting/mod.rs
src/librustc/infer/freshen.rs
src/librustc/infer/lexical_region_resolve/mod.rs
src/librustc/mir/mod.rs
src/librustc/ty/sty.rs
src/librustc/ty/util.rs
src/librustc/util/ppaux.rs
src/librustc_borrowck/borrowck/gather_loans/mod.rs
src/librustc_mir/borrow_check/error_reporting.rs
src/librustc_typeck/variance/constraints.rs
src/librustdoc/clean/mod.rs

index 2655e2acbbdfb369f19437a1c9c35bff1e53149a..ea3a1074aa2698b140f4020f7eeeff5a192f697a 100644 (file)
@@ -75,6 +75,9 @@ fn hash_stable<W: StableHasherResult>(&self,
             ty::ReFree(ref free_region) => {
                 free_region.hash_stable(hcx, hasher);
             }
+            ty::ReClosureBound(vid) => {
+                vid.hash_stable(hcx, hasher);
+            }
             ty::ReLateBound(..) |
             ty::ReVar(..) |
             ty::ReSkolemized(..) => {
index 50a37e12531a76df5768e367655f6ad3bc144fd5..f7bc092a3d7ae7b3351e9231c02556263faaf560 100644 (file)
@@ -475,6 +475,14 @@ fn regions(&mut self, r: ty::Region<'tcx>, r2: ty::Region<'tcx>)
                     ty::Bivariant | ty::Covariant | ty::Contravariant => (),
                 }
             }
+
+            ty::ReClosureBound(..) => {
+                span_bug!(
+                    self.span,
+                    "encountered unexpected ReClosureBound: {:?}",
+                    r,
+                );
+            }
         }
 
         // FIXME: This is non-ideal because we don't give a
index 514b29120a96aa438897ec84ebf01a707528d287..3e3aea0256e72e4ef816053900d888fd95e2e81b 100644 (file)
@@ -240,6 +240,14 @@ fn explain_span<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
             ty::ReErased => {
                 (format!("lifetime {:?}", region), None)
             }
+
+            // We shouldn't encounter an error message with ReClosureBound.
+            ty::ReClosureBound(..) => {
+                bug!(
+                    "encountered unexpected ReClosureBound: {:?}",
+                    region,
+                );
+            }
         };
         let message = format!("{}{}{}", prefix, description, suffix);
         if let Some(span) = span {
index 426c61e9ac083eb66042352befedeb6299938c7f..1783d5abfc7c6b5cabb3edb86adac499a7c4d305 100644 (file)
@@ -113,6 +113,13 @@ fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
                 // replace all free regions with 'erased
                 self.tcx().types.re_erased
             }
+
+            ty::ReClosureBound(..) => {
+                bug!(
+                    "encountered unexpected ReClosureBound: {:?}",
+                    r,
+                );
+            }
         }
     }
 
index 5a4f2157298b066715a3d92740f7ebb69b80a682..3ac4ec5bee41644390a3e5349096bedb702850bd 100644 (file)
@@ -258,7 +258,12 @@ fn expand_node(
     fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> {
         let tcx = self.region_rels.tcx;
         match (a, b) {
-            (&ReLateBound(..), _) | (_, &ReLateBound(..)) | (&ReErased, _) | (_, &ReErased) => {
+            (&ty::ReClosureBound(..), _) |
+            (_, &ty::ReClosureBound(..)) |
+            (&ReLateBound(..), _) |
+            (_, &ReLateBound(..)) |
+            (&ReErased, _) |
+            (_, &ReErased) => {
                 bug!("cannot relate region: LUB({:?}, {:?})", a, b);
             }
 
index d7afce7de46c90437ffc2b1c9fde12faf85ede46..dd3dd1e06de370945c7b0d4cf56e6f20edfc7bbc 100644 (file)
@@ -1831,6 +1831,15 @@ pub struct GeneratorLayout<'tcx> {
 /// instance of the closure is created, the corresponding free regions
 /// can be extracted from its type and constrained to have the given
 /// outlives relationship.
+///
+/// In some cases, we have to record outlives requirements between
+/// types and regions as well. In that case, if those types include
+/// any regions, those regions are recorded as `ReClosureBound`
+/// instances assigned one of these same indices. Those regions will
+/// be substituted away by the creator. We use `ReClosureBound` in
+/// that case because the regions must be allocated in the global
+/// TyCtxt, and hence we cannot use `ReVar` (which is what we use
+/// internally within the rest of the NLL code).
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub struct ClosureRegionRequirements<'gcx> {
     /// The number of external regions defined on the closure.  In our
index 2f72b3dde42f1562e8db1fae959260b09ffd7e89..02729c6d60084081689edd0d5e9b45e816f8f086 100644 (file)
@@ -1036,6 +1036,12 @@ pub enum RegionKind {
 
     /// Erased region, used by trait selection, in MIR and during trans.
     ReErased,
+
+    /// These are regions bound in the "defining type" for a
+    /// closure. They are used ONLY as part of the
+    /// `ClosureRegionRequirements` that are produced by MIR borrowck.
+    /// See `ClosureRegionRequirements` for more details.
+    ReClosureBound(RegionVid),
 }
 
 impl<'tcx> serialize::UseSpecializedDecodable for Region<'tcx> {}
@@ -1207,6 +1213,9 @@ pub fn type_flags(&self) -> TypeFlags {
             }
             ty::ReErased => {
             }
+            ty::ReClosureBound(..) => {
+                flags = flags | TypeFlags::HAS_FREE_REGIONS;
+            }
         }
 
         match *self {
index 2e9e45c9ffe16b9b436be9210dcb25f2f7ff5656..84d5f547f1b755c74c0cfef8587e85342d0331ae 100644 (file)
@@ -822,6 +822,8 @@ fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
             ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, .. }) => {
                 self.def_id(def_id);
             }
+
+            ty::ReClosureBound(..) |
             ty::ReLateBound(..) |
             ty::ReFree(..) |
             ty::ReScope(..) |
index 9ff3d73f5c40e95678b06e40bd1f042145e8f67c..5bfa646456857b2f88436841ff052c3278b6bc5f 100644 (file)
@@ -733,6 +733,9 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 ty::ReErased => Ok(()),
                 ty::ReStatic => write!(f, "'static"),
                 ty::ReEmpty => write!(f, "'<empty>"),
+
+                // The user should never encounter these in unsubstituted form.
+                ty::ReClosureBound(vid) => write!(f, "{:?}", vid),
             }
         }
         debug {
@@ -743,6 +746,11 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                            data.name)
                 }
 
+                ty::ReClosureBound(ref vid) => {
+                    write!(f, "ReClosureBound({:?})",
+                           vid)
+                }
+
                 ty::ReLateBound(binder_id, ref bound_region) => {
                     write!(f, "ReLateBound({:?}, {:?})",
                            binder_id,
index 8654f2a50e46bf1c693c328d359feee85dfbba3a..5cbe2822e5c038ed33f5192d7ac19802bf384b43 100644 (file)
@@ -367,6 +367,7 @@ fn guarantee_valid(&mut self,
                     ty::ReStatic => self.item_ub,
 
                     ty::ReEmpty |
+                    ty::ReClosureBound(..) |
                     ty::ReLateBound(..) |
                     ty::ReVar(..) |
                     ty::ReSkolemized(..) |
index 31a94499fd0cc369e7d6dddd9c3973bcd7098916..2c0fa9878aaf2572479a411e5582d16ae215e8d2 100644 (file)
@@ -381,6 +381,7 @@ pub(super) fn report_borrowed_value_does_not_live_long_enough(
             },
             (RegionKind::ReLateBound(_, _), _) |
             (RegionKind::ReSkolemized(_, _), _) |
+            (RegionKind::ReClosureBound(_), _) |
             (RegionKind::ReErased, _) => {
                 span_bug!(drop_span, "region does not make sense in this context");
             },
index ef6552c8e33f4517ef5a3422b6e0d7168d3ff85c..df42d5eaa0a3d6abd57e443aa1fcf7ffb8d2942e 100644 (file)
@@ -465,6 +465,7 @@ fn add_constraints_from_region(&mut self,
             }
 
             ty::ReFree(..) |
+            ty::ReClosureBound(..) |
             ty::ReScope(..) |
             ty::ReVar(..) |
             ty::ReSkolemized(..) |
index 91908de98a65d89a1117adb9218cbd3a22e45c82..c7657c9b2ff456f675c26022b926b9450f834ffb 100644 (file)
@@ -1055,6 +1055,7 @@ fn clean(&self, cx: &DocContext) -> Option<Lifetime> {
             ty::ReVar(..) |
             ty::ReSkolemized(..) |
             ty::ReEmpty |
+            ty::ReClosureBound(_) |
             ty::ReErased => None
         }
     }