Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion clippy_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ use rustc_middle::ty::{
self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, GenericArgKind, GenericArgsRef, IntTy, Ty, TyCtxt,
TypeFlags, TypeVisitableExt, TypeckResults, UintTy, UpvarCapture,
};
use rustc_session::config::Input;
use rustc_span::hygiene::{ExpnKind, MacroKind};
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{Ident, Symbol, kw};
Expand Down Expand Up @@ -2498,7 +2499,18 @@ pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool {

/// Checks if the node is in a `#[test]` function or has any parent node marked `#[cfg(test)]`
pub fn is_in_test(tcx: TyCtxt<'_>, hir_id: HirId) -> bool {
is_in_test_function(tcx, hir_id) || is_in_cfg_test(tcx, hir_id)
is_in_test_function(tcx, hir_id) || is_in_cfg_test(tcx, hir_id) || is_in_integration_test_file(tcx)
}

/// Check if the node is in an integration test file (i.e. under `tests/`).
fn is_in_integration_test_file(tcx: TyCtxt<'_>) -> bool {
if let Input::File(ref path) = tcx.sess.io.input
&& !tcx.sess.opts.unstable_opts.ui_testing
{
path.starts_with("tests")
} else {
false
}
}

/// Checks if the item of any of its parents has `#[cfg(...)]` attribute applied.
Expand Down
39 changes: 39 additions & 0 deletions tests/allow-unwrap-in-integration-tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use std::path::PathBuf;
use std::process::Command;
use test_utils::{CARGO_CLIPPY_PATH, IS_RUSTC_TEST_SUITE};

mod test_utils;

#[test]
fn test_allow_unwrap_in_integration_tests() {
if IS_RUSTC_TEST_SUITE {
return;
}
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let target_dir = root.join("target").join("integration_test");
let cwd = root.join("tests/integration_test");

// Make sure we start with a clean state
Command::new("cargo")
.current_dir(&cwd)
.env("CARGO_TARGET_DIR", &target_dir)
.arg("clean")
.output()
.unwrap();

let output = Command::new(&*CARGO_CLIPPY_PATH)
.current_dir(&cwd)
.env("CARGO_INCREMENTAL", "0")
.env("CARGO_TARGET_DIR", &target_dir)
.arg("clippy")
.arg("--all-targets")
.arg("--")
.arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir
.output()
.unwrap();

println!("status: {}", output.status);
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
assert!(output.status.success());
}
9 changes: 9 additions & 0 deletions tests/integration_test/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "integration_test"
version = "0.1.0"
edition = "2024"

[dependencies]

[lints.clippy]
unwrap_used = "deny"
1 change: 1 addition & 0 deletions tests/integration_test/clippy.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
allow-unwrap-in-tests = true
20 changes: 20 additions & 0 deletions tests/integration_test/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#![allow(clippy::disallowed_names)]

fn main() {
println!("testing 123");
}

#[cfg(test)]
mod tests {
fn foo() -> Option<u32> {
Some(1)
}

#[test]
fn integration_test() {
// should not lint in test file
// see https://github.com/rust-lang/rust-clippy/issues/13981
let bar = foo().unwrap();
println!("bar: {bar}");
}
}
20 changes: 20 additions & 0 deletions tests/integration_test/tests/unwrap_in_integration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#![allow(clippy::disallowed_names)]

fn foo() -> Option<u32> {
Some(1)
}

fn helper_function() {
// Should not lint in integration test file, see https://github.com/rust-lang/rust-clippy/issues/13981
let baz = foo().unwrap();
println!("baz: {baz}");
}

#[test]
fn integration_test() {
helper_function();

// Should not lint in integration test file, see https://github.com/rust-lang/rust-clippy/issues/13981
let bar = foo().unwrap();
println!("bar: {bar}");
}