Repository: intellij-rust/intellij-rust
Issue: Proc macro not expanding correctly, Access is denied. (os error 5)

## Environment

* **IntelliJ Rust plugin version:** 0.4.161.4292-213
* **Rust toolchain version:** rustc 1.59.0-nightly (0fb1c371d 2021-12-06)
* **IDE name and version:** Clion 2021.3 #CL-213.5744.254
* **Operating system:** Windows 10 and OSX Monterey

* **org.rust.cargo.evaluate.build.scripts:** Enabled
* **org.rust.macros.proc:** Enabled

## Problem description

Macros for sqlx::query! and sqlx::query_as! are not expanding correctly. Recieving the following error when using "Show recursive macro expansion" on both windows and mac

Note: When opening Clion on windows I instead chose "Run as administrator" this error disappears and I then get the following error -> #8236

```rs
{
    ::std::compile_error!("failed to open path target\\\\sqlx\\\\query-e7f6c011776e8db7cd330b54174fd76f7d0216b612387a5ffcfb81e6f0919683.json: Access is denied. (os error 5)" )
}
```


## Steps to reproduce

https://github.com/longfellowone/rustpluginerr

`git clone https://github.com/longfellowone/rustpluginerr.git`

`cd rustpluginerr`

`git checkout d771b883e9633fd508e144efd211373d60e68d52`

`docker-compose up -d`

`cargo install sqlx-cli` (If not already installed)

`sqlx migrate run`

`org.rust.cargo.evaluate.build.scripts` (Enable in Clion experimental features)

`org.rust.macros.proc` (Enable in Clion experimental features)

After project has finish indexing - In `main.rs` click `query_as!` then ALT+ENTER `Show recursive macro expansion`

You can toggle `SQLX_OFFLINE` in the `.env` (will need to restart/re-index after change)

With `SQLX_OFFLINE=false` (or commented out) you get the error above

With `SQLX_OFFLINE=true` you get the error below. (Note `DATABASE_URL` has been set in .env)

```
{
    ::std::compile_error!("`DATABASE_URL` must be set, or `cargo sqlx prepare` must have been run and sqlx-data.json must exist, to use query macros" )
}
```



Changed files:
src/main/kotlin/org/rust/lang/core/macros/proc/ProcMacroServerPool.kt, src/main/kotlin/org/rust/cargo/toolchain/impl/CargoMetadata.kt

diff --git a/src/main/kotlin/org/rust/cargo/toolchain/impl/CargoMetadata.kt b/src/main/kotlin/org/rust/cargo/toolchain/impl/CargoMetadata.kt
index 6ebf2edba..705760a28 100644
--- a/src/main/kotlin/org/rust/cargo/toolchain/impl/CargoMetadata.kt
+++ b/src/main/kotlin/org/rust/cargo/toolchain/impl/CargoMetadata.kt
@@ -21,6 +21,7 @@ import org.rust.openapiext.RsPathManager
 import org.rust.openapiext.findFileByMaybeRelativePath
 import org.rust.stdext.HashCode
 import org.rust.stdext.mapToSet
+import java.io.File
 import java.io.IOException
 import java.nio.file.Files
 import java.nio.file.Path
@@ -402,6 +403,9 @@ object CargoMetadata {
             "CARGO_PKG_LICENSE" to license.orEmpty(),
             "CARGO_PKG_LICENSE_FILE" to license_file.orEmpty(),
             "CARGO_CRATE_NAME" to name.replace('-', '_'),
+            // A hack to make `sqlx` use correct `target` directory. Really, we should just set
+            // PWD for proc macro expander process to `rootPath`
+            "CARGO_TARGET_DIR" to rootPath + File.separator + "target"
         )
 
         val outDir = buildScriptMessage?.out_dir
diff --git a/src/main/kotlin/org/rust/lang/core/macros/proc/ProcMacroServerPool.kt b/src/main/kotlin/org/rust/lang/core/macros/proc/ProcMacroServerPool.kt
index cdcbfb763..ea7942fbb 100644
--- a/src/main/kotlin/org/rust/lang/core/macros/proc/ProcMacroServerPool.kt
+++ b/src/main/kotlin/org/rust/lang/core/macros/proc/ProcMacroServerPool.kt
@@ -20,6 +20,7 @@ import com.intellij.openapi.diagnostic.debug
 import com.intellij.openapi.progress.ProcessCanceledException
 import com.intellij.openapi.util.Disposer
 import com.intellij.util.concurrency.AppExecutorUtil
+import com.intellij.util.io.createDirectories
 import org.rust.cargo.toolchain.BacktraceMode
 import org.rust.cargo.toolchain.RsToolchainBase
 import org.rust.cargo.toolchain.wsl.RsWslToolchain
@@ -306,13 +307,25 @@ private class ProcMacroServerProcess private constructor(
     }
 
     companion object {
+        private val workingDir: Path by lazy {
+            try {
+                RsPathManager.tempPluginDirInSystem().resolve("proc-macro-expander-pwd").apply {
+                    createDirectories()
+                    cleanDirectory()
+                }
+            } catch (e: IOException) {
+                MACRO_LOG.error(e)
+                Paths.get(".")
+            }
+        }
+
         @Throws(ProcessCreationException::class)
         fun createAndRun(toolchain: RsToolchainBase, expanderExecutable: Path): ProcMacroServerProcess {
             MACRO_LOG.debug { "Starting proc macro expander process $expanderExecutable" }
 
-           val commandLine = toolchain.createGeneralCommandLine(
+            val commandLine = toolchain.createGeneralCommandLine(
                 expanderExecutable,
-                Paths.get("."),
+                workingDir,
                 null,
                 BacktraceMode.NO,
                 // Let a proc macro know that it is ran from intellij-rust