Repository: rust-analyzer/rust-analyzer
Pull request #3388 (2020-03-01 15:55:12)

Remove inlay hint in diff views
If the left side of a diff view that contain the old version of the file apply inlays they are misplaced and produce a weird display:

![image](https://user-images.githubusercontent.com/131878/75628802-b1ac1900-5bdc-11ea-8c26-6722d8e38371.png)

After the change:

![image](https://user-images.githubusercontent.com/131878/75628831-e91ac580-5bdc-11ea-9039-c6b4ffbdb2be.png)

The detection is done by blacklisting the url schemes used by git and subversion scm extensions, whitelisting `file` is also possible but neither is perfect as VSCode now support both pluggable scm extensions and pluggable remote filesystems. But I suspect that the list of scm extensions is more easily manageable.

**Note**: I can rebase on #3378 if needed as it touches the same lines of code


Patch:
diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs
index 0934520d70..62aafd508e 100644
--- a/crates/ra_hir_def/src/path/lower.rs
+++ b/crates/ra_hir_def/src/path/lower.rs
@@ -101,12 +101,8 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
                 break;
             }
             ast::PathSegmentKind::SuperKw => {
-                let nested_super_count = if let PathKind::Super(n) = kind {
-                    n
-                } else {
-                    0
-                };
-                kind = PathKind::Super(nested_super_count + 1);
+                kind = PathKind::Super(1);
+                break;
             }
         }
         path = match qualifier(&path) {
diff --git a/crates/ra_hir_def/src/path/lower/lower_use.rs b/crates/ra_hir_def/src/path/lower/lower_use.rs
index 278d5196e7..b6d1125e20 100644
--- a/crates/ra_hir_def/src/path/lower/lower_use.rs
+++ b/crates/ra_hir_def/src/path/lower/lower_use.rs
@@ -103,13 +103,10 @@ fn convert_path(prefix: Option<ModPath>, path: ast::Path, hygiene: &Hygiene) ->
             ModPath::from_segments(PathKind::Super(0), iter::empty())
         }
         ast::PathSegmentKind::SuperKw => {
-            let nested_super_count = match prefix.map(|p| p.kind) {
-                Some(PathKind::Super(n)) => n,
-                Some(_) => return None,
-                None => 0,
-            };
-
-            ModPath::from_segments(PathKind::Super(nested_super_count + 1), iter::empty())
+            if prefix.is_some() {
+                return None;
+            }
+            ModPath::from_segments(PathKind::Super(1), iter::empty())
         }
         ast::PathSegmentKind::Type { .. } => {
             // not allowed in imports
diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs
index 9145aa183d..a6e0158b2a 100644
--- a/crates/ra_ide/src/completion/complete_dot.rs
+++ b/crates/ra_ide/src/completion/complete_dot.rs
@@ -545,43 +545,4 @@ mod tests {
         "###
         )
     }
-
-    #[test]
-    fn test_super_super_completion() {
-        assert_debug_snapshot!(
-        do_ref_completion(
-                r"
-                mod a {
-                    const A: usize = 0;
-
-                    mod b {
-                        const B: usize = 0;
-
-                        mod c {
-                            use super::super::<|>
-                        }
-                    }
-                }
-                ",
-        ),
-            @r###"
-        [
-            CompletionItem {
-                label: "A",
-                source_range: [217; 217),
-                delete: [217; 217),
-                insert: "A",
-                kind: Const,
-            },
-            CompletionItem {
-                label: "b",
-                source_range: [217; 217),
-                delete: [217; 217),
-                insert: "b",
-                kind: Module,
-            },
-        ]
-        "###
-        );
-    }
 }
diff --git a/editors/code/src/commands/syntax_tree.ts b/editors/code/src/commands/syntax_tree.ts
index 7218bfb900..2e08e8f115 100644
--- a/editors/code/src/commands/syntax_tree.ts
+++ b/editors/code/src/commands/syntax_tree.ts
@@ -2,6 +2,7 @@ import * as vscode from 'vscode';
 import * as ra from '../rust-analyzer-api';
 
 import { Ctx, Cmd } from '../ctx';
+import { isRustDocument } from '../util';
 
 // Opens the virtual file that will show the syntax tree
 //
