diff options
-rw-r--r-- | crates/hir/src/source_analyzer.rs | 17 | ||||
-rw-r--r-- | crates/ide/src/references.rs | 23 | ||||
-rw-r--r-- | editors/code/.eslintrc.js | 5 | ||||
-rw-r--r-- | editors/code/src/client.ts | 4 | ||||
-rw-r--r-- | editors/code/src/commands.ts | 12 | ||||
-rw-r--r-- | editors/code/src/debug.ts | 12 | ||||
-rw-r--r-- | editors/code/src/inlay_hints.ts | 2 | ||||
-rw-r--r-- | editors/code/src/main.ts | 13 | ||||
-rw-r--r-- | editors/code/src/run.ts | 7 | ||||
-rw-r--r-- | editors/code/src/snippets.ts | 4 |
10 files changed, 67 insertions, 32 deletions
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 626c3078a..bed3fa50f 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs | |||
@@ -222,8 +222,9 @@ impl SourceAnalyzer { | |||
222 | db: &dyn HirDatabase, | 222 | db: &dyn HirDatabase, |
223 | path: &ast::Path, | 223 | path: &ast::Path, |
224 | ) -> Option<PathResolution> { | 224 | ) -> Option<PathResolution> { |
225 | let parent = || path.syntax().parent(); | ||
225 | let mut prefer_value_ns = false; | 226 | let mut prefer_value_ns = false; |
226 | if let Some(path_expr) = path.syntax().parent().and_then(ast::PathExpr::cast) { | 227 | if let Some(path_expr) = parent().and_then(ast::PathExpr::cast) { |
227 | let expr_id = self.expr_id(db, &path_expr.into())?; | 228 | let expr_id = self.expr_id(db, &path_expr.into())?; |
228 | let infer = self.infer.as_ref()?; | 229 | let infer = self.infer.as_ref()?; |
229 | if let Some(assoc) = infer.assoc_resolutions_for_expr(expr_id) { | 230 | if let Some(assoc) = infer.assoc_resolutions_for_expr(expr_id) { |
@@ -237,7 +238,7 @@ impl SourceAnalyzer { | |||
237 | prefer_value_ns = true; | 238 | prefer_value_ns = true; |
238 | } | 239 | } |
239 | 240 | ||
240 | if let Some(path_pat) = path.syntax().parent().and_then(ast::PathPat::cast) { | 241 | if let Some(path_pat) = parent().and_then(ast::PathPat::cast) { |
241 | let pat_id = self.pat_id(&path_pat.into())?; | 242 | let pat_id = self.pat_id(&path_pat.into())?; |
242 | if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) { | 243 | if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) { |
243 | return Some(PathResolution::AssocItem(assoc.into())); | 244 | return Some(PathResolution::AssocItem(assoc.into())); |
@@ -249,7 +250,7 @@ impl SourceAnalyzer { | |||
249 | } | 250 | } |
250 | } | 251 | } |
251 | 252 | ||
252 | if let Some(rec_lit) = path.syntax().parent().and_then(ast::RecordExpr::cast) { | 253 | if let Some(rec_lit) = parent().and_then(ast::RecordExpr::cast) { |
253 | let expr_id = self.expr_id(db, &rec_lit.into())?; | 254 | let expr_id = self.expr_id(db, &rec_lit.into())?; |
254 | if let Some(VariantId::EnumVariantId(variant)) = | 255 | if let Some(VariantId::EnumVariantId(variant)) = |
255 | self.infer.as_ref()?.variant_resolution_for_expr(expr_id) | 256 | self.infer.as_ref()?.variant_resolution_for_expr(expr_id) |
@@ -258,8 +259,12 @@ impl SourceAnalyzer { | |||
258 | } | 259 | } |
259 | } | 260 | } |
260 | 261 | ||
261 | if let Some(rec_pat) = path.syntax().parent().and_then(ast::RecordPat::cast) { | 262 | if let Some(pat) = parent() |
262 | let pat_id = self.pat_id(&rec_pat.into())?; | 263 | .and_then(ast::RecordPat::cast) |
264 | .map(ast::Pat::from) | ||
265 | .or_else(|| parent().and_then(ast::TupleStructPat::cast).map(ast::Pat::from)) | ||
266 | { | ||
267 | let pat_id = self.pat_id(&pat)?; | ||
263 | if let Some(VariantId::EnumVariantId(variant)) = | 268 | if let Some(VariantId::EnumVariantId(variant)) = |
264 | self.infer.as_ref()?.variant_resolution_for_pat(pat_id) | 269 | self.infer.as_ref()?.variant_resolution_for_pat(pat_id) |
265 | { | 270 | { |
@@ -272,7 +277,7 @@ impl SourceAnalyzer { | |||
272 | 277 | ||
273 | // Case where path is a qualifier of another path, e.g. foo::bar::Baz where we | 278 | // Case where path is a qualifier of another path, e.g. foo::bar::Baz where we |
274 | // trying to resolve foo::bar. | 279 | // trying to resolve foo::bar. |
275 | if let Some(outer_path) = path.syntax().parent().and_then(ast::Path::cast) { | 280 | if let Some(outer_path) = parent().and_then(ast::Path::cast) { |
276 | if let Some(qualifier) = outer_path.qualifier() { | 281 | if let Some(qualifier) = outer_path.qualifier() { |
277 | if path == &qualifier { | 282 | if path == &qualifier { |
278 | return resolve_hir_path_qualifier(db, &self.resolver, &hir_path); | 283 | return resolve_hir_path_qualifier(db, &self.resolver, &hir_path); |
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 40d9487eb..6999dacee 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs | |||
@@ -1114,4 +1114,27 @@ trait Foo { | |||
1114 | "#]], | 1114 | "#]], |
1115 | ); | 1115 | ); |
1116 | } | 1116 | } |
1117 | |||
1118 | #[test] | ||
1119 | fn test_self_variant_with_payload() { | ||
1120 | check( | ||
1121 | r#" | ||
1122 | enum Foo { Bar() } | ||
1123 | |||
1124 | impl Foo { | ||
1125 | fn foo(self) { | ||
1126 | match self { | ||
1127 | Self::Bar$0() => (), | ||
1128 | } | ||
1129 | } | ||
1130 | } | ||
1131 | |||
1132 | "#, | ||
1133 | expect![[r#" | ||
1134 | Bar Variant FileId(0) 11..16 11..14 Other | ||
1135 | |||
1136 | FileId(0) 89..92 Other | ||
1137 | "#]], | ||
1138 | ); | ||
1139 | } | ||
1117 | } | 1140 | } |
diff --git a/editors/code/.eslintrc.js b/editors/code/.eslintrc.js index c6bf410f4..b145330a0 100644 --- a/editors/code/.eslintrc.js +++ b/editors/code/.eslintrc.js | |||
@@ -14,7 +14,7 @@ module.exports = { | |||
14 | "rules": { | 14 | "rules": { |
15 | "camelcase": ["error"], | 15 | "camelcase": ["error"], |
16 | "eqeqeq": ["error", "always", { "null": "ignore" }], | 16 | "eqeqeq": ["error", "always", { "null": "ignore" }], |
17 | "no-console": ["error"], | 17 | "no-console": ["error", { allow: ["warn", "error"] }], |
18 | "prefer-const": "error", | 18 | "prefer-const": "error", |
19 | "@typescript-eslint/member-delimiter-style": [ | 19 | "@typescript-eslint/member-delimiter-style": [ |
20 | "error", | 20 | "error", |
@@ -33,6 +33,7 @@ module.exports = { | |||
33 | "error", | 33 | "error", |
34 | "always" | 34 | "always" |
35 | ], | 35 | ], |
36 | "@typescript-eslint/no-unnecessary-type-assertion": "error" | 36 | "@typescript-eslint/no-unnecessary-type-assertion": "error", |
37 | "@typescript-eslint/no-floating-promises": "error" | ||
37 | } | 38 | } |
38 | }; | 39 | }; |
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index 539e487ec..aec5c70c0 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts | |||
@@ -11,7 +11,7 @@ export interface Env { | |||
11 | } | 11 | } |
12 | 12 | ||
13 | function renderCommand(cmd: ra.CommandLink) { | 13 | function renderCommand(cmd: ra.CommandLink) { |
14 | return `[${cmd.title}](command:${cmd.command}?${encodeURIComponent(JSON.stringify(cmd.arguments))} '${cmd.tooltip!}')`; | 14 | return `[${cmd.title}](command:${cmd.command}?${encodeURIComponent(JSON.stringify(cmd.arguments))} '${cmd.tooltip}')`; |
15 | } | 15 | } |
16 | 16 | ||
17 | function renderHoverActions(actions: ra.CommandLinkGroup[]): vscode.MarkdownString { | 17 | function renderHoverActions(actions: ra.CommandLinkGroup[]): vscode.MarkdownString { |
@@ -138,7 +138,7 @@ export function createClient(serverPath: string, cwd: string, extraEnv: Env): lc | |||
138 | command: "rust-analyzer.applyActionGroup", | 138 | command: "rust-analyzer.applyActionGroup", |
139 | title: "", | 139 | title: "", |
140 | arguments: [items.map((item) => { | 140 | arguments: [items.map((item) => { |
141 | return { label: item.title, arguments: item.command!!.arguments!![0] }; | 141 | return { label: item.title, arguments: item.command!.arguments![0] }; |
142 | })], | 142 | })], |
143 | }; | 143 | }; |
144 | 144 | ||
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts index cbda619ea..3729a71de 100644 --- a/editors/code/src/commands.ts +++ b/editors/code/src/commands.ts | |||
@@ -125,7 +125,7 @@ export function joinLines(ctx: Ctx): Cmd { | |||
125 | ranges: editor.selections.map((it) => client.code2ProtocolConverter.asRange(it)), | 125 | ranges: editor.selections.map((it) => client.code2ProtocolConverter.asRange(it)), |
126 | textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document), | 126 | textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document), |
127 | }); | 127 | }); |
128 | editor.edit((builder) => { | 128 | await editor.edit((builder) => { |
129 | client.protocol2CodeConverter.asTextEdits(items).forEach((edit: any) => { | 129 | client.protocol2CodeConverter.asTextEdits(items).forEach((edit: any) => { |
130 | builder.replace(edit.range, edit.newText); | 130 | builder.replace(edit.range, edit.newText); |
131 | }); | 131 | }); |
@@ -236,7 +236,7 @@ export function ssr(ctx: Ctx): Cmd { | |||
236 | const request = await vscode.window.showInputBox(options); | 236 | const request = await vscode.window.showInputBox(options); |
237 | if (!request) return; | 237 | if (!request) return; |
238 | 238 | ||
239 | vscode.window.withProgress({ | 239 | await vscode.window.withProgress({ |
240 | location: vscode.ProgressLocation.Notification, | 240 | location: vscode.ProgressLocation.Notification, |
241 | title: "Structured search replace in progress...", | 241 | title: "Structured search replace in progress...", |
242 | cancellable: false, | 242 | cancellable: false, |
@@ -457,10 +457,10 @@ export function reloadWorkspace(ctx: Ctx): Cmd { | |||
457 | } | 457 | } |
458 | 458 | ||
459 | export function showReferences(ctx: Ctx): Cmd { | 459 | export function showReferences(ctx: Ctx): Cmd { |
460 | return (uri: string, position: lc.Position, locations: lc.Location[]) => { | 460 | return async (uri: string, position: lc.Position, locations: lc.Location[]) => { |
461 | const client = ctx.client; | 461 | const client = ctx.client; |
462 | if (client) { | 462 | if (client) { |
463 | vscode.commands.executeCommand( | 463 | await vscode.commands.executeCommand( |
464 | 'editor.action.showReferences', | 464 | 'editor.action.showReferences', |
465 | vscode.Uri.parse(uri), | 465 | vscode.Uri.parse(uri), |
466 | client.protocol2CodeConverter.asPosition(position), | 466 | client.protocol2CodeConverter.asPosition(position), |
@@ -474,7 +474,7 @@ export function applyActionGroup(_ctx: Ctx): Cmd { | |||
474 | return async (actions: { label: string; arguments: lc.CodeAction }[]) => { | 474 | return async (actions: { label: string; arguments: lc.CodeAction }[]) => { |
475 | const selectedAction = await vscode.window.showQuickPick(actions); | 475 | const selectedAction = await vscode.window.showQuickPick(actions); |
476 | if (!selectedAction) return; | 476 | if (!selectedAction) return; |
477 | vscode.commands.executeCommand( | 477 | await vscode.commands.executeCommand( |
478 | 'rust-analyzer.resolveCodeAction', | 478 | 'rust-analyzer.resolveCodeAction', |
479 | selectedAction.arguments, | 479 | selectedAction.arguments, |
480 | ); | 480 | ); |
@@ -510,7 +510,7 @@ export function openDocs(ctx: Ctx): Cmd { | |||
510 | const doclink = await client.sendRequest(ra.openDocs, { position, textDocument }); | 510 | const doclink = await client.sendRequest(ra.openDocs, { position, textDocument }); |
511 | 511 | ||
512 | if (doclink != null) { | 512 | if (doclink != null) { |
513 | vscode.commands.executeCommand("vscode.open", vscode.Uri.parse(doclink)); | 513 | await vscode.commands.executeCommand("vscode.open", vscode.Uri.parse(doclink)); |
514 | } | 514 | } |
515 | }; | 515 | }; |
516 | 516 | ||
diff --git a/editors/code/src/debug.ts b/editors/code/src/debug.ts index 925126a16..3889a2773 100644 --- a/editors/code/src/debug.ts +++ b/editors/code/src/debug.ts | |||
@@ -77,7 +77,7 @@ async function getDebugConfiguration(ctx: Ctx, runnable: ra.Runnable): Promise<v | |||
77 | } | 77 | } |
78 | 78 | ||
79 | if (!debugEngine) { | 79 | if (!debugEngine) { |
80 | vscode.window.showErrorMessage(`Install [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)` | 80 | await vscode.window.showErrorMessage(`Install [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)` |
81 | + ` or [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) extension for debugging.`); | 81 | + ` or [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) extension for debugging.`); |
82 | return; | 82 | return; |
83 | } | 83 | } |
@@ -86,12 +86,14 @@ async function getDebugConfiguration(ctx: Ctx, runnable: ra.Runnable): Promise<v | |||
86 | if (ctx.config.debug.openDebugPane) { | 86 | if (ctx.config.debug.openDebugPane) { |
87 | debugOutput.show(true); | 87 | debugOutput.show(true); |
88 | } | 88 | } |
89 | 89 | // folder exists or RA is not active. | |
90 | const isMultiFolderWorkspace = vscode.workspace.workspaceFolders!.length > 1; | 90 | // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion |
91 | const firstWorkspace = vscode.workspace.workspaceFolders![0]; // folder exists or RA is not active. | 91 | const workspaceFolders = vscode.workspace.workspaceFolders!; |
92 | const isMultiFolderWorkspace = workspaceFolders.length > 1; | ||
93 | const firstWorkspace = workspaceFolders[0]; | ||
92 | const workspace = !isMultiFolderWorkspace || !runnable.args.workspaceRoot ? | 94 | const workspace = !isMultiFolderWorkspace || !runnable.args.workspaceRoot ? |
93 | firstWorkspace : | 95 | firstWorkspace : |
94 | vscode.workspace.workspaceFolders!.find(w => runnable.args.workspaceRoot?.includes(w.uri.fsPath)) || firstWorkspace; | 96 | workspaceFolders.find(w => runnable.args.workspaceRoot?.includes(w.uri.fsPath)) || firstWorkspace; |
95 | 97 | ||
96 | const wsFolder = path.normalize(workspace.uri.fsPath); | 98 | const wsFolder = path.normalize(workspace.uri.fsPath); |
97 | const workspaceQualifier = isMultiFolderWorkspace ? `:${workspace.name}` : ''; | 99 | const workspaceQualifier = isMultiFolderWorkspace ? `:${workspace.name}` : ''; |
diff --git a/editors/code/src/inlay_hints.ts b/editors/code/src/inlay_hints.ts index 38eb1c15b..61db6b8d0 100644 --- a/editors/code/src/inlay_hints.ts +++ b/editors/code/src/inlay_hints.ts | |||
@@ -36,7 +36,7 @@ export function activateInlayHints(ctx: Ctx) { | |||
36 | maybeUpdater.onConfigChange, maybeUpdater, ctx.subscriptions | 36 | maybeUpdater.onConfigChange, maybeUpdater, ctx.subscriptions |
37 | ); | 37 | ); |
38 | 38 | ||
39 | maybeUpdater.onConfigChange(); | 39 | maybeUpdater.onConfigChange().catch(console.error); |
40 | } | 40 | } |
41 | 41 | ||
42 | const typeHints = createHintStyle("type"); | 42 | const typeHints = createHintStyle("type"); |
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 1900d900a..5c0b0be26 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts | |||
@@ -76,7 +76,7 @@ async function tryActivate(context: vscode.ExtensionContext) { | |||
76 | // This a horribly, horribly wrong way to deal with this problem. | 76 | // This a horribly, horribly wrong way to deal with this problem. |
77 | ctx = await Ctx.create(config, context, serverPath, workspaceFolder.uri.fsPath); | 77 | ctx = await Ctx.create(config, context, serverPath, workspaceFolder.uri.fsPath); |
78 | 78 | ||
79 | setContextValue(RUST_PROJECT_CONTEXT_NAME, true); | 79 | await setContextValue(RUST_PROJECT_CONTEXT_NAME, true); |
80 | 80 | ||
81 | // Commands which invokes manually via command palette, shortcut, etc. | 81 | // Commands which invokes manually via command palette, shortcut, etc. |
82 | 82 | ||
@@ -142,7 +142,7 @@ async function tryActivate(context: vscode.ExtensionContext) { | |||
142 | } | 142 | } |
143 | 143 | ||
144 | export async function deactivate() { | 144 | export async function deactivate() { |
145 | setContextValue(RUST_PROJECT_CONTEXT_NAME, undefined); | 145 | await setContextValue(RUST_PROJECT_CONTEXT_NAME, undefined); |
146 | await ctx?.client.stop(); | 146 | await ctx?.client.stop(); |
147 | ctx = undefined; | 147 | ctx = undefined; |
148 | } | 148 | } |
@@ -183,10 +183,10 @@ async function bootstrapExtension(config: Config, state: PersistentState): Promi | |||
183 | 183 | ||
184 | const release = await downloadWithRetryDialog(state, async () => { | 184 | const release = await downloadWithRetryDialog(state, async () => { |
185 | return await fetchRelease("nightly", state.githubToken); | 185 | return await fetchRelease("nightly", state.githubToken); |
186 | }).catch((e) => { | 186 | }).catch(async (e) => { |
187 | log.error(e); | 187 | log.error(e); |
188 | if (state.releaseId === undefined) { // Show error only for the initial download | 188 | if (state.releaseId === undefined) { // Show error only for the initial download |
189 | vscode.window.showErrorMessage(`Failed to download rust-analyzer nightly ${e}`); | 189 | await vscode.window.showErrorMessage(`Failed to download rust-analyzer nightly ${e}`); |
190 | } | 190 | } |
191 | return undefined; | 191 | return undefined; |
192 | }); | 192 | }); |
@@ -298,7 +298,7 @@ async function getServer(config: Config, state: PersistentState): Promise<string | |||
298 | }; | 298 | }; |
299 | const platform = platforms[`${process.arch} ${process.platform}`]; | 299 | const platform = platforms[`${process.arch} ${process.platform}`]; |
300 | if (platform === undefined) { | 300 | if (platform === undefined) { |
301 | vscode.window.showErrorMessage( | 301 | await vscode.window.showErrorMessage( |
302 | "Unfortunately we don't ship binaries for your platform yet. " + | 302 | "Unfortunately we don't ship binaries for your platform yet. " + |
303 | "You need to manually clone rust-analyzer repository and " + | 303 | "You need to manually clone rust-analyzer repository and " + |
304 | "run `cargo xtask install --server` to build the language server from sources. " + | 304 | "run `cargo xtask install --server` to build the language server from sources. " + |
@@ -433,6 +433,7 @@ function warnAboutExtensionConflicts() { | |||
433 | vscode.window.showWarningMessage( | 433 | vscode.window.showWarningMessage( |
434 | `You have both the ${fst[0]} (${fst[1]}) and ${sec[0]} (${sec[1]}) ` + | 434 | `You have both the ${fst[0]} (${fst[1]}) and ${sec[0]} (${sec[1]}) ` + |
435 | "plugins enabled. These are known to conflict and cause various functions of " + | 435 | "plugins enabled. These are known to conflict and cause various functions of " + |
436 | "both plugins to not work correctly. You should disable one of them.", "Got it"); | 436 | "both plugins to not work correctly. You should disable one of them.", "Got it") |
437 | .then(() => { }, console.error); | ||
437 | }; | 438 | }; |
438 | } | 439 | } |
diff --git a/editors/code/src/run.ts b/editors/code/src/run.ts index 17573cd82..7ac7ca3cb 100644 --- a/editors/code/src/run.ts +++ b/editors/code/src/run.ts | |||
@@ -45,7 +45,7 @@ export async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick, | |||
45 | if (items.length === 0) { | 45 | if (items.length === 0) { |
46 | // it is the debug case, run always has at least 'cargo check ...' | 46 | // it is the debug case, run always has at least 'cargo check ...' |
47 | // see crates\rust-analyzer\src\main_loop\handlers.rs, handle_runnables | 47 | // see crates\rust-analyzer\src\main_loop\handlers.rs, handle_runnables |
48 | vscode.window.showErrorMessage("There's no debug target!"); | 48 | await vscode.window.showErrorMessage("There's no debug target!"); |
49 | return; | 49 | return; |
50 | } | 50 | } |
51 | 51 | ||
@@ -65,8 +65,8 @@ export async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick, | |||
65 | disposables.push( | 65 | disposables.push( |
66 | quickPick.onDidHide(() => close()), | 66 | quickPick.onDidHide(() => close()), |
67 | quickPick.onDidAccept(() => close(quickPick.selectedItems[0])), | 67 | quickPick.onDidAccept(() => close(quickPick.selectedItems[0])), |
68 | quickPick.onDidTriggerButton((_button) => { | 68 | quickPick.onDidTriggerButton(async (_button) => { |
69 | (async () => await makeDebugConfig(ctx, quickPick.activeItems[0].runnable))(); | 69 | await makeDebugConfig(ctx, quickPick.activeItems[0].runnable); |
70 | close(); | 70 | close(); |
71 | }), | 71 | }), |
72 | quickPick.onDidChangeActive((active) => { | 72 | quickPick.onDidChangeActive((active) => { |
@@ -145,6 +145,7 @@ export async function createTask(runnable: ra.Runnable, config: Config): Promise | |||
145 | overrideCargo: runnable.args.overrideCargo, | 145 | overrideCargo: runnable.args.overrideCargo, |
146 | }; | 146 | }; |
147 | 147 | ||
148 | // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion | ||
148 | const target = vscode.workspace.workspaceFolders![0]; // safe, see main activate() | 149 | const target = vscode.workspace.workspaceFolders![0]; // safe, see main activate() |
149 | const cargoTask = await tasks.buildCargoTask(target, definition, runnable.label, args, config.cargoRunner, true); | 150 | const cargoTask = await tasks.buildCargoTask(target, definition, runnable.label, args, config.cargoRunner, true); |
150 | cargoTask.presentationOptions.clear = true; | 151 | cargoTask.presentationOptions.clear = true; |
diff --git a/editors/code/src/snippets.ts b/editors/code/src/snippets.ts index fee736e7d..dc53ebe2e 100644 --- a/editors/code/src/snippets.ts +++ b/editors/code/src/snippets.ts | |||
@@ -62,7 +62,9 @@ function parseSnippet(snip: string): [string, [number, number]] | undefined { | |||
62 | const m = snip.match(/\$(0|\{0:([^}]*)\})/); | 62 | const m = snip.match(/\$(0|\{0:([^}]*)\})/); |
63 | if (!m) return undefined; | 63 | if (!m) return undefined; |
64 | const placeholder = m[2] ?? ""; | 64 | const placeholder = m[2] ?? ""; |
65 | const range: [number, number] = [m.index!!, placeholder.length]; | 65 | if (m.index == null) |
66 | return undefined; | ||
67 | const range: [number, number] = [m.index, placeholder.length]; | ||
66 | const insert = snip.replace(m[0], placeholder); | 68 | const insert = snip.replace(m[0], placeholder); |
67 | return [insert, range]; | 69 | return [insert, range]; |
68 | } | 70 | } |