diff options
| author | Ali MJ Al-Nasrawy <alimjalnasrawy@gmail.com> | 2023-03-03 06:26:01 +0300 |
|---|---|---|
| committer | Ali MJ Al-Nasrawy <alimjalnasrawy@gmail.com> | 2023-03-03 14:12:05 +0300 |
| commit | 10da7710cdd5d76261bcfcf31dd163c966b3ebb3 (patch) | |
| tree | 3bb1efa9d948caa45a05c3b85efe490486f4a030 | |
| parent | 9d74bff829174c4a707ee2ab17ac6e01490d9a6a (diff) | |
| download | rust-10da7710cdd5d76261bcfcf31dd163c966b3ebb3.tar.gz rust-10da7710cdd5d76261bcfcf31dd163c966b3ebb3.zip | |
ignore bivariant regions in opaque types
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`. |
