@@ -46,6 +46,12 @@ const DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS: &[&str] = &["i", "j", "x", "y", "z
4646const DEFAULT_ALLOWED_PREFIXES : & [ & str ] = & [ "to" , "as" , "into" , "from" , "try_into" , "try_from" ] ;
4747const DEFAULT_ALLOWED_TRAITS_WITH_RENAMED_PARAMS : & [ & str ] =
4848 & [ "core::convert::From" , "core::convert::TryFrom" , "core::str::FromStr" ] ;
49+ /// Default paths considered as fallible for `test_without_fail_case` lint.
50+ pub ( crate ) const DEFAULT_FALLIBLE_PATHS : & [ & str ] =
51+ & [ "core::panic" , "core::assert" , "core::assert_eq" , "core::assert_ne" ] ;
52+ /// Default paths considered as non-fallible for `test_without_fail_case` lint.
53+ pub ( crate ) const DEFAULT_NONFALLIBLE_PATHS : & [ & str ] =
54+ & [ "std::print" , "std::println" , "std::dbg" , "std::eprint" , "std::eprintln" ] ;
4955
5056/// Conf with parse errors
5157#[ derive( Default ) ]
@@ -628,6 +634,33 @@ define_Conf! {
628634 /// if no suggestion can be made.
629635 #[ lints( indexing_slicing) ]
630636 suppress_restriction_lint_in_const: bool = false ,
637+ /// List of full paths of macros and functions, that can fail. If a test, or a function
638+ /// that the test calls contains a call to any one of these, lint will mark the test fallible.
639+ #[ lints( test_without_fail_case) ]
640+ test_without_fail_case_fallible_paths: Vec <String > =
641+ DEFAULT_FALLIBLE_PATHS . iter( ) . map( ToString :: to_string) . collect( ) ,
642+ /// Whether to consider indexing as a fallible operation while assesing if a test can fail.
643+ /// Indexing is fallible, and thus the a test that is doing that can fail but it is likely
644+ /// that tests that fail this way were not intended.
645+ ///
646+ /// If set true, the lint will consider indexing into a slice a failable case
647+ /// and won't lint tests that has some sort of indexing. This analysis still done
648+ /// in a interprocedural manner. Meaning that any indexing opeartion done inside of
649+ /// a function that the test calls will still result the test getting marked fallible.
650+ ///
651+ /// By default this is set to `false`. That is because from a usability perspective,
652+ /// indexing an array is not the intended way to fail a test. So setting this `true`
653+ /// reduces false positives but makes the analysis more focused on possible byproducts
654+ /// of a test. That is the set of operations to get the point we assert something rather
655+ /// than the existance of asserting that thing.
656+ #[ lints( test_without_fail_case) ]
657+ test_without_fail_case_include_indexing_as_fallible: bool = false ,
658+ /// List of full paths of macros and functions, that we want to mark as "not going to fail".
659+ /// This allows us to make the lint more focused on actual short comings of our test suite
660+ /// by marking common routines non-fallible, even though they are fallible.
661+ #[ lints( test_without_fail_case) ]
662+ test_without_fail_case_non_fallible_paths: Vec <String > =
663+ DEFAULT_NONFALLIBLE_PATHS . iter( ) . map( ToString :: to_string) . collect( ) ,
631664 /// The maximum size of objects (in bytes) that will be linted. Larger objects are ok on the heap
632665 #[ lints( boxed_local, useless_vec) ]
633666 too_large_for_stack: u64 = 200 ,
@@ -724,6 +757,14 @@ pub fn lookup_conf_file() -> io::Result<(Option<PathBuf>, Vec<String>)> {
724757fn deserialize ( file : & SourceFile ) -> TryConf {
725758 match toml:: de:: Deserializer :: new ( file. src . as_ref ( ) . unwrap ( ) ) . deserialize_map ( ConfVisitor ( file) ) {
726759 Ok ( mut conf) => {
760+ extend_vec_if_indicator_present (
761+ & mut conf. conf . test_without_fail_case_fallible_paths ,
762+ DEFAULT_FALLIBLE_PATHS ,
763+ ) ;
764+ extend_vec_if_indicator_present (
765+ & mut conf. conf . test_without_fail_case_non_fallible_paths ,
766+ DEFAULT_NONFALLIBLE_PATHS ,
767+ ) ;
727768 extend_vec_if_indicator_present ( & mut conf. conf . disallowed_names , DEFAULT_DISALLOWED_NAMES ) ;
728769 extend_vec_if_indicator_present ( & mut conf. conf . allowed_prefixes , DEFAULT_ALLOWED_PREFIXES ) ;
729770 extend_vec_if_indicator_present (
0 commit comments