66//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
77#![ feature( rustc_attrs) ]
88
9- // Test we truncate derefs properly
9+ fn simple_move_closure ( ) {
10+ struct S ( String ) ;
11+ struct T ( S ) ;
12+
13+ let t = T ( S ( "s" . into ( ) ) ) ;
14+ let mut c = #[ rustc_capture_analysis]
15+ //~^ ERROR: attributes on expressions are experimental
16+ //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
17+ move || {
18+ //~^ ERROR: First Pass analysis includes:
19+ //~| ERROR: Min Capture analysis includes:
20+ t. 0 . 0 = "new S" . into ( ) ;
21+ //~^ NOTE: Capturing t[(0, 0),(0, 0)] -> ByValue
22+ //~| NOTE: Min Capture t[(0, 0),(0, 0)] -> ByValue
23+ } ;
24+ c ( ) ;
25+ }
26+
27+ // Test move closure use reborrows when using references
1028fn simple_ref ( ) {
1129 let mut s = 10 ;
1230 let ref_s = & mut s;
@@ -24,8 +42,8 @@ fn simple_ref() {
2442 c ( ) ;
2543}
2644
27- // Test we truncate derefs properly
28- fn struct_contains_ref_to_another_struct ( ) {
45+ // Test move closure use reborrows when using references
46+ fn struct_contains_ref_to_another_struct_1 ( ) {
2947 struct S ( String ) ;
3048 struct T < ' a > ( & ' a mut S ) ;
3149
@@ -46,27 +64,78 @@ fn struct_contains_ref_to_another_struct() {
4664 c ( ) ;
4765}
4866
49- // Test that we don't reduce precision when there is nothing deref.
50- fn no_ref ( ) {
67+ // Test that we can use reborrows to read data of Copy types
68+ // i.e. without truncating derefs
69+ fn struct_contains_ref_to_another_struct_2 ( ) {
70+ struct S ( i32 ) ;
71+ struct T < ' a > ( & ' a S ) ;
72+
73+ let s = S ( 0 ) ;
74+ let t = T ( & s) ;
75+
76+ let mut c = #[ rustc_capture_analysis]
77+ //~^ ERROR: attributes on expressions are experimental
78+ //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
79+ move || {
80+ //~^ ERROR: First Pass analysis includes:
81+ //~| ERROR: Min Capture analysis includes:
82+ let _t = t. 0 . 0 ;
83+ //~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow
84+ //~| NOTE: Min Capture t[(0, 0),Deref,(0, 0)] -> ImmBorrow
85+ } ;
86+
87+ c ( ) ;
88+ }
89+
90+ // Test that we can use truncate to move out of !Copy types
91+ fn struct_contains_ref_to_another_struct_3 ( ) {
5192 struct S ( String ) ;
52- struct T ( S ) ;
93+ struct T < ' a > ( & ' a S ) ;
94+
95+ let s = S ( "s" . into ( ) ) ;
96+ let t = T ( & s) ;
5397
54- let t = T ( S ( "s" . into ( ) ) ) ;
5598 let mut c = #[ rustc_capture_analysis]
5699 //~^ ERROR: attributes on expressions are experimental
57100 //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
58101 move || {
59102 //~^ ERROR: First Pass analysis includes:
60103 //~| ERROR: Min Capture analysis includes:
61- t. 0 . 0 = "new S" . into ( ) ;
62- //~^ NOTE: Capturing t[(0, 0),(0, 0)] -> ByValue
63- //~| NOTE: Min Capture t[(0, 0),(0, 0)] -> ByValue
104+ let _t = t. 0 . 0 ;
105+ //~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow
106+ //~| NOTE: Capturing t[(0, 0)] -> ByValue
107+ //~| NOTE: Min Capture t[(0, 0)] -> ByValue
108+ } ;
109+
110+ c ( ) ;
111+ }
112+
113+ // Test that derefs of box are truncated in move closures
114+ fn truncate_box_derefs ( ) {
115+ struct S ( i32 ) ;
116+
117+ let b = Box :: new ( S ( 10 ) ) ;
118+
119+ let c = #[ rustc_capture_analysis]
120+ //~^ ERROR: attributes on expressions are experimental
121+ //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
122+ move || {
123+ //~^ ERROR: First Pass analysis includes:
124+ //~| ERROR: Min Capture analysis includes:
125+ let _t = b. 0 ;
126+ //~^ NOTE: Capturing b[Deref,(0, 0)] -> ByValue
127+ //~| NOTE: Capturing b[] -> ByValue
128+ //~| NOTE: Min Capture b[] -> ByValue
64129 } ;
130+
65131 c ( ) ;
66132}
67133
68134fn main ( ) {
135+ simple_move_closure ( ) ;
69136 simple_ref ( ) ;
70- struct_contains_ref_to_another_struct ( ) ;
71- no_ref ( ) ;
137+ struct_contains_ref_to_another_struct_1 ( ) ;
138+ struct_contains_ref_to_another_struct_2 ( ) ;
139+ struct_contains_ref_to_another_struct_3 ( ) ;
140+ truncate_box_derefs ( ) ;
72141}
0 commit comments