Skip to content

Commit 7cdd02d

Browse files
committed
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 rust-lang#13974.
1 parent 061db52 commit 7cdd02d

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

src/librustc/middle/typeck/infer/region_inference/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,9 @@ impl<'a> RegionVarBindings<'a> {
299299
sub.repr(self.tcx),
300300
sup.repr(self.tcx)));
301301
}
302+
(_, ReStatic) => {
303+
// all regions are subregions of static, so we can ignore this
304+
}
302305
(ReInfer(ReVar(sub_id)), ReInfer(ReVar(sup_id))) => {
303306
self.add_constraint(ConstrainVarSubVar(sub_id, sup_id), origin);
304307
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// In this fn, the type `F` is a function that takes a reference to a
12+
// struct and returns another reference with the same lifetime.
13+
//
14+
// Meanwhile, the bare fn `foo` takes a reference to a struct with
15+
// *ANY* lifetime and returns a reference with the 'static lifetime.
16+
// This can safely be considered to be an instance of `F` because all
17+
// lifetimes are sublifetimes of 'static.
18+
19+
#![allow(dead_code)]
20+
#![allow(unused_variable)]
21+
22+
struct S;
23+
24+
// Given 'cx, return 'cx
25+
type F = fn<'cx>(&'cx S) -> &'cx S;
26+
fn want_F(f: F) { }
27+
28+
// Given anything, return 'static
29+
type G = fn<'cx>(&'cx S) -> &'static S;
30+
fn want_G(f: G) { }
31+
32+
// Should meet both.
33+
fn foo(x: &S) -> &'static S {
34+
fail!()
35+
}
36+
37+
// Should meet both.
38+
fn bar<'a,'b>(x: &'a S) -> &'b S {
39+
fail!()
40+
}
41+
42+
// Meets F, but not G.
43+
fn baz<'a>(x: &'a S) -> &'a S {
44+
fail!()
45+
}
46+
47+
fn supply_F() {
48+
want_F(foo);
49+
want_F(bar);
50+
want_F(baz);
51+
}
52+
53+
fn supply_G() {
54+
want_G(foo);
55+
want_G(bar);
56+
want_G(baz); //~ ERROR expected concrete lifetime
57+
}
58+
59+
pub fn main() {
60+
}

0 commit comments

Comments
 (0)