about summary refs log tree commit diff
path: root/editors/code
diff options
context:
space:
mode:
authorAmos Wenger <amoswenger@gmail.com>2022-11-25 13:06:31 +0100
committerAmos Wenger <amoswenger@gmail.com>2022-11-25 13:06:31 +0100
commite96c0b1d53189a6f3446389a2e8a44564459feea (patch)
treecb00889e8ee3416b0033e8a0a4813dcde6c1cfa8 /editors/code
parentd9e16c8289fbd94dc79e745ca21f3270e5bc6441 (diff)
parenta2a1d995458c60175ad3aa37b7b8c5b2752e968c (diff)
downloadrust-e96c0b1d53189a6f3446389a2e8a44564459feea.tar.gz
rust-e96c0b1d53189a6f3446389a2e8a44564459feea.zip
Merge commit 'a2a1d9954' into HEAD
Diffstat (limited to 'editors/code')
-rw-r--r--editors/code/package.json46
-rw-r--r--editors/code/src/client.ts42
-rw-r--r--editors/code/src/config.ts3
-rw-r--r--editors/code/src/ctx.ts3
-rw-r--r--editors/code/src/main.ts24
5 files changed, 108 insertions, 10 deletions
diff --git a/editors/code/package.json b/editors/code/package.json
index 1a97a9c0893..c4d4e428ea0 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -396,6 +396,11 @@
                     "default": true,
                     "type": "boolean"
                 },
+                "rust-analyzer.diagnostics.previewRustcOutput": {
+                    "markdownDescription": "Whether to show the main part of the rendered rustc output of a diagnostic message.",
+                    "default": false,
+                    "type": "boolean"
+                },
                 "$generated-start": {},
                 "rust-analyzer.assist.emitMustUse": {
                     "markdownDescription": "Whether to insert #[must_use] when generating `as_` methods\nfor enum variants.",
@@ -623,7 +628,7 @@
                     ]
                 },
                 "rust-analyzer.checkOnSave.overrideCommand": {
-                    "markdownDescription": "Override the command rust-analyzer uses instead of `cargo check` for\ndiagnostics on save. The command is required to output json and\nshould therefor include `--message-format=json` or a similar option.\n\nIf you're changing this because you're using some tool wrapping\nCargo, you might also want to change\n`#rust-analyzer.cargo.buildScripts.overrideCommand#`.\n\nIf there are multiple linked projects, this command is invoked for\neach of them, with the working directory being the project root\n(i.e., the folder containing the `Cargo.toml`).\n\nAn example command would be:\n\n```bash\ncargo check --workspace --message-format=json --all-targets\n```\n.",
+                    "markdownDescription": "Override the command rust-analyzer uses instead of `cargo check` for\ndiagnostics on save. The command is required to output json and\nshould therefore include `--message-format=json` or a similar option.\n\nIf you're changing this because you're using some tool wrapping\nCargo, you might also want to change\n`#rust-analyzer.cargo.buildScripts.overrideCommand#`.\n\nIf there are multiple linked projects, this command is invoked for\neach of them, with the working directory being the project root\n(i.e., the folder containing the `Cargo.toml`).\n\nAn example command would be:\n\n```bash\ncargo check --workspace --message-format=json --all-targets\n```\n.",
                     "default": null,
                     "type": [
                         "null",
@@ -634,11 +639,18 @@
                     }
                 },
                 "rust-analyzer.checkOnSave.target": {
-                    "markdownDescription": "Check for a specific target. Defaults to\n`#rust-analyzer.cargo.target#`.",
-                    "default": null,
-                    "type": [
-                        "null",
-                        "string"
+                    "markdownDescription": "Check for specific targets. Defaults to `#rust-analyzer.cargo.target#` if empty.\n\nCan be a single target, e.g. `\"x86_64-unknown-linux-gnu\"` or a list of targets, e.g.\n`[\"aarch64-apple-darwin\", \"x86_64-apple-darwin\"]`.\n\nAliased as `\"checkOnSave.targets\"`.",
+                    "default": [],
+                    "anyOf": [
+                        {
+                            "type": "string"
+                        },
+                        {
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        }
                     ]
                 },
                 "rust-analyzer.completion.autoimport.enable": {
@@ -935,6 +947,21 @@
                         "Only show type hints for return types of closures with blocks."
                     ]
                 },
+                "rust-analyzer.inlayHints.expressionAdjustmentHints.enable": {
+                    "markdownDescription": "Whether to show inlay hints for type adjustments.",
+                    "default": "never",
+                    "type": "string",
+                    "enum": [
+                        "always",
+                        "never",
+                        "reborrow"
+                    ],
+                    "enumDescriptions": [
+                        "Always show all adjustment hints.",
+                        "Never show adjustment hints.",
+                        "Only show auto borrow and dereference adjustment hints."
+                    ]
+                },
                 "rust-analyzer.inlayHints.lifetimeElisionHints.enable": {
                     "markdownDescription": "Whether to show inlay type hints for elided lifetimes in function signatures.",
                     "default": "never",
@@ -970,7 +997,7 @@
                     "type": "boolean"
                 },
                 "rust-analyzer.inlayHints.reborrowHints.enable": {
-                    "markdownDescription": "Whether to show inlay type hints for compiler inserted reborrows.",
+                    "markdownDescription": "Whether to show inlay hints for compiler inserted reborrows.\nThis setting is deprecated in favor of #rust-analyzer.inlayHints.expressionAdjustmentHints.enable#.",
                     "default": "never",
                     "type": "string",
                     "enum": [
@@ -1276,6 +1303,11 @@
                 "$generated-end": {}
             }
         },
