Skip to content

Commit 7345333

Browse files
committed
Do not check outlives when explicit bound contains escaping regions
This makes the code similar to the handling of `ty::Ref` in `src/librustc/ty/wf.rs`, except checking for non-escaping-regions somewhere down the call chain instead of at the root. Fixes rust-lang#53548
1 parent 63d6649 commit 7345333

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

src/librustc/ty/sty.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,8 @@ impl<T> Binder<T> {
753753
pub fn dummy<'tcx>(value: T) -> Binder<T>
754754
where T: TypeFoldable<'tcx>
755755
{
756-
debug_assert!(!value.has_escaping_regions());
756+
debug_assert!(!value.has_escaping_regions(),
757+
"Value has unexpected escaping regions: {:?}", value);
757758
Binder(value)
758759
}
759760

src/librustc/ty/wf.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -487,14 +487,16 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
487487
// Note: in fact we only permit builtin traits, not `Bar<'d>`, I
488488
// am looking forward to the future here.
489489

490-
if !data.has_escaping_regions() {
490+
if !data.has_escaping_regions() && !region.has_escaping_regions() {
491491
let implicit_bounds =
492492
object_region_bounds(self.infcx.tcx, data);
493493

494494
let explicit_bound = region;
495495

496496
for implicit_bound in implicit_bounds {
497497
let cause = self.cause(traits::ObjectTypeBound(ty, explicit_bound));
498+
debug!("Testing implicit bound {:?} with explicit bound {:?}, cause {:?}",
499+
implicit_bound, explicit_bound, cause);
498500
let outlives = ty::Binder::dummy(
499501
ty::OutlivesPredicate(explicit_bound, implicit_bound));
500502
self.out.push(traits::Obligation::new(cause,

src/test/run-pass/issue-53548.rs

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright 2018 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+
// Regression test for #53548: having a 'static bound on a trait
12+
// made it impossible to keep a trait object to it across an
13+
// await point inside a closure
14+
15+
#![feature(arbitrary_self_types, async_await, await_macro, futures_api, pin)]
16+
17+
use std::future::Future;
18+
use std::mem::PinMut;
19+
use std::task::{Poll, Context};
20+
21+
// A trait with 'static bound
22+
trait Trait: 'static {}
23+
24+
// Anything we can give to await!()
25+
struct DummyFut();
26+
impl Future for DummyFut {
27+
type Output = ();
28+
fn poll(self: PinMut<Self>, _ctx: &mut Context) -> Poll<()> {
29+
Poll::Pending
30+
}
31+
}
32+
33+
// The actual reproducer, requires that Trait is 'static and a trait
34+
// object to it is captured in a closure for successful reproduction.
35+
async fn foo(b: Box<Trait + 'static>) -> () {
36+
let _bar = move || { b; () };
37+
await!(DummyFut())
38+
}
39+
40+
pub fn main() {}

0 commit comments

Comments
 (0)