File tree Expand file tree Collapse file tree 3 files changed +21
-6
lines changed
compiler/rustc_typeck/src/check/generator_interior/drop_ranges Expand file tree Collapse file tree 3 files changed +21
-6
lines changed Original file line number Diff line number Diff line change @@ -157,8 +157,15 @@ impl<'tcx> Visitor<'tcx> for DropRangeVisitor<'tcx> {
157
157
}
158
158
ExprKind :: Loop ( body, ..) => {
159
159
let loop_begin = self . expr_index + 1 ;
160
- self . visit_block ( body) ;
161
- self . drop_ranges . add_control_edge ( self . expr_index , loop_begin) ;
160
+ if body. stmts . is_empty ( ) && body. expr . is_none ( ) {
161
+ // For empty loops we won't have updated self.expr_index after visiting the
162
+ // body, meaning we'd get an edge from expr_index to expr_index + 1, but
163
+ // instead we want an edge from expr_index + 1 to expr_index + 1.
164
+ self . drop_ranges . add_control_edge ( loop_begin, loop_begin) ;
165
+ } else {
166
+ self . visit_block ( body) ;
167
+ self . drop_ranges . add_control_edge ( self . expr_index , loop_begin) ;
168
+ }
162
169
}
163
170
ExprKind :: Break ( hir:: Destination { target_id : Ok ( target) , .. } , ..)
164
171
| ExprKind :: Continue ( hir:: Destination { target_id : Ok ( target) , .. } , ..) => {
Original file line number Diff line number Diff line change @@ -43,6 +43,13 @@ async fn non_sync_with_method_call() {
43
43
}
44
44
}
45
45
46
+ async fn non_sync_with_infinite_loop ( ) {
47
+ let f: & mut std:: fmt:: Formatter = loop { } ;
48
+ if non_sync ( ) . fmt ( f) . unwrap ( ) == ( ) {
49
+ fut ( ) . await ;
50
+ }
51
+ }
52
+
46
53
fn assert_send ( _: impl Send ) { }
47
54
48
55
pub fn pass_assert ( ) {
@@ -51,4 +58,5 @@ pub fn pass_assert() {
51
58
//~^ ERROR future cannot be sent between threads safely
52
59
assert_send ( non_sync_with_method_call ( ) ) ;
53
60
//~^ ERROR future cannot be sent between threads safely
61
+ assert_send ( non_sync_with_infinite_loop ( ) ) ;
54
62
}
Original file line number Diff line number Diff line change 1
1
error: future cannot be sent between threads safely
2
- --> $DIR/async-fn-nonsend.rs:50 :17
2
+ --> $DIR/async-fn-nonsend.rs:57 :17
3
3
|
4
4
LL | assert_send(non_send_temporary_in_match());
5
5
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_send_temporary_in_match` is not `Send`
@@ -16,13 +16,13 @@ LL | Some(_) => fut().await,
16
16
LL | }
17
17
| - `Some(non_send())` is later dropped here
18
18
note: required by a bound in `assert_send`
19
- --> $DIR/async-fn-nonsend.rs:46 :24
19
+ --> $DIR/async-fn-nonsend.rs:53 :24
20
20
|
21
21
LL | fn assert_send(_: impl Send) {}
22
22
| ^^^^ required by this bound in `assert_send`
23
23
24
24
error: future cannot be sent between threads safely
25
- --> $DIR/async-fn-nonsend.rs:52 :17
25
+ --> $DIR/async-fn-nonsend.rs:59 :17
26
26
|
27
27
LL | assert_send(non_sync_with_method_call());
28
28
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send`
40
40
LL | }
41
41
| - `f` is later dropped here
42
42
note: required by a bound in `assert_send`
43
- --> $DIR/async-fn-nonsend.rs:46 :24
43
+ --> $DIR/async-fn-nonsend.rs:53 :24
44
44
|
45
45
LL | fn assert_send(_: impl Send) {}
46
46
| ^^^^ required by this bound in `assert_send`
You can’t perform that action at this time.
0 commit comments