Skip to content

Commit 3fcb13a

Browse files
committed
handle projections with regions
1 parent 3a5842a commit 3fcb13a

14 files changed

+1758
-102
lines changed

src/librustc_mir/borrow_check/nll/region_infer/mod.rs

Lines changed: 187 additions & 92 deletions
Large diffs are not rendered by default.

src/librustc_mir/borrow_check/nll/universal_regions.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,17 +247,24 @@ impl<'tcx> UniversalRegions<'tcx> {
247247
(FIRST_GLOBAL_INDEX..self.num_universals).map(RegionVid::new)
248248
}
249249

250-
/// True if `r` is classied as a global region.
250+
/// True if `r` is classified as a global region.
251251
pub fn is_global_free_region(&self, r: RegionVid) -> bool {
252252
self.region_classification(r) == Some(RegionClassification::Global)
253253
}
254254

255-
/// True if `r` is classied as an external region.
255+
/// True if `r` is classified as an external region.
256256
pub fn is_extern_free_region(&self, r: RegionVid) -> bool {
257257
self.region_classification(r) == Some(RegionClassification::External)
258258
}
259259

260-
/// True if `r` is classied as an local region.
260+
/// True if `r` is a free region that is classified as global or
261+
/// extern. This is an important category, because these regions
262+
/// can be referenced in `ClosureRegionRequirements`.
263+
pub fn is_non_local_free_region(&self, r: RegionVid) -> bool {
264+
self.region_classification(r) == Some(RegionClassification::Local)
265+
}
266+
267+
/// True if `r` is classified as an local region.
261268
pub fn is_local_free_region(&self, r: RegionVid) -> bool {
262269
self.region_classification(r) == Some(RegionClassification::Local)
263270
}
@@ -324,6 +331,10 @@ impl<'tcx> UniversalRegions<'tcx> {
324331
relation: &TransitiveRelation<RegionVid>,
325332
fr0: RegionVid,
326333
) -> Option<RegionVid> {
334+
// This method assumes that `fr0` is one of the universally
335+
// quantified region variables.
336+
assert!(self.is_universal_region(fr0));
337+
327338
let mut external_parents = vec![];
328339
let mut queue = vec![&fr0];
329340

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright 2016 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+
// compile-flags:-Znll -Zborrowck=mir -Zverbose
12+
13+
// Tests closures that propagate an outlives relationship to their
14+
// creator where the subject is a projection with no regions (`<T as
15+
// Iterator>::Item`, to be exact).
16+
17+
#![allow(warnings)]
18+
#![feature(dyn_trait)]
19+
#![feature(rustc_attrs)]
20+
21+
trait Anything { }
22+
23+
impl<T> Anything for T { }
24+
25+
fn with_signature<'a, T, F>(x: Box<T>, op: F) -> Box<dyn Anything + 'a>
26+
where F: FnOnce(Box<T>) -> Box<dyn Anything + 'a>
27+
{
28+
op(x)
29+
}
30+
31+
#[rustc_regions]
32+
fn no_region<'a, T>(x: Box<T>) -> Box<dyn Anything + 'a>
33+
where
34+
T: Iterator,
35+
{
36+
with_signature(x, |mut y| Box::new(y.next()))
37+
//~^ WARNING not reporting region error due to -Znll
38+
//~| ERROR failed type test
39+
}
40+
41+
#[rustc_regions]
42+
fn correct_region<'a, T>(x: Box<T>) -> Box<dyn Anything + 'a>
43+
where
44+
T: 'a + Iterator,
45+
{
46+
with_signature(x, |mut y| Box::new(y.next()))
47+
}
48+
49+
#[rustc_regions]
50+
fn wrong_region<'a, 'b, T>(x: Box<T>) -> Box<dyn Anything + 'a>
51+
where
52+
T: 'b + Iterator,
53+
{
54+
with_signature(x, |mut y| Box::new(y.next()))
55+
//~^ WARNING not reporting region error due to -Znll
56+
//~| ERROR failed type test
57+
}
58+
59+
#[rustc_regions]
60+
fn outlives_region<'a, 'b, T>(x: Box<T>) -> Box<dyn Anything + 'a>
61+
where
62+
T: 'b + Iterator,
63+
'b: 'a,
64+
{
65+
with_signature(x, |mut y| Box::new(y.next()))
66+
}
67+
68+
fn main() {}
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
warning: not reporting region error due to -Znll
2+
--> $DIR/projection-no-regions-closure.rs:36:31
3+
|
4+
36 | with_signature(x, |mut y| Box::new(y.next()))
5+
| ^^^^^^^^^^^^^^^^^^
6+
7+
warning: not reporting region error due to -Znll
8+
--> $DIR/projection-no-regions-closure.rs:54:31
9+
|
10+
54 | with_signature(x, |mut y| Box::new(y.next()))
11+
| ^^^^^^^^^^^^^^^^^^
12+
13+
note: External requirements
14+
--> $DIR/projection-no-regions-closure.rs:36:23
15+
|
16+
36 | with_signature(x, |mut y| Box::new(y.next()))
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
18+
|
19+
= note: defining type: DefId(0/1:15 ~ projection_no_regions_closure[317d]::no_region[0]::{{closure}}[0]) with closure substs [
20+
'_#1r,
21+
T,
22+
i32,
23+
extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#2r>
24+
]
25+
= note: number of external vids: 3
26+
= note: where <T as std::iter::Iterator>::Item: '_#2r
27+
28+
note: External requirements
29+
--> $DIR/projection-no-regions-closure.rs:46:23
30+
|
31+
46 | with_signature(x, |mut y| Box::new(y.next()))
32+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
33+
|
34+
= note: defining type: DefId(0/1:18 ~ projection_no_regions_closure[317d]::correct_region[0]::{{closure}}[0]) with closure substs [
35+
'_#1r,
36+
T,
37+
i32,
38+
extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#2r>
39+
]
40+
= note: number of external vids: 3
41+
= note: where <T as std::iter::Iterator>::Item: '_#2r
42+
43+
note: External requirements
44+
--> $DIR/projection-no-regions-closure.rs:54:23
45+
|
46+
54 | with_signature(x, |mut y| Box::new(y.next()))
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
48+
|
49+
= note: defining type: DefId(0/1:22 ~ projection_no_regions_closure[317d]::wrong_region[0]::{{closure}}[0]) with closure substs [
50+
'_#1r,
51+
'_#2r,
52+
T,
53+
i32,
54+
extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#3r>
55+
]
56+
= note: number of external vids: 4
57+
= note: where <T as std::iter::Iterator>::Item: '_#3r
58+
59+
note: External requirements
60+
--> $DIR/projection-no-regions-closure.rs:65:23
61+
|
62+
65 | with_signature(x, |mut y| Box::new(y.next()))
63+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
64+
|
65+
= note: defining type: DefId(0/1:26 ~ projection_no_regions_closure[317d]::outlives_region[0]::{{closure}}[0]) with closure substs [
66+
'_#1r,
67+
'_#2r,
68+
T,
69+
i32,
70+
extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#3r>
71+
]
72+
= note: number of external vids: 4
73+
= note: where <T as std::iter::Iterator>::Item: '_#3r
74+
75+
error: failed type test: TypeTest { generic_kind: ProjectionTy { substs: Slice([T]), item_def_id: DefId(2/0:1697 ~ core[2633]::iter[0]::iterator[0]::Iterator[0]::Item[0]) }, lower_bound: '_#4r, point: bb0[5], span: $DIR/projection-no-regions-closure.rs:36:23: 36:49, test: IsOutlivedByAnyRegionIn(['_#2r]) }
76+
--> $DIR/projection-no-regions-closure.rs:36:23
77+
|
78+
36 | with_signature(x, |mut y| Box::new(y.next()))
79+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
80+
81+
note: No external requirements
82+
--> $DIR/projection-no-regions-closure.rs:32:1
83+
|
84+
32 | / fn no_region<'a, T>(x: Box<T>) -> Box<dyn Anything + 'a>
85+
33 | | where
86+
34 | | T: Iterator,
87+
35 | | {
88+
... |
89+
38 | | //~| ERROR failed type test
90+
39 | | }
91+
| |_^
92+
|
93+
= note: defining type: DefId(0/0:6 ~ projection_no_regions_closure[317d]::no_region[0]) with substs [
94+
'_#1r,
95+
T
96+
]
97+
98+
note: No external requirements
99+
--> $DIR/projection-no-regions-closure.rs:42:1
100+
|
101+
42 | / fn correct_region<'a, T>(x: Box<T>) -> Box<dyn Anything + 'a>
102+
43 | | where
103+
44 | | T: 'a + Iterator,
104+
45 | | {
105+
46 | | with_signature(x, |mut y| Box::new(y.next()))
106+
47 | | }
107+
| |_^
108+
|
109+
= note: defining type: DefId(0/0:7 ~ projection_no_regions_closure[317d]::correct_region[0]) with substs [
110+
'_#1r,
111+
T
112+
]
113+
114+
error: failed type test: TypeTest { generic_kind: ProjectionTy { substs: Slice([T]), item_def_id: DefId(2/0:1697 ~ core[2633]::iter[0]::iterator[0]::Iterator[0]::Item[0]) }, lower_bound: '_#6r, point: bb0[5], span: $DIR/projection-no-regions-closure.rs:54:23: 54:49, test: IsOutlivedByAnyRegionIn(['_#2r, '_#3r]) }
115+
--> $DIR/projection-no-regions-closure.rs:54:23
116+
|
117+
54 | with_signature(x, |mut y| Box::new(y.next()))
118+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
119+
120+
note: No external requirements
121+
--> $DIR/projection-no-regions-closure.rs:50:1
122+
|
123+
50 | / fn wrong_region<'a, 'b, T>(x: Box<T>) -> Box<dyn Anything + 'a>
124+
51 | | where
125+
52 | | T: 'b + Iterator,
126+
53 | | {
127+
... |
128+
56 | | //~| ERROR failed type test
129+
57 | | }
130+
| |_^
131+
|
132+
= note: defining type: DefId(0/0:8 ~ projection_no_regions_closure[317d]::wrong_region[0]) with substs [
133+
'_#1r,
134+
'_#2r,
135+
T
136+
]
137+
138+
note: No external requirements
139+
--> $DIR/projection-no-regions-closure.rs:60:1
140+
|
141+
60 | / fn outlives_region<'a, 'b, T>(x: Box<T>) -> Box<dyn Anything + 'a>
142+
61 | | where
143+
62 | | T: 'b + Iterator,
144+
63 | | 'b: 'a,
145+
64 | | {
146+
65 | | with_signature(x, |mut y| Box::new(y.next()))
147+
66 | | }
148+
| |_^
149+
|
150+
= note: defining type: DefId(0/0:9 ~ projection_no_regions_closure[317d]::outlives_region[0]) with substs [
151+
'_#1r,
152+
'_#2r,
153+
T
154+
]
155+
156+
error: aborting due to 2 previous errors
157+

src/test/ui/nll/ty-outlives/projection-fn.rs renamed to src/test/ui/nll/ty-outlives/projection-no-regions-fn.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// compile-flags:-Znll -Zborrowck=mir
11+
// compile-flags:-Znll -Zborrowck=mir -Zverbose
1212

1313
#![allow(warnings)]
1414
#![feature(dyn_trait)]

src/test/ui/nll/ty-outlives/projection-fn.stderr renamed to src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
warning: not reporting region error due to -Znll
2-
--> $DIR/projection-fn.rs:24:5
2+
--> $DIR/projection-no-regions-fn.rs:24:5
33
|
44
24 | Box::new(x.next())
55
| ^^^^^^^^^^^^^^^^^^
66

77
warning: not reporting region error due to -Znll
8-
--> $DIR/projection-fn.rs:40:5
8+
--> $DIR/projection-no-regions-fn.rs:40:5
99
|
1010
40 | Box::new(x.next())
1111
| ^^^^^^^^^^^^^^^^^^
1212

13-
error: failed type test: TypeTest { generic_kind: ProjectionTy { substs: Slice([T]), item_def_id: DefId(2/0:1695 ~ core[2633]::iter[0]::iterator[0]::Iterator[0]::Item[0]) }, lower_bound: '_#4r, point: bb5[0], span: $DIR/projection-fn.rs:24:5: 24:23, test: IsOutlivedByAnyRegionIn(['_#2r]) }
14-
--> $DIR/projection-fn.rs:24:5
13+
error: failed type test: TypeTest { generic_kind: ProjectionTy { substs: Slice([T]), item_def_id: DefId(2/0:1697 ~ core[2633]::iter[0]::iterator[0]::Iterator[0]::Item[0]) }, lower_bound: '_#4r, point: bb5[0], span: $DIR/projection-no-regions-fn.rs:24:5: 24:23, test: IsOutlivedByAnyRegionIn(['_#2r]) }
14+
--> $DIR/projection-no-regions-fn.rs:24:5
1515
|
1616
24 | Box::new(x.next())
1717
| ^^^^^^^^^^^^^^^^^^
1818

19-
error: failed type test: TypeTest { generic_kind: ProjectionTy { substs: Slice([T]), item_def_id: DefId(2/0:1695 ~ core[2633]::iter[0]::iterator[0]::Iterator[0]::Item[0]) }, lower_bound: '_#5r, point: bb5[0], span: $DIR/projection-fn.rs:40:5: 40:23, test: IsOutlivedByAnyRegionIn(['_#2r, '_#3r]) }
20-
--> $DIR/projection-fn.rs:40:5
19+
error: failed type test: TypeTest { generic_kind: ProjectionTy { substs: Slice([T]), item_def_id: DefId(2/0:1697 ~ core[2633]::iter[0]::iterator[0]::Iterator[0]::Item[0]) }, lower_bound: '_#5r, point: bb5[0], span: $DIR/projection-no-regions-fn.rs:40:5: 40:23, test: IsOutlivedByAnyRegionIn(['_#2r, '_#3r]) }
20+
--> $DIR/projection-no-regions-fn.rs:40:5
2121
|
2222
40 | Box::new(x.next())
2323
| ^^^^^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)