about summary refs log tree commit diff
path: root/src/test/ui/issues
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2019-02-01 10:41:08 -0500
committerFelix S. Klock II <pnkfelix@pnkfx.org>2019-02-15 14:38:26 +0100
commit4db6a9b82fcf7039c49cff53a6301a9d27f1a4df (patch)
treed1de7079e933790d1cd52fc8eeaefad8fc0b9e72 /src/test/ui/issues
parenta49c9fb8c37081dca139834d4f7d336b443e6d0b (diff)
downloadrust-4db6a9b82fcf7039c49cff53a6301a9d27f1a4df.tar.gz
rust-4db6a9b82fcf7039c49cff53a6301a9d27f1a4df.zip
make generalization code create new variables in correct universe
In our type inference system, when we "generalize" a type T to become
a suitable value for a type variable V, we sometimes wind up creating
new inference variables. So, for example, if we are making V be some
subtype of `&'X u32`, then we might instantiate V with `&'Y u32`.
This generalized type is then related `&'Y u32 <: &'X u32`, resulting
in a region constriant `'Y: 'X`. Previously, however, we were making
these fresh variables like `'Y` in the "current universe", but they
should be created in the universe of V. Moreover, we sometimes cheat
in an invariant context and avoid creating fresh variables if we know
the result must be equal -- we can only do that when the universes
work out.
Diffstat (limited to 'src/test/ui/issues')
-rw-r--r--src/test/ui/issues/issue-57843.rs24
-rw-r--r--src/test/ui/issues/issue-57843.stderr12
2 files changed, 36 insertions, 0 deletions
diff --git a/src/test/ui/issues/issue-57843.rs b/src/test/ui/issues/issue-57843.rs
new file mode 100644
index 00000000000..46608255266
--- /dev/null
+++ b/src/test/ui/issues/issue-57843.rs
@@ -0,0 +1,24 @@
+// Regression test for an ICE that occurred with the universes code:
+//
+// The signature of the closure `|_|` was being inferred to
+// `exists<'r> fn(&'r u8)`. This should result in a type error since
+// the signature `for<'r> fn(&'r u8)` is required. However, due to a
+// bug in the type variable generalization code, the placeholder for
+// `'r` was leaking out into the writeback phase, causing an ICE.
+
+trait ClonableFn<T> {
+    fn clone(&self) -> Box<dyn Fn(T)>;
+}
+
+impl<T, F: 'static> ClonableFn<T> for F
+where F: Fn(T) + Clone {
+    fn clone(&self) -> Box<dyn Fn(T)> {
+        Box::new(self.clone())
+    }
+}
+
+struct Foo(Box<dyn for<'a> ClonableFn<&'a bool>>);
+
+fn main() {
+    Foo(Box::new(|_| ())); //~ ERROR mismatched types
+}
diff --git a/src/test/ui/issues/issue-57843.stderr b/src/test/ui/issues/issue-57843.stderr
new file mode 100644
index 00000000000..4ef884cb3f5
--- /dev/null
+++ b/src/test/ui/issues/issue-57843.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-57843.rs:23:9
+   |
+LL |     Foo(Box::new(|_| ())); //~ ERROR mismatched types
+   |         ^^^^^^^^^^^^^^^^ one type is more general than the other
+   |
+   = note: expected type `std::ops::FnOnce<(&'a bool,)>`
+              found type `std::ops::FnOnce<(&bool,)>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.