about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-06-05 07:26:30 +0000
committerbors <bors@rust-lang.org>2023-06-05 07:26:30 +0000
commitc6a3fe051a7c4284821c12ffe922087fb8662f2b (patch)
treed92e24198d1a85159023b524caf75f2e9308e421
parent2f1b7cedcf5044ba620646c6758bbb99f46b8d95 (diff)
parent5531d46c95f4a2745458790a640abc0ec198fd78 (diff)
downloadrust-c6a3fe051a7c4284821c12ffe922087fb8662f2b.tar.gz
rust-c6a3fe051a7c4284821c12ffe922087fb8662f2b.zip
Auto merge of #14978 - HKalbasi:lifetime-display, r=HKalbasi
Emit `'_` for lifetime generics in `HirDisplay`

This makes the generated code not linted by `rust_2018_idioms` lint. But that is an allow by default lint, so should we do this? Maybe we should only do this for `DisplayTarget::SourceCode`?
-rw-r--r--crates/hir-ty/src/display.rs41
-rw-r--r--crates/hir-ty/src/tests/patterns.rs2
-rw-r--r--crates/hir-ty/src/tests/regression.rs4
-rw-r--r--crates/ide-assists/src/handlers/extract_function.rs24
4 files changed, 49 insertions, 22 deletions
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index d3dba52d5f0..f90e025c7cc 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -1223,7 +1223,8 @@ fn hir_fmt_generics(
     generic_def: Option<hir_def::GenericDefId>,
 ) -> Result<(), HirDisplayError> {
     let db = f.db;
-    if parameters.len(Interner) > 0 {
+    let lifetime_args_count = generic_def.map_or(0, |g| db.generic_params(g).lifetimes.len());
+    if parameters.len(Interner) + lifetime_args_count > 0 {
         let parameters_to_write = if f.display_target.is_source_code() || f.omit_verbose_types() {
             match generic_def
                 .map(|generic_def_id| db.generic_defaults(generic_def_id))
@@ -1268,26 +1269,28 @@ fn hir_fmt_generics(
         } else {
             parameters.as_slice(Interner)
         };
-        if !parameters_to_write.is_empty() {
+        if !parameters_to_write.is_empty() || lifetime_args_count != 0 {
             write!(f, "<")?;
-
-            if f.display_target.is_source_code() {
-                let mut first = true;
-                for generic_arg in parameters_to_write {
-                    if !first {
-                        write!(f, ", ")?;
-                    }
-                    first = false;
-
-                    if generic_arg.ty(Interner).map(|ty| ty.kind(Interner)) == Some(&TyKind::Error)
-                    {
-                        write!(f, "_")?;
-                    } else {
-                        generic_arg.hir_fmt(f)?;
-                    }
+            let mut first = true;
+            for _ in 0..lifetime_args_count {
+                if !first {
+                    write!(f, ", ")?;
+                }
+                first = false;
+                write!(f, "'_")?;
+            }
+            for generic_arg in parameters_to_write {
+                if !first {
+                    write!(f, ", ")?;
+                }
+                first = false;
+                if f.display_target.is_source_code()
+                    && generic_arg.ty(Interner).map(|ty| ty.kind(Interner)) == Some(&TyKind::Error)
+                {
+                    write!(f, "_")?;
+                } else {
+                    generic_arg.hir_fmt(f)?;
                 }
-            } else {
-                f.write_joined(parameters_to_write, ", ")?;
             }
 
             write!(f, ">")?;
diff --git a/crates/hir-ty/src/tests/patterns.rs b/crates/hir-ty/src/tests/patterns.rs
index d683113d5d6..0f5a3e1752c 100644
--- a/crates/hir-ty/src/tests/patterns.rs
+++ b/crates/hir-ty/src/tests/patterns.rs
@@ -1109,7 +1109,7 @@ fn var_args() {
 #[lang = "va_list"]
 pub struct VaListImpl<'f>;
 fn my_fn(foo: ...) {}
-       //^^^ VaListImpl
+       //^^^ VaListImpl<'_>
 "#,
     );
 }
diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs
index a7b0f46e5e5..f18c953a7af 100644
--- a/crates/hir-ty/src/tests/regression.rs
+++ b/crates/hir-ty/src/tests/regression.rs
@@ -896,13 +896,13 @@ fn flush(&self) {
 "#,
         expect![[r#"
             123..127 'self': &Mutex<T>
-            150..152 '{}': MutexGuard<T>
+            150..152 '{}': MutexGuard<'_, T>
             234..238 'self': &{unknown}
             240..290 '{     ...()); }': ()
             250..251 'w': &Mutex<BufWriter>
             276..287 '*(w.lock())': BufWriter
             278..279 'w': &Mutex<BufWriter>
-            278..286 'w.lock()': MutexGuard<BufWriter>
+            278..286 'w.lock()': MutexGuard<'_, BufWriter>
         "#]],
     );
 }
diff --git a/crates/ide-assists/src/handlers/extract_function.rs b/crates/ide-assists/src/handlers/extract_function.rs
index 7587aea55cf..2a67909e637 100644
--- a/crates/ide-assists/src/handlers/extract_function.rs
+++ b/crates/ide-assists/src/handlers/extract_function.rs
@@ -5479,6 +5479,30 @@ fn $0fun_name<T: Debug>(i: T) {
     }
 
     #[test]
+    fn dont_emit_type_with_hidden_lifetime_parameter() {
+        // FIXME: We should emit a `<T: Debug>` generic argument for the generated function
+        check_assist(
+            extract_function,
+            r#"
+struct Struct<'a, T>(&'a T);
+fn func<T: Debug>(i: Struct<'_, T>) {
+    $0foo(i);$0
+}
+"#,
+            r#"
+struct Struct<'a, T>(&'a T);
+fn func<T: Debug>(i: Struct<'_, T>) {
+    fun_name(i);
+}
+
+fn $0fun_name(i: Struct<'_, T>) {
+    foo(i);
+}
+"#,
+        );
+    }
+
+    #[test]
     fn preserve_generics_from_body() {
         check_assist(
             extract_function,