about summary refs log tree commit diff
diff options
context:
space:
mode:
authorhkalbasi <hamidrezakalbasi@protonmail.com>2022-12-21 18:54:49 +0330
committerhkalbasi <hamidrezakalbasi@protonmail.com>2022-12-21 18:54:49 +0330
commite1aa73ef40b8902b2cbdd8272978fcc1c47cf3c7 (patch)
tree2f73d440bb710749f0f4228ddcf44be6362bfc93
parent801a2231bf154a720db97d50e8e581d1f8666e2a (diff)
downloadrust-e1aa73ef40b8902b2cbdd8272978fcc1c47cf3c7.tar.gz
rust-e1aa73ef40b8902b2cbdd8272978fcc1c47cf3c7.zip
Disable inlay hint location links on vscode < 1.76
-rw-r--r--crates/ide/src/inlay_hints.rs14
-rw-r--r--crates/ide/src/inlay_hints/bind_pat.rs5
-rw-r--r--crates/ide/src/inlay_hints/chaining.rs76
-rw-r--r--crates/ide/src/inlay_hints/closing_brace.rs5
-rw-r--r--crates/ide/src/static_index.rs1
-rw-r--r--crates/rust-analyzer/src/bin/main.rs2
-rw-r--r--crates/rust-analyzer/src/config.rs18
-rw-r--r--docs/user/generated_config.adoc5
-rw-r--r--editors/code/package.json5
9 files changed, 121 insertions, 10 deletions
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 8163697fbfc..9aef78143d6 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -27,6 +27,7 @@ mod bind_pat;
 
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct InlayHintsConfig {
+    pub location_links: bool,
     pub render_colons: bool,
     pub type_hints: bool,
     pub parameter_hints: bool,
@@ -182,6 +183,7 @@ struct InlayHintLabelBuilder<'a> {
     db: &'a RootDatabase,
     result: InlayHintLabel,
     last_part: String,
+    location_link_enabled: bool,
     location: Option<FileRange>,
 }
 
@@ -193,6 +195,9 @@ impl fmt::Write for InlayHintLabelBuilder<'_> {
 
 impl HirWrite for InlayHintLabelBuilder<'_> {
     fn start_location_link(&mut self, def: ModuleDefId) {
+        if !self.location_link_enabled {
+            return;
+        }
         if self.location.is_some() {
             never!("location link is already started");
         }
@@ -204,6 +209,9 @@ impl HirWrite for InlayHintLabelBuilder<'_> {
     }
 
     fn end_location_link(&mut self) {
+        if !self.location_link_enabled {
+            return;
+        }
         self.make_new_part();
     }
 }
@@ -260,6 +268,7 @@ fn label_of_ty(
         db: sema.db,
         last_part: String::new(),
         location: None,
+        location_link_enabled: config.location_links,
         result: InlayHintLabel::default(),
     };
     rec(sema, &famous_defs, config.max_length, ty, &mut label_builder);
