about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-07-23 13:43:42 +0000
committerbors <bors@rust-lang.org>2020-07-23 13:43:42 +0000
commit39a295f52637817ba8584cb9bcebef91fd0a9f4f (patch)
tree3d9c987feb7802589db52babccb901dcd31a34e6 /src
parent371917ab218de72a625227ba6eed7e84e610a058 (diff)
parent45c01edaf21f9052eec8d04cb32c7724eb627e03 (diff)
downloadrust-39a295f52637817ba8584cb9bcebef91fd0a9f4f.tar.gz
rust-39a295f52637817ba8584cb9bcebef91fd0a9f4f.zip
Auto merge of #74509 - matthewjasper:empty-verify, r=nikomatsakis
Use `ReEmpty(U0)` as the implicit region bound in typeck

Fixes #74429

r? @nikomatsakis
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/check/mod.rs9
-rw-r--r--src/librustc_typeck/check/regionck.rs2
-rw-r--r--src/test/ui/regions/type-param-outlives-reempty-issue-74429-2.rs66
-rw-r--r--src/test/ui/regions/type-param-outlives-reempty-issue-74429.rs35
4 files changed, 102 insertions, 10 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 04e02704296..6e77aba3050 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -256,14 +256,6 @@ pub struct Inherited<'a, 'tcx> {
     /// opaque type.
     opaque_types_vars: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
 
-    /// Each type parameter has an implicit region bound that
-    /// indicates it must outlive at least the function body (the user
-    /// may specify stronger requirements). This field indicates the
-    /// region of the callee. If it is `None`, then the parameter
-    /// environment is for an item or something where the "callee" is
-    /// not clear.
-    implicit_region_bound: Option<ty::Region<'tcx>>,
-
     body_id: Option<hir::BodyId>,
 }
 
@@ -684,7 +676,6 @@ impl Inherited<'a, 'tcx> {
             deferred_generator_interiors: RefCell::new(Vec::new()),
             opaque_types: RefCell::new(Default::default()),
             opaque_types_vars: RefCell::new(Default::default()),
-            implicit_region_bound: None,
             body_id,
         }
     }
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index b72152d1911..221e5f72dc9 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -309,7 +309,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
     fn resolve_regions_and_report_errors(&self, mode: RegionckMode) {
         self.infcx.process_registered_region_obligations(
             self.outlives_environment.region_bound_pairs_map(),
-            self.implicit_region_bound,
+            Some(self.tcx.lifetimes.re_root_empty),
             self.param_env,
         );
 
diff --git a/src/test/ui/regions/type-param-outlives-reempty-issue-74429-2.rs b/src/test/ui/regions/type-param-outlives-reempty-issue-74429-2.rs
new file mode 100644
index 00000000000..a65c17e0efc
--- /dev/null
+++ b/src/test/ui/regions/type-param-outlives-reempty-issue-74429-2.rs
@@ -0,0 +1,66 @@
+// Regression test for #74429, where we didn't think that a type parameter
+// outlived `ReEmpty`.
+
+// check-pass
+
+use std::marker::PhantomData;
+use std::ptr::NonNull;
+
+pub unsafe trait RawData {
+    type Elem;
+}
+
+unsafe impl<A> RawData for OwnedRepr<A> {
+    type Elem = A;
+}
+
+unsafe impl<'a, A> RawData for ViewRepr<&'a A> {
+    type Elem = A;
+}
+
+pub struct OwnedRepr<A> {
+    ptr: PhantomData<A>,
+}
+
+// these Copy impls are not necessary for the repro, but allow the code to compile without error
+// on 1.44.1
+#[derive(Copy, Clone)]
+pub struct ViewRepr<A> {
+    life: PhantomData<A>,
+}
+
+#[derive(Copy, Clone)]
+pub struct ArrayBase<S>
+where
+    S: RawData,
+{
+    ptr: NonNull<S::Elem>,
+}
+
+pub type Array<A> = ArrayBase<OwnedRepr<A>>;
+
+pub type ArrayView<'a, A> = ArrayBase<ViewRepr<&'a A>>;
+
+impl<A, S> ArrayBase<S>
+where
+    S: RawData<Elem = A>,
+{
+    pub fn index_axis(&self) -> ArrayView<'_, A> {
+        unimplemented!()
+    }
+
+    pub fn axis_iter<'a>(&'a self) -> std::iter::Empty<&'a A> {
+        unimplemented!()
+    }
+}
+
+pub fn x<T: Copy>(a: Array<T>) {
+    // drop just avoids a must_use warning
+    drop((0..1).filter(|_| true));
+    let y = a.index_axis();
+    a.axis_iter().for_each(|_| {
+        drop(y);
+    });
+}
+
+fn main() {}
diff --git a/src/test/ui/regions/type-param-outlives-reempty-issue-74429.rs b/src/test/ui/regions/type-param-outlives-reempty-issue-74429.rs
new file mode 100644
index 00000000000..d463f311c34
--- /dev/null
+++ b/src/test/ui/regions/type-param-outlives-reempty-issue-74429.rs
@@ -0,0 +1,35 @@
+// Regression test for #74429, where we didn't think that a type parameter
+// outlived `ReEmpty`.
+
+// check-pass
+
+use std::marker::PhantomData;
+
+fn apply<T, F: FnOnce(T)>(_: T, _: F) {}
+
+#[derive(Clone, Copy)]
+struct Invariant<T> {
+    t: T,
+    p: PhantomData<fn(T) -> T>,
+}
+
+fn verify_reempty<T>(x: T) {
+    // r is inferred to have type `Invariant<&ReEmpty(U0) T>`
+    let r = Invariant { t: &x, p: PhantomData };
+    // Creates a new universe, all variables from now on are in `U1`, say.
+    let _: fn(&()) = |_| {};
+    // Closure parameter is of type `&ReEmpty(U1) T`, so the closure has an implied
+    // bound of `T: ReEmpty(U1)`
+    apply(&x, |_| {
+        // Requires `typeof(r)` is well-formed, i.e. `T: ReEmpty(U0)`. If we
+        // only have the implied bound from the closure parameter to use this
+        // requires `ReEmpty(U1): ReEmpty(U0)`, which isn't true so we reported
+        // an error.
+        //
+        // This doesn't happen any more because we ensure that `T: ReEmpty(U0)`
+        // is an implicit bound for all type parameters.
+        drop(r);
+    });
+}
+
+fn main() {}