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>(
344344 let args = args. as_coroutine ( ) ;
345345
346346 // 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 {
350355 constraints. outlives . extend ( args. upvar_tys ( ) . iter ( ) . map ( ty:: GenericArg :: from) ) ;
351356 constraints. outlives . push ( args. resume_ty ( ) . into ( ) ) ;
352357 }
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