@@ -416,6 +425,7 @@ mod tests {
     use super::ClosureReturnTypeHints;
 
     pub(super) const DISABLED_CONFIG: InlayHintsConfig = InlayHintsConfig {
+        location_links: false,
         render_colons: false,
         type_hints: false,
         parameter_hints: false,
@@ -430,6 +440,8 @@ mod tests {
         max_length: None,
         closing_brace_hints_min_lines: None,
     };
+    pub(super) const DISABLED_CONFIG_WITH_LINKS: InlayHintsConfig =
+        InlayHintsConfig { location_links: true, ..DISABLED_CONFIG };
     pub(super) const TEST_CONFIG: InlayHintsConfig = InlayHintsConfig {
         type_hints: true,
         parameter_hints: true,
@@ -437,7 +449,7 @@ mod tests {
         closure_return_type_hints: ClosureReturnTypeHints::WithBlock,
         binding_mode_hints: true,
         lifetime_elision_hints: LifetimeElisionHints::Always,
-        ..DISABLED_CONFIG
+        ..DISABLED_CONFIG_WITH_LINKS
     };
 
     #[track_caller]
diff --git a/crates/ide/src/inlay_hints/bind_pat.rs b/crates/ide/src/inlay_hints/bind_pat.rs
index c9f787e0748..7766d497918 100644
--- a/crates/ide/src/inlay_hints/bind_pat.rs
+++ b/crates/ide/src/inlay_hints/bind_pat.rs
@@ -194,7 +194,8 @@ mod tests {
     use crate::{fixture, inlay_hints::InlayHintsConfig};
 
     use crate::inlay_hints::tests::{
-        check, check_expect, check_with_config, DISABLED_CONFIG, TEST_CONFIG,
+        check, check_expect, check_with_config, DISABLED_CONFIG, DISABLED_CONFIG_WITH_LINKS,
+        TEST_CONFIG,
     };
     use crate::ClosureReturnTypeHints;
 
@@ -290,7 +291,7 @@ fn main() {
     fn iterator_hint_regression_issue_12674() {
         // Ensure we don't crash while solving the projection type of iterators.
         check_expect(
-            InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG },
+            InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS },
             r#"
 //- minicore: iterators
 struct S<T>(T);
diff --git a/crates/ide/src/inlay_hints/chaining.rs b/crates/ide/src/inlay_hints/chaining.rs
index c9aabcbb044..efeb2b79255 100644
--- a/crates/ide/src/inlay_hints/chaining.rs
+++ b/crates/ide/src/inlay_hints/chaining.rs
@@ -74,7 +74,10 @@ mod tests {
     use expect_test::expect;
 
     use crate::{
-        inlay_hints::tests::{check_expect, check_with_config, DISABLED_CONFIG, TEST_CONFIG},
+        inlay_hints::tests::{
+            check_expect, check_with_config, DISABLED_CONFIG, DISABLED_CONFIG_WITH_LINKS,
+            TEST_CONFIG,
+        },
         InlayHintsConfig,
     };
 
@@ -86,7 +89,11 @@ mod tests {
     #[test]
     fn chaining_hints_ignore_comments() {
         check_expect(
-            InlayHintsConfig { type_hints: false, chaining_hints: true, ..DISABLED_CONFIG },
+            InlayHintsConfig {
+                type_hints: false,
+                chaining_hints: true,
+                ..DISABLED_CONFIG_WITH_LINKS
+            },
             r#"
 struct A(B);
 impl A { fn into_b(self) -> B { self.0 } }
@@ -179,10 +186,69 @@ fn main() {
     }
 
     #[test]
-    fn struct_access_chaining_hints() {
+    fn disabled_location_links() {
         check_expect(
             InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG },
             r#"
+    struct A { pub b: B }
+    struct B { pub c: C }
+    struct C(pub bool);
+    struct D;
+
+    impl D {
+        fn foo(&self) -> i32 { 42 }
+    }
+
+    fn main() {
+        let x = A { b: B { c: C(true) } }
+            .b
+            .c
+            .0;
+        let x = D
+            .foo();
+    }"#,
+            expect![[r#"
+                [
+                    InlayHint {
+                        range: 143..190,
+                        kind: ChainingHint,
+                        label: [
+                            "C",
+                        ],
+                        tooltip: Some(
+                            HoverRanged(
+                                FileId(
+                                    0,
+                                ),
+                                143..190,
+                            ),
+                        ),
+                    },
+                    InlayHint {
+                        range: 143..179,
+                        kind: ChainingHint,
+                        label: [
+                            "B",
+                        ],
+                        tooltip: Some(
+                            HoverRanged(
+                                FileId(
+                                    0,
+                                ),
+                                143..179,
+                            ),
+                        ),
+                    },
+                ]
+            "#]],
+        );
+    }
+
+    #[test]
+    fn struct_access_chaining_hints() {
+        check_expect(
+            InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS },
+            r#"
 struct A { pub b: B }
 struct B { pub c: C }
 struct C(pub bool);
@@ -264,7 +330,7 @@ fn main() {
     #[test]
     fn generic_chaining_hints() {
         check_expect(
-            InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG },
+            InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS },
             r#"
 struct A<T>(T);
 struct B<T>(T);
@@ -372,7 +438,7 @@ fn main() {
     #[test]
     fn shorten_iterator_chaining_hints() {
         check_expect(
-            InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG },
+            InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS },
             r#"
 //- minicore: iterators
 use core::iter;
diff --git a/crates/ide/src/inlay_hints/closing_brace.rs b/crates/ide/src/inlay_hints/closing_brace.rs
index 57605b392a8..e340c64c54b 100644
--- a/crates/ide/src/inlay_hints/closing_brace.rs
+++ b/crates/ide/src/inlay_hints/closing_brace.rs
@@ -109,7 +109,10 @@ pub(super) fn hints(
         return None;
     }
 
-    let linked_location = name_range.map(|range| FileRange { file_id, range });
+    let linked_location = config
+        .location_links
+        .then(|| name_range.map(|range| FileRange { file_id, range }))
+        .flatten();
     acc.push(InlayHint {
         range: closing_token.text_range(),
         kind: InlayKind::ClosingBraceHint,
diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs
index 2380cf7381c..42b5951c842 100644
--- a/crates/ide/src/static_index.rs
+++ b/crates/ide/src/static_index.rs
@@ -106,6 +106,7 @@ impl StaticIndex<'_> {
             .analysis
             .inlay_hints(
                 &InlayHintsConfig {
+                    location_links: true,
                     render_colons: true,
                     type_hints: true,
                     parameter_hints: true,
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index 7bf595d2a45..ec5053e991d 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -183,6 +183,8 @@ fn run_server() -> Result<()> {
         }
     }
 
+    config.client_specific_adjustments(&initialize_params.client_info);
+
     let server_capabilities = rust_analyzer::server_capabilities(&config);
 
     let initialize_result = lsp_types::InitializeResult {
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 835b37c98e2..0bcc91eb411 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -20,7 +20,7 @@ use ide_db::{
     SnippetCap,
 };
 use itertools::Itertools;
-use lsp_types::{ClientCapabilities, MarkupKind};
+use lsp_types::{ClientCapabilities, ClientInfo, MarkupKind};
 use project_model::{
     CargoConfig, CargoFeatures, ProjectJson, ProjectJsonData, ProjectManifest, RustcSource,
     UnsetTestCrates,
@@ -333,6 +333,8 @@ config_data! {
         inlayHints_lifetimeElisionHints_enable: LifetimeElisionDef = "\"never\"",
         /// Whether to prefer using parameter names as the name for elided lifetime hints if possible.
         inlayHints_lifetimeElisionHints_useParameterNames: bool    = "false",
+        /// Whether to use location links for parts of type mentioned in inlay hints.
+        inlayHints_locationLinks: bool                             = "true",
         /// Maximum length for inlay hints. Set to null to have an unlimited length.
         inlayHints_maxLength: Option<usize>                        = "25",
         /// Whether to show function parameter name inlay hints at the call
@@ -714,6 +716,19 @@ impl Config {
         }
     }
 
+    pub fn client_specific_adjustments(&mut self, client_info: &Option<ClientInfo>) {
+        // FIXME: remove this when we drop support for vscode 1.65 and below
+        if let Some(client) = client_info {
+            if client.name.contains("Code") || client.name.contains("Codium") {
+                if let Some(version) = &client.version {
+                    if version.as_str() < "1.76" {
+                        self.data.inlayHints_locationLinks = false;
+                    }
+                }
+            }
+        }
+    }
+
     pub fn update(&mut self, mut json: serde_json::Value) -> Result<(), ConfigUpdateError> {
         tracing::info!("updating config from JSON: {:#}", json);
         if json.is_null() || json.as_object().map_or(false, |it| it.is_empty()) {
@@ -1196,6 +1211,7 @@ impl Config {
 
     pub fn inlay_hints(&self) -> InlayHintsConfig {
         InlayHintsConfig {
+            location_links: self.data.inlayHints_locationLinks,
             render_colons: self.data.inlayHints_renderColons,
             type_hints: self.data.inlayHints_typeHints_enable,
             parameter_hints: self.data.inlayHints_parameterHints_enable,
diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc
index db41c7bf109..47511aad0fe 100644
--- a/docs/user/generated_config.adoc
+++ b/docs/user/generated_config.adoc
@@ -469,6 +469,11 @@ Whether to show inlay type hints for elided lifetimes in function signatures.
 --
 Whether to prefer using parameter names as the name for elided lifetime hints if possible.
 --
+[[rust-analyzer.inlayHints.locationLinks]]rust-analyzer.inlayHints.locationLinks (default: `true`)::
++
+--
+Whether to use location links for parts of type mentioned in inlay hints.
+--
 [[rust-analyzer.inlayHints.maxLength]]rust-analyzer.inlayHints.maxLength (default: `25`)::
 +
 --
diff --git a/editors/code/package.json b/editors/code/package.json
index f9b0e28dadb..5b09ee6f7da 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -995,6 +995,11 @@
                     "default": false,
                     "type": "boolean"
                 },
+                "rust-analyzer.inlayHints.locationLinks": {
+                    "markdownDescription": "Whether to use location links for parts of type mentioned in inlay hints.",
+                    "default": true,
+                    "type": "boolean"
+                },
                 "rust-analyzer.inlayHints.maxLength": {
                     "markdownDescription": "Maximum length for inlay hints. Set to null to have an unlimited length.",
                     "default": 25,