Repository: rust-analyzer/rust-analyzer (rust)

Issue:
Introdce named lifetime does not work if there are already some type parameters
```rust
impl<I> fmt::Display for SepByBuilder<'_/*cursor here*/, I>
where
    I: Iterator,
    I::Item: fmt::Display,
{
```

Source: https://github.com/rust-analyzer/rust-analyzer/blob/b12d4316cc5ddd7f540304420a9cd63ed424173e/crates/ra_assists/src/handlers/introduce_named_lifetime.rs

cc @jbalint 

Pull request description:
introduce_named_lifetime assist wasn't applicable when type parameter
followed anonymous lifetime token

(fixes #4684)

Patch:
diff --git a/crates/ra_assists/src/handlers/introduce_named_lifetime.rs b/crates/ra_assists/src/handlers/introduce_named_lifetime.rs
index beb5b7366d..28fcbc9ba6 100644
--- a/crates/ra_assists/src/handlers/introduce_named_lifetime.rs
+++ b/crates/ra_assists/src/handlers/introduce_named_lifetime.rs
@@ -41,8 +41,6 @@ pub(crate) fn introduce_named_lifetime(acc: &mut Assists, ctx: &AssistContext) -
     if let Some(fn_def) = lifetime_token.ancestors().find_map(ast::FnDef::cast) {
         generate_fn_def_assist(acc, &fn_def, lifetime_token.text_range())
     } else if let Some(impl_def) = lifetime_token.ancestors().find_map(ast::ImplDef::cast) {
-        // only allow naming the last anonymous lifetime
-        lifetime_token.next_token().filter(|tok| tok.kind() == SyntaxKind::R_ANGLE)?;
         generate_impl_def_assist(acc, &impl_def, lifetime_token.text_range())
     } else {
         None
@@ -190,6 +188,23 @@ mod tests {
         );
     }
 
+    #[test]
+    fn test_impl_with_other_type_param() {
+        check_assist(
+            introduce_named_lifetime,
+            "impl<I> fmt::Display for SepByBuilder<'_<|>, I>
+        where
+            I: Iterator,
+            I::Item: fmt::Display,
+        {",
+            "impl<I, 'a> fmt::Display for SepByBuilder<'a, I>
+        where
+            I: Iterator,
+            I::Item: fmt::Display,
+        {",
+        )
+    }
+
     #[test]
     fn test_example_case_cursor_before_tick() {
         check_assist(
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs
index 4512448e02..e84efe2abd 100644
--- a/crates/ra_hir_def/src/path.rs
+++ b/crates/ra_hir_def/src/path.rs
@@ -273,7 +273,7 @@ impl From<Name> for ModPath {
 impl Display for ModPath {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let mut first_segment = true;
-        let mut add_segment = |s| -> fmt::Result {
+        let mut add_segment = |s| {
             if !first_segment {
                 f.write_str("::")?;
             }
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs
index 9c14b954af..67a924de53 100644
--- a/crates/ra_parser/src/grammar/items.rs
+++ b/crates/ra_parser/src/grammar/items.rs
@@ -118,17 +118,7 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul
         && p.at_contextual_kw("default")
         && (match p.nth(1) {
             T![impl] => true,
-            T![unsafe] => {
-                // test default_unsafe_impl
-                // default unsafe impl Foo {}
-                if p.nth(2) == T![impl] {
-                    p.bump_remap(T![default]);
-                    p.bump(T![unsafe]);
-                    has_mods = true;
-                }
-                false
-            }
-            T![fn] | T![type] | T![const] => {
+            T![fn] | T![type] => {
                 if let ItemFlavor::Mod = flavor {
                     true
                 } else {
@@ -208,9 +198,6 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul
         //     default type T = Bar;
         //     default fn foo() {}
         // }
-        T![const] => {
-            consts::const_def(p, m);
-        }
 
         // test unsafe_default_impl
         // unsafe default impl Foo {}
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml
index 458089e539..65b487db3b 100644
--- a/crates/rust-analyzer/Cargo.toml
+++ b/crates/rust-analyzer/Cargo.toml
@@ -10,7 +10,7 @@ doctest = false
 
 [[bin]]
 name = "rust-analyzer"
-path = "src/bin/main.rs"
+path = "./src/bin/main.rs"
 
 [dependencies]
 anyhow = "1.0.26"
@@ -32,7 +32,7 @@ threadpool = "1.7.1"
 
 stdx = { path = "../stdx" }
 
-lsp-server = "0.3.2"
+lsp-server = "0.3.1"
 ra_flycheck = { path = "../ra_flycheck" }
 ra_ide = { path = "../ra_ide" }
 ra_prof = { path = "../ra_prof" }
diff --git a/docs/dev/README.md b/docs/dev/README.md
index 194a40e15c..1de5a2aab1 100644
--- a/docs/dev/README.md
+++ b/docs/dev/README.md
@@ -170,7 +170,7 @@ https://www.tedinski.com/2018/02/06/system-boundaries.html
 
 We separate import groups with blank lines
 
-```rust
+```
 mod x;
 mod y;
 
@@ -195,7 +195,7 @@ Put `struct`s and `enum`s first, functions and impls last.
 
 Do
 
-```rust
+```
 // Good
 struct Foo {
   bars: Vec<Bar>
@@ -206,7 +206,7 @@ struct Bar;
 
 rather than
 
-```rust
+```
 // Not as good
 struct Bar;
 


Test patch:
diff --git a/crates/ra_syntax/test_data/parser/err/0043_default_const.rast b/crates/ra_syntax/test_data/parser/err/0043_default_const.rast
deleted file mode 100644
index 8eb583ef85..0000000000
--- a/crates/ra_syntax/test_data/parser/err/0043_default_const.rast
+++ /dev/null
@@ -1,40 +0,0 @@
-SOURCE_FILE@0..39
-  TRAIT_DEF@0..38
-    TRAIT_KW@0..5 "trait"
-    WHITESPACE@5..6 " "
-    NAME@6..7
-      IDENT@6..7 "T"
-    WHITESPACE@7..8 " "
-    ITEM_LIST@8..38
-      L_CURLY@8..9 "{"
-      WHITESPACE@9..12 "\n  "
-      MACRO_CALL@12..19
-        PATH@12..19
-          PATH_SEGMENT@12..19
-            NAME_REF@12..19
-              IDENT@12..19 "default"
-      WHITESPACE@19..20 " "
-      CONST_DEF@20..36
-        CONST_KW@20..25 "const"
-        WHITESPACE@25..26 " "
-        NAME@26..27
-          IDENT@26..27 "f"
-        COLON@27..28 ":"
-        WHITESPACE@28..29 " "
-        PATH_TYPE@29..31
-          PATH@29..31
-            PATH_SEGMENT@29..31
-              NAME_REF@29..31
-                IDENT@29..31 "u8"
-        WHITESPACE@31..32 " "
-        EQ@32..33 "="
-        WHITESPACE@33..34 " "
-        LITERAL@34..35
-          INT_NUMBER@34..35 "0"
-        SEMICOLON@35..36 ";"
-      WHITESPACE@36..37 "\n"
-      R_CURLY@37..38 "}"
-  WHITESPACE@38..39 "\n"
-error 19..19: expected BANG
-error 19..19: expected `{`, `[`, `(`
-error 19..19: expected SEMICOLON
diff --git a/crates/ra_syntax/test_data/parser/err/0043_default_const.rs b/crates/ra_syntax/test_data/parser/err/0043_default_const.rs
deleted file mode 100644
index 80f15474a5..0000000000
--- a/crates/ra_syntax/test_data/parser/err/0043_default_const.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-trait T {
-  default const f: u8 = 0;
-}
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0010_wrong_order_fns.rast b/crates/ra_syntax/test_data/parser/inline/err/0010_wrong_order_fns.rast
index 53f7ebaf9a..9be441110f 100644
--- a/crates/ra_syntax/test_data/parser/inline/err/0010_wrong_order_fns.rast
+++ b/crates/ra_syntax/test_data/parser/inline/err/0010_wrong_order_fns.rast
@@ -17,29 +17,23 @@ SOURCE_FILE@0..50
       L_CURLY@22..23 "{"
       R_CURLY@23..24 "}"
   WHITESPACE@24..25 "\n"
-  CONST_DEF@25..46
+  ERROR@25..31
     UNSAFE_KW@25..31 "unsafe"
-    WHITESPACE@31..32 " "
+  WHITESPACE@31..32 " "
+  FN_DEF@32..49
     CONST_KW@32..37 "const"
     WHITESPACE@37..38 " "
-    ERROR@38..40
-      FN_KW@38..40 "fn"
+    FN_KW@38..40 "fn"
     WHITESPACE@40..41 " "
-    PATH_TYPE@41..46
-      PATH@41..46
-        PATH_SEGMENT@41..46
-          NAME_REF@41..44
-            IDENT@41..44 "bar"
-          PARAM_LIST@44..46
-            L_PAREN@44..45 "("
-            R_PAREN@45..46 ")"
-  WHITESPACE@46..47 " "
-  ERROR@47..49
-    L_CURLY@47..48 "{"
-    R_CURLY@48..49 "}"
+    NAME@41..44
+      IDENT@41..44 "bar"
+    PARAM_LIST@44..46
+      L_PAREN@44..45 "("
+      R_PAREN@45..46 ")"
+    WHITESPACE@46..47 " "
+    BLOCK_EXPR@47..49
+      L_CURLY@47..48 "{"
+      R_CURLY@48..49 "}"
   WHITESPACE@49..50 "\n"
 error 6..6: expected existential, fn, trait or impl
-error 38..38: expected a name
-error 40..40: expected COLON
-error 46..46: expected SEMICOLON
-error 47..47: expected an item
+error 31..31: expected existential, fn, trait or impl
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0163_default_unsafe_impl.rast b/crates/ra_syntax/test_data/parser/inline/ok/0163_default_unsafe_impl.rast
deleted file mode 100644
index a9eda56681..0000000000
--- a/crates/ra_syntax/test_data/parser/inline/ok/0163_default_unsafe_impl.rast
+++ /dev/null
@@ -1,18 +0,0 @@
-SOURCE_FILE@0..27
-  IMPL_DEF@0..26
-    DEFAULT_KW@0..7 "default"
-    WHITESPACE@7..8 " "
-    UNSAFE_KW@8..14 "unsafe"
-    WHITESPACE@14..15 " "
-    IMPL_KW@15..19 "impl"
-    WHITESPACE@19..20 " "
-    PATH_TYPE@20..23
-      PATH@20..23
-        PATH_SEGMENT@20..23
-          NAME_REF@20..23
-            IDENT@20..23 "Foo"
-    WHITESPACE@23..24 " "
-    ITEM_LIST@24..26
-      L_CURLY@24..25 "{"
-      R_CURLY@25..26 "}"
-  WHITESPACE@26..27 "\n"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0163_default_unsafe_impl.rs b/crates/ra_syntax/test_data/parser/inline/ok/0163_default_unsafe_impl.rs
deleted file mode 100644
index ba0998ff4d..0000000000
--- a/crates/ra_syntax/test_data/parser/inline/ok/0163_default_unsafe_impl.rs
+++ /dev/null
@@ -1,1 +0,0 @@
-default unsafe impl Foo {}
diff --git a/crates/ra_syntax/test_data/parser/ok/0066_default_const.rast b/crates/ra_syntax/test_data/parser/ok/0066_default_const.rast
deleted file mode 100644
index dab0247ee6..0000000000
--- a/crates/ra_syntax/test_data/parser/ok/0066_default_const.rast
+++ /dev/null
@@ -1,44 +0,0 @@
-SOURCE_FILE@0..46
-  IMPL_DEF@0..45
-    IMPL_KW@0..4 "impl"
-    WHITESPACE@4..5 " "
-    PATH_TYPE@5..6
-      PATH@5..6
-        PATH_SEGMENT@5..6
-          NAME_REF@5..6
-            IDENT@5..6 "T"
-    WHITESPACE@6..7 " "
-    FOR_KW@7..10 "for"
-    WHITESPACE@10..11 " "
-    PATH_TYPE@11..14
-      PATH@11..14
-        PATH_SEGMENT@11..14
-          NAME_REF@11..14
-            IDENT@11..14 "Foo"
-    WHITESPACE@14..15 " "
-    ITEM_LIST@15..45
-      L_CURLY@15..16 "{"
-      WHITESPACE@16..19 "\n  "
-      CONST_DEF@19..43
-        DEFAULT_KW@19..26 "default"
-        WHITESPACE@26..27 " "
-        CONST_KW@27..32 "const"
-        WHITESPACE@32..33 " "
-        NAME@33..34
-          IDENT@33..34 "f"
-        COLON@34..35 ":"
-        WHITESPACE@35..36 " "
-        PATH_TYPE@36..38
-          PATH@36..38
-            PATH_SEGMENT@36..38
-              NAME_REF@36..38
-                IDENT@36..38 "u8"
-        WHITESPACE@38..39 " "
-        EQ@39..40 "="
-        WHITESPACE@40..41 " "
-        LITERAL@41..42
-          INT_NUMBER@41..42 "0"
-        SEMICOLON@42..43 ";"
-      WHITESPACE@43..44 "\n"
-      R_CURLY@44..45 "}"
-  WHITESPACE@45..46 "\n"
diff --git a/crates/ra_syntax/test_data/parser/ok/0066_default_const.rs b/crates/ra_syntax/test_data/parser/ok/0066_default_const.rs
deleted file mode 100644
index dfb3b92dca..0000000000
--- a/crates/ra_syntax/test_data/parser/ok/0066_default_const.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-impl T for Foo {
-  default const f: u8 = 0;
-}