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

Issue:
"Failed to set the current working dir to Cargo.toml" on `tonic`
Run `rust-analyzer analysis-stats .` on `tonic` (tested at 75e5201306ab2e968afcca8efd9dbd1ea8abbbe6):

```
Database loaded:     16.24s, 1248minstr, 32mb (metadata 2.02s, 28minstr, 930kb; build 14.01s, 10minstr, 67kb)
  item trees: 264
Item Tree Collection: 132.28ms, 1381minstr, 12mb
Failed to set the current working dir to /home/me/tonic/./Cargo.toml. Error: Os { code: 20, kind: NotADirectory, message: "Not a directory" }
Failed to set the current working dir to /home/me/tonic/./Cargo.toml. Error: Os { code: 20, kind: NotADirectory, message: "Not a directory" }
  crates: 124, mods: 558, decls: 8667, bodies: 7053, adts: 742, consts: 264
Item Collection:     8.34s, 69ginstr, 364mb
Body lowering:       1.78s, 14ginstr, 100mb                                                                                           
```

Pull request:
minor: Fix cwd used for proc macro expansion
Fixes #17980.

Patch:
diff --git a/LICENSE-APACHE b/LICENSE-APACHE
index 1b5ec8b78e..16fe87b06e 100644
--- a/LICENSE-APACHE
+++ b/LICENSE-APACHE
@@ -174,3 +174,28 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
    of your accepting any such warranty or additional liability.
 
 END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "[]"