+        "configurationDefaults": {
+            "explorer.fileNesting.patterns": {
+                "Cargo.toml": "Cargo.lock"
+            }
+        },
         "problemPatterns": [
             {
                 "name": "rustc",
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index fb667619c86..23e039722ee 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -4,7 +4,7 @@ import * as ra from "../src/lsp_ext";
 import * as Is from "vscode-languageclient/lib/common/utils/is";
 import { assert } from "./util";
 import { WorkspaceEdit } from "vscode";
-import { substituteVSCodeVariables } from "./config";
+import { Config, substituteVSCodeVariables } from "./config";
 import { randomUUID } from "crypto";
 
 export interface Env {
@@ -66,7 +66,8 @@ export async function createClient(
     traceOutputChannel: vscode.OutputChannel,
     outputChannel: vscode.OutputChannel,
     initializationOptions: vscode.WorkspaceConfiguration,
-    serverOptions: lc.ServerOptions
+    serverOptions: lc.ServerOptions,
+    config: Config
 ): Promise<lc.LanguageClient> {
     const clientOptions: lc.LanguageClientOptions = {
         documentSelector: [{ scheme: "file", language: "rust" }],
@@ -99,6 +100,43 @@ export async function createClient(
                     }
                 },
             },
+            async handleDiagnostics(
+                uri: vscode.Uri,
+                diagnostics: vscode.Diagnostic[],
+                next: lc.HandleDiagnosticsSignature
+            ) {
+                const preview = config.previewRustcOutput;
+                diagnostics.forEach((diag, idx) => {
+                    // Abuse the fact that VSCode leaks the LSP diagnostics data field through the
+                    // Diagnostic class, if they ever break this we are out of luck and have to go
+                    // back to the worst diagnostics experience ever:)
+
+                    // We encode the rendered output of a rustc diagnostic in the rendered field of
+                    // the data payload of the lsp diagnostic. If that field exists, overwrite the
+                    // diagnostic code such that clicking it opens the diagnostic in a readonly
+                    // text editor for easy inspection
+                    const rendered = (diag as unknown as { data?: { rendered?: string } }).data
+                        ?.rendered;
+                    if (rendered) {
+                        if (preview) {
+                            const index = rendered.match(/^(note|help):/m)?.index || 0;
+                            diag.message = rendered
+                                .substring(0, index)
+                                .replace(/^ -->[^\n]+\n/m, "");
+                        }
+                        diag.code = {
+                            target: vscode.Uri.from({
+                                scheme: "rust-analyzer-diagnostics-view",
+                                path: "/diagnostic message",
+                                fragment: uri.toString(),
+                                query: idx.toString(),
+                            }),
+                            value: "Click for full compiler diagnostic",
+                        };
+                    }
+                });
+                return next(uri, diagnostics);
+            },
             async provideHover(
                 document: vscode.TextDocument,
                 position: vscode.Position,
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index 632a7d86faa..d8dbd1df16d 100644
--- a/editors/code/src/config.ts
+++ b/editors/code/src/config.ts
@@ -238,6 +238,9 @@ export class Config {
             gotoTypeDef: this.get<boolean>("hover.actions.gotoTypeDef.enable"),
         };
     }
+    get previewRustcOutput() {
+        return this.get<boolean>("diagnostics.previewRustcOutput");
+    }
 }
 
 const VarRegex = new RegExp(/\$\{(.+?)\}/g);
diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts
index 3e366525ee2..d6cee5c8fc6 100644
--- a/editors/code/src/ctx.ts
+++ b/editors/code/src/ctx.ts
@@ -179,7 +179,8 @@ export class Ctx {
                 this.traceOutputChannel,
                 this.outputChannel,
                 initializationOptions,
-                serverOptions
+                serverOptions,
+                this.config
             );
             this.pushClientCleanup(
                 this._client.onNotification(ra.serverStatus, (params) =>
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index e76b657c1bf..25f1e83d109 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -48,6 +48,30 @@ async function activateServer(ctx: Ctx): Promise<RustAnalyzerExtensionApi> {
         ctx.pushExtCleanup(activateTaskProvider(ctx.config));
     }
 
+    ctx.pushExtCleanup(
+        vscode.workspace.registerTextDocumentContentProvider(
+            "rust-analyzer-diagnostics-view",
+            new (class implements vscode.TextDocumentContentProvider {
+                async provideTextDocumentContent(uri: vscode.Uri): Promise<string> {
+                    const diags = ctx.client?.diagnostics?.get(
+                        vscode.Uri.parse(uri.fragment, true)
+                    );
+                    if (!diags) {
+                        return "Unable to find original rustc diagnostic";
+                    }
+
+                    const diag = diags[parseInt(uri.query)];
+                    if (!diag) {
+                        return "Unable to find original rustc diagnostic";
+                    }
+                    const rendered = (diag as unknown as { data?: { rendered?: string } }).data
+                        ?.rendered;
+                    return rendered ?? "Unable to find original rustc diagnostic";
+                }
+            })()
+        )
+    );
+
     vscode.workspace.onDidChangeWorkspaceFolders(
         async (_) => ctx.onWorkspaceFolderChanges(),
         null,