diff --git a/detectors/avoid-panic-error/src/lib.rs b/detectors/avoid-panic-error/src/lib.rs
index 72895519..f8fcaeb8 100644
--- a/detectors/avoid-panic-error/src/lib.rs
+++ b/detectors/avoid-panic-error/src/lib.rs
@@ -3,8 +3,9 @@
extern crate rustc_ast;
extern crate rustc_span;
-use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_wrappers::span_lint_and_help;
use rustc_ast::{
+ ptr::P,
tokenstream::TokenTree,
visit::{walk_expr, Visitor},
AssocItemKind, AttrArgs, AttrKind, Block, Expr, ExprKind, FnRetTy, Item, ItemKind, MacCall,
@@ -93,16 +94,12 @@ impl EarlyLintPass for AvoidPanicError {
ItemKind::Impl(impl_item) => {
for assoc_item in &impl_item.items {
if let AssocItemKind::Fn(fn_item) = &assoc_item.kind {
- self.check_function(
- cx,
- &fn_item.sig.decl.output,
- fn_item.body.as_ref().unwrap(),
- );
+ self.check_function(cx, &fn_item.sig.decl.output, &fn_item.body);
}
}
}
ItemKind::Fn(fn_item) => {
- self.check_function(cx, &fn_item.sig.decl.output, fn_item.body.as_ref().unwrap());
+ self.check_function(cx, &fn_item.sig.decl.output, &fn_item.body);
}
ItemKind::Mod(_, ModKind::Loaded(items, _, _)) => {
for item in items {
@@ -112,11 +109,7 @@ impl EarlyLintPass for AvoidPanicError {
ItemKind::Trait(trait_item) => {
for item in &trait_item.items {
if let AssocItemKind::Fn(fn_item) = &item.kind {
- self.check_function(
- cx,
- &fn_item.sig.decl.output,
- fn_item.body.as_ref().unwrap(),
- );
+ self.check_function(cx, &fn_item.sig.decl.output, &fn_item.body);
}
}
}
@@ -126,10 +119,12 @@ impl EarlyLintPass for AvoidPanicError {
}
impl AvoidPanicError {
- fn check_function(&self, cx: &EarlyContext, output: &FnRetTy, body: &Block) {
- if is_result_type(output) {
- let mut visitor = PanicVisitor { cx };
- visitor.visit_block(body);
+ fn check_function(&self, cx: &EarlyContext, output: &FnRetTy, body: &Option
>) {
+ if let Some(body) = body {
+ if is_result_type(output) {
+ let mut visitor = PanicVisitor { cx };
+ visitor.visit_block(body);
+ }
}
}
}
diff --git a/detectors/dynamic-storage/Cargo.toml b/detectors/dynamic-storage/Cargo.toml
index c564b4ff..0860b324 100644
--- a/detectors/dynamic-storage/Cargo.toml
+++ b/detectors/dynamic-storage/Cargo.toml
@@ -7,7 +7,7 @@ version = "0.1.0"
crate-type = ["cdylib"]
[dependencies]
-clippy_utils = { workspace = true }
+clippy_wrappers = { workspace = true }
dylint_linting = { workspace = true }
if_chain = { workspace = true }
utils = { workspace = true }
diff --git a/detectors/dynamic-storage/src/lib.rs b/detectors/dynamic-storage/src/lib.rs
index 151a0c52..c33f4645 100644
--- a/detectors/dynamic-storage/src/lib.rs
+++ b/detectors/dynamic-storage/src/lib.rs
@@ -4,7 +4,7 @@ extern crate rustc_hir;
extern crate rustc_middle;
extern crate rustc_span;
-use clippy_utils::diagnostics::span_lint;
+use clippy_wrappers::span_lint;
use if_chain::if_chain;
use rustc_hir::{
intravisit::{walk_expr, FnKind, Visitor},
diff --git a/detectors/integer-overflow-or-underflow/Cargo.toml b/detectors/integer-overflow-or-underflow/Cargo.toml
index 15f1a7fd..f584b02b 100644
--- a/detectors/integer-overflow-or-underflow/Cargo.toml
+++ b/detectors/integer-overflow-or-underflow/Cargo.toml
@@ -7,7 +7,7 @@ version = "0.1.0"
crate-type = ["cdylib"]
[dependencies]
-clippy_utils = { workspace = true }
+clippy_wrappers = { workspace = true }
dylint_linting = { workspace = true }
if_chain = { workspace = true }
utils = { workspace = true }
diff --git a/detectors/integer-overflow-or-underflow/src/lib.rs b/detectors/integer-overflow-or-underflow/src/lib.rs
index 031282ca..130b844a 100644
--- a/detectors/integer-overflow-or-underflow/src/lib.rs
+++ b/detectors/integer-overflow-or-underflow/src/lib.rs
@@ -3,7 +3,7 @@
extern crate rustc_hir;
extern crate rustc_span;
-use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_wrappers::span_lint_and_help;
use rustc_hir::{
intravisit::{walk_expr, FnKind, Visitor},
BinOpKind, Body, Expr, ExprKind, FnDecl, UnOp,
diff --git a/detectors/iterators-over-indexing/src/lib.rs b/detectors/iterators-over-indexing/src/lib.rs
index 2126784d..4f39260e 100644
--- a/detectors/iterators-over-indexing/src/lib.rs
+++ b/detectors/iterators-over-indexing/src/lib.rs
@@ -20,6 +20,7 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{TyCtxt, TyKind};
use rustc_span::{symbol::Ident, Span};
use rustc_type_ir::Interner;
+use std::collections::HashSet;
use utils::get_node_type;
const LINT_MESSAGE: &str =
@@ -39,7 +40,7 @@ dylint_linting::declare_late_lint! {
}
struct ForLoopVisitor<'a, 'b> {
- span_constant: Vec,
+ span_constant: HashSet,
cx: &'b LateContext<'a>,
}
struct VectorAccessVisitor<'a, 'b> {
@@ -351,7 +352,7 @@ fn handle_expr<'a>(me: &mut ForLoopVisitor<'a, '_>, expr: &'a Expr<'a>) -> Resul
}
if visitor.has_vector_access {
- me.span_constant.push(expr.span);
+ me.span_constant.insert(expr.span);
}
Ok(())
@@ -377,7 +378,7 @@ impl<'tcx> LateLintPass<'tcx> for IteratorOverIndexing {
if let FnKind::Method(_ident, _sig) = kind {
let span_constant = {
let mut visitor = ForLoopVisitor {
- span_constant: vec![],
+ span_constant: HashSet::new(),
cx,
};
walk_expr(&mut visitor, body.value);
diff --git a/detectors/storage-change-events/Cargo.toml b/detectors/storage-change-events/Cargo.toml
index 97569970..80eac245 100644
--- a/detectors/storage-change-events/Cargo.toml
+++ b/detectors/storage-change-events/Cargo.toml
@@ -7,7 +7,7 @@ version = "0.1.0"
crate-type = ["cdylib"]
[dependencies]
-clippy_utils = { workspace = true }
+clippy_wrappers = { workspace = true }
dylint_linting = { workspace = true }
if_chain = { workspace = true }
utils = { workspace = true }
diff --git a/detectors/storage-change-events/src/lib.rs b/detectors/storage-change-events/src/lib.rs
index b119ff21..1c45369f 100644
--- a/detectors/storage-change-events/src/lib.rs
+++ b/detectors/storage-change-events/src/lib.rs
@@ -1,26 +1,21 @@
#![feature(rustc_private)]
extern crate rustc_hir;
-extern crate rustc_middle;
extern crate rustc_span;
-use clippy_utils::diagnostics::span_lint_and_help;
-
+use clippy_wrappers::span_lint_and_help;
use rustc_hir::{
intravisit::{walk_expr, Visitor},
Expr, ExprKind,
};
use rustc_lint::{LateContext, LateLintPass};
-
-use rustc_span::Span;
-
-use std::collections::HashMap;
-use std::collections::HashSet;
-use std::vec;
+use rustc_span::{def_id::DefId, Span};
+use std::{
+ collections::{HashMap, HashSet},
+ vec,
+};
use utils::{is_soroban_function, FunctionCallVisitor};
-use rustc_span::def_id::DefId;
-
const LINT_MESSAGE: &str = "Consider emiting an event when storage is modified";
dylint_linting::impl_late_lint! {
diff --git a/detectors/token-interface-events/Cargo.toml b/detectors/token-interface-events/Cargo.toml
index 644b6b4d..5fc56514 100644
--- a/detectors/token-interface-events/Cargo.toml
+++ b/detectors/token-interface-events/Cargo.toml
@@ -7,7 +7,7 @@ version = "0.1.0"
crate-type = ["cdylib"]
[dependencies]
-clippy_utils = { workspace = true }
+clippy_wrappers = { workspace = true }
dylint_linting = { workspace = true }
if_chain = { workspace = true }
utils = { workspace = true }
diff --git a/detectors/token-interface-events/src/lib.rs b/detectors/token-interface-events/src/lib.rs
index 69e3d264..1963452b 100644
--- a/detectors/token-interface-events/src/lib.rs
+++ b/detectors/token-interface-events/src/lib.rs
@@ -1,26 +1,21 @@
#![feature(rustc_private)]
extern crate rustc_hir;
-extern crate rustc_middle;
extern crate rustc_span;
-use clippy_utils::diagnostics::span_lint_and_help;
-
+use clippy_wrappers::span_lint_and_help;
use rustc_hir::{
intravisit::{walk_expr, Visitor},
Expr, ExprKind,
};
use rustc_lint::{LateContext, LateLintPass};
-
-use rustc_span::Span;
-
-use std::collections::HashMap;
-use std::collections::HashSet;
-use std::vec;
+use rustc_span::{def_id::DefId, Span};
+use std::{
+ collections::{HashMap, HashSet},
+ vec,
+};
use utils::{verify_token_interface_function, FunctionCallVisitor};
-use rustc_span::def_id::DefId;
-
const LINT_MESSAGE: &str = "This function belongs to the Token Interface and should emit an event";
dylint_linting::impl_late_lint! {
diff --git a/detectors/unsafe-expect/Cargo.toml b/detectors/unsafe-expect/Cargo.toml
index f451b997..24bde4b3 100644
--- a/detectors/unsafe-expect/Cargo.toml
+++ b/detectors/unsafe-expect/Cargo.toml
@@ -11,6 +11,7 @@ clippy_utils = { workspace = true }
clippy_wrappers = { workspace = true }
dylint_linting = { workspace = true }
if_chain = { workspace = true }
+utils = { workspace = true }
[package.metadata.rust-analyzer]
rustc_private = true
diff --git a/detectors/unsafe-expect/src/lib.rs b/detectors/unsafe-expect/src/lib.rs
index 42cd146f..4f3cb283 100644
--- a/detectors/unsafe-expect/src/lib.rs
+++ b/detectors/unsafe-expect/src/lib.rs
@@ -4,9 +4,7 @@
extern crate rustc_hir;
extern crate rustc_span;
-use std::{collections::HashSet, hash::Hash};
-
-use clippy_utils::higher;
+use clippy_utils::higher::IfOrIfLet;
use clippy_wrappers::span_lint_and_help;
use if_chain::if_chain;
use rustc_hir::{
@@ -17,6 +15,8 @@ use rustc_hir::{
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_span::{sym, Span, Symbol};
+use std::{collections::HashSet, hash::Hash};
+use utils::fn_returns;
const LINT_MESSAGE: &str = "Unsafe usage of `expect`";
const PANIC_INDUCING_FUNCTIONS: [&str; 2] = ["panic", "bail"];
@@ -149,6 +149,7 @@ struct UnsafeExpectVisitor<'a, 'tcx> {
cx: &'a LateContext<'tcx>,
conditional_checker: HashSet,
checked_exprs: HashSet,
+ linted_spans: HashSet,
}
impl UnsafeExpectVisitor<'_, '_> {
@@ -174,21 +175,23 @@ impl UnsafeExpectVisitor<'_, '_> {
None
}
- fn set_conditional_checker(&mut self, conditional_checkers: &HashSet) {
- for checker in conditional_checkers {
- self.conditional_checker.insert(*checker);
- if checker.check_type.is_safe_to_expect() {
- self.checked_exprs.insert(checker.checked_expr_hir_id);
- }
- }
- }
-
- fn reset_conditional_checker(&mut self, conditional_checkers: HashSet) {
+ fn update_conditional_checker(
+ &mut self,
+ conditional_checkers: &HashSet,
+ set: bool,
+ ) {
for checker in conditional_checkers {
- if checker.check_type.is_safe_to_expect() {
- self.checked_exprs.remove(&checker.checked_expr_hir_id);
+ if set {
+ self.conditional_checker.insert(*checker);
+ if checker.check_type.is_safe_to_expect() {
+ self.checked_exprs.insert(checker.checked_expr_hir_id);
+ }
+ } else {
+ if checker.check_type.is_safe_to_expect() {
+ self.checked_exprs.remove(&checker.checked_expr_hir_id);
+ }
+ self.conditional_checker.remove(checker);
}
- self.conditional_checker.remove(&checker);
}
}
@@ -236,6 +239,7 @@ impl UnsafeExpectVisitor<'_, '_> {
.get_expect_info(receiver)
.map_or(true, |id| !self.checked_exprs.contains(&id));
}
+
args.iter().any(|arg| self.contains_unsafe_method_call(arg))
|| self.contains_unsafe_method_call(receiver)
}
@@ -252,7 +256,9 @@ impl UnsafeExpectVisitor<'_, '_> {
fn check_expr_for_unsafe_expect(&mut self, expr: &Expr) {
match &expr.kind {
ExprKind::MethodCall(path_segment, receiver, args, _) => {
- if self.is_method_call_unsafe(path_segment, receiver, args) {
+ if self.is_method_call_unsafe(path_segment, receiver, args)
+ && !self.linted_spans.contains(&expr.span)
+ {
span_lint_and_help(
self.cx,
UNSAFE_EXPECT,
@@ -261,6 +267,7 @@ impl UnsafeExpectVisitor<'_, '_> {
None,
"Please, use a custom error instead of `expect`",
);
+ self.linted_spans.insert(expr.span);
}
}
ExprKind::Call(func, args) => {
@@ -312,17 +319,17 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafeExpectVisitor<'a, 'tcx> {
}
// Find `if` or `if let` expressions
- if let Some(higher::IfOrIfLet {
+ if let Some(IfOrIfLet {
cond,
then: if_expr,
r#else: _,
- }) = higher::IfOrIfLet::hir(expr)
+ }) = IfOrIfLet::hir(expr)
{
// If we are interested in the condition (if it is a CheckType) we traverse the body.
let conditional_checker = ConditionalChecker::from_expression(cond);
- self.set_conditional_checker(&conditional_checker);
+ self.update_conditional_checker(&conditional_checker, true);
walk_expr(self, if_expr);
- self.reset_conditional_checker(conditional_checker);
+ self.update_conditional_checker(&conditional_checker, false);
return;
}
@@ -338,13 +345,15 @@ impl<'tcx> LateLintPass<'tcx> for UnsafeExpect {
&mut self,
cx: &LateContext<'tcx>,
_: FnKind<'tcx>,
- _: &'tcx FnDecl<'tcx>,
+ fn_decl: &'tcx FnDecl<'tcx>,
body: &'tcx Body<'tcx>,
span: Span,
_: LocalDefId,
) {
- // If the function comes from a macro expansion, we don't want to analyze it.
- if span.from_expansion() {
+ // If the function comes from a macro expansion or does not return a Result<(), ()> or Option<()>, we don't want to analyze it.
+ if span.from_expansion()
+ || !fn_returns(fn_decl, sym::Result) && !fn_returns(fn_decl, sym::Option)
+ {
return;
}
@@ -352,6 +361,7 @@ impl<'tcx> LateLintPass<'tcx> for UnsafeExpect {
cx,
checked_exprs: HashSet::new(),
conditional_checker: HashSet::new(),
+ linted_spans: HashSet::new(),
};
walk_expr(&mut visitor, body.value);
diff --git a/detectors/unsafe-unwrap/Cargo.toml b/detectors/unsafe-unwrap/Cargo.toml
index cb8e056c..4812ff59 100644
--- a/detectors/unsafe-unwrap/Cargo.toml
+++ b/detectors/unsafe-unwrap/Cargo.toml
@@ -11,6 +11,7 @@ clippy_utils = { workspace = true }
clippy_wrappers = { workspace = true }
dylint_linting = { workspace = true }
if_chain = { workspace = true }
+utils = { workspace = true }
[package.metadata.rust-analyzer]
rustc_private = true
diff --git a/detectors/unsafe-unwrap/src/lib.rs b/detectors/unsafe-unwrap/src/lib.rs
index 6f2026d4..63b225ec 100644
--- a/detectors/unsafe-unwrap/src/lib.rs
+++ b/detectors/unsafe-unwrap/src/lib.rs
@@ -1,23 +1,22 @@
#![feature(rustc_private)]
#![allow(clippy::enum_variant_names)]
-extern crate rustc_ast;
extern crate rustc_hir;
extern crate rustc_span;
-use std::{collections::HashSet, hash::Hash};
-
-use clippy_utils::higher;
+use clippy_utils::higher::IfOrIfLet;
use clippy_wrappers::span_lint_and_help;
use if_chain::if_chain;
use rustc_hir::{
def::Res,
def_id::LocalDefId,
intravisit::{walk_expr, FnKind, Visitor},
- BinOpKind, Body, Expr, ExprKind, FnDecl, HirId, PathSegment, QPath, UnOp,
+ BinOpKind, Body, Expr, ExprKind, FnDecl, HirId, LetStmt, PathSegment, QPath, UnOp,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_span::{sym, Span, Symbol};
+use std::{collections::HashSet, hash::Hash};
+use utils::{fn_returns, get_node_type_opt, match_type_to_str};
const LINT_MESSAGE: &str = "Unsafe usage of `unwrap`";
const PANIC_INDUCING_FUNCTIONS: [&str; 2] = ["panic", "bail"];
@@ -65,6 +64,13 @@ dylint_linting::declare_late_lint! {
}
}
+// Enum to represent the type being unwrapped
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+enum UnwrapType {
+ Option,
+ Result,
+}
+
/// Represents the type of check performed on method call expressions to determine their safety or behavior.
#[derive(Clone, Copy, Hash, Eq, PartialEq)]
enum CheckType {
@@ -132,7 +138,7 @@ impl ConditionalChecker {
fn from_expression(condition: &Expr<'_>) -> HashSet {
match condition.kind {
// Single `not` expressions are supported
- ExprKind::Unary(op, condition) => Self::handle_condition(condition, op == UnOp::Not),
+ ExprKind::Unary(UnOp::Not, condition) => Self::handle_condition(condition, true),
// Multiple `or` expressions are supported
ExprKind::Binary(op, left_condition, right_condition) if op.node == BinOpKind::Or => {
let mut result = Self::from_expression(left_condition);
@@ -150,9 +156,33 @@ struct UnsafeUnwrapVisitor<'a, 'tcx> {
cx: &'a LateContext<'tcx>,
conditional_checker: HashSet,
checked_exprs: HashSet,
+ returns_result_or_option: bool,
}
impl UnsafeUnwrapVisitor<'_, '_> {
+ fn get_help_message(&self, unwrap_type: UnwrapType) -> &'static str {
+ match (self.returns_result_or_option, unwrap_type) {
+ (true, UnwrapType::Option) => "Consider using `ok_or` to convert Option to Result",
+ (true, UnwrapType::Result) => "Consider using the `?` operator for error propagation",
+ (false, UnwrapType::Option) => {
+ "Consider pattern matching or using `if let` instead of `unwrap`"
+ }
+ (false, UnwrapType::Result) => {
+ "Consider handling the error case explicitly or using `if let` instead of `unwrap`"
+ }
+ }
+ }
+
+ fn determine_unwrap_type(&self, receiver: &Expr<'_>) -> UnwrapType {
+ let type_opt = get_node_type_opt(self.cx, &receiver.hir_id);
+ if let Some(type_) = type_opt {
+ if match_type_to_str(self.cx, type_, "Result") {
+ return UnwrapType::Result;
+ }
+ }
+ UnwrapType::Option
+ }
+
fn is_panic_inducing_call(&self, func: &Expr<'_>) -> bool {
if let ExprKind::Path(QPath::Resolved(_, path)) = &func.kind {
return PANIC_INDUCING_FUNCTIONS.iter().any(|&func| {
@@ -175,21 +205,23 @@ impl UnsafeUnwrapVisitor<'_, '_> {
None
}
- fn set_conditional_checker(&mut self, conditional_checkers: &HashSet) {
- for checker in conditional_checkers {
- self.conditional_checker.insert(*checker);
- if checker.check_type.is_safe_to_unwrap() {
- self.checked_exprs.insert(checker.checked_expr_hir_id);
- }
- }
- }
-
- fn reset_conditional_checker(&mut self, conditional_checkers: HashSet) {
+ fn update_conditional_checker(
+ &mut self,
+ conditional_checkers: &HashSet,
+ set: bool,
+ ) {
for checker in conditional_checkers {
- if checker.check_type.is_safe_to_unwrap() {
- self.checked_exprs.remove(&checker.checked_expr_hir_id);
+ if set {
+ self.conditional_checker.insert(*checker);
+ if checker.check_type.is_safe_to_unwrap() {
+ self.checked_exprs.insert(checker.checked_expr_hir_id);
+ }
+ } else {
+ if checker.check_type.is_safe_to_unwrap() {
+ self.checked_exprs.remove(&checker.checked_expr_hir_id);
+ }
+ self.conditional_checker.remove(checker);
}
- self.conditional_checker.remove(&checker);
}
}
@@ -253,18 +285,20 @@ impl UnsafeUnwrapVisitor<'_, '_> {
}
impl<'a, 'tcx> Visitor<'tcx> for UnsafeUnwrapVisitor<'a, 'tcx> {
- fn visit_local(&mut self, local: &'tcx rustc_hir::LetStmt<'tcx>) -> Self::Result {
+ fn visit_local(&mut self, local: &'tcx LetStmt<'tcx>) -> Self::Result {
if let Some(init) = local.init {
match init.kind {
ExprKind::MethodCall(path_segment, receiver, args, _) => {
if self.is_method_call_unsafe(path_segment, receiver, args) {
+ let unwrap_type = self.determine_unwrap_type(receiver);
+ let help_message = self.get_help_message(unwrap_type);
span_lint_and_help(
self.cx,
UNSAFE_UNWRAP,
local.span,
LINT_MESSAGE,
None,
- "Please, use a custom error instead of `unwrap`",
+ help_message,
);
}
}
@@ -300,17 +334,17 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafeUnwrapVisitor<'a, 'tcx> {
}
// Find `if` or `if let` expressions
- if let Some(higher::IfOrIfLet {
+ if let Some(IfOrIfLet {
cond,
then: if_expr,
r#else: _,
- }) = higher::IfOrIfLet::hir(expr)
+ }) = IfOrIfLet::hir(expr)
{
// If we are interested in the condition (if it is a CheckType) we traverse the body.
let conditional_checker = ConditionalChecker::from_expression(cond);
- self.set_conditional_checker(&conditional_checker);
+ self.update_conditional_checker(&conditional_checker, true);
walk_expr(self, if_expr);
- self.reset_conditional_checker(conditional_checker);
+ self.update_conditional_checker(&conditional_checker, false);
return;
}
@@ -320,16 +354,18 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafeUnwrapVisitor<'a, 'tcx> {
if path_segment.ident.name == sym::unwrap;
then {
let receiver_hir_id = self.get_unwrap_info(receiver);
- // If the receiver is `None`, then we asume that the `unwrap` is unsafe
+ // If the receiver is `None` or `Err`, then we assume that the `unwrap` is unsafe
let is_checked_safe = receiver_hir_id.map_or(false, |id| self.checked_exprs.contains(&id));
if !is_checked_safe {
+ let unwrap_type = self.determine_unwrap_type(receiver);
+ let help_message = self.get_help_message(unwrap_type);
span_lint_and_help(
self.cx,
UNSAFE_UNWRAP,
expr.span,
LINT_MESSAGE,
None,
- "Please, use a custom error instead of `unwrap`",
+ help_message,
);
}
}
@@ -344,7 +380,7 @@ impl<'tcx> LateLintPass<'tcx> for UnsafeUnwrap {
&mut self,
cx: &LateContext<'tcx>,
_: FnKind<'tcx>,
- _: &'tcx FnDecl<'tcx>,
+ fn_decl: &'tcx FnDecl<'tcx>,
body: &'tcx Body<'tcx>,
span: Span,
_: LocalDefId,
@@ -358,6 +394,8 @@ impl<'tcx> LateLintPass<'tcx> for UnsafeUnwrap {
cx,
checked_exprs: HashSet::new(),
conditional_checker: HashSet::new(),
+ returns_result_or_option: fn_returns(fn_decl, sym::Result)
+ || fn_returns(fn_decl, sym::Option),
};
walk_expr(&mut visitor, body.value);
diff --git a/scripts/run-tests.py b/scripts/run-tests.py
index 1b2e3f3e..300aea2f 100644
--- a/scripts/run-tests.py
+++ b/scripts/run-tests.py
@@ -63,6 +63,7 @@ def run_integration_tests(detector, root):
root,
)
+ #print("stderr: ", stderr.read())
if stdout is None:
print(
f"{RED}Failed to run integration tests in {root} - Metadata returned empty.{ENDC}"
@@ -78,7 +79,7 @@ def run_integration_tests(detector, root):
detector_key = detector.replace("-", "_")
short_message = detector_metadata.get(detector_key, {}).get("short_message")
- returncode, _, stderr = run_subprocess(
+ returncode, stdout, stderr = run_subprocess(
[
"cargo",
"scout-audit",
@@ -91,12 +92,12 @@ def run_integration_tests(detector, root):
)
should_lint = root.endswith("vulnerable-example")
- if should_lint and short_message and short_message not in stderr:
+ if should_lint and short_message and short_message not in stdout:
returncode = 1
print_results(
returncode,
- stderr,
+ stdout,
"integration-test",
root,
time.time() - start_time,