about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-05-20 15:41:20 -0700
committerbors <bors@rust-lang.org>2014-05-20 15:41:20 -0700
commit6ecf7d97d0347ce2efd5410159798659a310e67a (patch)
tree5a9111e4c473b39495d9c48a951c2514261c9ec0
parent4dff9cbf58bb7a274a693eb7d19006402945fc7e (diff)
parent7cdd02db32bc29de3c046d41b349e98801fe685d (diff)
downloadrust-6ecf7d97d0347ce2efd5410159798659a310e67a.tar.gz
rust-6ecf7d97d0347ce2efd5410159798659a310e67a.zip
auto merge of #13975 : nikomatsakis/rust/issue-13794-fn-subtyping-and-static, r=pnkfelix
Tweak region inference to ignore constraints like `'a <= 'static`, since they
have no value. This also ensures that we can handle some obscure cases of fn
subtyping with bound regions that we didn't used to handle correctly.

Fixes #13974.
-rw-r--r--src/librustc/middle/typeck/infer/region_inference/mod.rs3
-rw-r--r--src/test/compile-fail/regions-fn-subtyping-return-static.rs60
2 files changed, 63 insertions, 0 deletions
diff --git a/src/librustc/middle/typeck/infer/region_inference/mod.rs b/src/librustc/middle/typeck/infer/region_inference/mod.rs
index 297a2921147..24265d342eb 100644
--- a/src/librustc/middle/typeck/infer/region_inference/mod.rs
+++ b/src/librustc/middle/typeck/infer/region_inference/mod.rs
@@ -299,6 +299,9 @@ impl<'a> RegionVarBindings<'a> {
                         sub.repr(self.tcx),
                         sup.repr(self.tcx)));
           }
+          (_, ReStatic) => {
+            // all regions are subregions of static, so we can ignore this
+          }
           (ReInfer(ReVar(sub_id)), ReInfer(ReVar(sup_id))) => {
             self.add_constraint(ConstrainVarSubVar(sub_id, sup_id), origin);
           }
diff --git a/src/test/compile-fail/regions-fn-subtyping-return-static.rs b/src/test/compile-fail/regions-fn-subtyping-return-static.rs
new file mode 100644
index 00000000000..c03040fe0f2
--- /dev/null
+++ b/src/test/compile-fail/regions-fn-subtyping-return-static.rs
@@ -0,0 +1,60 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// In this fn, the type `F` is a function that takes a reference to a
+// struct and returns another reference with the same lifetime.
+//
+// Meanwhile, the bare fn `foo` takes a reference to a struct with
+// *ANY* lifetime and returns a reference with the 'static lifetime.
+// This can safely be considered to be an instance of `F` because all
+// lifetimes are sublifetimes of 'static.
+
+#![allow(dead_code)]
+#![allow(unused_variable)]
+
+struct S;
+
+// Given 'cx, return 'cx
+type F = fn<'cx>(&'cx S) -> &'cx S;
+fn want_F(f: F) { }
+
+// Given anything, return 'static
+type G = fn<'cx>(&'cx S) -> &'static S;
+fn want_G(f: G) { }
+
+// Should meet both.
+fn foo(x: &S) -> &'static S {
+    fail!()
+}
+
+// Should meet both.
+fn bar<'a,'b>(x: &'a S) -> &'b S {
+    fail!()
+}
+
+// Meets F, but not G.
+fn baz<'a>(x: &'a S) -> &'a S {
+    fail!()
+}
+
+fn supply_F() {
+    want_F(foo);
+    want_F(bar);
+    want_F(baz);
+}
+
+fn supply_G() {
+    want_G(foo);
+    want_G(bar);
+    want_G(baz); //~ ERROR expected concrete lifetime
+}
+
+pub fn main() {
+}