Skip to content

Commit 261daf2

Browse files
committed
ignore higher-ranked WF requirements for trait objects
In the `issue-53548` test added in this commit, the `Box<dyn Trait>` type is expanded to `Box<dyn Trait + 'static>`, but the generator "witness" that results is `for<'r> { Box<dyn Trait + 'r> }`. The WF code was encountering an ICE (when debug-assertions were enabled) and an unexpected compilation error (without debug-asserions) when trying to process this `'r` region bound. In particular, to be WF, the region bound must meet the requirements of the trait, and hence we got `for<'r> { 'r: 'static }`. This would ICE because the `Binder` constructor we were using was assering that no higher-ranked regions were involved (because the WF code is supposed to skip those). The error (if debug-asserions were disabled) came because we obviously cannot prove that `'r: 'static` for any region `'r`. Pursuant with our "lazy WF" strategy for higher-ranked regions, the fix is not to require that `for<'r> { 'r: 'static }` holds (this is also analogous to what we would do for higher-ranked regions appearing within the trait in other positions).
1 parent 4632e33 commit 261daf2

File tree

3 files changed

+60
-2
lines changed

3 files changed

+60
-2
lines changed

Diff for: src/librustc/ty/wf.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -482,8 +482,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
482482
//
483483
// Note: in fact we only permit builtin traits, not `Bar<'d>`, I
484484
// am looking forward to the future here.
485-
486-
if !data.has_escaping_bound_vars() {
485+
if !data.has_escaping_bound_vars() && !region.has_escaping_bound_vars() {
487486
let implicit_bounds =
488487
object_region_bounds(self.infcx.tcx, data);
489488

Diff for: src/test/ui/generator/issue-53548-1.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// A variant of #53548 that does not actually require generators,
2+
// but which encountered the same ICE/error. See `issue-53548.rs`
3+
// for details.
4+
//
5+
// compile-pass
6+
7+
use std::cell::RefCell;
8+
use std::rc::Rc;
9+
10+
trait Trait: 'static {}
11+
12+
struct Store<C> {
13+
inner: Rc<RefCell<Option<C>>>,
14+
}
15+
16+
fn main() {
17+
let store = Store::<Box<for<'a> fn(&(dyn Trait + 'a))>> {
18+
inner: Default::default(),
19+
};
20+
}

Diff for: src/test/ui/generator/issue-53548.rs

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Regression test for #53548. The `Box<dyn Trait>` type below is
2+
// expanded to `Box<dyn Trait + 'static>`, but the generator "witness"
3+
// that results is `for<'r> { Box<dyn Trait + 'r> }`. The WF code was
4+
// encountering an ICE (when debug-assertions were enabled) and an
5+
// unexpected compilation error (without debug-asserions) when trying
6+
// to process this `'r` region bound. In particular, to be WF, the
7+
// region bound must meet the requirements of the trait, and hence we
8+
// got `for<'r> { 'r: 'static }`. This would ICE because the `Binder`
9+
// constructor we were using was assering that no higher-ranked
10+
// regions were involved (because the WF code is supposed to skip
11+
// those). The error (if debug-asserions were disabled) came because
12+
// we obviously cannot prove that `'r: 'static` for any region `'r`.
13+
// Pursuant with our "lazy WF" strategy for higher-ranked regions, the
14+
// fix is not to require that `for<'r> { 'r: 'static }` holds (this is
15+
// also analogous to what we would do for higher-ranked regions
16+
// appearing within the trait in other positions).
17+
//
18+
// compile-pass
19+
20+
#![feature(generators)]
21+
22+
use std::cell::RefCell;
23+
use std::rc::Rc;
24+
25+
trait Trait: 'static {}
26+
27+
struct Store<C> {
28+
inner: Rc<RefCell<Option<C>>>,
29+
}
30+
31+
fn main() {
32+
Box::new(static move || {
33+
let store = Store::<Box<dyn Trait>> {
34+
inner: Default::default(),
35+
};
36+
yield ();
37+
});
38+
}
39+

0 commit comments

Comments
 (0)