about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_resolve/src/late.rs25
-rw-r--r--src/test/ui/lifetimes/elided-lifetime-in-path-in-impl-Fn.rs19
2 files changed, 33 insertions, 11 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 9ea66c0b59d..31f30f39c87 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1319,7 +1319,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 | PathSource::Struct
                 | PathSource::TupleStruct(..) => false,
             };
-            let mut error = false;
+            let mut error = true;
+            let mut res = LifetimeRes::Error;
             for rib in self.lifetime_ribs.iter().rev() {
                 match rib.kind {
                     // In create-parameter mode we error here because we don't want to support
@@ -1329,7 +1330,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     //     impl Foo for std::cell::Ref<u32> // note lack of '_
                     //     async fn foo(_: std::cell::Ref<u32>) { ... }
                     LifetimeRibKind::AnonymousCreateParameter(_) => {
-                        error = true;
                         break;
                     }
                     // `PassThrough` is the normal case.
@@ -1338,19 +1338,22 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     // `PathSegment`, for which there is no associated `'_` or `&T` with no explicit
                     // lifetime. Instead, we simply create an implicit lifetime, which will be checked
                     // later, at which point a suitable error will be emitted.
-                    LifetimeRibKind::AnonymousPassThrough(..)
-                    | LifetimeRibKind::AnonymousReportError
-                    | LifetimeRibKind::Item => break,
+                    LifetimeRibKind::AnonymousPassThrough(binder) => {
+                        error = false;
+                        res = LifetimeRes::Anonymous { binder, elided: true };
+                        break;
+                    }
+                    LifetimeRibKind::AnonymousReportError | LifetimeRibKind::Item => {
+                        // FIXME(cjgillot) This resolution is wrong, but this does not matter
+                        // since these cases are erroneous anyway.
+                        res = LifetimeRes::Anonymous { binder: DUMMY_NODE_ID, elided: true };
+                        error = false;
+                        break;
+                    }
                     _ => {}
                 }
             }
 
-            let res = if error {
-                LifetimeRes::Error
-            } else {
-                LifetimeRes::Anonymous { binder: segment_id, elided: true }
-            };
-
             let node_ids = self.r.next_node_ids(expected_lifetimes);
             self.record_lifetime_res(
                 segment_id,
diff --git a/src/test/ui/lifetimes/elided-lifetime-in-path-in-impl-Fn.rs b/src/test/ui/lifetimes/elided-lifetime-in-path-in-impl-Fn.rs
new file mode 100644
index 00000000000..9c9965d8fb8
--- /dev/null
+++ b/src/test/ui/lifetimes/elided-lifetime-in-path-in-impl-Fn.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+struct Foo<'a>(&'a ());
+
+fn with_fn() -> fn(Foo) {
+    |_| ()
+}
+
+fn with_impl_fn() -> impl Fn(Foo) {
+    |_| ()
+}
+
+fn with_where_fn<T>()
+where
+    T: Fn(Foo),
+{
+}
+
+fn main() {}