about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-02-19 18:00:50 +0100
committerLukas Wirth <lukastw97@gmail.com>2024-02-19 18:16:02 +0100
commita822291a025f495aacef9201807fce77971e8097 (patch)
tree064891497c57f18f3fcff08982c4634ef5b95f0e
parent2223b4fa71e543ac6dd1abd4770a69fab8dbdec1 (diff)
downloadrust-a822291a025f495aacef9201807fce77971e8097.tar.gz
rust-a822291a025f495aacef9201807fce77971e8097.zip
Infallible definition hovers
-rw-r--r--crates/ide-db/src/defs.rs13
-rw-r--r--crates/ide/src/hover.rs37
-rw-r--r--crates/ide/src/hover/render.rs14
-rw-r--r--crates/ide/src/hover/tests.rs105
-rw-r--r--crates/ide/src/static_index.rs4
5 files changed, 135 insertions, 38 deletions
diff --git a/crates/ide-db/src/defs.rs b/crates/ide-db/src/defs.rs
index d95d94ec72e..747c90561de 100644
--- a/crates/ide-db/src/defs.rs
+++ b/crates/ide-db/src/defs.rs
@@ -213,8 +213,8 @@ impl Definition {
         })
     }
 
-    pub fn label(&self, db: &RootDatabase) -> Option<String> {
-        let label = match *self {
+    pub fn label(&self, db: &RootDatabase) -> String {
+        match *self {
             Definition::Macro(it) => it.display(db).to_string(),
             Definition::Field(it) => it.display(db).to_string(),
             Definition::TupleField(it) => it.display(db).to_string(),
@@ -241,7 +241,11 @@ impl Definition {
                 }
             }
             Definition::SelfType(impl_def) => {
-                impl_def.self_ty(db).as_adt().and_then(|adt| Definition::Adt(adt).label(db))?
+                let self_ty = &impl_def.self_ty(db);
+                match self_ty.as_adt() {
+                    Some(it) => it.display(db).to_string(),
+                    None => self_ty.display(db).to_string(),
+                }
             }
             Definition::GenericParam(it) => it.display(db).to_string(),
             Definition::Label(it) => it.name(db).display(db).to_string(),
@@ -249,8 +253,7 @@ impl Definition {
             Definition::BuiltinAttr(it) => format!("#[{}]", it.name(db)),
             Definition::ToolModule(it) => it.name(db).to_string(),
             Definition::DeriveHelper(it) => format!("derive_helper {}", it.name(db).display(db)),
-        };
-        Some(label)
+        }
     }
 }
 
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 19b181ae3b6..4a7350feb38 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -147,7 +147,7 @@ fn hover_simple(
     if let Some(doc_comment) = token_as_doc_comment(&original_token) {
         cov_mark::hit!(no_highlight_on_comment_hover);
         return doc_comment.get_definition_with_descend_at(sema, offset, |def, node, range| {
-            let res = hover_for_definition(sema, file_id, def, &node, config)?;
+            let res = hover_for_definition(sema, file_id, def, &node, config);
             Some(RangeInfo::new(range, res))
         });
     }
@@ -161,7 +161,7 @@ fn hover_simple(
             Definition::from(resolution?),
             &original_token.parent()?,
             config,
-        )?;
+        );
         return Some(RangeInfo::new(range, res));
     }
 
@@ -215,7 +215,7 @@ fn hover_simple(
                 })
                 .flatten()
                 .unique_by(|&(def, _)| def)
