Repository: intellij-rust/intellij-rust
Issue: Name resolution caches are not invalidated properly

## Environment

* **IntelliJ Rust plugin version:** 0.3.146.3798-211-nightly
* **Rust toolchain version:** 1.51.0 (2fd73fabe 2021-03-23) x86_64-apple-darwin
* **IDE name and version:** IntelliJ IDEA 2021.1 Ultimate Edition (IU-211.6693.111)
* **Operating system:** macOS 10.15.6
* **Macro expansion engine:** new
* **Name resolution engine:** new

## Problem description
Name resolution works unexpectedly after changing library name in `Cargo.toml`

## Steps to reproduce
- create the following project:

`Cargo.toml`
```toml
[package]
name = "rust_project"
version = "0.1.0"
authors = []
edition = "2018"

[lib]
name = "lib"
proc-macro = true
```

`src/lib.rs`
```rust
extern crate proc_macro;
use proc_macro::TokenStream;
#[proc_macro_attribute]
pub fn foo(attr: TokenStream, item: TokenStream) -> TokenStream { item }
```

`src/main.rs`
```rust
use lib::foo;

#[lib::foo]
fn baz() {}

fn main() {}
```

* change library name in `Cargo.toml` from `lib` to `libb`, for example, and invoke `Refresh Cargo projects` actions. After that, `Goto definition` for all references in `use lib::foo`  and `lib` in `#[lib::foo]` works as previously. Only structured change (for example, the addition of new function) helps to drop old resolve info.

* make revert change, i.e. change `libb` from `Cargo.toml` to `lib` again and launch `Refresh Cargo projects`. `Goto definition` action works only for `foo` reference in `#[lib::foo]`.

_Originally posted by @Undin in https://github.com/intellij-rust/intellij-rust/issues/7119#issuecomment-822358187_

Changed files:
src/test/kotlin/org/rustSlowTests/lang/resolve/CargoProjectResolveTest.kt, src/main/kotlin/org/rust/lang/core/resolve2/CrateModificationTracker.kt

diff --git a/src/main/kotlin/org/rust/lang/core/resolve2/CrateModificationTracker.kt b/src/main/kotlin/org/rust/lang/core/resolve2/CrateModificationTracker.kt
index 2383170a1..331adfcea 100644
--- a/src/main/kotlin/org/rust/lang/core/resolve2/CrateModificationTracker.kt
+++ b/src/main/kotlin/org/rust/lang/core/resolve2/CrateModificationTracker.kt
@@ -23,6 +23,7 @@ import org.rust.openapiext.checkReadAccessAllowed
 import org.rust.openapiext.testAssert
 import org.rust.openapiext.toPsiFile
 import org.rust.stdext.mapNotNullToSet
+import org.rust.stdext.mapToSet
 
 /**
  * Calculates new value of [DefMapHolder.shouldRebuild] field.
@@ -89,6 +90,7 @@ data class CrateMetaData(
     val env: Map<String, String>,
     // TODO: Probably we need to store modificationStamp of DefMap for each dependency
     private val dependencies: Set<CratePersistentId>,
+    private val dependenciesNames: Set<String>,
     val procMacroArtifact: CargoWorkspaceData.ProcMacroArtifact?,
 ) {
     constructor(crate: Crate) : this(
@@ -97,6 +99,7 @@ data class CrateMetaData(
         cfgOptions = crate.cfgOptions,
         env = crate.env,
         dependencies = crate.flatDependencies.mapNotNullToSet { it.id },
+        dependenciesNames = crate.dependencies.mapToSet { it.normName },
         procMacroArtifact = crate.procMacroArtifact
     )
 }
diff --git a/src/test/kotlin/org/rustSlowTests/lang/resolve/CargoProjectResolveTest.kt b/src/test/kotlin/org/rustSlowTests/lang/resolve/CargoProjectResolveTest.kt
index af2b00a6a..8a127ffb9 100644
--- a/src/test/kotlin/org/rustSlowTests/lang/resolve/CargoProjectResolveTest.kt
+++ b/src/test/kotlin/org/rustSlowTests/lang/resolve/CargoProjectResolveTest.kt
@@ -11,6 +11,7 @@ import com.intellij.openapi.roots.ModuleRootModificationUtil
 import com.intellij.openapi.roots.ex.ProjectRootManagerEx
 import com.intellij.openapi.util.SystemInfo
 import com.intellij.openapi.util.io.FileUtil
+import com.intellij.openapi.vfs.VfsUtil
 import com.intellij.testFramework.fixtures.impl.TempDirTestFixtureImpl
 import org.rust.*
 import org.rust.cargo.RsWithToolchainTestBase
@@ -1032,6 +1033,74 @@ class CargoProjectResolveTest : RsWithToolchainTestBase() {
         checkReferenceIsResolved<RsPath>("build.rs")
     }
 
+    fun `test change crate name`() = buildProject {
+        toml("Cargo.toml", """
+            [package]
+            name = "hello"
+            version = "0.1.0"
+
+            [lib]
+            name = "foo1"
+        """)
+        dir("src") {
+            rust("main.rs", """
+                fn main() {
+                    foo2::func();
+                }       //^
+            """)
+            rust("lib.rs", "pub fn func() {}")
+        }
+    }.run {
+        val projectManifest = cargoProjectDirectory.findFileByRelativePath("Cargo.toml")!!
+        checkReferenceIsResolved<RsPath>("src/main.rs", shouldNotResolve = true)
+        runWriteAction {
+            VfsUtil.saveText(projectManifest, VfsUtil.loadText(projectManifest).replace("foo1", "foo2"))
+        }
+        project.testCargoProjects.refreshAllProjectsSync()
+        checkReferenceIsResolved<RsPath>("src/main.rs")
+    }
+
+    fun `test change dependency name`() = buildProject {
+        toml("Cargo.toml", """
+            [package]
+            name = "hello"
+            version = "0.1.0"
+
+            [dependencies]
+            foo1 = { path = "./foo", package = "foo" }
+        """)
+
+        dir("src") {
+            rust("main.rs", """
+                fn main() {
+                    foo2::func();
+                }       //^
+            """)
+        }
+
+        dir("foo") {
+            toml("Cargo.toml", """
+                [package]
+                name = "foo"
+                version = "0.1.0"
+            """)
+
+            dir("src") {
+                rust("lib.rs", "pub fn func() {}")
+            }
+        }
+    }.run {
+        val projectManifest = cargoProjectDirectory.findFileByRelativePath("Cargo.toml")!!
+        checkReferenceIsResolved<RsPath>("src/main.rs", shouldNotResolve = true)
+        runWriteAction {
+            val textOld = """foo1 = { path = "./foo", package = "foo" }"""
+            val textNew = """foo2 = { path = "./foo", package = "foo" }"""
+            VfsUtil.saveText(projectManifest, VfsUtil.loadText(projectManifest).replace(textOld, textNew))
+        }
+        project.testCargoProjects.refreshAllProjectsSync()
+        checkReferenceIsResolved<RsPath>("src/main.rs")
+    }
+
     private fun excludeDirectoryFromIndex(path: String) {
         runWriteAction {
             ProjectRootManagerEx.getInstanceEx(project).mergeRootsChangesDuring {