From ec3f3074a1d2f0c3f8a4fd245c79a774cf19a7ca Mon Sep 17 00:00:00 2001
From: Camille GILLOT <gillot.camille@gmail.com>
Date: Sat, 30 Jul 2022 17:58:26 +0200
Subject: [PATCH] Always create elided lifetimes, even if inferred.

---
 compiler/rustc_resolve/src/late.rs            | 43 +++++++++----------
 ...ime-in-path-in-type-relative-expression.rs | 17 ++++++++
 2 files changed, 37 insertions(+), 23 deletions(-)
 create mode 100644 src/test/ui/lifetimes/elided-lifetime-in-path-in-type-relative-expression.rs

diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index ed65100ae77..dea3eaecda6 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1644,14 +1644,30 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 continue;
             }
 
-            let missing = match source {
-                PathSource::Trait(..) | PathSource::TraitItem(..) | PathSource::Type => true,
+            let node_ids = self.r.next_node_ids(expected_lifetimes);
+            self.record_lifetime_res(
+                segment_id,
+                LifetimeRes::ElidedAnchor { start: node_ids.start, end: node_ids.end },
+                LifetimeElisionCandidate::Ignore,
+            );
+
+            let inferred = match source {
+                PathSource::Trait(..) | PathSource::TraitItem(..) | PathSource::Type => false,
                 PathSource::Expr(..)
                 | PathSource::Pat
                 | PathSource::Struct
-                | PathSource::TupleStruct(..) => false,
+                | PathSource::TupleStruct(..) => true,
             };
-            if !missing && !segment.has_generic_args {
+            if inferred {
+                // Do not create a parameter for patterns and expressions: type checking can infer
+                // the appropriate lifetime for us.
+                for id in node_ids {
+                    self.record_lifetime_res(
+                        id,
+                        LifetimeRes::Infer,
+                        LifetimeElisionCandidate::Named,
+                    );
+                }
                 continue;
             }
 
@@ -1666,25 +1682,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             };
             let ident = Ident::new(kw::UnderscoreLifetime, elided_lifetime_span);
 
-            let node_ids = self.r.next_node_ids(expected_lifetimes);
-            self.record_lifetime_res(
-                segment_id,
-                LifetimeRes::ElidedAnchor { start: node_ids.start, end: node_ids.end },
-                LifetimeElisionCandidate::Ignore,
-            );
-
-            if !missing {
-                // Do not create a parameter for patterns and expressions.
-                for id in node_ids {
-                    self.record_lifetime_res(
-                        id,
-                        LifetimeRes::Infer,
-                        LifetimeElisionCandidate::Named,
-                    );
-                }
-                continue;
-            }
-
             let missing_lifetime = MissingLifetime {
                 id: node_ids.start,
                 span: elided_lifetime_span,
diff --git a/src/test/ui/lifetimes/elided-lifetime-in-path-in-type-relative-expression.rs b/src/test/ui/lifetimes/elided-lifetime-in-path-in-type-relative-expression.rs
new file mode 100644
index 00000000000..b9d2711fd9c
--- /dev/null
+++ b/src/test/ui/lifetimes/elided-lifetime-in-path-in-type-relative-expression.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+struct Sqlite {}
+
+trait HasArguments<'q> {
+    type Arguments;
+}
+
+impl<'q> HasArguments<'q> for Sqlite {
+    type Arguments = std::marker::PhantomData<&'q ()>;
+}
+
+fn foo() {
+    let _ = <Sqlite as HasArguments>::Arguments::default();
+}
+
+fn main() {}