-                .filter_map(|(def, node)| hover_for_definition(sema, file_id, def, &node, config))
+                .map(|(def, node)| hover_for_definition(sema, file_id, def, &node, config))
                 .reduce(|mut acc: HoverResult, HoverResult { markup, actions }| {
                     acc.actions.extend(actions);
                     acc.markup = Markup::from(format!("{}\n---\n{markup}", acc.markup));
@@ -373,9 +373,9 @@ pub(crate) fn hover_for_definition(
     def: Definition,
     scope_node: &SyntaxNode,
     config: &HoverConfig,
-) -> Option<HoverResult> {
+) -> HoverResult {
     let famous_defs = match &def {
-        Definition::BuiltinType(_) => Some(FamousDefs(sema, sema.scope(scope_node)?.krate())),
+        Definition::BuiltinType(_) => sema.scope(scope_node).map(|it| FamousDefs(sema, it.krate())),
         _ => None,
     };
 
@@ -396,20 +396,19 @@ pub(crate) fn hover_for_definition(
     };
     let notable_traits = def_ty.map(|ty| notable_traits(db, &ty)).unwrap_or_default();
 
-    render::definition(sema.db, def, famous_defs.as_ref(), &notable_traits, config).map(|markup| {
-        HoverResult {
-            markup: render::process_markup(sema.db, def, &markup, config),
-            actions: [
-                show_implementations_action(sema.db, def),
-                show_fn_references_action(sema.db, def),
-                runnable_action(sema, def, file_id),
-                goto_type_action_for_def(sema.db, def, &notable_traits),
-            ]
-            .into_iter()
-            .flatten()
-            .collect(),
-        }
-    })
+    let markup = render::definition(sema.db, def, famous_defs.as_ref(), &notable_traits, config);
+    HoverResult {
+        markup: render::process_markup(sema.db, def, &markup, config),
+        actions: [
+            show_implementations_action(sema.db, def),
+            show_fn_references_action(sema.db, def),
+            runnable_action(sema, def, file_id),
+            goto_type_action_for_def(sema.db, def, &notable_traits),
+        ]
+        .into_iter()
+        .flatten()
+        .collect(),
+    }
 }
 
 fn notable_traits(
diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs
index eff055c9599..42342d94b6d 100644
--- a/crates/ide/src/hover/render.rs
+++ b/crates/ide/src/hover/render.rs
@@ -264,7 +264,7 @@ pub(super) fn keyword(
     let markup = process_markup(
         sema.db,
         Definition::Module(doc_owner),
-        &markup(Some(docs.into()), description, None)?,
+        &markup(Some(docs.into()), description, None),
         config,
     );
     Some(HoverResult { markup, actions })
@@ -396,11 +396,11 @@ pub(super) fn definition(
     famous_defs: Option<&FamousDefs<'_, '_>>,
     notable_traits: &[(Trait, Vec<(Option<Type>, Name)>)],
     config: &HoverConfig,
-) -> Option<Markup> {
+) -> Markup {
     let mod_path = definition_mod_path(db, &def);
-    let label = def.label(db)?;
+    let label = def.label(db);
     let docs = def.docs(db, famous_defs);
-    let value = match def {
+    let value = (|| match def {
         Definition::Variant(it) => {
             if !it.parent_enum(db).is_data_carrying(db) {
                 match it.eval(db) {
@@ -436,7 +436,7 @@ pub(super) fn definition(
             Some(body.to_string())
         }
         _ => None,
-    };
+    })();
 
     let layout_info = match def {
         Definition::Field(it) => render_memory_layout(
@@ -683,7 +683,7 @@ fn definition_mod_path(db: &RootDatabase, def: &Definition) -> Option<String> {
     def.module(db).map(|module| path(db, module, definition_owner_name(db, def)))
 }
 
-fn markup(docs: Option<String>, desc: String, mod_path: Option<String>) -> Option<Markup> {
+fn markup(docs: Option<String>, desc: String, mod_path: Option<String>) -> Markup {
     let mut buf = String::new();
 
     if let Some(mod_path) = mod_path {
@@ -696,7 +696,7 @@ fn markup(docs: Option<String>, desc: String, mod_path: Option<String>) -> Optio
     if let Some(doc) = docs {
         format_to!(buf, "\n___\n\n{}", doc);
     }
-    Some(buf.into())
+    buf.into()
 }
 
 fn find_std_module(famous_defs: &FamousDefs<'_, '_>, name: &str) -> Option<hir::Module> {
diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs
index 69ddc1e45ef..157f8ff371e 100644
--- a/crates/ide/src/hover/tests.rs
+++ b/crates/ide/src/hover/tests.rs
@@ -1279,11 +1279,11 @@ impl Thing {
     );
     check(
         r#"
-        enum Thing { A }
-        impl Thing {
-            pub fn thing(a: Self$0) {}
-        }
-        "#,
+enum Thing { A }
+impl Thing {
+    pub fn thing(a: Self$0) {}
+}
+"#,
         expect![[r#"
                 *Self*
 
@@ -1298,6 +1298,42 @@ impl Thing {
                 ```
             "#]],
     );
+    check(
+        r#"
+impl usize {
+    pub fn thing(a: Self$0) {}
+}
+"#,
+        expect![[r#"
+            *Self*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            usize
+            ```
+        "#]],
+    );
+    check(
+        r#"
+impl fn() -> usize {
+    pub fn thing(a: Self$0) {}
+}
+"#,
+        expect![[r#"
+            *Self*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            fn() -> usize
+            ```
+        "#]],
+    );
 }
 
 #[test]
@@ -7202,6 +7238,65 @@ impl Iterator for S {
 }
 
 #[test]
+fn extern_items() {
+    check(
+        r#"
+extern "C" {
+    static STATIC$0: ();
+}
+"#,
+        expect![[r#"
+            *STATIC*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            static STATIC: ()
+            ```
+        "#]],
+    );
+    check(
+        r#"
+extern "C" {
+    fn fun$0();
+}
+"#,
+        expect![[r#"
+            *fun*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            unsafe fn fun()
+            ```
+        "#]],
+    );
+    check(
+        r#"
+extern "C" {
+    type Ty$0;
+}
+"#,
+        expect![[r#"
+            *Ty*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+             // size = 0, align = 1
+            type Ty
+            ```
+        "#]],
+    );
+}
+
+#[test]
 fn notable_ranged() {
     check_hover_range(
         r#"
diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs
index 5feaf21aa97..2929a7522e5 100644
--- a/crates/ide/src/static_index.rs
+++ b/crates/ide/src/static_index.rs
@@ -186,7 +186,7 @@ impl StaticIndex<'_> {
             } else {
                 let it = self.tokens.insert(TokenStaticData {
                     documentation: documentation_for_definition(&sema, def, &node),
-                    hover: hover_for_definition(&sema, file_id, def, &node, &hover_config),
+                    hover: Some(hover_for_definition(&sema, file_id, def, &node, &hover_config)),
                     definition: def.try_to_nav(self.db).map(UpmappingResult::call_site).map(|it| {
                         FileRange { file_id: it.file_id, range: it.focus_or_full_range() }
                     }),
@@ -196,7 +196,7 @@ impl StaticIndex<'_> {
                     enclosing_moniker: current_crate
                         .zip(def.enclosing_definition(self.db))
                         .and_then(|(cc, enclosing_def)| def_to_moniker(self.db, enclosing_def, cc)),
-                    signature: def.label(self.db),
+                    signature: Some(def.label(self.db)),
                     kind: def_to_kind(self.db, def),
                 });
                 self.def_map.insert(def, it);