+   replaced with your own identifying information. (Don't include
+   the brackets!)  The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+	http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs b/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs
deleted file mode 100644
index eedb2ea3b9..0000000000
--- a/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs
+++ /dev/null
@@ -1,256 +0,0 @@
-use ide_db::assists::{AssistId, AssistKind};
-use syntax::{
-    ast::{self, make},
-    ted, AstNode, T,
-};
-
-use crate::{AssistContext, Assists};
-
-// Assist: toggle_macro_delimiter
-//
-// Change macro delimiters in the order of `( -> { -> [ -> (`.
-//
-// ```
-// macro_rules! sth {
-//     () => {};
-// }
-//
-// sth!$0( );
-// ```
-// ->
-// ```
-// macro_rules! sth {
-//     () => {};
-// }
-//
-// sth!{ }
-// ```
-pub(crate) fn toggle_macro_delimiter(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
-    #[derive(Debug)]
-    enum MacroDelims {
-        LPar,
-        RPar,
-        LBra,
-        RBra,
-        LCur,
-        RCur,
-    }
-
-    let makro = ctx.find_node_at_offset::<ast::MacroCall>()?.clone_for_update();
-    let makro_text_range = makro.syntax().text_range();
-
-    let cursor_offset = ctx.offset();
-    let semicolon = makro.semicolon_token();
-    let token_tree = makro.token_tree()?;
-
-    let ltoken = token_tree.left_delimiter_token()?;
-    let rtoken = token_tree.right_delimiter_token()?;
-
-    if !ltoken.text_range().contains(cursor_offset) && !rtoken.text_range().contains(cursor_offset)
-    {
-        return None;
-    }
-
-    let token = match ltoken.kind() {
-        T!['{'] => MacroDelims::LCur,
-        T!['('] => MacroDelims::LPar,
-        T!['['] => MacroDelims::LBra,
-        T!['}'] => MacroDelims::RBra,
-        T![')'] => MacroDelims::RPar,
-        T!['}'] => MacroDelims::RCur,
-        _ => return None,
-    };
-
-    acc.add(
-        AssistId("toggle_macro_delimiter", AssistKind::Refactor),
-        match token {
-            MacroDelims::LPar => "Replace delimiters with braces",
-            MacroDelims::RPar => "Replace delimiters with braces",
-            MacroDelims::LBra => "Replace delimiters with parentheses",
-            MacroDelims::RBra => "Replace delimiters with parentheses",
-            MacroDelims::LCur => "Replace delimiters with brackets",
-            MacroDelims::RCur => "Replace delimiters with brackets",
-        },
-        token_tree.syntax().text_range(),
-        |builder| {
-            match token {
-                MacroDelims::LPar | MacroDelims::RPar => {
-                    ted::replace(ltoken, make::token(T!['{']));
-                    ted::replace(rtoken, make::token(T!['}']));
-                    if let Some(sc) = semicolon {
-                        ted::remove(sc);
-                    }
-                }
-                MacroDelims::LBra | MacroDelims::RBra => {
-                    ted::replace(ltoken, make::token(T!['(']));
-                    ted::replace(rtoken, make::token(T![')']));
-                }
-                MacroDelims::LCur | MacroDelims::RCur => {
-                    ted::replace(ltoken, make::token(T!['[']));
-                    ted::replace(rtoken, make::token(T![']']));
-                }
-            }
-            builder.replace(makro_text_range, makro.syntax().text());
-        },
-    )
-}
-
-#[cfg(test)]
-mod tests {
-    use crate::tests::{check_assist, check_assist_not_applicable};
-
-    use super::*;
-
-    #[test]
-    fn test_par() {
-        check_assist(
-            toggle_macro_delimiter,
-            r#"
-macro_rules! sth {
-    () => {};
-}
-
-sth!$0( );
-            "#,
-            r#"
-macro_rules! sth {
-    () => {};
-}
-
-sth!{ }
-            "#,
-        )
-    }
-
-    #[test]
-    fn test_braces() {
-        check_assist(
-            toggle_macro_delimiter,
-            r#"
-macro_rules! sth {
-    () => {};
-}
-
-sth!$0{ };
-            "#,
-            r#"
-macro_rules! sth {
-    () => {};
-}
-
-sth![ ];
-            "#,
-        )
-    }
-
-    #[test]
-    fn test_brackets() {
-        check_assist(
-            toggle_macro_delimiter,
-            r#"
-macro_rules! sth {
-    () => {};
-}
-
-sth!$0[ ];
-            "#,
-            r#"
-macro_rules! sth {
-    () => {};
-}
-
-sth!( );
-            "#,
-        )
-    }
-
-    #[test]
-    fn test_indent() {
-        check_assist(
-            toggle_macro_delimiter,
-            r#"
-mod abc {
-    macro_rules! sth {
-        () => {};
-    }
-
-    sth!$0{ };
-}
-            "#,
-            r#"
-mod abc {
-    macro_rules! sth {
-        () => {};
-    }
-
-    sth![ ];
-}
-            "#,
-        )
-    }
-
-    #[test]
-    fn test_unrelated_par() {
-        check_assist_not_applicable(
-            toggle_macro_delimiter,
-            r#"
-macro_rules! prt {
-    ($e:expr) => {{
-        println!("{}", stringify!{$e});
-    }};
-}
-
-prt!(($03 + 5));
-
-            "#,
-        )
-    }
-
-    #[test]
-    fn test_longer_macros() {
-        check_assist(
-            toggle_macro_delimiter,
-            r#"
-macro_rules! prt {
-    ($e:expr) => {{
-        println!("{}", stringify!{$e});
-    }};
-}
-
-prt!$0((3 + 5));
-"#,
-            r#"
-macro_rules! prt {
-    ($e:expr) => {{
-        println!("{}", stringify!{$e});
-    }};
-}
-
-prt!{(3 + 5)}
-"#,
-        )
-    }
-
-    // FIXME @alibektas : Inner macro_call is not seen as such. So this doesn't work.
-    #[test]
-    fn test_nested_macros() {
-        check_assist_not_applicable(
-            toggle_macro_delimiter,
-            r#"
-macro_rules! prt {
-    ($e:expr) => {{
-        println!("{}", stringify!{$e});
-    }};
-}
-
-macro_rules! abc {
-    ($e:expr) => {{
-        println!("{}", stringify!{$e});
-    }};
-}
-
-prt!{abc!($03 + 5)};
-"#,
-        )
-    }
-}
diff --git a/crates/ide-assists/src/lib.rs b/crates/ide-assists/src/lib.rs
index b97f0f2739..a9399ba6b7 100644
--- a/crates/ide-assists/src/lib.rs
+++ b/crates/ide-assists/src/lib.rs
@@ -213,7 +213,6 @@ mod handlers {
     mod term_search;
     mod toggle_async_sugar;
     mod toggle_ignore;
-    mod toggle_macro_delimiter;
     mod unmerge_match_arm;
     mod unmerge_use;
     mod unnecessary_async;
@@ -344,7 +343,6 @@ mod handlers {
             split_import::split_import,
             term_search::term_search,
             toggle_ignore::toggle_ignore,
-            toggle_macro_delimiter::toggle_macro_delimiter,
             unmerge_match_arm::unmerge_match_arm,
             unmerge_use::unmerge_use,
             unnecessary_async::unnecessary_async,
diff --git a/crates/project-model/src/env.rs b/crates/project-model/src/env.rs
index ec0f94b8f0..ff9d2035f6 100644
--- a/crates/project-model/src/env.rs
+++ b/crates/project-model/src/env.rs
@@ -65,7 +65,7 @@ pub(crate) fn inject_rustc_tool_env(
     // NOTE: Technically we should set this for all crates, but that will worsen the deduplication
     // logic so for now just keeping it proc-macros ought to be fine.
     if kind.is_proc_macro() {
-        env.set("CARGO_RUSTC_CURRENT_DIR", cargo.manifest_path().to_string());
+        env.set("CARGO_RUSTC_CURRENT_DIR", cargo.manifest_path().parent().to_string());
     }
 }
 
diff --git a/crates/salsa/LICENSE-APACHE b/crates/salsa/LICENSE-APACHE
index 1b5ec8b78e..16fe87b06e 100644
--- a/crates/salsa/LICENSE-APACHE
+++ b/crates/salsa/LICENSE-APACHE
@@ -174,3 +174,28 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
    of your accepting any such warranty or additional liability.
 
 END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "[]"
+   replaced with your own identifying information. (Don't include
+   the brackets!)  The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+	http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.


Test patch:
diff --git a/crates/ide-assists/src/tests/generated.rs b/crates/ide-assists/src/tests/generated.rs
index 595ce1affb..a2287b2977 100644
--- a/crates/ide-assists/src/tests/generated.rs
+++ b/crates/ide-assists/src/tests/generated.rs
@@ -3091,27 +3091,6 @@ fn arithmetics {
     )
 }
 
-#[test]
-fn doctest_toggle_macro_delimiter() {
-    check_doc_test(
-        "toggle_macro_delimiter",
-        r#####"
-macro_rules! sth {
-    () => {};
-}
-
-sth!$0( );
-"#####,
-        r#####"
-macro_rules! sth {
-    () => {};
-}
-
-sth!{ }
-"#####,
-    )
-}
-
 #[test]
 fn doctest_unmerge_match_arm() {
     check_doc_test(
diff --git a/crates/project-model/src/tests.rs b/crates/project-model/src/tests.rs
index 920ee7bd4f..f540bb94c1 100644
--- a/crates/project-model/src/tests.rs
+++ b/crates/project-model/src/tests.rs
@@ -278,7 +278,7 @@ fn crate_graph_dedup() {
     assert_eq!(regex_crate_graph.iter().count(), 60);
 
     crate_graph.extend(regex_crate_graph, &mut regex_proc_macros, |(_, a), (_, b)| a == b);
-    assert_eq!(crate_graph.iter().count(), 119);
+    assert_eq!(crate_graph.iter().count(), 118);
 }
 
 #[test]