From 61113916740667de8bee5e08e56b9be59db09082 Mon Sep 17 00:00:00 2001 From: Michael <78988079+mhasel@users.noreply.github.com> Date: Fri, 2 Feb 2024 10:36:39 +0100 Subject: [PATCH] fix(validation): fix false-positive unresolved generic symbol validation for formal parameters (#1066) * fix(validation): fix false-positive unresolved generic symbol validation for formal parameters * remove unreferenced snapshots --- src/validation/statement.rs | 4 +++ .../tests/generic_validation_tests.rs | 30 +++++++++++++++++++ ...s__generic_call_with_formal_parameter.snap | 29 ++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 src/validation/tests/snapshots/rusty__validation__tests__generic_validation_tests__generic_call_with_formal_parameter.snap diff --git a/src/validation/statement.rs b/src/validation/statement.rs index 7445fa8ba9..77a34e4576 100644 --- a/src/validation/statement.rs +++ b/src/validation/statement.rs @@ -1189,6 +1189,10 @@ fn validate_type_nature( { if let DataTypeInformation::Generic { generic_symbol, nature, .. } = type_hint.get_type_information() { + // we might be validating an identifier of a formal parameter assignment (FOO(x := 0)) + if let AstStatement::Identifier(_) = statement.get_stmt() { + return; + } validator.push_diagnostic( Diagnostic::error(format!("Could not resolve generic type {generic_symbol} with {nature}")) .with_error_code("E064") diff --git a/src/validation/tests/generic_validation_tests.rs b/src/validation/tests/generic_validation_tests.rs index 4c26cc74e6..1be22f3c99 100644 --- a/src/validation/tests/generic_validation_tests.rs +++ b/src/validation/tests/generic_validation_tests.rs @@ -1599,3 +1599,33 @@ fn any_date_multiple_parameters() { let diagnostics = parse_and_validate_buffered(src); assert_snapshot!(&diagnostics); } + +#[test] +fn generic_call_with_formal_parameter() { + let src = " + FUNCTION FOO < T: ANY_NUM >: T + VAR_INPUT + x: T; + END_VAR + END_FUNCTION + + FUNCTION FOO__DINT: DINT + VAR_INPUT + x: DINT; + END_VAR + FOO__DINT := x + 0; + END_FUNCTION + + FUNCTION main: DINT + VAR + myLocalNumber: DINT := 2; + END_VAR + myLocalNumber := FOO(x := myLocalNumber); // okay + myLocalNumber := FOO(y := 0); // unresolved reference + myLocalNumber := FOO(x := 'INVALID TYPE NATURE'); // invalid type nature + END_FUNCTION +"; + + let diagnostics = parse_and_validate_buffered(src); + insta::assert_snapshot!(diagnostics); +} diff --git a/src/validation/tests/snapshots/rusty__validation__tests__generic_validation_tests__generic_call_with_formal_parameter.snap b/src/validation/tests/snapshots/rusty__validation__tests__generic_validation_tests__generic_call_with_formal_parameter.snap new file mode 100644 index 0000000000..3117cf5b16 --- /dev/null +++ b/src/validation/tests/snapshots/rusty__validation__tests__generic_validation_tests__generic_call_with_formal_parameter.snap @@ -0,0 +1,29 @@ +--- +source: src/validation/tests/generic_validation_tests.rs +expression: diagnostics +--- +error: Invalid call parameters + ┌─ :20:30 + │ +20 │ myLocalNumber := FOO(y := 0); // unresolved reference + │ ^^^^^^ Invalid call parameters + +error: Could not resolve reference to y + ┌─ :20:30 + │ +20 │ myLocalNumber := FOO(y := 0); // unresolved reference + │ ^ Could not resolve reference to y + +error: Invalid type nature for generic argument. __STRING_19 is no ANY_NUMBER + ┌─ :21:35 + │ +21 │ myLocalNumber := FOO(x := 'INVALID TYPE NATURE'); // invalid type nature + │ ^^^^^^^^^^^^^^^^^^^^^ Invalid type nature for generic argument. __STRING_19 is no ANY_NUMBER + +error: Invalid assignment: cannot assign 'STRING' to 'USINT' + ┌─ :21:30 + │ +21 │ myLocalNumber := FOO(x := 'INVALID TYPE NATURE'); // invalid type nature + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid assignment: cannot assign 'STRING' to 'USINT' + +