about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAli MJ Al-Nasrawy <alimjalnasrawy@gmail.com>2023-10-19 10:42:25 +0000
committerAli MJ Al-Nasrawy <alimjalnasrawy@gmail.com>2024-03-28 06:00:26 +0000
commit6b6ed2ea28e591ccae99048f226f98abfcd2e087 (patch)
tree11913b3b6bfb71a7e61166079fef5a4f5f2b7651
parentf4940e4d22006e902989bbe41ad0484d549495f5 (diff)
downloadrust-6b6ed2ea28e591ccae99048f226f98abfcd2e087.tar.gz
rust-6b6ed2ea28e591ccae99048f226f98abfcd2e087.zip
reject external lifetimes as invalid arguments
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.stderr21
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`.