diff options
| author | bors <bors@rust-lang.org> | 2014-05-20 15:41:20 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-05-20 15:41:20 -0700 |
| commit | 6ecf7d97d0347ce2efd5410159798659a310e67a (patch) | |
| tree | 5a9111e4c473b39495d9c48a951c2514261c9ec0 | |
| parent | 4dff9cbf58bb7a274a693eb7d19006402945fc7e (diff) | |
| parent | 7cdd02db32bc29de3c046d41b349e98801fe685d (diff) | |
| download | rust-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.rs | 3 | ||||
| -rw-r--r-- | src/test/compile-fail/regions-fn-subtyping-return-static.rs | 60 |
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() { +} |
