about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2014-05-06 11:17:41 -0400
committerNiko Matsakis <niko@alum.mit.edu>2014-05-08 20:31:12 -0400
commit7cdd02db32bc29de3c046d41b349e98801fe685d (patch)
treed8c8f2e613e02bc7e027f537e5b4bb7903fd0445
parent061db52b2b3a68477819fa7709350d3c25bb5741 (diff)
downloadrust-7cdd02db32bc29de3c046d41b349e98801fe685d.tar.gz
rust-7cdd02db32bc29de3c046d41b349e98801fe685d.zip
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 bb6d479870b..5afbb48ca3c 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() {
+}