From c5613258bb3f10907ba1127f363102bf842637cd Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 29 Oct 2023 17:45:01 -0400 Subject: [PATCH] Ignore RPIT duplicated lifetimes in opaque_types_defined_by --- compiler/rustc_middle/src/ty/util.rs | 2 +- compiler/rustc_ty_utils/src/opaque_types.rs | 9 ++++++++- ...plicate-lifetimes-from-rpit-containing-tait.rs | 13 +++++++++++++ ...licate-lifetimes-from-rpit-containing-tait2.rs | 15 +++++++++++++++ 4 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 tests/ui/type-alias-impl-trait/duplicate-lifetimes-from-rpit-containing-tait.rs create mode 100644 tests/ui/type-alias-impl-trait/duplicate-lifetimes-from-rpit-containing-tait2.rs diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index d29d1902404..c155f83734e 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -460,7 +460,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Checks whether each generic argument is simply a unique generic parameter. pub fn uses_unique_generic_params( self, - args: GenericArgsRef<'tcx>, + args: &[ty::GenericArg<'tcx>], ignore_regions: CheckRegions, ) -> Result<(), NotUniqueParam<'tcx>> { let mut seen = GrowableBitSet::default(); diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index d1a154fe20d..f7d54566cb7 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -154,7 +154,14 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { self.opaques.push(alias_ty.def_id.expect_local()); - match self.tcx.uses_unique_generic_params(alias_ty.args, CheckRegions::Bound) { + let parent_count = self.tcx.generics_of(alias_ty.def_id).parent_count; + // Only check that the parent generics of the TAIT/RPIT are unique. + // the args owned by the opaque are going to always be duplicate + // lifetime params for RPITs, and empty for TAITs. + match self + .tcx + .uses_unique_generic_params(&alias_ty.args[..parent_count], CheckRegions::Bound) + { Ok(()) => { // FIXME: implement higher kinded lifetime bounds on nested opaque types. They are not // supported at all, so this is sound to do, but once we want to support them, you'll diff --git a/tests/ui/type-alias-impl-trait/duplicate-lifetimes-from-rpit-containing-tait.rs b/tests/ui/type-alias-impl-trait/duplicate-lifetimes-from-rpit-containing-tait.rs new file mode 100644 index 00000000000..4c56fe2d1dc --- /dev/null +++ b/tests/ui/type-alias-impl-trait/duplicate-lifetimes-from-rpit-containing-tait.rs @@ -0,0 +1,13 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +type Opaque<'lt> = impl Sized + 'lt; + +fn test<'a>( + arg: impl Iterator, +) -> impl Iterator> { + arg +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/duplicate-lifetimes-from-rpit-containing-tait2.rs b/tests/ui/type-alias-impl-trait/duplicate-lifetimes-from-rpit-containing-tait2.rs new file mode 100644 index 00000000000..97f8c799fc5 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/duplicate-lifetimes-from-rpit-containing-tait2.rs @@ -0,0 +1,15 @@ +// check-pass +// edition: 2021 + +#![feature(type_alias_impl_trait)] + +struct Foo<'a>(&'a ()); + +impl<'a> Foo<'a> { + async fn new() -> () { + type T = impl Sized; + let _: T = (); + } +} + +fn main() {}