From 7f3572fa0da8b8a50422714570bf83f056b6d6d3 Mon Sep 17 00:00:00 2001
From: Lukas Wirth <lukastw97@gmail.com>
Date: Sun, 10 Apr 2022 12:42:16 +0200
Subject: [PATCH] Simplify

---
 crates/base_db/src/input.rs           | 27 +++++++++++++++++++++++++++
 crates/ide/src/doc_links.rs           | 22 +++++++++++++++-------
 crates/ide/src/hover/tests.rs         |  4 ++--
 crates/ide/src/moniker.rs             | 15 +++++----------
 crates/ide_db/src/famous_defs.rs      | 10 +++-------
 crates/project_model/src/tests.rs     |  2 +-
 crates/project_model/src/workspace.rs |  9 +--------
 7 files changed, 54 insertions(+), 35 deletions(-)

diff --git a/crates/base_db/src/input.rs b/crates/base_db/src/input.rs
index e6d94f1d0dd..9fcaa4b06dd 100644
--- a/crates/base_db/src/input.rs
+++ b/crates/base_db/src/input.rs
@@ -135,6 +135,33 @@ pub enum LangCrateOrigin {
     Other,
 }
 
+impl From<&str> for LangCrateOrigin {
+    fn from(s: &str) -> Self {
+        match s {
+            "alloc" => LangCrateOrigin::Alloc,
+            "core" => LangCrateOrigin::Core,
+            "proc-macro" => LangCrateOrigin::ProcMacro,
+            "std" => LangCrateOrigin::Std,
+            "test" => LangCrateOrigin::Test,
+            _ => LangCrateOrigin::Other,
+        }
+    }
+}
+
+impl fmt::Display for LangCrateOrigin {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let text = match self {
+            LangCrateOrigin::Alloc => "alloc",
+            LangCrateOrigin::Core => "core",
+            LangCrateOrigin::ProcMacro => "proc_macro",
+            LangCrateOrigin::Std => "std",
+            LangCrateOrigin::Test => "test",
+            LangCrateOrigin::Other => "other",
+        };
+        f.write_str(text)
+    }
+}
+
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct CrateDisplayName {
     // The name we use to display various paths (with `_`).
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs
index a98cd214c30..a1e170634b7 100644
--- a/crates/ide/src/doc_links.rs
+++ b/crates/ide/src/doc_links.rs
@@ -12,6 +12,7 @@ use url::Url;
 
 use hir::{db::HirDatabase, Adt, AsAssocItem, AssocItem, AssocItemContainer, Crate, HasAttrs};
 use ide_db::{
+    base_db::{CrateOrigin, LangCrateOrigin, SourceDatabase},
     defs::{Definition, NameClass, NameRefClass},
     helpers::pick_best_token,
     RootDatabase,
@@ -293,7 +294,7 @@ fn get_doc_link(db: &RootDatabase, def: Definition) -> Option<String> {
     let (target, file, frag) = filename_and_frag_for_def(db, def)?;
 
     let krate = crate_of_def(db, target)?;
-    let mut url = get_doc_base_url(db, &krate)?;
+    let mut url = get_doc_base_url(db, krate)?;
 
     if let Some(path) = mod_path_of_def(db, target) {
         url = url.join(&path).ok()?;
@@ -315,7 +316,7 @@ fn rewrite_intra_doc_link(
 
     let resolved = resolve_doc_path_for_def(db, def, link, ns)?;
     let krate = crate_of_def(db, resolved)?;
-    let mut url = get_doc_base_url(db, &krate)?;
+    let mut url = get_doc_base_url(db, krate)?;
 
     let (_, file, frag) = filename_and_frag_for_def(db, resolved)?;
     if let Some(path) = mod_path_of_def(db, resolved) {
@@ -335,7 +336,7 @@ fn rewrite_url_link(db: &RootDatabase, def: Definition, target: &str) -> Option<
     }
 
     let krate = crate_of_def(db, def)?;
-    let mut url = get_doc_base_url(db, &krate)?;
+    let mut url = get_doc_base_url(db, krate)?;
     let (def, file, frag) = filename_and_frag_for_def(db, def)?;
 
     if let Some(path) = mod_path_of_def(db, def) {
@@ -406,13 +407,20 @@ fn map_links<'e>(
 /// https://doc.rust-lang.org/std/iter/trait.Iterator.html#tymethod.next
 /// ^^^^^^^^^^^^^^^^^^^^^^^^^^
 /// ```
-fn get_doc_base_url(db: &RootDatabase, krate: &Crate) -> Option<Url> {
+fn get_doc_base_url(db: &RootDatabase, krate: Crate) -> Option<Url> {
     let display_name = krate.display_name(db)?;
-    let base = match &**display_name.crate_name() {
+
+    let base = match db.crate_graph()[krate.into()].origin {
         // std and co do not specify `html_root_url` any longer so we gotta handwrite this ourself.
         // FIXME: Use the toolchains channel instead of nightly
-        name @ ("core" | "std" | "alloc" | "proc_macro" | "test") => {
-            format!("https://doc.rust-lang.org/nightly/{}", name)
+        CrateOrigin::Lang(
+            origin @ (LangCrateOrigin::Alloc
+            | LangCrateOrigin::Core
+            | LangCrateOrigin::ProcMacro
+            | LangCrateOrigin::Std
+            | LangCrateOrigin::Test),
+        ) => {
+            format!("https://doc.rust-lang.org/nightly/{origin}")
         }
         _ => {
             krate.get_html_root_url(db).or_else(|| {
diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs
index 67dc9884ed3..57e049c10dd 100644
--- a/crates/ide/src/hover/tests.rs
+++ b/crates/ide/src/hover/tests.rs
@@ -4531,7 +4531,7 @@ foo_macro!(
 
             ---
 
-            Doc comment for [`Foo`](https://doc.rust-lang.org/nightly/test/struct.Foo.html)
+            Doc comment for [`Foo`](https://docs.rs/test/*/test/struct.Foo.html)
         "#]],
     );
 }
@@ -4556,7 +4556,7 @@ pub struct Foo;
 
             ---
 
-            Doc comment for [`Foo`](https://doc.rust-lang.org/nightly/test/struct.Foo.html)
+            Doc comment for [`Foo`](https://docs.rs/test/*/test/struct.Foo.html)
         "#]],
     );
 }
diff --git a/crates/ide/src/moniker.rs b/crates/ide/src/moniker.rs
index 0f75abe55c1..6bab9fa1ebb 100644
--- a/crates/ide/src/moniker.rs
+++ b/crates/ide/src/moniker.rs
@@ -153,17 +153,12 @@ pub(crate) fn def_to_moniker(
                 CrateOrigin::CratesIo { repo } => (repo?, krate.version(db)?),
                 CrateOrigin::Lang(lang) => (
                     "https://github.com/rust-lang/rust/".to_string(),
-                    format!(
-                        "https://github.com/rust-lang/rust/library/{}",
-                        match lang {
-                            LangCrateOrigin::Alloc => "alloc",
-                            LangCrateOrigin::Core => "core",
-                            LangCrateOrigin::ProcMacro => "proc_macro",
-                            LangCrateOrigin::Std => "std",
-                            LangCrateOrigin::Test => "test",
-                            LangCrateOrigin::Other => "",
+                    match lang {
+                        LangCrateOrigin::Other => {
+                            "https://github.com/rust-lang/rust/library/".into()
                         }
-                    ),
+                        lang => format!("https://github.com/rust-lang/rust/library/{lang}",),
+                    },
                 ),
             };
             PackageInformation { name, repo, version }
diff --git a/crates/ide_db/src/famous_defs.rs b/crates/ide_db/src/famous_defs.rs
index 58d99ff9dfd..f17fd0faa53 100644
--- a/crates/ide_db/src/famous_defs.rs
+++ b/crates/ide_db/src/famous_defs.rs
@@ -158,13 +158,9 @@ impl FamousDefs<'_, '_> {
         let mut path = path.split(':');
         let trait_ = path.next_back()?;
         let lang_crate = path.next()?;
-        let lang_crate = match lang_crate {
-            "core" => LangCrateOrigin::Core,
-            "alloc" => LangCrateOrigin::Alloc,
-            "test" => LangCrateOrigin::Test,
-            "proc_macro" => LangCrateOrigin::ProcMacro,
-            "std" => LangCrateOrigin::Std,
-            _ => return None,
+        let lang_crate = match LangCrateOrigin::from(lang_crate) {
+            LangCrateOrigin::Other => return None,
+            lang_crate => lang_crate,
         };
         let std_crate = self.find_lang_crate(lang_crate)?;
         let mut module = std_crate.root_module(db);
diff --git a/crates/project_model/src/tests.rs b/crates/project_model/src/tests.rs
index 351e820adab..3d089b61b5a 100644
--- a/crates/project_model/src/tests.rs
+++ b/crates/project_model/src/tests.rs
@@ -1368,7 +1368,7 @@ fn rust_project_hello_world_project_model() {
                         ],
                         proc_macro: [],
                         origin: Lang(
-                            ProcMacro,
+                            Other,
                         ),
                         is_proc_macro: false,
                     },
diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs
index 509219f0b66..e33ae608620 100644
--- a/crates/project_model/src/workspace.rs
+++ b/crates/project_model/src/workspace.rs
@@ -908,14 +908,7 @@ fn sysroot_to_crate_graph(
                 env,
                 proc_macro,
                 false,
-                CrateOrigin::Lang(match &*sysroot[krate].name {
-                    "alloc" => LangCrateOrigin::Alloc,
-                    "core" => LangCrateOrigin::Core,
-                    "proc_macro" => LangCrateOrigin::ProcMacro,
-                    "std" => LangCrateOrigin::Std,
-                    "test" => LangCrateOrigin::Test,
-                    _ => LangCrateOrigin::Other,
-                }),
+                CrateOrigin::Lang(LangCrateOrigin::from(&*sysroot[krate].name)),
             );
             Some((krate, crate_id))
         })