Repository: rust-lang/rust-analyzer
Pull request #13116 (2022-08-25 18:32:01)

Make use of NoHash hashing for FileId and CrateId
Both of these are mere integers so there is nothing to hash here.

Ideally we would use this for `la_arena::Idx` too, but that doesn't work due to the orphan rule, and `la_arena` is unfortunately a public library so we can't really do much here... Unless we remove the trait restriction but I'd like not to


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 8f4a17dc5c..9f10d92c4e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -704,6 +704,7 @@ dependencies = [
  "ide-db",
  "itertools",
  "parser",
+ "stdx",
  "syntax",
  "test-utils",
  "text-edit",
@@ -1921,6 +1922,7 @@ dependencies = [
  "indexmap",
  "paths",
  "rustc-hash",
+ "stdx",
 ]
 
 [[package]]
diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs
index 9580ce8007..b388e47dee 100644
--- a/crates/base-db/src/input.rs
+++ b/crates/base-db/src/input.rs
@@ -9,10 +9,11 @@
 use std::{fmt, ops, panic::RefUnwindSafe, str::FromStr, sync::Arc};
 
 use cfg::CfgOptions;
-use rustc_hash::{FxHashMap, FxHashSet};
+use rustc_hash::FxHashMap;
+use stdx::hash::{NoHashHashMap, NoHashHashSet};
 use syntax::SmolStr;
 use tt::Subtree;
-use vfs::{file_set::FileSet, FileId, VfsPath};
+use vfs::{file_set::FileSet, AnchoredPath, FileId, VfsPath};
 
 /// Files are grouped into source roots. A source root is a directory on the
 /// file systems which is watched for changes. Typically it corresponds to a
@@ -31,22 +32,30 @@ pub struct SourceRoot {
     /// Libraries are considered mostly immutable, this assumption is used to
     /// optimize salsa's query structure
     pub is_library: bool,
-    pub(crate) file_set: FileSet,
+    file_set: FileSet,
 }
 
 impl SourceRoot {
     pub fn new_local(file_set: FileSet) -> SourceRoot {
         SourceRoot { is_library: false, file_set }
     }
+
     pub fn new_library(file_set: FileSet) -> SourceRoot {
         SourceRoot { is_library: true, file_set }
     }
+
     pub fn path_for_file(&self, file: &FileId) -> Option<&VfsPath> {
         self.file_set.path_for_file(file)
     }
+
     pub fn file_for_path(&self, path: &VfsPath) -> Option<&FileId> {
         self.file_set.file_for_path(path)
     }
+
+    pub fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId> {
+        self.file_set.resolve_path(path)
+    }
+
     pub fn iter(&self) -> impl Iterator<Item = FileId> + '_ {
         self.file_set.iter()
     }
@@ -72,12 +81,19 @@ impl SourceRoot {
 /// <https://github.com/rust-lang/rust-analyzer/blob/master/docs/dev/architecture.md#serialization>
 #[derive(Debug, Clone, Default /* Serialize, Deserialize */)]
 pub struct CrateGraph {
-    arena: FxHashMap<CrateId, CrateData>,
+    arena: NoHashHashMap<CrateId, CrateData>,
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub struct CrateId(pub u32);
 
+impl stdx::hash::NoHashHashable for CrateId {}
+impl std::hash::Hash for CrateId {
+    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+        self.0.hash(state);
+    }
+}
+
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct CrateName(SmolStr);
 
@@ -342,7 +358,7 @@ impl CrateGraph {
         // Check if adding a dep from `from` to `to` creates a cycle. To figure
         // that out, look for a  path in the *opposite* direction, from `to` to
         // `from`.
-        if let Some(path) = self.find_path(&mut FxHashSet::default(), dep.crate_id, from) {
+        if let Some(path) = self.find_path(&mut NoHashHashSet::default(), dep.crate_id, from) {
             let path = path.into_iter().map(|it| (it, self[it].display_name.clone())).collect();
             let err = CyclicDependenciesError { path };
             assert!(err.from().0 == from && err.to().0 == dep.crate_id);
@@ -365,7 +381,7 @@ impl CrateGraph {
     /// including the crate itself.
     pub fn transitive_deps(&self, of: CrateId) -> impl Iterator<Item = CrateId> {
         let mut worklist = vec![of];
-        let mut deps = FxHashSet::default();
+        let mut deps = NoHashHashSet::default();
 
         while let Some(krate) = worklist.pop() {
             if !deps.insert(krate) {
@@ -382,10 +398,10 @@ impl CrateGraph {
     /// including the crate itself.
     pub fn transitive_rev_deps(&self, of: CrateId) -> impl Iterator<Item = CrateId> {
         let mut worklist = vec![of];
-        let mut rev_deps = FxHashSet::default();
+        let mut rev_deps = NoHashHashSet::default();
         rev_deps.insert(of);
 
-        let mut inverted_graph = FxHashMap::<_, Vec<_>>::default();
+        let mut inverted_graph = NoHashHashMap::<_, Vec<_>>::default();
         self.arena.iter().for_each(|(&krate, data)| {
             data.dependencies
                 .iter()
@@ -409,7 +425,7 @@ impl CrateGraph {
     /// come before the crate itself).
     pub fn crates_in_topological_order(&self) -> Vec<CrateId> {
         let mut res = Vec::new();
-        let mut visited = FxHashSet::default();
+        let mut visited = NoHashHashSet::default();
 
         for krate in self.arena.keys().copied() {
             go(self, &mut visited, &mut res, krate);
@@ -419,7 +435,7 @@ impl CrateGraph {
 
         fn go(
             graph: &CrateGraph,
-            visited: &mut FxHashSet<CrateId>,
+            visited: &mut NoHashHashSet<CrateId>,
             res: &mut Vec<CrateId>,
             source: CrateId,
         ) {
@@ -459,7 +475,7 @@ impl CrateGraph {
 
     fn find_path(
         &self,
-        visited: &mut FxHashSet<CrateId>,
+        visited: &mut NoHashHashSet<CrateId>,
         from: CrateId,
         to: CrateId,
     ) -> Option<Vec<CrateId>> {
diff --git a/crates/base-db/src/lib.rs b/crates/base-db/src/lib.rs
index 2d0a95b09d..da11e4ae7b 100644
--- a/crates/base-db/src/lib.rs
+++ b/crates/base-db/src/lib.rs
@@ -8,7 +8,7 @@ pub mod fixture;
 
 use std::{panic, sync::Arc};
 
-use rustc_hash::FxHashSet;
+use stdx::hash::NoHashHashSet;
 use syntax::{ast, Parse, SourceFile, TextRange, TextSize};
 
 pub use crate::{
@@ -58,7 +58,7 @@ pub trait FileLoader {
     /// Text of the file.
     fn file_text(&self, file_id: FileId) -> Arc<String>;
     fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId>;
-    fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>>;
+    fn relevant_crates(&self, file_id: FileId) -> Arc<NoHashHashSet<CrateId>>;
 }
 
 /// Database which stores all significant input facts: source code and project
@@ -94,10 +94,10 @@ pub trait SourceDatabaseExt: SourceDatabase {
     #[salsa::input]
     fn source_root(&self, id: SourceRootId) -> Arc<SourceRoot>;
 
-    fn source_root_crates(&self, id: SourceRootId) -> Arc<FxHashSet<CrateId>>;
+    fn source_root_crates(&self, id: SourceRootId) -> Arc<NoHashHashSet<CrateId>>;
 }
 
-fn source_root_crates(db: &dyn SourceDatabaseExt, id: SourceRootId) -> Arc<FxHashSet<CrateId>> {
+fn source_root_crates(db: &dyn SourceDatabaseExt, id: SourceRootId) -> Arc<NoHashHashSet<CrateId>> {
     let graph = db.crate_graph();
     let res = graph
         .iter()
@@ -120,10 +120,10 @@ impl<T: SourceDatabaseExt> FileLoader for FileLoaderDelegate<&'_ T> {
         // FIXME: this *somehow* should be platform agnostic...
         let source_root = self.0.file_source_root(path.anchor);
         let source_root = self.0.source_root(source_root);
-        source_root.file_set.resolve_path(path)
+        source_root.resolve_path(path)
     }
 
-    fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
+    fn relevant_crates(&self, file_id: FileId) -> Arc<NoHashHashSet<CrateId>> {
         let _p = profile::span("relevant_crates");
         let source_root = self.0.file_source_root(file_id);
         self.0.source_root_crates(source_root)
diff --git a/crates/ide-db/src/lib.rs b/crates/ide-db/src/lib.rs
index 966bba616f..1ec62a8425 100644
--- a/crates/ide-db/src/lib.rs
+++ b/crates/ide-db/src/lib.rs
@@ -52,6 +52,7 @@ use hir::{
     db::{AstDatabase, DefDatabase, HirDatabase},
     symbols::FileSymbolKind,
 };
+use stdx::hash::NoHashHashSet;
 
 use crate::{line_index::LineIndex, symbol_index::SymbolsDatabase};
 pub use rustc_hash::{FxHashMap, FxHashSet, FxHasher};
@@ -118,7 +119,7 @@ impl FileLoader for RootDatabase {
     fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId> {
         FileLoaderDelegate(self).resolve_path(path)
     }
-    fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
+    fn relevant_crates(&self, file_id: FileId) -> Arc<NoHashHashSet<CrateId>> {
         FileLoaderDelegate(self).relevant_crates(file_id)
     }
 }
diff --git a/crates/ide-db/src/line_index.rs b/crates/ide-db/src/line_index.rs
index 68ad07ee83..75d49ff2fd 100644
--- a/crates/ide-db/src/line_index.rs
+++ b/crates/ide-db/src/line_index.rs
@@ -2,7 +2,7 @@
 //! representation.
 use std::{iter, mem};
 
-use rustc_hash::FxHashMap;
+use stdx::hash::NoHashHashMap;
 use syntax::{TextRange, TextSize};
 
 #[derive(Clone, Debug, PartialEq, Eq)]
@@ -10,7 +10,7 @@ pub struct LineIndex {
     /// Offset the the beginning of each line, zero-based
     pub(crate) newlines: Vec<TextSize>,
     /// List of non-ASCII characters on each line
-    pub(crate) utf16_lines: FxHashMap<u32, Vec<Utf16Char>>,
+    pub(crate) utf16_lines: NoHashHashMap<u32, Vec<Utf16Char>>,
 }
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -55,7 +55,7 @@ impl Utf16Char {
 
 impl LineIndex {
     pub fn new(text: &str) -> LineIndex {
-        let mut utf16_lines = FxHashMap::default();
+        let mut utf16_lines = NoHashHashMap::default();
         let mut utf16_chars = Vec::new();
 
         let mut newlines = vec![0.into()];
diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs
index 2f4aa11317..7deffe8e0f 100644
--- a/crates/ide-db/src/search.rs
+++ b/crates/ide-db/src/search.rs
@@ -9,7 +9,7 @@ use std::{mem, sync::Arc};
 use base_db::{FileId, FileRange, SourceDatabase, SourceDatabaseExt};
 use hir::{DefWithBody, HasAttrs, HasSource, InFile, ModuleSource, Semantics, Visibility};
 use once_cell::unsync::Lazy;
-use rustc_hash::FxHashMap;
+use stdx::hash::NoHashHashMap;
 use syntax::{ast, match_ast, AstNode, TextRange, TextSize};
 
 use crate::{
@@ -20,7 +20,7 @@ use crate::{
 
 #[derive(Debug, Default, Clone)]
 pub struct UsageSearchResult {
-    pub references: FxHashMap<FileId, Vec<FileReference>>,
+    pub references: NoHashHashMap<FileId, Vec<FileReference>>,
 }
 
 impl UsageSearchResult {
@@ -45,7 +45,7 @@ impl UsageSearchResult {
 
 impl IntoIterator for UsageSearchResult {
     type Item = (FileId, Vec<FileReference>);
-    type IntoIter = <FxHashMap<FileId, Vec<FileReference>> as IntoIterator>::IntoIter;
+    type IntoIter = <NoHashHashMap<FileId, Vec<FileReference>> as IntoIterator>::IntoIter;
 
     fn into_iter(self) -> Self::IntoIter {
         self.references.into_iter()
@@ -78,17 +78,17 @@ pub enum ReferenceCategory {
 /// e.g. for things like local variables.
 #[derive(Clone, Debug)]
 pub struct SearchScope {
-    entries: FxHashMap<FileId, Option<TextRange>>,
+    entries: NoHashHashMap<FileId, Option<TextRange>>,
 }
 
 impl SearchScope {
-    fn new(entries: FxHashMap<FileId, Option<TextRange>>) -> SearchScope {
+    fn new(entries: NoHashHashMap<FileId, Option<TextRange>>) -> SearchScope {
         SearchScope { entries }
     }
 
     /// Build a search scope spanning the entire crate graph of files.
     fn crate_graph(db: &RootDatabase) -> SearchScope {
-        let mut entries = FxHashMap::default();
+        let mut entries = NoHashHashMap::default();
 
         let graph = db.crate_graph();
         for krate in graph.iter() {
@@ -102,7 +102,7 @@ impl SearchScope {
 
     /// Build a search scope spanning all the reverse dependencies of the given crate.
     fn reverse_dependencies(db: &RootDatabase, of: hir::Crate) -> SearchScope {
-        let mut entries = FxHashMap::default();
+        let mut entries = NoHashHashMap::default();
         for rev_dep in of.transitive_reverse_dependencies(db) {
             let root_file = rev_dep.root_file(db);
             let source_root_id = db.file_source_root(root_file);
@@ -117,14 +117,12 @@ impl SearchScope {
         let root_file = of.root_file(db);
         let source_root_id = db.file_source_root(root_file);
         let source_root = db.source_root(source_root_id);
-        SearchScope {
-            entries: source_root.iter().map(|id| (id, None)).collect::<FxHashMap<_, _>>(),
-        }
+        SearchScope { entries: source_root.iter().map(|id| (id, None)).collect() }
     }
 
     /// Build a search scope spanning the given module and all its submodules.
     fn module_and_children(db: &RootDatabase, module: hir::Module) -> SearchScope {
-        let mut entries = FxHashMap::default();
+        let mut entries = NoHashHashMap::default();
 
         let (file_id, range) = {
             let InFile { file_id, value } = module.definition_source(db);
@@ -157,7 +155,7 @@ impl SearchScope {
 
     /// Build an empty search scope.
     pub fn empty() -> SearchScope {
-        SearchScope::new(FxHashMap::default())
+        SearchScope::new(NoHashHashMap::default())
     }
 
     /// Build a empty search scope spanning the given file.
diff --git a/crates/ide-db/src/source_change.rs b/crates/ide-db/src/source_change.rs
index 21314ad74e..8e338061df 100644
--- a/crates/ide-db/src/source_change.rs
+++ b/crates/ide-db/src/source_change.rs
@@ -6,8 +6,7 @@
 use std::{collections::hash_map::Entry, iter, mem};
 
 use base_db::{AnchoredPathBuf, FileId};
-use rustc_hash::FxHashMap;
-use stdx::never;
+use stdx::{hash::NoHashHashMap, never};
 use syntax::{algo, AstNode, SyntaxNode, SyntaxNodePtr, TextRange, TextSize};
 use text_edit::{TextEdit, TextEditBuilder};
 
@@ -15,7 +14,7 @@ use crate::SnippetCap;
 
 #[derive(Default, Debug, Clone)]
 pub struct SourceChange {
-    pub source_file_edits: FxHashMap<FileId, TextEdit>,
+    pub source_file_edits: NoHashHashMap<FileId, TextEdit>,
     pub file_system_edits: Vec<FileSystemEdit>,
     pub is_snippet: bool,
 }
@@ -24,7 +23,7 @@ impl SourceChange {
     /// Creates a new SourceChange with the given label
     /// from the edits.
     pub fn from_edits(
-        source_file_edits: FxHashMap<FileId, TextEdit>,
+        source_file_edits: NoHashHashMap<FileId, TextEdit>,
         file_system_edits: Vec<FileSystemEdit>,
     ) -> Self {
         SourceChange { source_file_edits, file_system_edits, is_snippet: false }
@@ -78,8 +77,8 @@ impl Extend<FileSystemEdit> for SourceChange {
     }
 }
 
-impl From<FxHashMap<FileId, TextEdit>> for SourceChange {
-    fn from(source_file_edits: FxHashMap<FileId, TextEdit>) -> SourceChange {
+impl From<NoHashHashMap<FileId, TextEdit>> for SourceChange {
+    fn from(source_file_edits: NoHashHashMap<FileId, TextEdit>) -> SourceChange {
         SourceChange { source_file_edits, file_system_edits: Vec::new(), is_snippet: false }
     }
 }
diff --git a/crates/ide-ssr/Cargo.toml b/crates/ide-ssr/Cargo.toml
index d36dd02d45..73314e0f33 100644
--- a/crates/ide-ssr/Cargo.toml
+++ b/crates/ide-ssr/Cargo.toml
@@ -20,6 +20,7 @@ parser = { path = "../parser", version = "0.0.0" }
 syntax = { path = "../syntax", version = "0.0.0" }
 ide-db = { path = "../ide-db", version = "0.0.0" }
 hir = { path = "../hir", version = "0.0.0" }
+stdx = { path = "../stdx", version = "0.0.0" }
 
 [dev-dependencies]
 test-utils = { path = "../test-utils" }
diff --git a/crates/ide-ssr/src/lib.rs b/crates/ide-ssr/src/lib.rs
index 739e0ccb43..d9834ee63a 100644
--- a/crates/ide-ssr/src/lib.rs
+++ b/crates/ide-ssr/src/lib.rs
@@ -86,11 +86,9 @@ pub use crate::{errors::SsrError, from_comment::ssr_from_comment, matching::Matc
 
 use crate::{errors::bail, matching::MatchFailureReason};
 use hir::Semantics;
-use ide_db::{
-    base_db::{FileId, FilePosition, FileRange},
-    FxHashMap,
-};
+use ide_db::base_db::{FileId, FilePosition, FileRange};
 use resolving::ResolvedRule;
+use stdx::hash::NoHashHashMap;
 use syntax::{ast, AstNode, SyntaxNode, TextRange};
 use text_edit::TextEdit;
 
@@ -170,9 +168,9 @@ impl<'db> MatchFinder<'db> {
     }
 
     /// Finds matches for all added rules and returns edits for all found matches.
-    pub fn edits(&self) -> FxHashMap<FileId, TextEdit> {
+    pub fn edits(&self) -> NoHashHashMap<FileId, TextEdit> {
         use ide_db::base_db::SourceDatabaseExt;
-        let mut matches_by_file = FxHashMap::default();
+        let mut matches_by_file = NoHashHashMap::default();
         for m in self.matches().matches {
             matches_by_file
                 .entry(m.range.file_id)
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs
index 92ce26b422..582e9fe7e8 100644
--- a/crates/ide/src/doc_links.rs
+++ b/crates/ide/src/doc_links.rs
@@ -184,10 +184,10 @@ pub(crate) fn resolve_doc_path_for_def(
         Definition::TypeAlias(it) => it.resolve_doc_path(db, link, ns),
         Definition::Macro(it) => it.resolve_doc_path(db, link, ns),
         Definition::Field(it) => it.resolve_doc_path(db, link, ns),
-        Definition::SelfType(it) => it.resolve_doc_path(db, link, ns),
         Definition::BuiltinAttr(_)
         | Definition::ToolModule(_)
         | Definition::BuiltinType(_)
+        | Definition::SelfType(_)
         | Definition::Local(_)
         | Definition::GenericParam(_)
         | Definition::Label(_)
diff --git a/crates/ide/src/prime_caches.rs b/crates/ide/src/prime_caches.rs
index 2962700360..87b3ef380c 100644
--- a/crates/ide/src/prime_caches.rs
+++ b/crates/ide/src/prime_caches.rs
@@ -12,8 +12,9 @@ use ide_db::{
         salsa::{Database, ParallelDatabase, Snapshot},
         Cancelled, CrateGraph, CrateId, SourceDatabase, SourceDatabaseExt,
     },
-    FxHashSet, FxIndexMap,
+    FxIndexMap,
 };
+use stdx::hash::NoHashHashSet;
 
 use crate::RootDatabase;
 
@@ -141,7 +142,7 @@ pub(crate) fn parallel_prime_caches(
     }
 }
 
-fn compute_crates_to_prime(db: &RootDatabase, graph: &CrateGraph) -> FxHashSet<CrateId> {
+fn compute_crates_to_prime(db: &RootDatabase, graph: &CrateGraph) -> NoHashHashSet<CrateId> {
     // We're only interested in the workspace crates and the `ImportMap`s of their direct
     // dependencies, though in practice the latter also compute the `DefMap`s.
     // We don't prime transitive dependencies because they're generally not visible in
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs
index 1a6beec188..99614b645e 100644
--- a/crates/ide/src/references.rs
+++ b/crates/ide/src/references.rs
@@ -14,8 +14,9 @@ use ide_db::{
     base_db::FileId,
     defs::{Definition, NameClass, NameRefClass},
     search::{ReferenceCategory, SearchScope, UsageSearchResult},
-    FxHashMap, RootDatabase,
+    RootDatabase,
 };
+use stdx::hash::NoHashHashMap;
 use syntax::{
     algo::find_node_at_offset,
     ast::{self, HasName},
@@ -29,7 +30,7 @@ use crate::{FilePosition, NavigationTarget, TryToNav};
 #[derive(Debug, Clone)]
 pub struct ReferenceSearchResult {
     pub declaration: Option<Declaration>,
-    pub references: FxHashMap<FileId, Vec<(TextRange, Option<ReferenceCategory>)>>,
+    pub references: NoHashHashMap<FileId, Vec<(TextRange, Option<ReferenceCategory>)>>,
 }
 
 #[derive(Debug, Clone)]
diff --git a/crates/ide/src/view_crate_graph.rs b/crates/ide/src/view_crate_graph.rs
index bf7b7efe28..17a1e385b7 100644
--- a/crates/ide/src/view_crate_graph.rs
+++ b/crates/ide/src/view_crate_graph.rs
@@ -3,8 +3,9 @@ use std::sync::Arc;
 use dot::{Id, LabelText};
 use ide_db::{
     base_db::{CrateGraph, CrateId, Dependency, SourceDatabase, SourceDatabaseExt},
-    FxHashSet, RootDatabase,
+    RootDatabase,
 };
+use stdx::hash::NoHashHashSet;
 
 // Feature: View Crate Graph
 //
@@ -41,7 +42,7 @@ pub(crate) fn view_crate_graph(db: &RootDatabase, full: bool) -> Result<String,
 
 struct DotCrateGraph {
     graph: Arc<CrateGraph>,
-    crates_to_render: FxHashSet<CrateId>,
+    crates_to_render: NoHashHashSet<CrateId>,
 }
 
 type Edge<'a> = (CrateId, &'a Dependency);
diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs
index 8d6f50f558..818bbed6af 100644
--- a/crates/project-model/src/workspace.rs
+++ b/crates/project-model/src/workspace.rs
@@ -13,7 +13,7 @@ use cfg::{CfgDiff, CfgOptions};
 use paths::{AbsPath, AbsPathBuf};
 use rustc_hash::{FxHashMap, FxHashSet};
 use semver::Version;
-use stdx::always;
+use stdx::{always, hash::NoHashHashMap};
 
 use crate::{
     build_scripts::BuildScriptOutput,
@@ -471,7 +471,7 @@ fn project_json_to_crate_graph(
         .map(|sysroot| sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load));
 
     let mut cfg_cache: FxHashMap<&str, Vec<CfgFlag>> = FxHashMap::default();
-    let crates: FxHashMap<CrateId, CrateId> = project
+    let crates: NoHashHashMap<CrateId, CrateId> = project
         .crates()
         .filter_map(|(crate_id, krate)| {
             let file_path = &krate.root_module;
diff --git a/crates/rust-analyzer/src/diagnostics.rs b/crates/rust-analyzer/src/diagnostics.rs
index 09150c77d7..f516c194da 100644
--- a/crates/rust-analyzer/src/diagnostics.rs
+++ b/crates/rust-analyzer/src/diagnostics.rs
@@ -4,11 +4,12 @@ pub(crate) mod to_proto;
 use std::{mem, sync::Arc};
 
 use ide::FileId;
-use rustc_hash::{FxHashMap, FxHashSet};
+use ide_db::FxHashMap;
+use stdx::hash::{NoHashHashMap, NoHashHashSet};
 
 use crate::lsp_ext;
 
-pub(crate) type CheckFixes = Arc<FxHashMap<usize, FxHashMap<FileId, Vec<Fix>>>>;
+pub(crate) type CheckFixes = Arc<NoHashHashMap<usize, NoHashHashMap<FileId, Vec<Fix>>>>;
 
 #[derive(Debug, Default, Clone)]
 pub struct DiagnosticsMapConfig {
@@ -19,12 +20,12 @@ pub struct DiagnosticsMapConfig {
 
 #[derive(Debug, Default, Clone)]
 pub(crate) struct DiagnosticCollection {
-    // FIXME: should be FxHashMap<FileId, Vec<ra_id::Diagnostic>>
-    pub(crate) native: FxHashMap<FileId, Vec<lsp_types::Diagnostic>>,
+    // FIXME: should be NoHashHashMap<FileId, Vec<ra_id::Diagnostic>>
+    pub(crate) native: NoHashHashMap<FileId, Vec<lsp_types::Diagnostic>>,
     // FIXME: should be Vec<flycheck::Diagnostic>
-    pub(crate) check: FxHashMap<usize, FxHashMap<FileId, Vec<lsp_types::Diagnostic>>>,
+    pub(crate) check: NoHashHashMap<usize, NoHashHashMap<FileId, Vec<lsp_types::Diagnostic>>>,
     pub(crate) check_fixes: CheckFixes,
-    changes: FxHashSet<FileId>,
+    changes: NoHashHashSet<FileId>,
 }
 
 #[derive(Debug, Clone)]
@@ -105,7 +106,7 @@ impl DiagnosticCollection {
         native.chain(check)
     }
 
-    pub(crate) fn take_changes(&mut self) -> Option<FxHashSet<FileId>> {
+    pub(crate) fn take_changes(&mut self) -> Option<NoHashHashSet<FileId>> {
         if self.changes.is_empty() {
             return None;
         }
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index c55bbbbe6e..706e1742df 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -14,6 +14,7 @@ use parking_lot::{Mutex, RwLock};
 use proc_macro_api::ProcMacroServer;
 use project_model::{CargoWorkspace, ProjectWorkspace, Target, WorkspaceBuildScripts};
 use rustc_hash::FxHashMap;
+use stdx::hash::NoHashHashMap;
 use vfs::AnchoredPathBuf;
 
 use crate::{
@@ -67,7 +68,7 @@ pub(crate) struct GlobalState {
     pub(crate) flycheck_sender: Sender<flycheck::Message>,
     pub(crate) flycheck_receiver: Receiver<flycheck::Message>,
 
-    pub(crate) vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>,
+    pub(crate) vfs: Arc<RwLock<(vfs::Vfs, NoHashHashMap<FileId, LineEndings>)>>,
     pub(crate) vfs_config_version: u32,
     pub(crate) vfs_progress_config_version: u32,
     pub(crate) vfs_progress_n_total: usize,
@@ -113,7 +114,7 @@ pub(crate) struct GlobalStateSnapshot {
     pub(crate) check_fixes: CheckFixes,
     mem_docs: MemDocs,
     pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>,
-    vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>,
+    vfs: Arc<RwLock<(vfs::Vfs, NoHashHashMap<FileId, LineEndings>)>>,
     pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>,
 }
 
@@ -157,7 +158,7 @@ impl GlobalState {
             flycheck_sender,
             flycheck_receiver,
 
-            vfs: Arc::new(RwLock::new((vfs::Vfs::default(), FxHashMap::default()))),
+            vfs: Arc::new(RwLock::new((vfs::Vfs::default(), NoHashHashMap::default()))),
             vfs_config_version: 0,
             vfs_progress_config_version: 0,
             vfs_progress_n_total: 0,
diff --git a/crates/rust-analyzer/src/semantic_tokens.rs b/crates/rust-analyzer/src/semantic_tokens.rs
index c48410ed55..4493da19c1 100644
--- a/crates/rust-analyzer/src/semantic_tokens.rs
+++ b/crates/rust-analyzer/src/semantic_tokens.rs
@@ -8,130 +8,102 @@ use lsp_types::{
 };
 
 macro_rules! define_semantic_token_types {
-    (
-        standard {
-            $($standard:ident),*$(,)?
-        }
-        custom {
-            $(($custom:ident, $string:literal)),*$(,)?
-        }
-
-    ) => {
-        $(pub(crate) const $standard: SemanticTokenType = SemanticTokenType::$standard;)*
-        $(pub(crate) const $custom: SemanticTokenType = SemanticTokenType::new($string);)*
+    ($(($ident:ident, $string:literal)),*$(,)?) => {
+        $(pub(crate) const $ident: SemanticTokenType = SemanticTokenType::new($string);)*
 
         pub(crate) const SUPPORTED_TYPES: &[SemanticTokenType] = &[
-            $(SemanticTokenType::$standard,)*
-            $($custom),*
+            SemanticTokenType::CLASS,
+            SemanticTokenType::COMMENT,
+            SemanticTokenType::ENUM_MEMBER,
+            SemanticTokenType::ENUM,
+            SemanticTokenType::FUNCTION,
+            SemanticTokenType::INTERFACE,
+            SemanticTokenType::KEYWORD,
+            SemanticTokenType::MACRO,
+            SemanticTokenType::METHOD,
+            SemanticTokenType::NAMESPACE,
+            SemanticTokenType::NUMBER,
+            SemanticTokenType::OPERATOR,
+            SemanticTokenType::PARAMETER,
+            SemanticTokenType::PROPERTY,
+            SemanticTokenType::REGEXP,
+            SemanticTokenType::STRING,
+            SemanticTokenType::STRUCT,
+            SemanticTokenType::TYPE_PARAMETER,
+            SemanticTokenType::TYPE,
+            SemanticTokenType::VARIABLE,
+            SemanticTokenType::DECORATOR,
+            $($ident),*
         ];
     };
 }
 
 define_semantic_token_types![
-    standard {
-        COMMENT,
-        DECORATOR,
-        ENUM_MEMBER,
-        ENUM,
-        FUNCTION,
-        INTERFACE,
-        KEYWORD,
-        MACRO,
-        METHOD,
-        NAMESPACE,
-        NUMBER,
-        OPERATOR,
-        PARAMETER,
-        PROPERTY,
-        STRING,
-        STRUCT,
-        TYPE_PARAMETER,
-        VARIABLE,
-    }
-
-    custom {
-        (ANGLE, "angle"),
-        (ARITHMETIC, "arithmetic"),
-        (ATTRIBUTE, "attribute"),
-        (ATTRIBUTE_BRACKET, "attributeBracket"),
-        (BITWISE, "bitwise"),
-        (BOOLEAN, "boolean"),
-        (BRACE, "brace"),
-        (BRACKET, "bracket"),
-        (BUILTIN_ATTRIBUTE, "builtinAttribute"),
-        (BUILTIN_TYPE, "builtinType"),
-        (CHAR, "character"),
-        (COLON, "colon"),
-        (COMMA, "comma"),
-        (COMPARISON, "comparison"),
-        (CONST_PARAMETER, "constParameter"),
-        (DERIVE, "derive"),
-        (DERIVE_HELPER, "deriveHelper"),
-        (DOT, "dot"),
-        (ESCAPE_SEQUENCE, "escapeSequence"),
-        (FORMAT_SPECIFIER, "formatSpecifier"),
-        (GENERIC, "generic"),
-        (LABEL, "label"),
-        (LIFETIME, "lifetime"),
-        (LOGICAL, "logical"),
-        (MACRO_BANG, "macroBang"),
-        (PARENTHESIS, "parenthesis"),
-        (PUNCTUATION, "punctuation"),
-        (SELF_KEYWORD, "selfKeyword"),
-        (SELF_TYPE_KEYWORD, "selfTypeKeyword"),
-        (SEMICOLON, "semicolon"),
-        (TYPE_ALIAS, "typeAlias"),
-        (TOOL_MODULE, "toolModule"),
-        (UNION, "union"),
-        (UNRESOLVED_REFERENCE, "unresolvedReference"),
-    }
+    (ANGLE, "angle"),
+    (ARITHMETIC, "arithmetic"),
+    (ATTRIBUTE_BRACKET, "attributeBracket"),
+    (BITWISE, "bitwise"),
+    (BOOLEAN, "boolean"),
+    (BRACE, "brace"),
+    (BRACKET, "bracket"),
+    (BUILTIN_ATTRIBUTE, "builtinAttribute"),
+    (BUILTIN_TYPE, "builtinType"),
+    (CHAR, "character"),
+    (COLON, "colon"),
+    (COMMA, "comma"),
+    (COMPARISON, "comparison"),
+    (CONST_PARAMETER, "constParameter"),
+    (DERIVE, "derive"),
+    (DERIVE_HELPER, "deriveHelper"),
+    (DOT, "dot"),
+    (ESCAPE_SEQUENCE, "escapeSequence"),
+    (FORMAT_SPECIFIER, "formatSpecifier"),
+    (GENERIC, "generic"),
+    (LABEL, "label"),
+    (LIFETIME, "lifetime"),
+    (LOGICAL, "logical"),
+    (MACRO_BANG, "macroBang"),
+    (PARENTHESIS, "parenthesis"),
+    (PUNCTUATION, "punctuation"),
+    (SELF_KEYWORD, "selfKeyword"),
+    (SELF_TYPE_KEYWORD, "selfTypeKeyword"),
+    (SEMICOLON, "semicolon"),
+    (TYPE_ALIAS, "typeAlias"),
+    (TOOL_MODULE, "toolModule"),
+    (UNION, "union"),
+    (UNRESOLVED_REFERENCE, "unresolvedReference"),
 ];
 
 macro_rules! define_semantic_token_modifiers {
-    (
-        standard {
-            $($standard:ident),*$(,)?
-        }
-        custom {
-            $(($custom:ident, $string:literal)),*$(,)?
-        }
-
-    ) => {
-
-        $(pub(crate) const $standard: SemanticTokenModifier = SemanticTokenModifier::$standard;)*
-        $(pub(crate) const $custom: SemanticTokenModifier = SemanticTokenModifier::new($string);)*
+    ($(($ident:ident, $string:literal)),*$(,)?) => {
+        $(pub(crate) const $ident: SemanticTokenModifier = SemanticTokenModifier::new($string);)*
 
         pub(crate) const SUPPORTED_MODIFIERS: &[SemanticTokenModifier] = &[
-            $(SemanticTokenModifier::$standard,)*
-            $($custom),*
+            SemanticTokenModifier::DOCUMENTATION,
+            SemanticTokenModifier::DECLARATION,
+            SemanticTokenModifier::STATIC,
+            SemanticTokenModifier::DEFAULT_LIBRARY,
+            $($ident),*
         ];
     };
 }
 
 define_semantic_token_modifiers![
-    standard {
-        DOCUMENTATION,
-        DECLARATION,
-        STATIC,
-        DEFAULT_LIBRARY,
-    }
-    custom {
-        (ASYNC, "async"),
-        (ATTRIBUTE_MODIFIER, "attribute"),
-        (CALLABLE, "callable"),
-        (CONSTANT, "constant"),
-        (CONSUMING, "consuming"),
-        (CONTROL_FLOW, "controlFlow"),
-        (CRATE_ROOT, "crateRoot"),
-        (INJECTED, "injected"),
-        (INTRA_DOC_LINK, "intraDocLink"),
-        (LIBRARY, "library"),
-        (MUTABLE, "mutable"),
-        (PUBLIC, "public"),
-        (REFERENCE, "reference"),
-        (TRAIT_MODIFIER, "trait"),
-        (UNSAFE, "unsafe"),
-    }
+    (ASYNC, "async"),
+    (ATTRIBUTE_MODIFIER, "attribute"),
+    (CALLABLE, "callable"),
+    (CONSTANT, "constant"),
+    (CONSUMING, "consuming"),
+    (CONTROL_FLOW, "controlFlow"),
+    (CRATE_ROOT, "crateRoot"),
+    (INJECTED, "injected"),
+    (INTRA_DOC_LINK, "intraDocLink"),
+    (LIBRARY, "library"),
+    (MUTABLE, "mutable"),
+    (PUBLIC, "public"),
+    (REFERENCE, "reference"),
+    (TRAIT_MODIFIER, "trait"),
+    (UNSAFE, "unsafe"),
 ];
 
 #[derive(Default)]
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 102cd60295..99f7b57399 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -558,64 +558,64 @@ fn semantic_token_type_and_modifiers(
     let mut mods = semantic_tokens::ModifierSet::default();
     let type_ = match highlight.tag {
         HlTag::Symbol(symbol) => match symbol {
-            SymbolKind::Attribute => semantic_tokens::DECORATOR,
+            SymbolKind::Attribute => lsp_types::SemanticTokenType::DECORATOR,
             SymbolKind::Derive => semantic_tokens::DERIVE,
             SymbolKind::DeriveHelper => semantic_tokens::DERIVE_HELPER,
-            SymbolKind::Module => semantic_tokens::NAMESPACE,
+            SymbolKind::Module => lsp_types::SemanticTokenType::NAMESPACE,
             SymbolKind::Impl => semantic_tokens::TYPE_ALIAS,
-            SymbolKind::Field => semantic_tokens::PROPERTY,
-            SymbolKind::TypeParam => semantic_tokens::TYPE_PARAMETER,
+            SymbolKind::Field => lsp_types::SemanticTokenType::PROPERTY,
+            SymbolKind::TypeParam => lsp_types::SemanticTokenType::TYPE_PARAMETER,
             SymbolKind::ConstParam => semantic_tokens::CONST_PARAMETER,
             SymbolKind::LifetimeParam => semantic_tokens::LIFETIME,
             SymbolKind::Label => semantic_tokens::LABEL,
-            SymbolKind::ValueParam => semantic_tokens::PARAMETER,
+            SymbolKind::ValueParam => lsp_types::SemanticTokenType::PARAMETER,
             SymbolKind::SelfParam => semantic_tokens::SELF_KEYWORD,
             SymbolKind::SelfType => semantic_tokens::SELF_TYPE_KEYWORD,
-            SymbolKind::Local => semantic_tokens::VARIABLE,
+            SymbolKind::Local => lsp_types::SemanticTokenType::VARIABLE,
             SymbolKind::Function => {
                 if highlight.mods.contains(HlMod::Associated) {
-                    semantic_tokens::METHOD
+                    lsp_types::SemanticTokenType::METHOD
                 } else {
-                    semantic_tokens::FUNCTION
+                    lsp_types::SemanticTokenType::FUNCTION
                 }
             }
             SymbolKind::Const => {
                 mods |= semantic_tokens::CONSTANT;
-                mods |= semantic_tokens::STATIC;
-                semantic_tokens::VARIABLE
+                mods |= lsp_types::SemanticTokenModifier::STATIC;
+                lsp_types::SemanticTokenType::VARIABLE
             }
             SymbolKind::Static => {
-                mods |= semantic_tokens::STATIC;
-                semantic_tokens::VARIABLE
+                mods |= lsp_types::SemanticTokenModifier::STATIC;
+                lsp_types::SemanticTokenType::VARIABLE
             }
-            SymbolKind::Struct => semantic_tokens::STRUCT,
-            SymbolKind::Enum => semantic_tokens::ENUM,
-            SymbolKind::Variant => semantic_tokens::ENUM_MEMBER,
+            SymbolKind::Struct => lsp_types::SemanticTokenType::STRUCT,
+            SymbolKind::Enum => lsp_types::SemanticTokenType::ENUM,
+            SymbolKind::Variant => lsp_types::SemanticTokenType::ENUM_MEMBER,
             SymbolKind::Union => semantic_tokens::UNION,
             SymbolKind::TypeAlias => semantic_tokens::TYPE_ALIAS,
-            SymbolKind::Trait => semantic_tokens::INTERFACE,
-            SymbolKind::Macro => semantic_tokens::MACRO,
+            SymbolKind::Trait => lsp_types::SemanticTokenType::INTERFACE,
+            SymbolKind::Macro => lsp_types::SemanticTokenType::MACRO,
             SymbolKind::BuiltinAttr => semantic_tokens::BUILTIN_ATTRIBUTE,
             SymbolKind::ToolModule => semantic_tokens::TOOL_MODULE,
         },
         HlTag::AttributeBracket => semantic_tokens::ATTRIBUTE_BRACKET,
         HlTag::BoolLiteral => semantic_tokens::BOOLEAN,
         HlTag::BuiltinType => semantic_tokens::BUILTIN_TYPE,
-        HlTag::ByteLiteral | HlTag::NumericLiteral => semantic_tokens::NUMBER,
+        HlTag::ByteLiteral | HlTag::NumericLiteral => lsp_types::SemanticTokenType::NUMBER,
         HlTag::CharLiteral => semantic_tokens::CHAR,
-        HlTag::Comment => semantic_tokens::COMMENT,
+        HlTag::Comment => lsp_types::SemanticTokenType::COMMENT,
         HlTag::EscapeSequence => semantic_tokens::ESCAPE_SEQUENCE,
         HlTag::FormatSpecifier => semantic_tokens::FORMAT_SPECIFIER,
-        HlTag::Keyword => semantic_tokens::KEYWORD,
+        HlTag::Keyword => lsp_types::SemanticTokenType::KEYWORD,
         HlTag::None => semantic_tokens::GENERIC,
         HlTag::Operator(op) => match op {
             HlOperator::Bitwise => semantic_tokens::BITWISE,
             HlOperator::Arithmetic => semantic_tokens::ARITHMETIC,
             HlOperator::Logical => semantic_tokens::LOGICAL,
             HlOperator::Comparison => semantic_tokens::COMPARISON,
-            HlOperator::Other => semantic_tokens::OPERATOR,
+            HlOperator::Other => lsp_types::SemanticTokenType::OPERATOR,
         },
-        HlTag::StringLiteral => semantic_tokens::STRING,
+        HlTag::StringLiteral => lsp_types::SemanticTokenType::STRING,
         HlTag::UnresolvedReference => semantic_tokens::UNRESOLVED_REFERENCE,
         HlTag::Punctuation(punct) => match punct {
             HlPunct::Bracket => semantic_tokens::BRACKET,
@@ -640,16 +640,16 @@ fn semantic_token_type_and_modifiers(
             HlMod::Consuming => semantic_tokens::CONSUMING,
             HlMod::ControlFlow => semantic_tokens::CONTROL_FLOW,
             HlMod::CrateRoot => semantic_tokens::CRATE_ROOT,
-            HlMod::DefaultLibrary => semantic_tokens::DEFAULT_LIBRARY,
-            HlMod::Definition => semantic_tokens::DECLARATION,
-            HlMod::Documentation => semantic_tokens::DOCUMENTATION,
+            HlMod::DefaultLibrary => lsp_types::SemanticTokenModifier::DEFAULT_LIBRARY,
+            HlMod::Definition => lsp_types::SemanticTokenModifier::DECLARATION,
+            HlMod::Documentation => lsp_types::SemanticTokenModifier::DOCUMENTATION,
             HlMod::Injected => semantic_tokens::INJECTED,
             HlMod::IntraDocLink => semantic_tokens::INTRA_DOC_LINK,
             HlMod::Library => semantic_tokens::LIBRARY,
             HlMod::Mutable => semantic_tokens::MUTABLE,
             HlMod::Public => semantic_tokens::PUBLIC,
             HlMod::Reference => semantic_tokens::REFERENCE,
-            HlMod::Static => semantic_tokens::STATIC,
+            HlMod::Static => lsp_types::SemanticTokenModifier::STATIC,
             HlMod::Trait => semantic_tokens::TRAIT_MODIFIER,
             HlMod::Unsafe => semantic_tokens::UNSAFE,
         };
diff --git a/crates/stdx/src/hash.rs b/crates/stdx/src/hash.rs
new file mode 100644
index 0000000000..9909d71bdf
--- /dev/null
+++ b/crates/stdx/src/hash.rs
@@ -0,0 +1,80 @@
+//! A none hashing [`Hasher`] implementation.
+use std::{
+    hash::{BuildHasher, Hasher},
+    marker::PhantomData,
+};
+
+pub type NoHashHashMap<K, V> = std::collections::HashMap<K, V, NoHashHasherBuilder<K>>;
+pub type NoHashHashSet<K> = std::collections::HashSet<K, NoHashHasherBuilder<K>>;
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub struct NoHashHasherBuilder<T>(PhantomData<T>);
+
+impl<T> Default for NoHashHasherBuilder<T> {
+    fn default() -> Self {
+        Self(Default::default())
+    }
+}
+
+pub trait NoHashHashable {}
+impl NoHashHashable for usize {}
+impl NoHashHashable for u32 {}
+
+pub struct NoHashHasher(u64);
+
+impl<T: NoHashHashable> BuildHasher for NoHashHasherBuilder<T> {
+    type Hasher = NoHashHasher;
+    fn build_hasher(&self) -> Self::Hasher {
+        NoHashHasher(0)
+    }
+}
+
+impl Hasher for NoHashHasher {
+    fn finish(&self) -> u64 {
+        self.0
+    }
+
+    fn write(&mut self, _: &[u8]) {
+        unimplemented!("NoHashHasher should only be used for hashing primitive integers")
+    }
+
+    fn write_u8(&mut self, i: u8) {
+        self.0 = i as u64;
+    }
+
+    fn write_u16(&mut self, i: u16) {
+        self.0 = i as u64;
+    }
+
+    fn write_u32(&mut self, i: u32) {
+        self.0 = i as u64;
+    }
+
+    fn write_u64(&mut self, i: u64) {
+        self.0 = i as u64;
+    }
+
+    fn write_usize(&mut self, i: usize) {
+        self.0 = i as u64;
+    }
+
+    fn write_i8(&mut self, i: i8) {
+        self.0 = i as u64;
+    }
+
+    fn write_i16(&mut self, i: i16) {
+        self.0 = i as u64;
+    }
+
+    fn write_i32(&mut self, i: i32) {
+        self.0 = i as u64;
+    }
+
+    fn write_i64(&mut self, i: i64) {
+        self.0 = i as u64;
+    }
+
+    fn write_isize(&mut self, i: isize) {
+        self.0 = i as u64;
+    }
+}
diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs
index b4d45206c4..51e109798d 100644
--- a/crates/stdx/src/lib.rs
+++ b/crates/stdx/src/lib.rs
@@ -7,6 +7,7 @@ use std::{cmp::Ordering, ops, time::Instant};
 use std::{io as sio, iter};
 
 mod macros;
+pub mod hash;
 pub mod process;
 pub mod panic_context;
 pub mod non_empty_vec;
diff --git a/crates/vfs/Cargo.toml b/crates/vfs/Cargo.toml
index c637734878..d7549a2841 100644
--- a/crates/vfs/Cargo.toml
+++ b/crates/vfs/Cargo.toml
@@ -12,6 +12,7 @@ doctest = false
 [dependencies]
 rustc-hash = "1.1.0"
 fst = "0.4.7"
+indexmap = "1.9.1"
 
 paths = { path = "../paths", version = "0.0.0" }
-indexmap = "1.9.1"
+stdx = { path = "../stdx", version = "0.0.0" }
diff --git a/crates/vfs/src/file_set.rs b/crates/vfs/src/file_set.rs
index 6a89263e53..e0ef737b3f 100644
--- a/crates/vfs/src/file_set.rs
+++ b/crates/vfs/src/file_set.rs
@@ -6,6 +6,7 @@ use std::fmt;
 
 use fst::{IntoStreamer, Streamer};
 use rustc_hash::FxHashMap;
+use stdx::hash::NoHashHashMap;
 
 use crate::{AnchoredPath, FileId, Vfs, VfsPath};
 
@@ -13,7 +14,7 @@ use crate::{AnchoredPath, FileId, Vfs, VfsPath};
 #[derive(Default, Clone, Eq, PartialEq)]
 pub struct FileSet {
     files: FxHashMap<VfsPath, FileId>,
-    paths: FxHashMap<FileId, VfsPath>,
+    paths: NoHashHashMap<FileId, VfsPath>,
 }
 
 impl FileSet {
diff --git a/crates/vfs/src/lib.rs b/crates/vfs/src/lib.rs
index 7badb1c363..afc9a0fa6f 100644
--- a/crates/vfs/src/lib.rs
+++ b/crates/vfs/src/lib.rs
@@ -59,9 +59,16 @@ pub use paths::{AbsPath, AbsPathBuf};
 /// Handle to a file in [`Vfs`]
 ///
 /// Most functions in rust-analyzer use this when they need to refer to a file.
-#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
+#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
 pub struct FileId(pub u32);
 
+impl stdx::hash::NoHashHashable for FileId {}
+impl std::hash::Hash for FileId {
+    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+        self.0.hash(state);
+    }
+}
+
 /// Storage for all files read by rust-analyzer.
 ///
 /// For more information see the [crate-level](crate) documentation.


Test patch:
diff --git a/crates/hir-def/src/test_db.rs b/crates/hir-def/src/test_db.rs
index 9cdc18d6b6..b7908bddaa 100644
--- a/crates/hir-def/src/test_db.rs
+++ b/crates/hir-def/src/test_db.rs
@@ -10,7 +10,7 @@ use base_db::{
     SourceDatabase, Upcast,
 };
 use hir_expand::{db::AstDatabase, InFile};
-use rustc_hash::FxHashSet;
+use stdx::hash::NoHashHashSet;
 use syntax::{algo, ast, AstNode};
 
 use crate::{
@@ -76,7 +76,7 @@ impl FileLoader for TestDB {
     fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId> {
         FileLoaderDelegate(self).resolve_path(path)
     }
-    fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
+    fn relevant_crates(&self, file_id: FileId) -> Arc<NoHashHashSet<CrateId>> {
         FileLoaderDelegate(self).relevant_crates(file_id)
     }
 }
diff --git a/crates/hir-ty/src/test_db.rs b/crates/hir-ty/src/test_db.rs
index dc7252f707..118e5311e9 100644
--- a/crates/hir-ty/src/test_db.rs
+++ b/crates/hir-ty/src/test_db.rs
@@ -10,7 +10,7 @@ use base_db::{
 };
 use hir_def::{db::DefDatabase, ModuleId};
 use hir_expand::db::AstDatabase;
-use rustc_hash::{FxHashMap, FxHashSet};
+use stdx::hash::{NoHashHashMap, NoHashHashSet};
 use syntax::TextRange;
 use test_utils::extract_annotations;
 
@@ -80,7 +80,7 @@ impl FileLoader for TestDB {
     fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId> {
         FileLoaderDelegate(self).resolve_path(path)
     }
-    fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
+    fn relevant_crates(&self, file_id: FileId) -> Arc<NoHashHashSet<CrateId>> {
         FileLoaderDelegate(self).relevant_crates(file_id)
     }
 }
@@ -102,7 +102,7 @@ impl TestDB {
         self.module_for_file_opt(file_id).unwrap()
     }
 
-    pub(crate) fn extract_annotations(&self) -> FxHashMap<FileId, Vec<(TextRange, String)>> {
+    pub(crate) fn extract_annotations(&self) -> NoHashHashMap<FileId, Vec<(TextRange, String)>> {
         let mut files = Vec::new();
         let crate_graph = self.crate_graph();
         for krate in crate_graph.iter() {
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
index eef5baea98..a747b4bc1f 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
@@ -56,7 +56,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="field declaration">bar</span><span class="colon">:</span> <span class="builtin_type">bool</span><span class="comma">,</span>
 <span class="brace">}</span>
 
-<span class="comment documentation">/// This is an impl of </span><span class="struct documentation injected intra_doc_link">[`Foo`]</span><span class="comment documentation"> with a code block.</span>
+<span class="comment documentation">/// This is an impl with a code block.</span>
 <span class="comment documentation">///</span>
 <span class="comment documentation">/// ```</span>
 <span class="comment documentation">///</span><span class="comment documentation"> </span><span class="keyword injected">fn</span><span class="none injected"> </span><span class="function declaration injected">foo</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="none injected"> </span><span class="brace injected">{</span>
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index 46cc667fc4..51ddea63ac 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -624,7 +624,7 @@ struct Foo {
     bar: bool,
 }
 
-/// This is an impl of [`Foo`] with a code block.
+/// This is an impl with a code block.
 ///
 /// ```
 /// fn foo() {
diff --git a/crates/project-model/src/tests.rs b/crates/project-model/src/tests.rs
index 8d0fa757c2..9ccb6e9101 100644
--- a/crates/project-model/src/tests.rs
+++ b/crates/project-model/src/tests.rs
@@ -185,10 +185,10 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                         is_proc_macro: false,
                     },
                     CrateId(
-                        2,
+                        1,
                     ): CrateData {
                         root_file_id: FileId(
-                            3,
+                            2,
                         ),
                         edition: Edition2018,
                         version: Some(
@@ -197,9 +197,9 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "an_example",
+                                    "hello_world",
                                 ),
-                                canonical_name: "an-example",
+                                canonical_name: "hello-world",
                             },
                         ),
                         cfg_options: CfgOptions(
@@ -260,77 +260,85 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                         is_proc_macro: false,
                     },
                     CrateId(
-                        4,
+                        2,
                     ): CrateData {
                         root_file_id: FileId(
-                            5,
+                            3,
                         ),
-                        edition: Edition2015,
+                        edition: Edition2018,
                         version: Some(
-                            "0.2.98",
+                            "0.1.0",
                         ),
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "libc",
+                                    "an_example",
                                 ),
-                                canonical_name: "libc",
+                                canonical_name: "an-example",
                             },
                         ),
                         cfg_options: CfgOptions(
                             [
                                 "debug_assertions",
-                                "feature=default",
-                                "feature=std",
                             ],
                         ),
                         potential_cfg_options: CfgOptions(
                             [
                                 "debug_assertions",
-                                "feature=align",
-                                "feature=const-extern-fn",
-                                "feature=default",
-                                "feature=extra_traits",
-                                "feature=rustc-dep-of-std",
-                                "feature=std",
-                                "feature=use_std",
                             ],
                         ),
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
                                 "CARGO_PKG_VERSION_MAJOR": "0",
-                                "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98",
-                                "CARGO_PKG_VERSION": "0.2.98",
+                                "CARGO_MANIFEST_DIR": "$ROOT$hello-world",
+                                "CARGO_PKG_VERSION": "0.1.0",
                                 "CARGO_PKG_AUTHORS": "",
-                                "CARGO_CRATE_NAME": "libc",
+                                "CARGO_CRATE_NAME": "hello_world",
                                 "CARGO_PKG_LICENSE_FILE": "",
                                 "CARGO_PKG_HOMEPAGE": "",
                                 "CARGO_PKG_DESCRIPTION": "",
-                                "CARGO_PKG_NAME": "libc",
-                                "CARGO_PKG_VERSION_PATCH": "98",
+                                "CARGO_PKG_NAME": "hello-world",
+                                "CARGO_PKG_VERSION_PATCH": "0",
                                 "CARGO": "cargo",
                                 "CARGO_PKG_REPOSITORY": "",
-                                "CARGO_PKG_VERSION_MINOR": "2",
+                                "CARGO_PKG_VERSION_MINOR": "1",
                                 "CARGO_PKG_VERSION_PRE": "",
                             },
                         },
-                        dependencies: [],
+                        dependencies: [
+                            Dependency {
+                                crate_id: CrateId(
+                                    0,
+                                ),
+                                name: CrateName(
+                                    "hello_world",
+                                ),
+                                prelude: true,
+                            },
+                            Dependency {
+                                crate_id: CrateId(
+                                    4,
+                                ),
+                                name: CrateName(
+                                    "libc",
+                                ),
+                                prelude: true,
+                            },
+                        ],
                         proc_macro: Err(
                             "crate has not (yet) been built",
                         ),
                         origin: CratesIo {
-                            repo: Some(
-                                "https://github.com/rust-lang/libc",
-                            ),
+                            repo: None,
                         },
                         is_proc_macro: false,
                     },
                     CrateId(
-                        1,
+                        3,
                     ): CrateData {
                         root_file_id: FileId(
-                            2,
+                            4,
                         ),
                         edition: Edition2018,
                         version: Some(
@@ -339,9 +347,9 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "hello_world",
+                                    "it",
                                 ),
-                                canonical_name: "hello-world",
+                                canonical_name: "it",
                             },
                         ),
                         cfg_options: CfgOptions(
@@ -402,77 +410,69 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                         is_proc_macro: false,
                     },
                     CrateId(
-                        3,
+                        4,
                     ): CrateData {
                         root_file_id: FileId(
-                            4,
+                            5,
                         ),
-                        edition: Edition2018,
+                        edition: Edition2015,
                         version: Some(
-                            "0.1.0",
+                            "0.2.98",
                         ),
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "it",
+                                    "libc",
                                 ),
-                                canonical_name: "it",
+                                canonical_name: "libc",
                             },
                         ),
                         cfg_options: CfgOptions(
                             [
                                 "debug_assertions",
+                                "feature=default",
+                                "feature=std",
                             ],
                         ),
                         potential_cfg_options: CfgOptions(
                             [
                                 "debug_assertions",
+                                "feature=align",
+                                "feature=const-extern-fn",
+                                "feature=default",
+                                "feature=extra_traits",
+                                "feature=rustc-dep-of-std",
+                                "feature=std",
+                                "feature=use_std",
                             ],
                         ),
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
                                 "CARGO_PKG_VERSION_MAJOR": "0",
-                                "CARGO_MANIFEST_DIR": "$ROOT$hello-world",
-                                "CARGO_PKG_VERSION": "0.1.0",
+                                "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98",
+                                "CARGO_PKG_VERSION": "0.2.98",
                                 "CARGO_PKG_AUTHORS": "",
-                                "CARGO_CRATE_NAME": "hello_world",
+                                "CARGO_CRATE_NAME": "libc",
                                 "CARGO_PKG_LICENSE_FILE": "",
                                 "CARGO_PKG_HOMEPAGE": "",
                                 "CARGO_PKG_DESCRIPTION": "",
-                                "CARGO_PKG_NAME": "hello-world",
-                                "CARGO_PKG_VERSION_PATCH": "0",
+                                "CARGO_PKG_NAME": "libc",
+                                "CARGO_PKG_VERSION_PATCH": "98",
                                 "CARGO": "cargo",
                                 "CARGO_PKG_REPOSITORY": "",
-                                "CARGO_PKG_VERSION_MINOR": "1",
+                                "CARGO_PKG_VERSION_MINOR": "2",
                                 "CARGO_PKG_VERSION_PRE": "",
                             },
                         },
-                        dependencies: [
-                            Dependency {
-                                crate_id: CrateId(
-                                    0,
-                                ),
-                                name: CrateName(
-                                    "hello_world",
-                                ),
-                                prelude: true,
-                            },
-                            Dependency {
-                                crate_id: CrateId(
-                                    4,
-                                ),
-                                name: CrateName(
-                                    "libc",
-                                ),
-                                prelude: true,
-                            },
-                        ],
+                        dependencies: [],
                         proc_macro: Err(
                             "crate has not (yet) been built",
                         ),
                         origin: CratesIo {
-                            repo: None,
+                            repo: Some(
+                                "https://github.com/rust-lang/libc",
+                            ),
                         },
                         is_proc_macro: false,
                     },
@@ -567,10 +567,10 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                         is_proc_macro: false,
                     },
                     CrateId(
-                        2,
+                        1,
                     ): CrateData {
                         root_file_id: FileId(
-                            3,
+                            2,
                         ),
                         edition: Edition2018,
                         version: Some(
@@ -579,9 +579,9 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "an_example",
+                                    "hello_world",
                                 ),
-                                canonical_name: "an-example",
+                                canonical_name: "hello-world",
                             },
                         ),
                         cfg_options: CfgOptions(
@@ -644,77 +644,10 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                         is_proc_macro: false,
                     },
                     CrateId(
-                        4,
-                    ): CrateData {
-                        root_file_id: FileId(
-                            5,
-                        ),
-                        edition: Edition2015,
-                        version: Some(
-                            "0.2.98",
-                        ),
-                        display_name: Some(
-                            CrateDisplayName {
-                                crate_name: CrateName(
-                                    "libc",
-                                ),
-                                canonical_name: "libc",
-                            },
-                        ),
-                        cfg_options: CfgOptions(
-                            [
-                                "debug_assertions",
-                                "feature=default",
-                                "feature=std",
-                            ],
-                        ),
-                        potential_cfg_options: CfgOptions(
-                            [
-                                "debug_assertions",
-                                "feature=align",
-                                "feature=const-extern-fn",
-                                "feature=default",
-                                "feature=extra_traits",
-                                "feature=rustc-dep-of-std",
-                                "feature=std",
-                                "feature=use_std",
-                            ],
-                        ),
-                        env: Env {
-                            entries: {
-                                "CARGO_PKG_LICENSE": "",
-                                "CARGO_PKG_VERSION_MAJOR": "0",
-                                "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98",
-                                "CARGO_PKG_VERSION": "0.2.98",
-                                "CARGO_PKG_AUTHORS": "",
-                                "CARGO_CRATE_NAME": "libc",
-                                "CARGO_PKG_LICENSE_FILE": "",
-                                "CARGO_PKG_HOMEPAGE": "",
-                                "CARGO_PKG_DESCRIPTION": "",
-                                "CARGO_PKG_NAME": "libc",
-                                "CARGO_PKG_VERSION_PATCH": "98",
-                                "CARGO": "cargo",
-                                "CARGO_PKG_REPOSITORY": "",
-                                "CARGO_PKG_VERSION_MINOR": "2",
-                                "CARGO_PKG_VERSION_PRE": "",
-                            },
-                        },
-                        dependencies: [],
-                        proc_macro: Err(
-                            "crate has not (yet) been built",
-                        ),
-                        origin: CratesIo {
-                            repo: Some(
-                                "https://github.com/rust-lang/libc",
-                            ),
-                        },
-                        is_proc_macro: false,
-                    },
-                    CrateId(
-                        1,
+                        2,
                     ): CrateData {
                         root_file_id: FileId(
-                            2,
+                            3,
                         ),
                         edition: Edition2018,
                         version: Some(
@@ -723,9 +656,9 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "hello_world",
+                                    "an_example",
                                 ),
-                                canonical_name: "hello-world",
+                                canonical_name: "an-example",
                             },
                         ),
                         cfg_options: CfgOptions(
@@ -864,92 +797,91 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                         },
                         is_proc_macro: false,
                     },
-                },
-            }"#]],
-    )
-}
-
-#[test]
-fn cargo_hello_world_project_model() {
-    let crate_graph = load_cargo("hello-world-metadata.json");
-    check_crate_graph(
-        crate_graph,
-        expect![[r#"
-            CrateGraph {
-                arena: {
                     CrateId(
-                        0,
+                        4,
                     ): CrateData {
                         root_file_id: FileId(
-                            1,
+                            5,
                         ),
-                        edition: Edition2018,
+                        edition: Edition2015,
                         version: Some(
-                            "0.1.0",
+                            "0.2.98",
                         ),
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "hello_world",
+                                    "libc",
                                 ),
-                                canonical_name: "hello-world",
+                                canonical_name: "libc",
                             },
                         ),
                         cfg_options: CfgOptions(
                             [
                                 "debug_assertions",
-                                "test",
+                                "feature=default",
+                                "feature=std",
                             ],
                         ),
                         potential_cfg_options: CfgOptions(
                             [
                                 "debug_assertions",
-                                "test",
+                                "feature=align",
+                                "feature=const-extern-fn",
+                                "feature=default",
+                                "feature=extra_traits",
+                                "feature=rustc-dep-of-std",
+                                "feature=std",
+                                "feature=use_std",
                             ],
                         ),
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
                                 "CARGO_PKG_VERSION_MAJOR": "0",
-                                "CARGO_MANIFEST_DIR": "$ROOT$hello-world",
-                                "CARGO_PKG_VERSION": "0.1.0",
+                                "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98",
+                                "CARGO_PKG_VERSION": "0.2.98",
                                 "CARGO_PKG_AUTHORS": "",
-                                "CARGO_CRATE_NAME": "hello_world",
+                                "CARGO_CRATE_NAME": "libc",
                                 "CARGO_PKG_LICENSE_FILE": "",
                                 "CARGO_PKG_HOMEPAGE": "",
                                 "CARGO_PKG_DESCRIPTION": "",
-                                "CARGO_PKG_NAME": "hello-world",
-                                "CARGO_PKG_VERSION_PATCH": "0",
+                                "CARGO_PKG_NAME": "libc",
+                                "CARGO_PKG_VERSION_PATCH": "98",
                                 "CARGO": "cargo",
                                 "CARGO_PKG_REPOSITORY": "",
-                                "CARGO_PKG_VERSION_MINOR": "1",
+                                "CARGO_PKG_VERSION_MINOR": "2",
                                 "CARGO_PKG_VERSION_PRE": "",
                             },
                         },
-                        dependencies: [
-                            Dependency {
-                                crate_id: CrateId(
-                                    4,
-                                ),
-                                name: CrateName(
-                                    "libc",
-                                ),
-                                prelude: true,
-                            },
-                        ],
+                        dependencies: [],
                         proc_macro: Err(
                             "crate has not (yet) been built",
                         ),
                         origin: CratesIo {
-                            repo: None,
+                            repo: Some(
+                                "https://github.com/rust-lang/libc",
+                            ),
                         },
                         is_proc_macro: false,
                     },
+                },
+            }"#]],
+    )
+}
+
+#[test]
+fn cargo_hello_world_project_model() {
+    let crate_graph = load_cargo("hello-world-metadata.json");
+    check_crate_graph(
+        crate_graph,
+        expect![[r#"
+            CrateGraph {
+                arena: {
                     CrateId(
-                        2,
+                        0,
                     ): CrateData {
                         root_file_id: FileId(
-                            3,
+                            1,
                         ),
                         edition: Edition2018,
                         version: Some(
@@ -958,9 +890,9 @@ fn cargo_hello_world_project_model() {
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "an_example",
+                                    "hello_world",
                                 ),
-                                canonical_name: "an-example",
+                                canonical_name: "hello-world",
                             },
                         ),
                         cfg_options: CfgOptions(
@@ -995,15 +927,6 @@ fn cargo_hello_world_project_model() {
                             },
                         },
                         dependencies: [
-                            Dependency {
-                                crate_id: CrateId(
-                                    0,
-                                ),
-                                name: CrateName(
-                                    "hello_world",
-                                ),
-                                prelude: true,
-                            },
                             Dependency {
                                 crate_id: CrateId(
                                     4,
@@ -1023,77 +946,87 @@ fn cargo_hello_world_project_model() {
                         is_proc_macro: false,
                     },
                     CrateId(
-                        4,
+                        1,
                     ): CrateData {
                         root_file_id: FileId(
-                            5,
+                            2,
                         ),
-                        edition: Edition2015,
+                        edition: Edition2018,
                         version: Some(
-                            "0.2.98",
+                            "0.1.0",
                         ),
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "libc",
+                                    "hello_world",
                                 ),
-                                canonical_name: "libc",
+                                canonical_name: "hello-world",
                             },
                         ),
                         cfg_options: CfgOptions(
                             [
                                 "debug_assertions",
-                                "feature=default",
-                                "feature=std",
+                                "test",
                             ],
                         ),
                         potential_cfg_options: CfgOptions(
                             [
                                 "debug_assertions",
-                                "feature=align",
-                                "feature=const-extern-fn",
-                                "feature=default",
-                                "feature=extra_traits",
-                                "feature=rustc-dep-of-std",
-                                "feature=std",
-                                "feature=use_std",
+                                "test",
                             ],
                         ),
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
                                 "CARGO_PKG_VERSION_MAJOR": "0",
-                                "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98",
-                                "CARGO_PKG_VERSION": "0.2.98",
+                                "CARGO_MANIFEST_DIR": "$ROOT$hello-world",
+                                "CARGO_PKG_VERSION": "0.1.0",
                                 "CARGO_PKG_AUTHORS": "",
-                                "CARGO_CRATE_NAME": "libc",
+                                "CARGO_CRATE_NAME": "hello_world",
                                 "CARGO_PKG_LICENSE_FILE": "",
                                 "CARGO_PKG_HOMEPAGE": "",
                                 "CARGO_PKG_DESCRIPTION": "",
-                                "CARGO_PKG_NAME": "libc",
-                                "CARGO_PKG_VERSION_PATCH": "98",
+                                "CARGO_PKG_NAME": "hello-world",
+                                "CARGO_PKG_VERSION_PATCH": "0",
                                 "CARGO": "cargo",
                                 "CARGO_PKG_REPOSITORY": "",
-                                "CARGO_PKG_VERSION_MINOR": "2",
+                                "CARGO_PKG_VERSION_MINOR": "1",
                                 "CARGO_PKG_VERSION_PRE": "",
                             },
                         },
-                        dependencies: [],
+                        dependencies: [
+                            Dependency {
+                                crate_id: CrateId(
+                                    0,
+                                ),
+                                name: CrateName(
+                                    "hello_world",
+                                ),
+                                prelude: true,
+                            },
+                            Dependency {
+                                crate_id: CrateId(
+                                    4,
+                                ),
+                                name: CrateName(
+                                    "libc",
+                                ),
+                                prelude: true,
+                            },
+                        ],
                         proc_macro: Err(
                             "crate has not (yet) been built",
                         ),
                         origin: CratesIo {
-                            repo: Some(
-                                "https://github.com/rust-lang/libc",
-                            ),
+                            repo: None,
                         },
                         is_proc_macro: false,
                     },
                     CrateId(
-                        1,
+                        2,
                     ): CrateData {
                         root_file_id: FileId(
-                            2,
+                            3,
                         ),
                         edition: Edition2018,
                         version: Some(
@@ -1102,9 +1035,9 @@ fn cargo_hello_world_project_model() {
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "hello_world",
+                                    "an_example",
                                 ),
-                                canonical_name: "hello-world",
+                                canonical_name: "an-example",
                             },
                         ),
                         cfg_options: CfgOptions(
@@ -1243,6 +1176,73 @@ fn cargo_hello_world_project_model() {
                         },
                         is_proc_macro: false,
                     },
+                    CrateId(
+                        4,
+                    ): CrateData {
+                        root_file_id: FileId(
+                            5,
+                        ),
+                        edition: Edition2015,
+                        version: Some(
+                            "0.2.98",
+                        ),
+                        display_name: Some(
+                            CrateDisplayName {
+                                crate_name: CrateName(
+                                    "libc",
+                                ),
+                                canonical_name: "libc",
+                            },
+                        ),
+                        cfg_options: CfgOptions(
+                            [
+                                "debug_assertions",
+                                "feature=default",
+                                "feature=std",
+                            ],
+                        ),
+                        potential_cfg_options: CfgOptions(
+                            [
+                                "debug_assertions",
+                                "feature=align",
+                                "feature=const-extern-fn",
+                                "feature=default",
+                                "feature=extra_traits",
+                                "feature=rustc-dep-of-std",
+                                "feature=std",
+                                "feature=use_std",
+                            ],
+                        ),
+                        env: Env {
+                            entries: {
+                                "CARGO_PKG_LICENSE": "",
+                                "CARGO_PKG_VERSION_MAJOR": "0",
+                                "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98",
+                                "CARGO_PKG_VERSION": "0.2.98",
+                                "CARGO_PKG_AUTHORS": "",
+                                "CARGO_CRATE_NAME": "libc",
+                                "CARGO_PKG_LICENSE_FILE": "",
+                                "CARGO_PKG_HOMEPAGE": "",
+                                "CARGO_PKG_DESCRIPTION": "",
+                                "CARGO_PKG_NAME": "libc",
+                                "CARGO_PKG_VERSION_PATCH": "98",
+                                "CARGO": "cargo",
+                                "CARGO_PKG_REPOSITORY": "",
+                                "CARGO_PKG_VERSION_MINOR": "2",
+                                "CARGO_PKG_VERSION_PRE": "",
+                            },
+                        },
+                        dependencies: [],
+                        proc_macro: Err(
+                            "crate has not (yet) been built",
+                        ),
+                        origin: CratesIo {
+                            repo: Some(
+                                "https://github.com/rust-lang/libc",
+                            ),
+                        },
+                        is_proc_macro: false,
+                    },
                 },
             }"#]],
     )
@@ -1301,19 +1301,53 @@ fn rust_project_hello_world_project_model() {
                         is_proc_macro: false,
                     },
                     CrateId(
-                        10,
+                        1,
                     ): CrateData {
                         root_file_id: FileId(
-                            11,
+                            2,
                         ),
                         edition: Edition2018,
                         version: None,
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "unwind",
+                                    "core",
                                 ),
-                                canonical_name: "unwind",
+                                canonical_name: "core",
+                            },
+                        ),
+                        cfg_options: CfgOptions(
+                            [],
+                        ),
+                        potential_cfg_options: CfgOptions(
+                            [],
+                        ),
+                        env: Env {
+                            entries: {},
+                        },
+                        dependencies: [],
+                        proc_macro: Err(
+                            "no proc macro loaded for sysroot crate",
+                        ),
+                        origin: Lang(
+                            Core,
+                        ),
+                        is_proc_macro: false,
+                    },
+                    CrateId(
+                        2,
+                    ): CrateData {
+                        root_file_id: FileId(
+                            3,
+                        ),
+                        edition: Edition2018,
+                        version: None,
+                        display_name: Some(
+                            CrateDisplayName {
+                                crate_name: CrateName(
+                                    "panic_abort",
+                                ),
+                                canonical_name: "panic_abort",
                             },
                         ),
                         cfg_options: CfgOptions(
@@ -1335,19 +1369,19 @@ fn rust_project_hello_world_project_model() {
                         is_proc_macro: false,
                     },
                     CrateId(
-                        7,
+                        3,
                     ): CrateData {
                         root_file_id: FileId(
-                            8,
+                            4,
                         ),
                         edition: Edition2018,
                         version: None,
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "std_detect",
+                                    "panic_unwind",
                                 ),
-                                canonical_name: "std_detect",
+                                canonical_name: "panic_unwind",
                             },
                         ),
                         cfg_options: CfgOptions(
@@ -1413,19 +1447,19 @@ fn rust_project_hello_world_project_model() {
                         is_proc_macro: false,
                     },
                     CrateId(
-                        1,
+                        5,
                     ): CrateData {
                         root_file_id: FileId(
-                            2,
+                            6,
                         ),
                         edition: Edition2018,
                         version: None,
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "core",
+                                    "profiler_builtins",
                                 ),
-                                canonical_name: "core",
+                                canonical_name: "profiler_builtins",
                             },
                         ),
                         cfg_options: CfgOptions(
@@ -1442,24 +1476,24 @@ fn rust_project_hello_world_project_model() {
                             "no proc macro loaded for sysroot crate",
                         ),
                         origin: Lang(
-                            Core,
+                            Other,
                         ),
                         is_proc_macro: false,
                     },
                     CrateId(
-                        11,
+                        6,
                     ): CrateData {
                         root_file_id: FileId(
-                            12,
+                            7,
                         ),
                         edition: Edition2018,
                         version: None,
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "hello_world",
+                                    "std",
                                 ),
-                                canonical_name: "hello_world",
+                                canonical_name: "std",
                             },
                         ),
                         cfg_options: CfgOptions(
@@ -1472,6 +1506,15 @@ fn rust_project_hello_world_project_model() {
                             entries: {},
                         },
                         dependencies: [
+                            Dependency {
+                                crate_id: CrateId(
+                                    0,
+                                ),
+                                name: CrateName(
+                                    "alloc",
+                                ),
+                                prelude: true,
+                            },
                             Dependency {
                                 crate_id: CrateId(
                                     1,
@@ -1483,19 +1526,46 @@ fn rust_project_hello_world_project_model() {
                             },
                             Dependency {
                                 crate_id: CrateId(
-                                    0,
+                                    2,
                                 ),
                                 name: CrateName(
-                                    "alloc",
+                                    "panic_abort",
                                 ),
                                 prelude: true,
                             },
                             Dependency {
                                 crate_id: CrateId(
-                                    6,
+                                    3,
                                 ),
                                 name: CrateName(
-                                    "std",
+                                    "panic_unwind",
+                                ),
+                                prelude: true,
+                            },
+                            Dependency {
+                                crate_id: CrateId(
+                                    5,
+                                ),
+                                name: CrateName(
+                                    "profiler_builtins",
+                                ),
+                                prelude: true,
+                            },
+                            Dependency {
+                                crate_id: CrateId(
+                                    7,
+                                ),
+                                name: CrateName(
+                                    "std_detect",
+                                ),
+                                prelude: true,
+                            },
+                            Dependency {
+                                crate_id: CrateId(
+                                    8,
+                                ),
+                                name: CrateName(
+                                    "term",
                                 ),
                                 prelude: true,
                             },
@@ -1506,31 +1576,40 @@ fn rust_project_hello_world_project_model() {
                                 name: CrateName(
                                     "test",
                                 ),
-                                prelude: false,
+                                prelude: true,
+                            },
+                            Dependency {
+                                crate_id: CrateId(
+                                    10,
+                                ),
+                                name: CrateName(
+                                    "unwind",
+                                ),
+                                prelude: true,
                             },
                         ],
                         proc_macro: Err(
-                            "no proc macro dylib present",
+                            "no proc macro loaded for sysroot crate",
+                        ),
+                        origin: Lang(
+                            Std,
                         ),
-                        origin: CratesIo {
-                            repo: None,
-                        },
                         is_proc_macro: false,
                     },
                     CrateId(
-                        8,
+                        7,
                     ): CrateData {
                         root_file_id: FileId(
-                            9,
+                            8,
                         ),
                         edition: Edition2018,
                         version: None,
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "term",
+                                    "std_detect",
                                 ),
-                                canonical_name: "term",
+                                canonical_name: "std_detect",
                             },
                         ),
                         cfg_options: CfgOptions(
@@ -1552,19 +1631,19 @@ fn rust_project_hello_world_project_model() {
                         is_proc_macro: false,
                     },
                     CrateId(
-                        5,
+                        8,
                     ): CrateData {
                         root_file_id: FileId(
-                            6,
+                            9,
                         ),
                         edition: Edition2018,
                         version: None,
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "profiler_builtins",
+                                    "term",
                                 ),
-                                canonical_name: "profiler_builtins",
+                                canonical_name: "term",
                             },
                         ),
                         cfg_options: CfgOptions(
@@ -1586,19 +1665,19 @@ fn rust_project_hello_world_project_model() {
                         is_proc_macro: false,
                     },
                     CrateId(
-                        2,
+                        9,
                     ): CrateData {
                         root_file_id: FileId(
-                            3,
+                            10,
                         ),
                         edition: Edition2018,
                         version: None,
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "panic_abort",
+                                    "test",
                                 ),
-                                canonical_name: "panic_abort",
+                                canonical_name: "test",
                             },
                         ),
                         cfg_options: CfgOptions(
@@ -1615,24 +1694,24 @@ fn rust_project_hello_world_project_model() {
                             "no proc macro loaded for sysroot crate",
                         ),
                         origin: Lang(
-                            Other,
+                            Test,
                         ),
                         is_proc_macro: false,
                     },
                     CrateId(
-                        9,
+                        10,
                     ): CrateData {
                         root_file_id: FileId(
-                            10,
+                            11,
                         ),
                         edition: Edition2018,
                         version: None,
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "test",
+                                    "unwind",
                                 ),
-                                canonical_name: "test",
+                                canonical_name: "unwind",
                             },
                         ),
                         cfg_options: CfgOptions(
@@ -1649,24 +1728,24 @@ fn rust_project_hello_world_project_model() {
                             "no proc macro loaded for sysroot crate",
                         ),
                         origin: Lang(
-                            Test,
+                            Other,
                         ),
                         is_proc_macro: false,
                     },
                     CrateId(
-                        6,
+                        11,
                     ): CrateData {
                         root_file_id: FileId(
-                            7,
+                            12,
                         ),
                         edition: Edition2018,
                         version: None,
                         display_name: Some(
                             CrateDisplayName {
                                 crate_name: CrateName(
-                                    "std",
+                                    "hello_world",
                                 ),
-                                canonical_name: "std",
+                                canonical_name: "hello_world",
                             },
                         ),
                         cfg_options: CfgOptions(
@@ -1679,15 +1758,6 @@ fn rust_project_hello_world_project_model() {
                             entries: {},
                         },
                         dependencies: [
-                            Dependency {
-                                crate_id: CrateId(
-                                    0,
-                                ),
-                                name: CrateName(
-                                    "alloc",
-                                ),
-                                prelude: true,
-                            },
                             Dependency {
                                 crate_id: CrateId(
                                     1,
@@ -1699,46 +1769,19 @@ fn rust_project_hello_world_project_model() {
                             },
                             Dependency {
                                 crate_id: CrateId(
-                                    2,
-                                ),
-                                name: CrateName(
-                                    "panic_abort",
-                                ),
-                                prelude: true,
-                            },
-                            Dependency {
-                                crate_id: CrateId(
-                                    3,
-                                ),
-                                name: CrateName(
-                                    "panic_unwind",
-                                ),
-                                prelude: true,
-                            },
-                            Dependency {
-                                crate_id: CrateId(
-                                    5,
-                                ),
-                                name: CrateName(
-                                    "profiler_builtins",
-                                ),
-                                prelude: true,
-                            },
-                            Dependency {
-                                crate_id: CrateId(
-                                    7,
+                                    0,
                                 ),
                                 name: CrateName(
-                                    "std_detect",
+                                    "alloc",
                                 ),
                                 prelude: true,
                             },
                             Dependency {
                                 crate_id: CrateId(
-                                    8,
+                                    6,
                                 ),
                                 name: CrateName(
-                                    "term",
+                                    "std",
                                 ),
                                 prelude: true,
                             },
@@ -1749,58 +1792,15 @@ fn rust_project_hello_world_project_model() {
                                 name: CrateName(
                                     "test",
                                 ),
-                                prelude: true,
-                            },
-                            Dependency {
-                                crate_id: CrateId(
-                                    10,
-                                ),
-                                name: CrateName(
-                                    "unwind",
-                                ),
-                                prelude: true,
+                                prelude: false,
                             },
                         ],
                         proc_macro: Err(
-                            "no proc macro loaded for sysroot crate",
-                        ),
-                        origin: Lang(
-                            Std,
-                        ),
-                        is_proc_macro: false,
-                    },
-                    CrateId(
-                        3,
-                    ): CrateData {
-                        root_file_id: FileId(
-                            4,
-                        ),
-                        edition: Edition2018,
-                        version: None,
-                        display_name: Some(
-                            CrateDisplayName {
-                                crate_name: CrateName(
-                                    "panic_unwind",
-                                ),
-                                canonical_name: "panic_unwind",
-                            },
-                        ),
-                        cfg_options: CfgOptions(
-                            [],
-                        ),
-                        potential_cfg_options: CfgOptions(
-                            [],
+                            "no proc macro dylib present",
                         ),
-                        env: Env {
-                            entries: {},
+                        origin: CratesIo {
+                            repo: None,
                         },
-                        dependencies: [],
-                        proc_macro: Err(
-                            "no proc macro loaded for sysroot crate",
-                        ),
-                        origin: Lang(
-                            Other,
-                        ),
                         is_proc_macro: false,
                     },
                 },