@@ -133,7 +133,7 @@ pub fn compute_dropck_outlives_inner<'tcx>(
133133 result. overflows. len( ) ,
134134 ty_stack. len( )
135135 ) ;
136- dtorck_constraint_for_ty_inner ( tcx, DUMMY_SP , for_ty , depth, ty, & mut constraints) ?;
136+ dtorck_constraint_for_ty_inner ( tcx, param_env , DUMMY_SP , depth, ty, & mut constraints) ?;
137137
138138 // "outlives" represent types/regions that may be touched
139139 // by a destructor.
@@ -185,16 +185,15 @@ pub fn compute_dropck_outlives_inner<'tcx>(
185185
186186/// Returns a set of constraints that needs to be satisfied in
187187/// order for `ty` to be valid for destruction.
188+ #[ instrument( level = "debug" , skip( tcx, param_env, span, constraints) ) ]
188189pub fn dtorck_constraint_for_ty_inner < ' tcx > (
189190 tcx : TyCtxt < ' tcx > ,
191+ param_env : ty:: ParamEnv < ' tcx > ,
190192 span : Span ,
191- for_ty : Ty < ' tcx > ,
192193 depth : usize ,
193194 ty : Ty < ' tcx > ,
194195 constraints : & mut DropckConstraint < ' tcx > ,
195196) -> Result < ( ) , NoSolution > {
196- debug ! ( "dtorck_constraint_for_ty_inner({:?}, {:?}, {:?}, {:?})" , span, for_ty, depth, ty) ;
197-
198197 if !tcx. recursion_limit ( ) . value_within_limit ( depth) {
199198 constraints. overflows . push ( ty) ;
200199 return Ok ( ( ) ) ;
@@ -224,13 +223,13 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
224223 ty:: Array ( ety, _) | ty:: Slice ( ety) => {
225224 // single-element containers, behave like their element
226225 rustc_data_structures:: stack:: ensure_sufficient_stack ( || {
227- dtorck_constraint_for_ty_inner ( tcx, span , for_ty , depth + 1 , * ety, constraints)
226+ dtorck_constraint_for_ty_inner ( tcx, param_env , span , depth + 1 , * ety, constraints)
228227 } ) ?;
229228 }
230229
231230 ty:: Tuple ( tys) => rustc_data_structures:: stack:: ensure_sufficient_stack ( || {
232231 for ty in tys. iter ( ) {
233- dtorck_constraint_for_ty_inner ( tcx, span , for_ty , depth + 1 , ty, constraints) ?;
232+ dtorck_constraint_for_ty_inner ( tcx, param_env , span , depth + 1 , ty, constraints) ?;
234233 }
235234 Ok :: < _ , NoSolution > ( ( ) )
236235 } ) ?,
@@ -249,7 +248,14 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
249248
250249 rustc_data_structures:: stack:: ensure_sufficient_stack ( || {
251250 for ty in args. as_closure ( ) . upvar_tys ( ) {
252- dtorck_constraint_for_ty_inner ( tcx, span, for_ty, depth + 1 , ty, constraints) ?;
251+ dtorck_constraint_for_ty_inner (
252+ tcx,
253+ param_env,
254+ span,
255+ depth + 1 ,
256+ ty,
257+ constraints,
258+ ) ?;
253259 }
254260 Ok :: < _ , NoSolution > ( ( ) )
255261 } ) ?
@@ -278,8 +284,8 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
278284 // only take place through references with lifetimes
279285 // derived from lifetimes attached to the upvars and resume
280286 // argument, and we *do* incorporate those here.
281-
282- if !args. as_coroutine ( ) . is_valid ( ) {
287+ let args = args . as_coroutine ( ) ;
288+ if !args. is_valid ( ) {
283289 // By the time this code runs, all type variables ought to
284290 // be fully resolved.
285291 tcx. sess . delay_span_bug (
@@ -289,10 +295,13 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
289295 return Err ( NoSolution ) ;
290296 }
291297
292- constraints
293- . outlives
294- . extend ( args. as_coroutine ( ) . upvar_tys ( ) . iter ( ) . map ( ty:: GenericArg :: from) ) ;
295- constraints. outlives . push ( args. as_coroutine ( ) . resume_ty ( ) . into ( ) ) ;
298+ // While we conservatively assume that all coroutines require drop
299+ // to avoid query cycles during MIR building, we can check the actual
300+ // witness during borrowck to avoid unnecessary liveness constraints.
301+ if args. witness ( ) . needs_drop ( tcx, tcx. erase_regions ( param_env) ) {
302+ constraints. outlives . extend ( args. upvar_tys ( ) . iter ( ) . map ( ty:: GenericArg :: from) ) ;
303+ constraints. outlives . push ( args. resume_ty ( ) . into ( ) ) ;
304+ }
296305 }
297306
298307 ty:: Adt ( def, args) => {
0 commit comments