diff options
| author | Ali MJ Al-Nasrawy <alimjalnasrawy@gmail.com> | 2023-10-19 10:42:25 +0000 |
|---|---|---|
| committer | Ali MJ Al-Nasrawy <alimjalnasrawy@gmail.com> | 2024-03-28 06:00:26 +0000 |
| commit | 6b6ed2ea28e591ccae99048f226f98abfcd2e087 (patch) | |
| tree | 11913b3b6bfb71a7e61166079fef5a4f5f2b7651 | |
| parent | f4940e4d22006e902989bbe41ad0484d549495f5 (diff) | |
| download | rust-6b6ed2ea28e591ccae99048f226f98abfcd2e087.tar.gz rust-6b6ed2ea28e591ccae99048f226f98abfcd2e087.zip | |
reject external lifetimes as invalid arguments
3 files changed, 50 insertions, 4 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 7fbf4fbf085..8a03d59b710 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -18,6 +18,7 @@ use rustc_trait_selection::traits::ObligationCtxt; use crate::session_diagnostics::LifetimeMismatchOpaqueParam; use crate::session_diagnostics::NonGenericOpaqueTypeParam; +use crate::universal_regions::RegionClassification; use super::RegionInferenceContext; @@ -162,10 +163,15 @@ impl<'tcx> RegionInferenceContext<'tcx> { NllRegionVariableOrigin::FreeRegion => self .universal_regions .universal_regions() - .filter(|&ur| self.universal_region_relations.equal(vid, ur)) - // FIXME(aliemjay): universal regions with no `external_name` - // are extenal closure regions, which should be rejected eventually. - .find_map(|ur| self.definitions[ur].external_name), + .filter(|&ur| { + // See [rustc-dev-guide chapter] ยง "Closure restrictions". + !matches!( + self.universal_regions.region_classification(ur), + Some(RegionClassification::External) + ) + }) + .find(|&ur| self.universal_region_relations.equal(vid, ur)) + .map(|ur| self.definitions[ur].external_name.unwrap()), NllRegionVariableOrigin::Placeholder(placeholder) => { Some(ty::Region::new_placeholder(infcx.tcx, placeholder)) } diff --git a/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.rs b/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.rs new file mode 100644 index 00000000000..9101e4385b3 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.rs @@ -0,0 +1,19 @@ +#![feature(type_alias_impl_trait)] + +mod case1 { + type Opaque<'x> = impl Sized + 'x; + fn foo<'s>() -> Opaque<'s> { + let _ = || { let _: Opaque<'s> = (); }; + //~^ ERROR expected generic lifetime parameter, found `'_` + } +} + +mod case2 { + type Opaque<'x> = impl Sized + 'x; + fn foo<'s>() -> Opaque<'s> { + let _ = || -> Opaque<'s> {}; + //~^ ERROR expected generic lifetime parameter, found `'_` + } +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.stderr b/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.stderr new file mode 100644 index 00000000000..a8fd1f691dd --- /dev/null +++ b/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.stderr @@ -0,0 +1,21 @@ +error[E0792]: expected generic lifetime parameter, found `'_` + --> $DIR/defined-in-closure-external-lifetime.rs:6:29 + | +LL | type Opaque<'x> = impl Sized + 'x; + | -- this generic parameter must be used with a generic lifetime parameter +LL | fn foo<'s>() -> Opaque<'s> { +LL | let _ = || { let _: Opaque<'s> = (); }; + | ^^^^^^^^^^ + +error[E0792]: expected generic lifetime parameter, found `'_` + --> $DIR/defined-in-closure-external-lifetime.rs:14:34 + | +LL | type Opaque<'x> = impl Sized + 'x; + | -- this generic parameter must be used with a generic lifetime parameter +LL | fn foo<'s>() -> Opaque<'s> { +LL | let _ = || -> Opaque<'s> {}; + | ^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0792`. |
