diff --git a/crates/dreamchecker/src/lib.rs b/crates/dreamchecker/src/lib.rs index 681d071d..045e8cc3 100644 --- a/crates/dreamchecker/src/lib.rs +++ b/crates/dreamchecker/src/lib.rs @@ -3242,6 +3242,20 @@ impl<'o, 's> AnalyzeProc<'o, 's> { } } + if proc.is_builtin() + && args.is_empty() + && proc.name() == "Find" + && matches!(proc.ty().path.as_str(), "/list" | "/alist") + { + error( + location, + "list.Find() with no arguments searches for null, write Find(null) if that is intended", + ) + .set_severity(Severity::Warning) + .with_errortype("empty_find") + .register(self.context); + } + // filter call checking // TODO: some filters have limits for their numerical params // eg "rays" type "threshold" param defaults to 0.5, can be 0 to 1 diff --git a/crates/dreamchecker/tests/proc_tests.rs b/crates/dreamchecker/tests/proc_tests.rs index f5c4d7f0..90dd8c25 100644 --- a/crates/dreamchecker/tests/proc_tests.rs +++ b/crates/dreamchecker/tests/proc_tests.rs @@ -57,3 +57,20 @@ fn return_type_failure() { .trim(); check_errors_match(code, RETURN_TYPE_FAILURE_ERRORS); } + +pub const EMPTY_LIST_FIND_ERRORS: &[(u32, u16, &str)] = &[ ( + 3, + 20, + "list.Find() with no arguments searches for null, write Find(null) if that is intended", +) ]; + +#[test] +fn empty_list_find_warns() { + let code = r##" +/proc/test() + var/list/list_foo = list("a", null, "c") + return list_foo.Find() +"## + .trim(); + check_errors_match(code, EMPTY_LIST_FIND_ERRORS); +}