File tree Expand file tree Collapse file tree 3 files changed +53
-3
lines changed
compiler/rustc_trait_selection/src/traits/query Expand file tree Collapse file tree 3 files changed +53
-3
lines changed Original file line number Diff line number Diff line change @@ -344,9 +344,14 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
344
344
let args = args. as_coroutine ( ) ;
345
345
346
346
// While we conservatively assume that all coroutines require drop
347
- // to avoid query cycles during MIR building, we can check the actual
348
- // witness during borrowck to avoid unnecessary liveness constraints.
349
- if args. witness ( ) . needs_drop ( tcx, tcx. erase_regions ( typing_env) ) {
347
+ // to avoid query cycles during MIR building, we can be more precise
348
+ // here and check the specific components of the coroutines. This
349
+ // includes the witness types, upvars, *and* the resume ty.
350
+ let typing_env = tcx. erase_regions ( typing_env) ;
351
+ let needs_drop = args. witness ( ) . needs_drop ( tcx, typing_env)
352
+ || args. upvar_tys ( ) . iter ( ) . any ( |ty| ty. needs_drop ( tcx, typing_env) )
353
+ || args. resume_ty ( ) . needs_drop ( tcx, typing_env) ;
354
+ if needs_drop {
350
355
constraints. outlives . extend ( args. upvar_tys ( ) . iter ( ) . map ( ty:: GenericArg :: from) ) ;
351
356
constraints. outlives . push ( args. resume_ty ( ) . into ( ) ) ;
352
357
}
Original file line number Diff line number Diff line change
1
+ //@ edition: 2018
2
+ // Regression test for <https://github.com/rust-lang/rust/issues/144155>.
3
+
4
+ struct NeedsDrop < ' a > ( & ' a Vec < i32 > ) ;
5
+
6
+ async fn await_point ( ) { }
7
+
8
+ impl Drop for NeedsDrop < ' _ > {
9
+ fn drop ( & mut self ) { }
10
+ }
11
+
12
+ fn foo ( ) {
13
+ let v = vec ! [ 1 , 2 , 3 ] ;
14
+ let x = NeedsDrop ( & v) ;
15
+ let c = async {
16
+ std:: future:: ready ( ( ) ) . await ;
17
+ drop ( x) ;
18
+ } ;
19
+ drop ( v) ;
20
+ //~^ ERROR cannot move out of `v` because it is borrowed
21
+ }
22
+
23
+ fn main ( ) { }
Original file line number Diff line number Diff line change
1
+ error[E0505]: cannot move out of `v` because it is borrowed
2
+ --> $DIR/drop-live-upvar.rs:19:10
3
+ |
4
+ LL | let v = vec![1, 2, 3];
5
+ | - binding `v` declared here
6
+ LL | let x = NeedsDrop(&v);
7
+ | -- borrow of `v` occurs here
8
+ ...
9
+ LL | drop(v);
10
+ | ^ move out of `v` occurs here
11
+ LL |
12
+ LL | }
13
+ | - borrow might be used here, when `c` is dropped and runs the destructor for coroutine
14
+ |
15
+ help: consider cloning the value if the performance cost is acceptable
16
+ |
17
+ LL | let x = NeedsDrop(&v.clone());
18
+ | ++++++++
19
+
20
+ error: aborting due to 1 previous error
21
+
22
+ For more information about this error, try `rustc --explain E0505`.
You can’t perform that action at this time.
0 commit comments