about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs29
1 files changed, 20 insertions, 9 deletions
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index ccf11c61b57..2f5e2e417a6 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -344,12 +344,14 @@ where
         // the problem is to add `T: 'r`, which isn't true. So, if there are no
         // inference variables, we use a verify constraint instead of adding
         // edges, which winds up enforcing the same condition.
+        let is_opaque = alias_ty.kind(self.tcx) == ty::Opaque;
         if approx_env_bounds.is_empty()
             && trait_bounds.is_empty()
-            && (alias_ty.needs_infer() || alias_ty.kind(self.tcx) == ty::Opaque)
+            && (alias_ty.needs_infer() || is_opaque)
         {
             debug!("no declared bounds");
-            self.substs_must_outlive(alias_ty.substs, origin, region);
+            let opt_variances = is_opaque.then(|| self.tcx.variances_of(alias_ty.def_id));
+            self.substs_must_outlive(alias_ty.substs, origin, region, opt_variances);
             return;
         }
 
@@ -395,22 +397,31 @@ where
         self.delegate.push_verify(origin, GenericKind::Alias(alias_ty), region, verify_bound);
     }
 
+    #[instrument(level = "debug", skip(self))]
     fn substs_must_outlive(
         &mut self,
         substs: SubstsRef<'tcx>,
         origin: infer::SubregionOrigin<'tcx>,
         region: ty::Region<'tcx>,
+        opt_variances: Option<&[ty::Variance]>,
     ) {
         let constraint = origin.to_constraint_category();
-        for k in substs {
+        for (index, k) in substs.iter().enumerate() {
             match k.unpack() {
                 GenericArgKind::Lifetime(lt) => {
-                    self.delegate.push_sub_region_constraint(
-                        origin.clone(),
-                        region,
-                        lt,
-                        constraint,
-                    );
+                    let variance = if let Some(variances) = opt_variances {
+                        variances[index]
+                    } else {
+                        ty::Invariant
+                    };
+                    if variance == ty::Invariant {
+                        self.delegate.push_sub_region_constraint(
+                            origin.clone(),
+                            region,
+                            lt,
+                            constraint,
+                        );
+                    }
                 }
                 GenericArgKind::Type(ty) => {
                     self.type_must_outlive(origin.clone(), ty, region, constraint);