Skip to content

Commit

Permalink
Fix inspection "Unused must_use" for tokio::main proc macro
Browse files Browse the repository at this point in the history
We don't expand `tokio::main` async function, so return type of such function was considered as `impl Future`, though actually `tokio::main` expands to function returning unit

[skip ci]
  • Loading branch information
dima74 committed Jul 26, 2023
1 parent 8eb0ece commit 0bd6317
Showing 1 changed file with 20 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import org.rust.ide.inspections.RsProblemsHolder
import org.rust.ide.inspections.RsWithMacrosInspectionVisitor
import org.rust.ide.utils.template.newTemplateBuilder
import org.rust.lang.core.psi.*
import org.rust.lang.core.psi.KnownProcMacroKind.*
import org.rust.lang.core.psi.ext.RsItemElement
import org.rust.lang.core.psi.ext.expandedStmtsAndTailExpr
import org.rust.lang.core.psi.ext.findFirstMetaItem
Expand Down Expand Up @@ -85,8 +86,14 @@ private class InspectionResult(@InspectionMessage val description: String, val f

private fun inspectAndProposeFixes(expr: RsExpr): InspectionResult? {
val fixes = mutableListOf<LocalQuickFix>()
val function = when (expr) {
is RsDotExpr -> expr.methodCall?.getFunctionCallContext()?.function
is RsCallExpr -> expr.getFunctionCallContext()?.function
else -> null
}
if (isAsyncHardcodedProcMacro(function)) return null
val description = checkTypeMustUse(expr.type, expr, fixes)
?: checkFuncMustUse(expr)
?: checkFuncMustUse(function)
?: return null
if (expr.returnsStdResult()) {
fixes += FixAddExpect(expr)
Expand All @@ -96,14 +103,18 @@ private fun inspectAndProposeFixes(expr: RsExpr): InspectionResult? {
return InspectionResult(description, fixes)
}

private fun checkFuncMustUse(expr: RsExpr): @Nls String? {
val func = when (expr) {
is RsDotExpr -> expr.methodCall?.getFunctionCallContext()?.function
is RsCallExpr -> expr.getFunctionCallContext()?.function
else -> null
} ?: return null
if (!func.hasMustUseAttr()) return null
return RsBundle.message("inspection.UnusedMustUse.description.function.attribute", func.name.toString())
// `#[tokio::main] async fn main() { ... }` actually doesn't return `Future`
private fun isAsyncHardcodedProcMacro(function: RsFunction?): Boolean {
if (function == null) return false
val hardcodedProcMacros = ProcMacroAttribute.getHardcodedProcMacroAttributes(function)
return hardcodedProcMacros.any {
it == ASYNC_MAIN || it == ASYNC_TEST || it == ASYNC_BENCH
}
}

private fun checkFuncMustUse(function: RsFunction?): @Nls String? {
if (function == null || !function.hasMustUseAttr()) return null
return RsBundle.message("inspection.UnusedMustUse.description.function.attribute", function.name.toString())
}

private fun checkTypeMustUse(type: Ty, expr: RsExpr, fixes: MutableList<LocalQuickFix>): @Nls String? {
Expand Down

0 comments on commit 0bd6317

Please sign in to comment.