7591: Fix/no floating promises r=matklad a=sahandevs

closes #3515

- added `@typescript-eslint/no-floating-promises: error` rule
- changed `"no-console": ["error"]` to `"no-console": ["error", { allow: ["warn", "error"] }]` (we at least log the error messages of the floating promises)
- fixed lint/compile errors

7622: Resolve TupleStructPat in SourceAnalyzer::resolve_path r=Veykril a=Veykril

Closes #7594
bors r+

Co-authored-by: Sahandevs <sahandevs@gmail.com>
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
bors[bot] 2021-02-10 08:44:53 +00:00 committed by GitHub
commit ff5ef2830c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 67 additions and 32 deletions

View File

@ -222,8 +222,9 @@ impl SourceAnalyzer {
db: &dyn HirDatabase, db: &dyn HirDatabase,
path: &ast::Path, path: &ast::Path,
) -> Option<PathResolution> { ) -> Option<PathResolution> {
let parent = || path.syntax().parent();
let mut prefer_value_ns = false; let mut prefer_value_ns = false;
if let Some(path_expr) = path.syntax().parent().and_then(ast::PathExpr::cast) { if let Some(path_expr) = parent().and_then(ast::PathExpr::cast) {
let expr_id = self.expr_id(db, &path_expr.into())?; let expr_id = self.expr_id(db, &path_expr.into())?;
let infer = self.infer.as_ref()?; let infer = self.infer.as_ref()?;
if let Some(assoc) = infer.assoc_resolutions_for_expr(expr_id) { if let Some(assoc) = infer.assoc_resolutions_for_expr(expr_id) {
@ -237,7 +238,7 @@ impl SourceAnalyzer {
prefer_value_ns = true; prefer_value_ns = true;
} }
if let Some(path_pat) = path.syntax().parent().and_then(ast::PathPat::cast) { if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
let pat_id = self.pat_id(&path_pat.into())?; let pat_id = self.pat_id(&path_pat.into())?;
if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) { if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) {
return Some(PathResolution::AssocItem(assoc.into())); return Some(PathResolution::AssocItem(assoc.into()));
@ -249,7 +250,7 @@ impl SourceAnalyzer {
} }
} }
if let Some(rec_lit) = path.syntax().parent().and_then(ast::RecordExpr::cast) { if let Some(rec_lit) = parent().and_then(ast::RecordExpr::cast) {
let expr_id = self.expr_id(db, &rec_lit.into())?; let expr_id = self.expr_id(db, &rec_lit.into())?;
if let Some(VariantId::EnumVariantId(variant)) = if let Some(VariantId::EnumVariantId(variant)) =
self.infer.as_ref()?.variant_resolution_for_expr(expr_id) self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
@ -258,8 +259,12 @@ impl SourceAnalyzer {
} }
} }
if let Some(rec_pat) = path.syntax().parent().and_then(ast::RecordPat::cast) { if let Some(pat) = parent()
let pat_id = self.pat_id(&rec_pat.into())?; .and_then(ast::RecordPat::cast)
.map(ast::Pat::from)
.or_else(|| parent().and_then(ast::TupleStructPat::cast).map(ast::Pat::from))
{
let pat_id = self.pat_id(&pat)?;
if let Some(VariantId::EnumVariantId(variant)) = if let Some(VariantId::EnumVariantId(variant)) =
self.infer.as_ref()?.variant_resolution_for_pat(pat_id) self.infer.as_ref()?.variant_resolution_for_pat(pat_id)
{ {
@ -272,7 +277,7 @@ impl SourceAnalyzer {
// Case where path is a qualifier of another path, e.g. foo::bar::Baz where we // Case where path is a qualifier of another path, e.g. foo::bar::Baz where we
// trying to resolve foo::bar. // trying to resolve foo::bar.
if let Some(outer_path) = path.syntax().parent().and_then(ast::Path::cast) { if let Some(outer_path) = parent().and_then(ast::Path::cast) {
if let Some(qualifier) = outer_path.qualifier() { if let Some(qualifier) = outer_path.qualifier() {
if path == &qualifier { if path == &qualifier {
return resolve_hir_path_qualifier(db, &self.resolver, &hir_path); return resolve_hir_path_qualifier(db, &self.resolver, &hir_path);

View File

@ -1114,4 +1114,27 @@ trait Foo {
"#]], "#]],
); );
} }
#[test]
fn test_self_variant_with_payload() {
check(
r#"
enum Foo { Bar() }
impl Foo {
fn foo(self) {
match self {
Self::Bar$0() => (),
}
}
}
"#,
expect![[r#"
Bar Variant FileId(0) 11..16 11..14 Other
FileId(0) 89..92 Other
"#]],
);
}
} }

View File

@ -14,7 +14,7 @@ module.exports = {
"rules": { "rules": {
"camelcase": ["error"], "camelcase": ["error"],
"eqeqeq": ["error", "always", { "null": "ignore" }], "eqeqeq": ["error", "always", { "null": "ignore" }],
"no-console": ["error"], "no-console": ["error", { allow: ["warn", "error"] }],
"prefer-const": "error", "prefer-const": "error",
"@typescript-eslint/member-delimiter-style": [ "@typescript-eslint/member-delimiter-style": [
"error", "error",
@ -33,6 +33,7 @@ module.exports = {
"error", "error",
"always" "always"
], ],
"@typescript-eslint/no-unnecessary-type-assertion": "error" "@typescript-eslint/no-unnecessary-type-assertion": "error",
"@typescript-eslint/no-floating-promises": "error"
} }
}; };

View File

@ -11,7 +11,7 @@ export interface Env {
} }
function renderCommand(cmd: ra.CommandLink) { function renderCommand(cmd: ra.CommandLink) {
return `[${cmd.title}](command:${cmd.command}?${encodeURIComponent(JSON.stringify(cmd.arguments))} '${cmd.tooltip!}')`; return `[${cmd.title}](command:${cmd.command}?${encodeURIComponent(JSON.stringify(cmd.arguments))} '${cmd.tooltip}')`;
} }
function renderHoverActions(actions: ra.CommandLinkGroup[]): vscode.MarkdownString { function renderHoverActions(actions: ra.CommandLinkGroup[]): vscode.MarkdownString {
@ -138,7 +138,7 @@ export function createClient(serverPath: string, cwd: string, extraEnv: Env): lc
command: "rust-analyzer.applyActionGroup", command: "rust-analyzer.applyActionGroup",
title: "", title: "",
arguments: [items.map((item) => { arguments: [items.map((item) => {
return { label: item.title, arguments: item.command!!.arguments!![0] }; return { label: item.title, arguments: item.command!.arguments![0] };
})], })],
}; };

View File

@ -125,7 +125,7 @@ export function joinLines(ctx: Ctx): Cmd {
ranges: editor.selections.map((it) => client.code2ProtocolConverter.asRange(it)), ranges: editor.selections.map((it) => client.code2ProtocolConverter.asRange(it)),
textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document), textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
}); });
editor.edit((builder) => { await editor.edit((builder) => {
client.protocol2CodeConverter.asTextEdits(items).forEach((edit: any) => { client.protocol2CodeConverter.asTextEdits(items).forEach((edit: any) => {
builder.replace(edit.range, edit.newText); builder.replace(edit.range, edit.newText);
}); });
@ -236,7 +236,7 @@ export function ssr(ctx: Ctx): Cmd {
const request = await vscode.window.showInputBox(options); const request = await vscode.window.showInputBox(options);
if (!request) return; if (!request) return;
vscode.window.withProgress({ await vscode.window.withProgress({
location: vscode.ProgressLocation.Notification, location: vscode.ProgressLocation.Notification,
title: "Structured search replace in progress...", title: "Structured search replace in progress...",
cancellable: false, cancellable: false,
@ -457,10 +457,10 @@ export function reloadWorkspace(ctx: Ctx): Cmd {
} }
export function showReferences(ctx: Ctx): Cmd { export function showReferences(ctx: Ctx): Cmd {
return (uri: string, position: lc.Position, locations: lc.Location[]) => { return async (uri: string, position: lc.Position, locations: lc.Location[]) => {
const client = ctx.client; const client = ctx.client;
if (client) { if (client) {
vscode.commands.executeCommand( await vscode.commands.executeCommand(
'editor.action.showReferences', 'editor.action.showReferences',
vscode.Uri.parse(uri), vscode.Uri.parse(uri),
client.protocol2CodeConverter.asPosition(position), client.protocol2CodeConverter.asPosition(position),
@ -474,7 +474,7 @@ export function applyActionGroup(_ctx: Ctx): Cmd {
return async (actions: { label: string; arguments: lc.CodeAction }[]) => { return async (actions: { label: string; arguments: lc.CodeAction }[]) => {
const selectedAction = await vscode.window.showQuickPick(actions); const selectedAction = await vscode.window.showQuickPick(actions);
if (!selectedAction) return; if (!selectedAction) return;
vscode.commands.executeCommand( await vscode.commands.executeCommand(
'rust-analyzer.resolveCodeAction', 'rust-analyzer.resolveCodeAction',
selectedAction.arguments, selectedAction.arguments,
); );
@ -510,7 +510,7 @@ export function openDocs(ctx: Ctx): Cmd {
const doclink = await client.sendRequest(ra.openDocs, { position, textDocument }); const doclink = await client.sendRequest(ra.openDocs, { position, textDocument });
if (doclink != null) { if (doclink != null) {
vscode.commands.executeCommand("vscode.open", vscode.Uri.parse(doclink)); await vscode.commands.executeCommand("vscode.open", vscode.Uri.parse(doclink));
} }
}; };

View File

@ -77,7 +77,7 @@ async function getDebugConfiguration(ctx: Ctx, runnable: ra.Runnable): Promise<v
} }
if (!debugEngine) { if (!debugEngine) {
vscode.window.showErrorMessage(`Install [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)` await vscode.window.showErrorMessage(`Install [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)`
+ ` or [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) extension for debugging.`); + ` or [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) extension for debugging.`);
return; return;
} }
@ -86,12 +86,14 @@ async function getDebugConfiguration(ctx: Ctx, runnable: ra.Runnable): Promise<v
if (ctx.config.debug.openDebugPane) { if (ctx.config.debug.openDebugPane) {
debugOutput.show(true); debugOutput.show(true);
} }
// folder exists or RA is not active.
const isMultiFolderWorkspace = vscode.workspace.workspaceFolders!.length > 1; // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
const firstWorkspace = vscode.workspace.workspaceFolders![0]; // folder exists or RA is not active. const workspaceFolders = vscode.workspace.workspaceFolders!;
const isMultiFolderWorkspace = workspaceFolders.length > 1;
const firstWorkspace = workspaceFolders[0];
const workspace = !isMultiFolderWorkspace || !runnable.args.workspaceRoot ? const workspace = !isMultiFolderWorkspace || !runnable.args.workspaceRoot ?
firstWorkspace : firstWorkspace :
vscode.workspace.workspaceFolders!.find(w => runnable.args.workspaceRoot?.includes(w.uri.fsPath)) || firstWorkspace; workspaceFolders.find(w => runnable.args.workspaceRoot?.includes(w.uri.fsPath)) || firstWorkspace;
const wsFolder = path.normalize(workspace.uri.fsPath); const wsFolder = path.normalize(workspace.uri.fsPath);
const workspaceQualifier = isMultiFolderWorkspace ? `:${workspace.name}` : ''; const workspaceQualifier = isMultiFolderWorkspace ? `:${workspace.name}` : '';

View File

@ -36,7 +36,7 @@ export function activateInlayHints(ctx: Ctx) {
maybeUpdater.onConfigChange, maybeUpdater, ctx.subscriptions maybeUpdater.onConfigChange, maybeUpdater, ctx.subscriptions
); );
maybeUpdater.onConfigChange(); maybeUpdater.onConfigChange().catch(console.error);
} }
const typeHints = createHintStyle("type"); const typeHints = createHintStyle("type");

View File

@ -76,7 +76,7 @@ async function tryActivate(context: vscode.ExtensionContext) {
// This a horribly, horribly wrong way to deal with this problem. // This a horribly, horribly wrong way to deal with this problem.
ctx = await Ctx.create(config, context, serverPath, workspaceFolder.uri.fsPath); ctx = await Ctx.create(config, context, serverPath, workspaceFolder.uri.fsPath);
setContextValue(RUST_PROJECT_CONTEXT_NAME, true); await setContextValue(RUST_PROJECT_CONTEXT_NAME, true);
// Commands which invokes manually via command palette, shortcut, etc. // Commands which invokes manually via command palette, shortcut, etc.
@ -142,7 +142,7 @@ async function tryActivate(context: vscode.ExtensionContext) {
} }
export async function deactivate() { export async function deactivate() {
setContextValue(RUST_PROJECT_CONTEXT_NAME, undefined); await setContextValue(RUST_PROJECT_CONTEXT_NAME, undefined);
await ctx?.client.stop(); await ctx?.client.stop();
ctx = undefined; ctx = undefined;
} }
@ -183,10 +183,10 @@ async function bootstrapExtension(config: Config, state: PersistentState): Promi
const release = await downloadWithRetryDialog(state, async () => { const release = await downloadWithRetryDialog(state, async () => {
return await fetchRelease("nightly", state.githubToken); return await fetchRelease("nightly", state.githubToken);
}).catch((e) => { }).catch(async (e) => {
log.error(e); log.error(e);
if (state.releaseId === undefined) { // Show error only for the initial download if (state.releaseId === undefined) { // Show error only for the initial download
vscode.window.showErrorMessage(`Failed to download rust-analyzer nightly ${e}`); await vscode.window.showErrorMessage(`Failed to download rust-analyzer nightly ${e}`);
} }
return undefined; return undefined;
}); });
@ -298,7 +298,7 @@ async function getServer(config: Config, state: PersistentState): Promise<string
}; };
const platform = platforms[`${process.arch} ${process.platform}`]; const platform = platforms[`${process.arch} ${process.platform}`];
if (platform === undefined) { if (platform === undefined) {
vscode.window.showErrorMessage( await vscode.window.showErrorMessage(
"Unfortunately we don't ship binaries for your platform yet. " + "Unfortunately we don't ship binaries for your platform yet. " +
"You need to manually clone rust-analyzer repository and " + "You need to manually clone rust-analyzer repository and " +
"run `cargo xtask install --server` to build the language server from sources. " + "run `cargo xtask install --server` to build the language server from sources. " +
@ -433,6 +433,7 @@ function warnAboutExtensionConflicts() {
vscode.window.showWarningMessage( vscode.window.showWarningMessage(
`You have both the ${fst[0]} (${fst[1]}) and ${sec[0]} (${sec[1]}) ` + `You have both the ${fst[0]} (${fst[1]}) and ${sec[0]} (${sec[1]}) ` +
"plugins enabled. These are known to conflict and cause various functions of " + "plugins enabled. These are known to conflict and cause various functions of " +
"both plugins to not work correctly. You should disable one of them.", "Got it"); "both plugins to not work correctly. You should disable one of them.", "Got it")
.then(() => { }, console.error);
}; };
} }

View File

@ -45,7 +45,7 @@ export async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick,
if (items.length === 0) { if (items.length === 0) {
// it is the debug case, run always has at least 'cargo check ...' // it is the debug case, run always has at least 'cargo check ...'
// see crates\rust-analyzer\src\main_loop\handlers.rs, handle_runnables // see crates\rust-analyzer\src\main_loop\handlers.rs, handle_runnables
vscode.window.showErrorMessage("There's no debug target!"); await vscode.window.showErrorMessage("There's no debug target!");
return; return;
} }
@ -65,8 +65,8 @@ export async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick,
disposables.push( disposables.push(
quickPick.onDidHide(() => close()), quickPick.onDidHide(() => close()),
quickPick.onDidAccept(() => close(quickPick.selectedItems[0])), quickPick.onDidAccept(() => close(quickPick.selectedItems[0])),
quickPick.onDidTriggerButton((_button) => { quickPick.onDidTriggerButton(async (_button) => {
(async () => await makeDebugConfig(ctx, quickPick.activeItems[0].runnable))(); await makeDebugConfig(ctx, quickPick.activeItems[0].runnable);
close(); close();
}), }),
quickPick.onDidChangeActive((active) => { quickPick.onDidChangeActive((active) => {
@ -145,6 +145,7 @@ export async function createTask(runnable: ra.Runnable, config: Config): Promise
overrideCargo: runnable.args.overrideCargo, overrideCargo: runnable.args.overrideCargo,
}; };
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
const target = vscode.workspace.workspaceFolders![0]; // safe, see main activate() const target = vscode.workspace.workspaceFolders![0]; // safe, see main activate()
const cargoTask = await tasks.buildCargoTask(target, definition, runnable.label, args, config.cargoRunner, true); const cargoTask = await tasks.buildCargoTask(target, definition, runnable.label, args, config.cargoRunner, true);
cargoTask.presentationOptions.clear = true; cargoTask.presentationOptions.clear = true;

View File

@ -62,7 +62,9 @@ function parseSnippet(snip: string): [string, [number, number]] | undefined {
const m = snip.match(/\$(0|\{0:([^}]*)\})/); const m = snip.match(/\$(0|\{0:([^}]*)\})/);
if (!m) return undefined; if (!m) return undefined;
const placeholder = m[2] ?? ""; const placeholder = m[2] ?? "";
const range: [number, number] = [m.index!!, placeholder.length]; if (m.index == null)
return undefined;
const range: [number, number] = [m.index, placeholder.length];
const insert = snip.replace(m[0], placeholder); const insert = snip.replace(m[0], placeholder);
return [insert, range]; return [insert, range];
} }