about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src/traits/query
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2023-10-24 19:16:15 +0200
committerlcnr <rust@lcnr.de>2023-11-02 17:20:13 +0100
commit57253552de475856a1f3bddedcd76e775892f770 (patch)
tree0faada76404ba88b4849167422b28f82eaf1e119 /compiler/rustc_trait_selection/src/traits/query
parentf0df3d2dfbdab3567520366c979df4e20b2796f9 (diff)
downloadrust-57253552de475856a1f3bddedcd76e775892f770.tar.gz
rust-57253552de475856a1f3bddedcd76e775892f770.zip
dropck_outlives check generator witness needs_drop
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/query')
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs35
1 files changed, 22 insertions, 13 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
index 0783eec6fe8..69403bd4351 100644
--- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
@@ -133,7 +133,7 @@ pub fn compute_dropck_outlives_inner<'tcx>(
             result.overflows.len(),
             ty_stack.len()
         );
-        dtorck_constraint_for_ty_inner(tcx, DUMMY_SP, for_ty, depth, ty, &mut constraints)?;
+        dtorck_constraint_for_ty_inner(tcx, param_env, DUMMY_SP, depth, ty, &mut constraints)?;
 
         // "outlives" represent types/regions that may be touched
         // by a destructor.
@@ -185,16 +185,15 @@ pub fn compute_dropck_outlives_inner<'tcx>(
 
 /// Returns a set of constraints that needs to be satisfied in
 /// order for `ty` to be valid for destruction.
+#[instrument(level = "debug", skip(tcx, param_env, span, constraints))]
 pub fn dtorck_constraint_for_ty_inner<'tcx>(
     tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     span: Span,
-    for_ty: Ty<'tcx>,
     depth: usize,
     ty: Ty<'tcx>,
     constraints: &mut DropckConstraint<'tcx>,
 ) -> Result<(), NoSolution> {
-    debug!("dtorck_constraint_for_ty_inner({:?}, {:?}, {:?}, {:?})", span, for_ty, depth, ty);
-
     if !tcx.recursion_limit().value_within_limit(depth) {
         constraints.overflows.push(ty);
         return Ok(());
@@ -224,13 +223,13 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
         ty::Array(ety, _) | ty::Slice(ety) => {
             // single-element containers, behave like their element
             rustc_data_structures::stack::ensure_sufficient_stack(|| {
-                dtorck_constraint_for_ty_inner(tcx, span, for_ty, depth + 1, *ety, constraints)
+                dtorck_constraint_for_ty_inner(tcx, param_env, span, depth + 1, *ety, constraints)
             })?;
         }
 
         ty::Tuple(tys) => rustc_data_structures::stack::ensure_sufficient_stack(|| {
             for ty in tys.iter() {
-                dtorck_constraint_for_ty_inner(tcx, span, for_ty, depth + 1, ty, constraints)?;
+                dtorck_constraint_for_ty_inner(tcx, param_env, span, depth + 1, ty, constraints)?;
             }
             Ok::<_, NoSolution>(())
         })?,
@@ -249,7 +248,14 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
 
             rustc_data_structures::stack::ensure_sufficient_stack(|| {
                 for ty in args.as_closure().upvar_tys() {
-                    dtorck_constraint_for_ty_inner(tcx, span, for_ty, depth + 1, ty, constraints)?;
+                    dtorck_constraint_for_ty_inner(
+                        tcx,
+                        param_env,
+                        span,
+                        depth + 1,
+                        ty,
+                        constraints,
+                    )?;
                 }
                 Ok::<_, NoSolution>(())
             })?
@@ -278,8 +284,8 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
             // only take place through references with lifetimes
             // derived from lifetimes attached to the upvars and resume
             // argument, and we *do* incorporate those here.
-
-            if !args.as_coroutine().is_valid() {
+            let args = args.as_coroutine();
+            if !args.is_valid() {
                 // By the time this code runs, all type variables ought to
                 // be fully resolved.
                 tcx.sess.delay_span_bug(
@@ -289,10 +295,13 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
                 return Err(NoSolution);
             }
 
-            constraints
-                .outlives
-                .extend(args.as_coroutine().upvar_tys().iter().map(ty::GenericArg::from));
-            constraints.outlives.push(args.as_coroutine().resume_ty().into());
+            // While we conservatively assume that all coroutines require drop
+            // to avoid query cycles during MIR building, we can check the actual
+            // witness during borrowck to avoid unnecessary liveness constraints.
+            if args.witness().needs_drop(tcx, param_env) {
+                constraints.outlives.extend(args.upvar_tys().iter().map(ty::GenericArg::from));
+                constraints.outlives.push(args.resume_ty().into());
+            }
         }
 
         ty::Adt(def, args) => {