use subtyping when we create a closure instead of for upvar types
We used to make the upvar types in the closure `==` but that was stronger than we needed. Subtyping suffices, since we are copying the upvar value into the closure field. This in turn allows us to infer smaller lifetimes in captured values in some cases (like the example here), avoiding errors.
This commit is contained in:
parent
fc3c90cf8a
commit
f71de45b23
@ -217,7 +217,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
.upvar_tys(closure_def_id, self.tcx)
|
||||
.zip(final_upvar_tys)
|
||||
{
|
||||
self.demand_eqtype(span, final_upvar_ty, upvar_ty);
|
||||
self.demand_suptype(span, upvar_ty, final_upvar_ty);
|
||||
}
|
||||
|
||||
// If we are also inferred the closure kind here,
|
||||
|
@ -1,15 +1,15 @@
|
||||
error[E0277]: the trait bound `No: Foo` is not satisfied in `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&'static OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`
|
||||
error[E0277]: the trait bound `No: Foo` is not satisfied in `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`
|
||||
--> $DIR/auto-trait-regions.rs:40:5
|
||||
|
|
||||
LL | assert_foo(gen); //~ ERROR the trait bound `No: Foo` is not satisfied
|
||||
| ^^^^^^^^^^ within `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&'static OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`, the trait `Foo` is not implemented for `No`
|
||||
| ^^^^^^^^^^ within `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`, the trait `Foo` is not implemented for `No`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<No as Foo>
|
||||
= note: required because it appears within the type `OnlyFooIfStaticRef`
|
||||
= note: required because it appears within the type `&OnlyFooIfStaticRef`
|
||||
= note: required because it appears within the type `for<'r> {&'r OnlyFooIfStaticRef, ()}`
|
||||
= note: required because it appears within the type `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&'static OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`
|
||||
= note: required because it appears within the type `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`
|
||||
note: required by `assert_foo`
|
||||
--> $DIR/auto-trait-regions.rs:30:1
|
||||
|
|
||||
|
@ -0,0 +1,31 @@
|
||||
// Copyright 2016 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 contrast to `region-escape-via-bound-invariant`, in this case we
|
||||
// *can* return a value of type `&'x u32`, even though `'x` does not
|
||||
// appear in the bounds. This is because `&` is contravariant, and so
|
||||
// we are *actually* returning a `&'y u32`.
|
||||
//
|
||||
// See https://github.com/rust-lang/rust/issues/46541 for more details.
|
||||
|
||||
// run-pass
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![feature(conservative_impl_trait)]
|
||||
#![feature(in_band_lifetimes)]
|
||||
#![feature(nll)]
|
||||
|
||||
fn foo(x: &'x u32) -> impl Fn() -> &'y u32
|
||||
where 'x: 'y
|
||||
{
|
||||
move || x
|
||||
}
|
||||
|
||||
fn main() { }
|
Loading…
Reference in New Issue
Block a user