about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAli MJ Al-Nasrawy <alimjalnasrawy@gmail.com>2023-03-03 06:26:01 +0300
committerAli MJ Al-Nasrawy <alimjalnasrawy@gmail.com>2023-03-03 14:12:05 +0300
commit10da7710cdd5d76261bcfcf31dd163c966b3ebb3 (patch)
tree3bb1efa9d948caa45a05c3b85efe490486f4a030
parent9d74bff829174c4a707ee2ab17ac6e01490d9a6a (diff)
downloadrust-10da7710cdd5d76261bcfcf31dd163c966b3ebb3.tar.gz
rust-10da7710cdd5d76261bcfcf31dd163c966b3ebb3.zip
ignore bivariant regions in opaque types
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs30
-rw-r--r--tests/ui/nll/closure-requirements/type-test-subject-opaque-2.rs4
-rw-r--r--tests/ui/nll/closure-requirements/type-test-subject-opaque-2.stderr18
3 files changed, 32 insertions, 20 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index e526ccd71ca..3137e71781c 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -1097,6 +1097,36 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     ) -> Option<ClosureOutlivesSubject<'tcx>> {
         let tcx = infcx.tcx;
 
+        // Opaque types' substs may include useless lifetimes.
+        // We will replace them with ReStatic.
+        struct OpaqueFolder<'tcx> {
+            tcx: TyCtxt<'tcx>,
+        }
+        impl<'tcx> ty::TypeFolder<TyCtxt<'tcx>> for OpaqueFolder<'tcx> {
+            fn interner(&self) -> TyCtxt<'tcx> {
+                self.tcx
+            }
+            fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
+                use ty::TypeSuperFoldable as _;
+                let tcx = self.tcx;
+                let &ty::Alias(ty::Opaque, ty::AliasTy { substs, def_id, .. }) = t.kind() else {
+                    return t.super_fold_with(self);
+                };
+                let substs =
+                    std::iter::zip(substs, tcx.variances_of(def_id)).map(|(arg, v)| {
+                        match (arg.unpack(), v) {
+                            (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => {
+                                tcx.lifetimes.re_static.into()
+                            }
+                            _ => arg.fold_with(self),
+                        }
+                    });
+                tcx.mk_opaque(def_id, tcx.mk_substs_from_iter(substs))
+            }
+        }
+
+        let ty = ty.fold_with(&mut OpaqueFolder { tcx });
+
         let ty = tcx.fold_regions(ty, |r, _depth| {
             let r_vid = self.to_region_vid(r);
             let r_scc = self.constraint_sccs.scc(r_vid);
diff --git a/tests/ui/nll/closure-requirements/type-test-subject-opaque-2.rs b/tests/ui/nll/closure-requirements/type-test-subject-opaque-2.rs
index fc1923bb76f..55905850f0c 100644
--- a/tests/ui/nll/closure-requirements/type-test-subject-opaque-2.rs
+++ b/tests/ui/nll/closure-requirements/type-test-subject-opaque-2.rs
@@ -1,5 +1,5 @@
-// check-fail
-// known-bug: #107516
+// Resgression test for #107516.
+// check-pass
 
 fn iter1<'a: 'a>() -> impl Iterator<Item = &'static str> {
     None.into_iter()
diff --git a/tests/ui/nll/closure-requirements/type-test-subject-opaque-2.stderr b/tests/ui/nll/closure-requirements/type-test-subject-opaque-2.stderr
deleted file mode 100644
index f6266dd4eb5..00000000000
--- a/tests/ui/nll/closure-requirements/type-test-subject-opaque-2.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error[E0310]: the opaque type `iter1<'_>::{opaque#0}` may not live long enough
-  --> $DIR/type-test-subject-opaque-2.rs:15:16
-   |
-LL |     let _ = || Bivar(iter1());
-   |                ^^^^^^^^^^^^^^
-   |
-   = help: consider adding an explicit lifetime bound `iter1<'_>::{opaque#0}: 'static`...
-   = note: ...so that the type `impl Iterator<Item = &'static str>` will meet its required lifetime bounds
-
-error: `iter2<'_>::{opaque#0}<'_>` does not live long enough
-  --> $DIR/type-test-subject-opaque-2.rs:16:16
-   |
-LL |     let _ = || Bivar(iter2());
-   |                ^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0310`.