@@ -19,7 +20,7 @@ export function syntaxTree(ctx: Ctx): Cmd {
     vscode.workspace.onDidChangeTextDocument(
         (event: vscode.TextDocumentChangeEvent) => {
             const doc = event.document;
-            if (doc.languageId !== 'rust') return;
+            if (!isRustDocument(doc)) return;
             afterLs(() => tdcp.eventEmitter.fire(tdcp.uri));
         },
         null,
@@ -28,7 +29,7 @@ export function syntaxTree(ctx: Ctx): Cmd {
 
     vscode.window.onDidChangeActiveTextEditor(
         (editor: vscode.TextEditor | undefined) => {
-            if (!editor || editor.document.languageId !== 'rust') return;
+            if (!editor || !isRustDocument(editor.document)) return;
             tdcp.eventEmitter.fire(tdcp.uri);
         },
         null,
diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts
index 43540e0d8e..b4e983a0cd 100644
--- a/editors/code/src/ctx.ts
+++ b/editors/code/src/ctx.ts
@@ -3,6 +3,7 @@ import * as lc from 'vscode-languageclient';
 
 import { Config } from './config';
 import { createClient } from './client';
+import { isRustDocument } from './util';
 
 export class Ctx {
     private constructor(
@@ -23,11 +24,17 @@ export class Ctx {
 
     get activeRustEditor(): vscode.TextEditor | undefined {
         const editor = vscode.window.activeTextEditor;
-        return editor && editor.document.languageId === 'rust'
+        return editor && isRustDocument(editor.document)
             ? editor
             : undefined;
     }
 
+    get visibleRustEditors(): vscode.TextEditor[] {
+        return vscode.window.visibleTextEditors.filter(
+            editor => isRustDocument(editor.document),
+        );
+    }
+
     registerCommand(name: string, factory: (ctx: Ctx) => Cmd) {
         const fullName = `rust-analyzer.${name}`;
         const cmd = factory(this);
diff --git a/editors/code/src/highlighting.ts b/editors/code/src/highlighting.ts
index 3e0cbdc561..036183834b 100644
--- a/editors/code/src/highlighting.ts
+++ b/editors/code/src/highlighting.ts
@@ -4,7 +4,7 @@ import * as ra from './rust-analyzer-api';
 import { ColorTheme, TextMateRuleSettings } from './color_theme';
 
 import { Ctx } from './ctx';
-import { sendRequestWithRetry } from './util';
+import { sendRequestWithRetry, isRustDocument } from './util';
 
 export function activateHighlighting(ctx: Ctx) {
     const highlighter = new Highlighter(ctx);
@@ -36,7 +36,7 @@ export function activateHighlighting(ctx: Ctx) {
 
     vscode.window.onDidChangeActiveTextEditor(
         async (editor: vscode.TextEditor | undefined) => {
-            if (!editor || editor.document.languageId !== 'rust') return;
+            if (!editor || !isRustDocument(editor.document)) return;
             if (!ctx.config.highlightingOn) return;
             const client = ctx.client;
             if (!client) return;
diff --git a/editors/code/src/inlay_hints.ts b/editors/code/src/inlay_hints.ts
index 6871bc1118..08d3a64a77 100644
--- a/editors/code/src/inlay_hints.ts
+++ b/editors/code/src/inlay_hints.ts
@@ -2,7 +2,7 @@ import * as vscode from 'vscode';
 import * as ra from './rust-analyzer-api';
 
 import { Ctx } from './ctx';
-import { log, sendRequestWithRetry } from './util';
+import { log, sendRequestWithRetry, isRustDocument } from './util';
 
 export function activateInlayHints(ctx: Ctx) {
     const hintsUpdater = new HintsUpdater(ctx);
@@ -15,7 +15,7 @@ export function activateInlayHints(ctx: Ctx) {
     vscode.workspace.onDidChangeTextDocument(
         async event => {
             if (event.contentChanges.length === 0) return;
-            if (event.document.languageId !== 'rust') return;
+            if (!isRustDocument(event.document)) return;
             await hintsUpdater.refresh();
         },
         null,
@@ -77,7 +77,7 @@ class HintsUpdater {
     }
 
     clear() {
-        this.allEditors.forEach(it => {
+        this.ctx.visibleRustEditors.forEach(it => {
             this.setTypeDecorations(it, []);
             this.setParameterDecorations(it, []);
         });
@@ -85,13 +85,7 @@ class HintsUpdater {
 
     async refresh() {
         if (!this.enabled) return;
-        await Promise.all(this.allEditors.map(it => this.refreshEditor(it)));
-    }
-
-    private get allEditors(): vscode.TextEditor[] {
-        return vscode.window.visibleTextEditors.filter(
-            editor => editor.document.languageId === 'rust',
-        );
+        await Promise.all(this.ctx.visibleRustEditors.map(it => this.refreshEditor(it)));
     }
 
     private async refreshEditor(editor: vscode.TextEditor): Promise<void> {
diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts
index f56c6badaf..7c95769bb8 100644
--- a/editors/code/src/util.ts
+++ b/editors/code/src/util.ts
@@ -1,6 +1,7 @@
 import * as lc from "vscode-languageclient";
 import * as vscode from "vscode";
 import { strict as nativeAssert } from "assert";
+import { TextDocument } from "vscode";
 
 export function assert(condition: boolean, explanation: string): asserts condition {
     try {
@@ -65,3 +66,10 @@ export async function sendRequestWithRetry<TParam, TRet>(
 function sleep(ms: number) {
     return new Promise(resolve => setTimeout(resolve, ms));
 }
+
+export function isRustDocument(document: TextDocument) {
+    return document.languageId === 'rust'
+        // SCM diff views have the same URI as the on-disk document but not the same content
+        && document.uri.scheme !== 'git'
+        && document.uri.scheme !== 'svn';
+}
\ No newline at end of file


Test patch:
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs
index dda5ed699c..82f0f835c8 100644
--- a/crates/ra_hir_def/src/nameres/tests.rs
+++ b/crates/ra_hir_def/src/nameres/tests.rs
@@ -65,42 +65,6 @@ fn crate_def_map_smoke_test() {
     "###)
 }
 
-#[test]
-fn crate_def_map_super_super() {
-    let map = def_map(
-        "
-        //- /lib.rs
-        mod a {
-            const A: usize = 0;
-
-            mod b {
-                const B: usize = 0;
-
-                mod c {
-                    use super::super::*;
-                }
-            }
-        }
-        ",
-    );
-    assert_snapshot!(map, @r###"
-        ⋮crate
-        ⋮a: t
-        ⋮
-        ⋮crate::a
-        ⋮A: v
-        ⋮b: t
-        ⋮
-        ⋮crate::a::b
-        ⋮B: v
-        ⋮c: t
-        ⋮
-        ⋮crate::a::b::c
-        ⋮A: v
-        ⋮b: t
-    "###)
-}
-
 #[test]
 fn bogus_paths() {
     covers!(bogus_paths);