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.
This commit is contained in:
commit
6ecf7d97d0
@ -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);
|
||||
}
|
||||
|
60
src/test/compile-fail/regions-fn-subtyping-return-static.rs
Normal file
60
src/test/compile-fail/regions-fn-subtyping-return-static.rs
Normal file
@ -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() {
|
||||
}
|
Loading…
Reference in New Issue
Block a user