From cdb05a081b882e598978424eab2a7de18b251f1b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 19 Mar 2025 14:09:13 +0000 Subject: [PATCH] Create rule S7413 Await should be used for awaitable returns in async blocks and functions (#4752) * Create rule S7413 * Update rule.adoc * Update metadata.json * Update rule.adoc * Update rule.adoc * Update metadata.json --------- Co-authored-by: sallaigy Co-authored-by: Gyula Sallai --- rules/S7413/metadata.json | 2 ++ rules/S7413/rust/metadata.json | 24 +++++++++++++++++++++++ rules/S7413/rust/rule.adoc | 36 ++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 rules/S7413/metadata.json create mode 100644 rules/S7413/rust/metadata.json create mode 100644 rules/S7413/rust/rule.adoc diff --git a/rules/S7413/metadata.json b/rules/S7413/metadata.json new file mode 100644 index 0000000000..2c63c08510 --- /dev/null +++ b/rules/S7413/metadata.json @@ -0,0 +1,2 @@ +{ +} diff --git a/rules/S7413/rust/metadata.json b/rules/S7413/rust/metadata.json new file mode 100644 index 0000000000..998c70c202 --- /dev/null +++ b/rules/S7413/rust/metadata.json @@ -0,0 +1,24 @@ +{ + "title": "Await should be used for awaitable returns in async blocks and functions", + "type": "BUG", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + "clippy" + ], + "defaultSeverity": "Critical", + "ruleSpecification": "RSPEC-7413", + "sqKey": "S7413", + "scope": "All", + "defaultQualityProfiles": ["Sonar way"], + "quickfix": "unknown", + "code": { + "impacts": { + "RELIABILITY": "HIGH" + }, + "attribute": "LOGICAL" + } +} diff --git a/rules/S7413/rust/rule.adoc b/rules/S7413/rust/rule.adoc new file mode 100644 index 0000000000..ea07c8cb55 --- /dev/null +++ b/rules/S7413/rust/rule.adoc @@ -0,0 +1,36 @@ + +== Why is this an issue? +When an async block or function returns a value that is itself awaitable (like a `Future`), it often indicates that the developer forgot to await that value. This creates a nested future that must be awaited twice to get the actual result, which is rarely the intended behavior. Missing an await can lead to unexpected behavior where async operations never actually execute, nested futures that require multiple awaits to resolve, hard-to-debug problems, potential deadlocks, or blocking in async contexts. + + +=== Code examples + +==== Noncompliant code example +[source,rust,diff-id=1,diff-type=noncompliant] +---- +async fn foo() {} + +fn bar() { + let x = async { + foo() // Noncompliant: returns a future that needs to be awaited + }; +} +---- + +==== Compliant solution + +[source,rust,diff-id=1,diff-type=compliant] +---- +async fn foo() {} + +fn bar() { + let x = async { + foo().await // Properly awaits the inner future + }; +} +---- + +== Resources +=== Documentation + +* Clippy Lints - https://rust-lang.github.io/rust-clippy/master/index.html#async_yields_async