diff --git a/compiler/plc_ast/src/ast.rs b/compiler/plc_ast/src/ast.rs index fa62eeefc5..83a218d5ec 100644 --- a/compiler/plc_ast/src/ast.rs +++ b/compiler/plc_ast/src/ast.rs @@ -1057,20 +1057,8 @@ pub fn pre_process(unit: &mut CompilationUnit, id_provider: IdProvider) { pre_processor::pre_process(unit, id_provider) } impl Operator { - /// returns true, if this operator results in a bool value - pub fn is_bool_type(&self) -> bool { - matches!( - self, - Operator::Equal - | Operator::NotEqual - | Operator::Less - | Operator::Greater - | Operator::LessOrEqual - | Operator::GreaterOrEqual - ) - } - - /// returns true, if this operator is a comparison operator + /// returns true, if this operator is a comparison operator, + /// resulting in a bool value /// (=, <>, >, <, >=, <=) pub fn is_comparison_operator(&self) -> bool { matches!( diff --git a/compiler/plc_ast/src/literals.rs b/compiler/plc_ast/src/literals.rs index 130da73b61..0ae714d346 100644 --- a/compiler/plc_ast/src/literals.rs +++ b/compiler/plc_ast/src/literals.rs @@ -259,6 +259,18 @@ impl AstLiteral { | AstLiteral::DateAndTime { .. } ) } + + pub fn is_numerical(&self) -> bool { + matches!( + self, + AstLiteral::Integer { .. } + | AstLiteral::Real { .. } + | AstLiteral::Time { .. } + | AstLiteral::Date { .. } + | AstLiteral::TimeOfDay { .. } + | AstLiteral::DateAndTime { .. } + ) + } } impl Debug for AstLiteral { diff --git a/compiler/plc_diagnostics/src/diagnostics/diagnostics_registry.rs b/compiler/plc_diagnostics/src/diagnostics/diagnostics_registry.rs index e70d967784..396f16502e 100644 --- a/compiler/plc_diagnostics/src/diagnostics/diagnostics_registry.rs +++ b/compiler/plc_diagnostics/src/diagnostics/diagnostics_registry.rs @@ -300,7 +300,7 @@ lazy_static! { Error, include_str!("./error_codes/E066.md"), E067, - Info, + Warning, include_str!("./error_codes/E067.md"), //Implicit typecast E068, Error, diff --git a/src/resolver.rs b/src/resolver.rs index 8124b54bf0..13610f19c0 100644 --- a/src/resolver.rs +++ b/src/resolver.rs @@ -1327,7 +1327,7 @@ impl<'i> TypeAnnotator<'i> { ) }; - let target_name = if data.operator.is_bool_type() { + let target_name = if data.operator.is_comparison_operator() { BOOL_TYPE.to_string() } else { bigger_type.get_name().to_string() diff --git a/src/validation.rs b/src/validation.rs index d470db4c89..57a3d7a343 100644 --- a/src/validation.rs +++ b/src/validation.rs @@ -30,7 +30,6 @@ mod variable; #[cfg(test)] mod tests; -#[derive(Clone)] pub struct ValidationContext<'s, T: AnnotationMap> { annotations: &'s T, index: &'s Index, @@ -86,6 +85,17 @@ impl<'s, T: AnnotationMap> ValidationContext<'s, T> { } } +impl<'s, T: AnnotationMap> Clone for ValidationContext<'s, T> { + fn clone(&self) -> Self { + ValidationContext { + annotations: self.annotations, + index: self.index, + qualifier: self.qualifier, + is_call: self.is_call, + } + } +} + /// This trait should be implemented by any validator used by `validation::Validator` pub trait Validators { fn push_diagnostic(&mut self, diagnostic: Diagnostic); diff --git a/src/validation/statement.rs b/src/validation/statement.rs index 8b92e653d3..6292443376 100644 --- a/src/validation/statement.rs +++ b/src/validation/statement.rs @@ -3,8 +3,8 @@ use std::{collections::HashSet, mem::discriminant}; use plc_ast::control_statements::ForLoopStatement; use plc_ast::{ ast::{ - flatten_expression_list, AstNode, AstStatement, DirectAccess, DirectAccessType, JumpStatement, - Operator, ReferenceAccess, + flatten_expression_list, AstNode, AstStatement, BinaryExpression, CallStatement, DirectAccess, + DirectAccessType, JumpStatement, Operator, ReferenceAccess, UnaryExpression, }, control_statements::{AstControlStatement, ConditionalBlock}, literals::{Array, AstLiteral, StringValue}, @@ -833,9 +833,8 @@ fn validate_assignment( location.clone(), )); } - } else if right.is_literal() { - // TODO: See https://github.com/PLC-lang/rusty/issues/857 - // validate_assignment_type_sizes(validator, left_type, right_type, location, context) + } else { + validate_assignment_type_sizes(validator, left_type, right, context) } } } @@ -1343,26 +1342,106 @@ fn validate_type_nature( } } -fn _validate_assignment_type_sizes( +fn validate_assignment_type_sizes( validator: &mut Validator, left: &DataType, - right: &DataType, - location: &SourceLocation, + right: &AstNode, context: &ValidationContext, ) { - if left.get_type_information().get_size(context.index) - < right.get_type_information().get_size(context.index) - { - validator.push_diagnostic( - Diagnostic::new(format!( - "Potential loss of information due to assigning '{}' to variable of type '{}'.", - left.get_name(), - right.get_name() - )) - .with_error_code("E067") - .with_location(location.clone()), - ) + use std::collections::HashMap; + fn get_expression_types_and_locations<'b, T: AnnotationMap>( + expression: &AstNode, + context: &'b ValidationContext, + lhs_is_signed_int: bool, + is_builtin_call: bool, + ) -> HashMap<&'b DataType, Vec> { + let mut map: HashMap<&DataType, Vec> = HashMap::new(); + match expression.get_stmt_peeled() { + AstStatement::BinaryExpression(BinaryExpression { operator, left, right, .. }) + if !operator.is_comparison_operator() => + { + get_expression_types_and_locations(left, context, lhs_is_signed_int, false) + .into_iter() + .for_each(|(k, v)| map.entry(k).or_default().extend(v)); + // the RHS type in a MOD expression has no impact on the resulting value type + if matches!(operator, Operator::Modulo) { + return map + }; + get_expression_types_and_locations(right, context, lhs_is_signed_int, false) + .into_iter() + .for_each(|(k, v)| map.entry(k).or_default().extend(v)); + } + AstStatement::UnaryExpression(UnaryExpression { operator, value }) + if !operator.is_comparison_operator() => + { + get_expression_types_and_locations(value, context, lhs_is_signed_int, false) + .into_iter() + .for_each(|(k, v)| map.entry(k).or_default().extend(v)); + } + // `get_literal_actual_signed_type_name` will always return `LREAL` for FP literals, so they will be handled by the fall-through case according to their annotated type + AstStatement::Literal(lit) if !matches!(lit, &AstLiteral::Real(_)) => { + if !lit.is_numerical() { + return map + } + if let Some(dt) = get_literal_actual_signed_type_name(lit, lhs_is_signed_int) + .map(|name| context.index.get_type(name).unwrap_or(context.index.get_void_type())) + { + map.entry(dt).or_default().push(expression.get_location()); + } + } + AstStatement::CallStatement(CallStatement { operator, parameters }) + // special handling for builtin selector functions MUX and SEL + if matches!(operator.get_flat_reference_name().unwrap_or_default(), "MUX" | "SEL") => + { + let Some(args) = parameters else { + return map + }; + if let AstStatement::ExpressionList(list) = args.get_stmt_peeled() { + // skip the selector argument since it will never be assigned to the target type + list.iter().skip(1).flat_map(|arg| { + get_expression_types_and_locations(arg, context, lhs_is_signed_int, true) + }) + .for_each(|(k, v)| map.entry(k).or_default().extend(v)); + }; + } + _ => { + if !(context.annotations.get_generic_nature(expression).is_none() || is_builtin_call) { + return map + }; + if let Some(dt) = context.annotations.get_type(expression, context.index) { + map.entry(dt).or_default().push(expression.get_location()); + } + } + }; + map } + + let lhs = left.get_type_information(); + let lhs_size = lhs.get_size(context.index); + let results_in_truncation = |rhs: &DataType| { + let rhs = rhs.get_type_information(); + let rhs_size = rhs.get_size(context.index); + lhs_size < rhs_size + || (lhs_size == rhs_size + && ((lhs.is_signed_int() && rhs.is_unsigned_int()) || (lhs.is_int() && rhs.is_float()))) + }; + + get_expression_types_and_locations(right, context, lhs.is_signed_int(), false) + .into_iter() + .filter(|(dt, _)| !dt.is_aggregate_type() && results_in_truncation(dt)) + .for_each(|(dt, location)| { + location.into_iter().for_each(|loc| { + validator.push_diagnostic( + Diagnostic::new(format!( + "Implicit downcast from '{}' to '{}'.", + get_datatype_name_or_slice(validator.context, dt), + get_datatype_name_or_slice(validator.context, left) + )) + .with_error_code("E067") + .with_location(loc), + ); + }) + }); } mod helper { diff --git a/src/validation/tests/assignment_validation_tests.rs b/src/validation/tests/assignment_validation_tests.rs index 4d36838a0c..9903c2c83b 100644 --- a/src/validation/tests/assignment_validation_tests.rs +++ b/src/validation/tests/assignment_validation_tests.rs @@ -963,6 +963,223 @@ fn string_type_alias_assignment_can_be_validated() { assert_snapshot!(diagnostics); } +#[test] +fn integral_promotion_in_expression_does_not_cause_downcast_warning() { + let diagnostics = parse_and_validate_buffered( + " + FUNCTION main : INT + VAR + a, b, c : SINT; + END_VAR + + a := a + b + c + 100; + END_FUNCTION + ", + ); + + assert!(diagnostics.is_empty()) +} + +#[test] +fn downcast_will_report_bigger_types_in_expression() { + let diagnostics = parse_and_validate_buffered( + " + FUNCTION main : INT + VAR + a, b, c : SINT; + d, e : DINT; + END_VAR + a := a + b + c + d + e; + END_FUNCTION + ", + ); + + assert_snapshot!(diagnostics) +} + +#[test] +fn literals_out_of_range_for_lhs_will_result_in_downcast_warning() { + let diagnostics = parse_and_validate_buffered( + " + FUNCTION main : INT + VAR + a : SINT; + b : USINT; + END_VAR + + a := a + 255 + 1000; // literals out of range of i8 -> warning + b := b + 255; // 255 is in range of u8 -> no warning, but will silently overflow for anything other than b == 0. Not sure if there is a better way to guard against this + a := a + b; // B is same size as a, but unsigned -> warning + a := a + USINT#100; // will fit into a, but is cast to unsigned type -> warning + END_FUNCTION + ", + ); + + assert_snapshot!(diagnostics) +} + +#[test] +fn literals_out_of_range_inside_unary_expressions_will_cause_no_warning() { + // GIVEN literals behind unary expressions (which will be annotated as DINT) + // WHEN we validate + let diagnostics = parse_and_validate_buffered( + " + FUNCTION main : INT + VAR + a : INT; + END_VAR + a := a; + a := a + 254; + a := a + 254 - 20; + a := a + 254 + (-(10+10)); //rewrite this as a unary expression + END_FUNCTION + ", + ); + //WE EXPECT NO VALIDATION PROBLEMS + assert!(diagnostics.is_empty()) +} + +#[test] +fn literals_out_of_range_in_a_modulo_operation_cannot_exceed_the_left_operand() { + // GIVEN an expression INT MOD DINT + // WHEN we validate + let diagnostics = parse_and_validate_buffered( + " + FUNCTION main : INT + VAR + a : INT; + END_VAR + a := a + (a MOD 40000); + END_FUNCTION + ", + ); + //THEN we expect no validation problems, since a mod d should remain in a's datatype + assert!(diagnostics.is_empty()) +} + +#[test] +fn modulo_operation_validates_if_the_left_hand_type_fits_into_the_target_type() { + // GIVEN an expression INT MOD DINT + // WHEN we validate + let diagnostics = parse_and_validate_buffered( + " + FUNCTION main : INT + VAR + a : INT; + d : DINT := 9; + END_VAR + a := a + (d MOD a); + END_FUNCTION + ", + ); + //THEN we expect a downcast warning, since d mod a might overflow INT + assert_snapshot!(diagnostics) +} + +#[test] +fn rhs_of_a_mod_operation_is_ignored_in_downcast_validation() { + // GIVEN an expression INT MOD DINT + // WHEN we validate + let diagnostics = parse_and_validate_buffered( + " + FUNCTION main : INT + VAR + a : INT; + d : DINT := 9; + l : LINT; + END_VAR + a := a + (a MOD d); + a := a + (a MOD LINT#10); + a := a + (a MOD l); + END_FUNCTION + ", + ); + //THEN we expect a downcast warning, since d mod a might overflow INT + assert!(diagnostics.is_empty()) +} + +#[test] +fn builtin_sel_does_not_report_false_positive_downcasts_for_literals() { + // GIVEN an expression INT MOD DINT + // WHEN we validate + let diagnostics = parse_and_validate_buffered( + " + FUNCTION main : INT + VAR + a : INT; + b : INT; + END_VAR + a := SEL(TRUE, a, b); + a := SEL(FALSE, a, 1000); + END_FUNCTION + ", + ); + //THEN we expect no validation problems, since all arguments to SEL fit into the target type + assert!(diagnostics.is_empty()) +} + +#[test] +fn builtin_mux_does_not_report_false_positive_downcasts() { + // GIVEN an expression INT MOD DINT + // WHEN we validate + let diagnostics = parse_and_validate_buffered( + " + FUNCTION main : INT + VAR + a : INT; + b : INT; + END_VAR + a := MUX(0, a, b); + a := MUX(2, a, b, 1000); + END_FUNCTION + ", + ); + //THEN we expect no validation problems, since all arguments to MUX fit into the target type + assert!(diagnostics.is_empty()) +} + +#[test] +fn builtins_report_downcasts_depending_on_parameters() { + // GIVEN an expression INT MOD DINT + // WHEN we validate + let diagnostics = parse_and_validate_buffered( + " + FUNCTION main : INT + VAR + a : INT; + b : DINT; + END_VAR + a := SEL(TRUE, a, b); // b: DINT => INT + a := MUX(0, a, b); // b: DINT => INT + a := MUX(b, a, 1000); // selector arg is ignored + END_FUNCTION + ", + ); + //THEN we expect individual parameters to be validated and the selector argument to be ignored + assert_snapshot!(diagnostics) +} + +#[test] +fn call_results_are_validated_for_downcasts() { + // GIVEN a call-result assignment DINT to INT + // WHEN we validate + let diagnostics = parse_and_validate_buffered( + " + FUNCTION foo : DINT + foo := 9; + END_FUNCTION + FUNCTION main : INT + VAR + a : INT; + END_VAR + a := FOO(); + END_FUNCTION + ", + ); + //THEN we expect a downcast validation + assert_snapshot!(diagnostics) +} + #[test] fn void_assignment_validation() { let diagnostics = parse_and_validate_buffered( diff --git a/src/validation/tests/builtin_validation_tests.rs b/src/validation/tests/builtin_validation_tests.rs index d59f82d946..154791af4e 100644 --- a/src/validation/tests/builtin_validation_tests.rs +++ b/src/validation/tests/builtin_validation_tests.rs @@ -19,8 +19,7 @@ fn arithmetic_builtins_allow_mixing_of_fp_and_int_params() { END_FUNCTION ", ); - - assert!(diagnostics.is_empty()); + assert_snapshot!(diagnostics); } #[test] diff --git a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__array_assignment_validation.snap b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__array_assignment_validation.snap index d096315314..7f65f283d0 100644 --- a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__array_assignment_validation.snap +++ b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__array_assignment_validation.snap @@ -56,6 +56,30 @@ error[E043]: Array assignments must be surrounded with `[]` 39 │ v_arr_int_3 := (1, 2, 3, 4, 5, 6); // INVALID -> missing │ ^^^^^^^^^^^^^^^^ Array assignments must be surrounded with `[]` +warning[E067]: Implicit downcast from 'DINT' to 'INT'. + ┌─ :40:23 + │ +40 │ v_arr_int_3[0] := v_dint; // valid + │ ^^^^^^ Implicit downcast from 'DINT' to 'INT'. + +warning[E067]: Implicit downcast from 'DINT' to 'INT'. + ┌─ :41:23 + │ +41 │ v_arr_int_3[0] := DINT#10; // valid + │ ^^^^^^^ Implicit downcast from 'DINT' to 'INT'. + +warning[E067]: Implicit downcast from 'REAL' to 'INT'. + ┌─ :42:23 + │ +42 │ v_arr_int_3[0] := v_real; // valid + │ ^^^^^^ Implicit downcast from 'REAL' to 'INT'. + +warning[E067]: Implicit downcast from 'REAL' to 'INT'. + ┌─ :43:23 + │ +43 │ v_arr_int_3[0] := REAL#2.0; // valid + │ ^^^^^^^^ Implicit downcast from 'REAL' to 'INT'. + error[E037]: Invalid assignment: cannot assign 'STRING' to 'INT' ┌─ :44:5 │ @@ -103,5 +127,3 @@ error[E037]: Invalid assignment: cannot assign 'ARRAY[0..3] OF INT' to 'DINT' │ 52 │ v_dint := v_arr_int_3; // INVALID │ ^^^^^^^^^^^^^^^^^^^^^ Invalid assignment: cannot assign 'ARRAY[0..3] OF INT' to 'DINT' - - diff --git a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__bit_assignment_validation.snap b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__bit_assignment_validation.snap index 19c391902d..b07e175e1a 100644 --- a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__bit_assignment_validation.snap +++ b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__bit_assignment_validation.snap @@ -2,6 +2,66 @@ source: src/validation/tests/assignment_validation_tests.rs expression: diagnostics --- +warning[E067]: Implicit downcast from 'LREAL' to 'BYTE'. + ┌─ :29:15 + │ +29 │ v_byte := v_lreal; // valid + │ ^^^^^^^ Implicit downcast from 'LREAL' to 'BYTE'. + +warning[E067]: Implicit downcast from 'REAL' to 'BYTE'. + ┌─ :30:15 + │ +30 │ v_byte := REAL#2.0; // valid + │ ^^^^^^^^ Implicit downcast from 'REAL' to 'BYTE'. + +warning[E067]: Implicit downcast from 'UDINT' to 'BYTE'. + ┌─ :31:15 + │ +31 │ v_byte := v_udint; // valid + │ ^^^^^^^ Implicit downcast from 'UDINT' to 'BYTE'. + +warning[E067]: Implicit downcast from 'UDINT' to 'BYTE'. + ┌─ :32:15 + │ +32 │ v_byte := UDINT#10; // valid + │ ^^^^^^^^ Implicit downcast from 'UDINT' to 'BYTE'. + +warning[E067]: Implicit downcast from 'DINT' to 'BYTE'. + ┌─ :33:15 + │ +33 │ v_byte := v_dint; // valid + │ ^^^^^^ Implicit downcast from 'DINT' to 'BYTE'. + +warning[E067]: Implicit downcast from 'DINT' to 'BYTE'. + ┌─ :34:15 + │ +34 │ v_byte := DINT#20; // valid + │ ^^^^^^^ Implicit downcast from 'DINT' to 'BYTE'. + +warning[E067]: Implicit downcast from 'TIME' to 'BYTE'. + ┌─ :35:15 + │ +35 │ v_byte := v_time; // valid + │ ^^^^^^ Implicit downcast from 'TIME' to 'BYTE'. + +warning[E067]: Implicit downcast from 'TIME' to 'BYTE'. + ┌─ :36:15 + │ +36 │ v_byte := TIME#10h20m30s; // valid + │ ^^^^^^^^^^^^^^ Implicit downcast from 'TIME' to 'BYTE'. + +warning[E067]: Implicit downcast from 'WORD' to 'BYTE'. + ┌─ :37:15 + │ +37 │ v_byte := v_word; // valid + │ ^^^^^^ Implicit downcast from 'WORD' to 'BYTE'. + +warning[E067]: Implicit downcast from 'WORD' to 'BYTE'. + ┌─ :38:15 + │ +38 │ v_byte := WORD#16#ffff; // valid + │ ^^^^^^^^^^^^ Implicit downcast from 'WORD' to 'BYTE'. + error[E037]: Invalid assignment: cannot assign 'STRING' to 'BYTE' ┌─ :39:5 │ @@ -32,16 +92,38 @@ error[E037]: Invalid assignment: cannot assign 'CHAR' to 'BYTE' 43 │ v_byte := CHAR#'c'; // INVALID │ ^^^^^^^^^^^^^^^^^^ Invalid assignment: cannot assign 'CHAR' to 'BYTE' +warning[E067]: Implicit downcast from 'TIME_OF_DAY' to 'BYTE'. + ┌─ :44:15 + │ +44 │ v_byte := v_tod; // valid + │ ^^^^^ Implicit downcast from 'TIME_OF_DAY' to 'BYTE'. + +warning[E067]: Implicit downcast from 'TIME_OF_DAY' to 'BYTE'. + ┌─ :45:15 + │ +45 │ v_byte := TOD#15:36:30; // valid + │ ^^^^^^^^^^^^ Implicit downcast from 'TIME_OF_DAY' to 'BYTE'. + +warning[E067]: Implicit downcast from 'INT' to 'BYTE'. + ┌─ :46:15 + │ +46 │ v_byte := v_ptr_int^; // valid + │ ^^^^^^^^^^ Implicit downcast from 'INT' to 'BYTE'. + error[E037]: Invalid assignment: cannot assign 'STRING' to 'BYTE' ┌─ :47:5 │ 47 │ v_byte := v_ptr_string^; // INVALID │ ^^^^^^^^^^^^^^^^^^^^^^^ Invalid assignment: cannot assign 'STRING' to 'BYTE' +warning[E067]: Implicit downcast from 'INT' to 'BYTE'. + ┌─ :48:15 + │ +48 │ v_byte := v_arr_int_3[0]; // valid + │ ^^^^^^^^^^^^^^ Implicit downcast from 'INT' to 'BYTE'. + error[E037]: Invalid assignment: cannot assign 'STRING' to 'BYTE' ┌─ :49:5 │ 49 │ v_byte := v_arr_string_3[0]; // INVALID │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid assignment: cannot assign 'STRING' to 'BYTE' - - diff --git a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__builtins_report_downcasts_depending_on_parameters.snap b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__builtins_report_downcasts_depending_on_parameters.snap new file mode 100644 index 0000000000..ba1b9e9af4 --- /dev/null +++ b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__builtins_report_downcasts_depending_on_parameters.snap @@ -0,0 +1,15 @@ +--- +source: src/validation/tests/assignment_validation_tests.rs +expression: diagnostics +--- +warning[E067]: Implicit downcast from 'DINT' to 'INT'. + ┌─ :7:31 + │ +7 │ a := SEL(TRUE, a, b); // b: DINT => INT + │ ^ Implicit downcast from 'DINT' to 'INT'. + +warning[E067]: Implicit downcast from 'DINT' to 'INT'. + ┌─ :8:28 + │ +8 │ a := MUX(0, a, b); // b: DINT => INT + │ ^ Implicit downcast from 'DINT' to 'INT'. diff --git a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__call_results_are_validated_for_downcasts.snap b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__call_results_are_validated_for_downcasts.snap new file mode 100644 index 0000000000..8b0c123eb3 --- /dev/null +++ b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__call_results_are_validated_for_downcasts.snap @@ -0,0 +1,9 @@ +--- +source: src/validation/tests/assignment_validation_tests.rs +expression: diagnostics +--- +warning[E067]: Implicit downcast from 'DINT' to 'INT'. + ┌─ :9:18 + │ +9 │ a := FOO(); + │ ^^^^^^ Implicit downcast from 'DINT' to 'INT'. diff --git a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__date_assignment_validation.snap b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__date_assignment_validation.snap index fd54249f7a..d73081d983 100644 --- a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__date_assignment_validation.snap +++ b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__date_assignment_validation.snap @@ -2,6 +2,12 @@ source: src/validation/tests/assignment_validation_tests.rs expression: "&diagnostics" --- +warning[E067]: Implicit downcast from 'LREAL' to 'DATE'. + ┌─ :29:15 + │ +29 │ v_date := v_lreal; // valid + │ ^^^^^^^ Implicit downcast from 'LREAL' to 'DATE'. + error[E037]: Invalid assignment: cannot assign 'STRING' to 'DATE' ┌─ :39:5 │ @@ -43,5 +49,3 @@ error[E037]: Invalid assignment: cannot assign 'STRING' to 'DATE' │ 49 │ v_date := v_arr_string_3[0]; // INVALID │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid assignment: cannot assign 'STRING' to 'DATE' - - diff --git a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__downcast_will_report_bigger_types_in_expression.snap b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__downcast_will_report_bigger_types_in_expression.snap new file mode 100644 index 0000000000..8577a360f4 --- /dev/null +++ b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__downcast_will_report_bigger_types_in_expression.snap @@ -0,0 +1,15 @@ +--- +source: src/validation/tests/assignment_validation_tests.rs +expression: diagnostics +--- +warning[E067]: Implicit downcast from 'DINT' to 'SINT'. + ┌─ :7:30 + │ +7 │ a := a + b + c + d + e; + │ ^ Implicit downcast from 'DINT' to 'SINT'. + +warning[E067]: Implicit downcast from 'DINT' to 'SINT'. + ┌─ :7:34 + │ +7 │ a := a + b + c + d + e; + │ ^ Implicit downcast from 'DINT' to 'SINT'. diff --git a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__duration_assignment_validation.snap b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__duration_assignment_validation.snap index 47ade9ba95..d24db4067d 100644 --- a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__duration_assignment_validation.snap +++ b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__duration_assignment_validation.snap @@ -2,6 +2,12 @@ source: src/validation/tests/assignment_validation_tests.rs expression: diagnostics --- +warning[E067]: Implicit downcast from 'LREAL' to 'TIME'. + ┌─ :29:15 + │ +29 │ v_time := v_lreal; // valid + │ ^^^^^^^ Implicit downcast from 'LREAL' to 'TIME'. + error[E037]: Invalid assignment: cannot assign 'STRING' to 'TIME' ┌─ :39:5 │ @@ -43,5 +49,3 @@ error[E037]: Invalid assignment: cannot assign 'STRING' to 'TIME' │ 49 │ v_time := v_arr_string_3[0]; // INVALID │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid assignment: cannot assign 'STRING' to 'TIME' - - diff --git a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__enum_variants_mismatch.snap b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__enum_variants_mismatch.snap deleted file mode 100644 index ebd8b7082f..0000000000 --- a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__enum_variants_mismatch.snap +++ /dev/null @@ -1,29 +0,0 @@ ---- -source: src/validation/tests/assignment_validation_tests.rs -expression: diagnostics ---- -error[E040]: Assigned value is not a variant of main.color - ┌─ :11:22 - │ -11 │ color := Dog; // warning - │ ^^^ Assigned value is not a variant of main.color - -error[E040]: Assigned value is not a variant of main.water - ┌─ :12:22 - │ -12 │ water := blue; // warning - │ ^^^^ Assigned value is not a variant of main.water - -error[E040]: Assigned value is not a variant of main.color - ┌─ :13:22 - │ -13 │ color := sparkling; // warning - │ ^^^^^^^^^ Assigned value is not a variant of main.color - -error[E040]: Assigned value is not a variant of main.color - ┌─ :14:22 - │ -14 │ color := 2; // warning - │ ^ Assigned value is not a variant of main.color - - diff --git a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__implicit_action_downcasts_are_validated.snap b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__implicit_action_downcasts_are_validated.snap index e77131d0e7..339554e9bc 100644 --- a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__implicit_action_downcasts_are_validated.snap +++ b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__implicit_action_downcasts_are_validated.snap @@ -2,10 +2,20 @@ source: src/validation/tests/assignment_validation_tests.rs expression: "&diagnostics" --- +warning[E067]: Implicit downcast from 'LINT' to 'DINT'. + ┌─ :26:20 + │ +26 │ fb.foo(var1, var2, var3); + │ ^^^^ Implicit downcast from 'LINT' to 'DINT'. + +warning[E067]: Implicit downcast from 'LWORD' to 'DWORD'. + ┌─ :26:26 + │ +26 │ fb.foo(var1, var2, var3); + │ ^^^^ Implicit downcast from 'LWORD' to 'DWORD'. + error[E037]: Invalid assignment: cannot assign 'STRING' to 'BYTE' ┌─ :26:32 │ 26 │ fb.foo(var1, var2, var3); │ ^^^^ Invalid assignment: cannot assign 'STRING' to 'BYTE' - - diff --git a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__int_assignment_validation.snap b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__int_assignment_validation.snap index 1459585992..c37018fd02 100644 --- a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__int_assignment_validation.snap +++ b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__int_assignment_validation.snap @@ -2,6 +2,42 @@ source: src/validation/tests/assignment_validation_tests.rs expression: diagnostics --- +warning[E067]: Implicit downcast from 'LREAL' to 'UDINT'. + ┌─ :31:16 + │ +31 │ v_udint := v_lreal; // valid + │ ^^^^^^^ Implicit downcast from 'LREAL' to 'UDINT'. + +warning[E067]: Implicit downcast from 'REAL' to 'UDINT'. + ┌─ :32:16 + │ +32 │ v_udint := REAL#2.0; // valid + │ ^^^^^^^^ Implicit downcast from 'REAL' to 'UDINT'. + +warning[E067]: Implicit downcast from 'ULINT' to 'UDINT'. + ┌─ :33:16 + │ +33 │ v_udint := v_ulint; // valid + │ ^^^^^^^ Implicit downcast from 'ULINT' to 'UDINT'. + +warning[E067]: Implicit downcast from 'ULINT' to 'UDINT'. + ┌─ :34:16 + │ +34 │ v_udint := ULINT#10; // valid + │ ^^^^^^^^ Implicit downcast from 'ULINT' to 'UDINT'. + +warning[E067]: Implicit downcast from 'TIME' to 'UDINT'. + ┌─ :37:16 + │ +37 │ v_udint := v_time; // valid + │ ^^^^^^ Implicit downcast from 'TIME' to 'UDINT'. + +warning[E067]: Implicit downcast from 'TIME' to 'UDINT'. + ┌─ :38:16 + │ +38 │ v_udint := TIME#10h20m30s; // valid + │ ^^^^^^^^^^^^^^ Implicit downcast from 'TIME' to 'UDINT'. + error[E037]: Invalid assignment: cannot assign 'STRING' to 'UDINT' ┌─ :41:5 │ @@ -32,6 +68,18 @@ error[E037]: Invalid assignment: cannot assign 'CHAR' to 'UDINT' 45 │ v_udint := CHAR#'c'; // INVALID │ ^^^^^^^^^^^^^^^^^^^ Invalid assignment: cannot assign 'CHAR' to 'UDINT' +warning[E067]: Implicit downcast from 'TIME_OF_DAY' to 'UDINT'. + ┌─ :46:16 + │ +46 │ v_udint := v_tod; // valid + │ ^^^^^ Implicit downcast from 'TIME_OF_DAY' to 'UDINT'. + +warning[E067]: Implicit downcast from 'TIME_OF_DAY' to 'UDINT'. + ┌─ :47:16 + │ +47 │ v_udint := TOD#15:36:30; // valid + │ ^^^^^^^^^^^^ Implicit downcast from 'TIME_OF_DAY' to 'UDINT'. + error[E037]: Invalid assignment: cannot assign 'STRING' to 'UDINT' ┌─ :49:5 │ @@ -44,6 +92,54 @@ error[E037]: Invalid assignment: cannot assign 'STRING' to 'UDINT' 51 │ v_udint := v_arr_string_3[0]; // INVALID │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid assignment: cannot assign 'STRING' to 'UDINT' +warning[E067]: Implicit downcast from 'LREAL' to 'DINT'. + ┌─ :54:15 + │ +54 │ v_dint := v_lreal; // valid + │ ^^^^^^^ Implicit downcast from 'LREAL' to 'DINT'. + +warning[E067]: Implicit downcast from 'REAL' to 'DINT'. + ┌─ :55:15 + │ +55 │ v_dint := REAL#2.0; // valid + │ ^^^^^^^^ Implicit downcast from 'REAL' to 'DINT'. + +warning[E067]: Implicit downcast from 'UDINT' to 'DINT'. + ┌─ :56:15 + │ +56 │ v_dint := v_udint; // valid + │ ^^^^^^^ Implicit downcast from 'UDINT' to 'DINT'. + +warning[E067]: Implicit downcast from 'UDINT' to 'DINT'. + ┌─ :57:15 + │ +57 │ v_dint := UDINT#10; // valid + │ ^^^^^^^^ Implicit downcast from 'UDINT' to 'DINT'. + +warning[E067]: Implicit downcast from 'LINT' to 'DINT'. + ┌─ :58:15 + │ +58 │ v_dint := v_lint; // valid + │ ^^^^^^ Implicit downcast from 'LINT' to 'DINT'. + +warning[E067]: Implicit downcast from 'LINT' to 'DINT'. + ┌─ :59:15 + │ +59 │ v_dint := LINT#20; // valid + │ ^^^^^^^ Implicit downcast from 'LINT' to 'DINT'. + +warning[E067]: Implicit downcast from 'TIME' to 'DINT'. + ┌─ :60:15 + │ +60 │ v_dint := v_time; // valid + │ ^^^^^^ Implicit downcast from 'TIME' to 'DINT'. + +warning[E067]: Implicit downcast from 'TIME' to 'DINT'. + ┌─ :61:15 + │ +61 │ v_dint := TIME#10h20m30s; // valid + │ ^^^^^^^^^^^^^^ Implicit downcast from 'TIME' to 'DINT'. + error[E037]: Invalid assignment: cannot assign 'STRING' to 'DINT' ┌─ :64:5 │ @@ -74,6 +170,18 @@ error[E037]: Invalid assignment: cannot assign 'CHAR' to 'DINT' 68 │ v_dint := CHAR#'c'; // INVALID │ ^^^^^^^^^^^^^^^^^^ Invalid assignment: cannot assign 'CHAR' to 'DINT' +warning[E067]: Implicit downcast from 'TIME_OF_DAY' to 'DINT'. + ┌─ :69:15 + │ +69 │ v_dint := v_tod; // valid + │ ^^^^^ Implicit downcast from 'TIME_OF_DAY' to 'DINT'. + +warning[E067]: Implicit downcast from 'TIME_OF_DAY' to 'DINT'. + ┌─ :70:15 + │ +70 │ v_dint := TOD#15:36:30; // valid + │ ^^^^^^^^^^^^ Implicit downcast from 'TIME_OF_DAY' to 'DINT'. + error[E037]: Invalid assignment: cannot assign 'STRING' to 'DINT' ┌─ :72:5 │ @@ -85,5 +193,3 @@ error[E037]: Invalid assignment: cannot assign 'STRING' to 'DINT' │ 74 │ v_dint := v_arr_string_3[0]; // INVALID │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid assignment: cannot assign 'STRING' to 'DINT' - - diff --git a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__literals_out_of_range_for_lhs_will_result_in_downcast_warning.snap b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__literals_out_of_range_for_lhs_will_result_in_downcast_warning.snap new file mode 100644 index 0000000000..88a9a1fd9b --- /dev/null +++ b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__literals_out_of_range_for_lhs_will_result_in_downcast_warning.snap @@ -0,0 +1,27 @@ +--- +source: src/validation/tests/assignment_validation_tests.rs +expression: diagnostics +--- +warning[E067]: Implicit downcast from 'INT' to 'SINT'. + ┌─ :8:22 + │ +8 │ a := a + 255 + 1000; // literals out of range of i8 -> warning + │ ^^^ Implicit downcast from 'INT' to 'SINT'. + +warning[E067]: Implicit downcast from 'INT' to 'SINT'. + ┌─ :8:28 + │ +8 │ a := a + 255 + 1000; // literals out of range of i8 -> warning + │ ^^^^ Implicit downcast from 'INT' to 'SINT'. + +warning[E067]: Implicit downcast from 'USINT' to 'SINT'. + ┌─ :10:22 + │ +10 │ a := a + b; // B is same size as a, but unsigned -> warning + │ ^ Implicit downcast from 'USINT' to 'SINT'. + +warning[E067]: Implicit downcast from 'USINT' to 'SINT'. + ┌─ :11:22 + │ +11 │ a := a + USINT#100; // will fit into a, but is cast to unsigned type -> warning + │ ^^^^^^^^^ Implicit downcast from 'USINT' to 'SINT'. diff --git a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__modulo_operation_validates_if_the_left_hand_type_fits_into_the_target_type.snap b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__modulo_operation_validates_if_the_left_hand_type_fits_into_the_target_type.snap new file mode 100644 index 0000000000..20d4c089bb --- /dev/null +++ b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__modulo_operation_validates_if_the_left_hand_type_fits_into_the_target_type.snap @@ -0,0 +1,9 @@ +--- +source: src/validation/tests/assignment_validation_tests.rs +expression: diagnostics +--- +warning[E067]: Implicit downcast from 'DINT' to 'INT'. + ┌─ :7:23 + │ +7 │ a := a + (d MOD a); + │ ^ Implicit downcast from 'DINT' to 'INT'. diff --git a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__pointer_assignment_validation.snap b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__pointer_assignment_validation.snap index bdf0f60aab..ba7d90088a 100644 --- a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__pointer_assignment_validation.snap +++ b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__pointer_assignment_validation.snap @@ -32,6 +32,36 @@ warning[E090]: Pointers REF_TO INT and __POINTER_TO_REAL have different types 31 │ v_ptr_int := &v_real; // INVALID -> TODO: should be valid │ ^^^^^^^^^^^^^^^^^^^^ Pointers REF_TO INT and __POINTER_TO_REAL have different types +warning[E067]: Implicit downcast from 'REAL' to 'INT'. + ┌─ :32:19 + │ +32 │ v_ptr_int^ := v_real; // valid + │ ^^^^^^ Implicit downcast from 'REAL' to 'INT'. + +warning[E067]: Implicit downcast from 'UDINT' to 'INT'. + ┌─ :34:19 + │ +34 │ v_ptr_int^ := v_udint; // valid + │ ^^^^^^^ Implicit downcast from 'UDINT' to 'INT'. + +warning[E067]: Implicit downcast from 'DINT' to 'INT'. + ┌─ :36:19 + │ +36 │ v_ptr_int^ := v_dint; // valid + │ ^^^^^^ Implicit downcast from 'DINT' to 'INT'. + +warning[E067]: Implicit downcast from 'TIME' to 'INT'. + ┌─ :38:19 + │ +38 │ v_ptr_int^ := v_time; // valid + │ ^^^^^^ Implicit downcast from 'TIME' to 'INT'. + +warning[E067]: Implicit downcast from 'WORD' to 'INT'. + ┌─ :40:19 + │ +40 │ v_ptr_int^ := v_word; // valid + │ ^^^^^^ Implicit downcast from 'WORD' to 'INT'. + warning[E090]: Pointers REF_TO INT and __POINTER_TO_STRING have different types ┌─ :41:5 │ @@ -50,10 +80,14 @@ error[E037]: Invalid assignment: cannot assign 'CHAR' to 'INT' 44 │ v_ptr_int^ := v_char; // INVALID │ ^^^^^^^^^^^^^^^^^^^^ Invalid assignment: cannot assign 'CHAR' to 'INT' +warning[E067]: Implicit downcast from 'DATE' to 'INT'. + ┌─ :46:19 + │ +46 │ v_ptr_int^ := v_date; // valid + │ ^^^^^^ Implicit downcast from 'DATE' to 'INT'. + error[E037]: Invalid assignment: cannot assign 'STRING' to 'INT' ┌─ :48:5 │ 48 │ v_ptr_int^ := v_arr_string_3[0]; // INVALID │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid assignment: cannot assign 'STRING' to 'INT' - - diff --git a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__real_assignment_validation.snap b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__real_assignment_validation.snap index 0d761baa6d..f890b8eaf5 100644 --- a/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__real_assignment_validation.snap +++ b/src/validation/tests/snapshots/rusty__validation__tests__assignment_validation_tests__real_assignment_validation.snap @@ -2,6 +2,24 @@ source: src/validation/tests/assignment_validation_tests.rs expression: diagnostics --- +warning[E067]: Implicit downcast from 'LREAL' to 'REAL'. + ┌─ :29:15 + │ +29 │ v_real := v_lreal; // valid + │ ^^^^^^^ Implicit downcast from 'LREAL' to 'REAL'. + +warning[E067]: Implicit downcast from 'TIME' to 'REAL'. + ┌─ :35:15 + │ +35 │ v_real := v_time; // valid + │ ^^^^^^ Implicit downcast from 'TIME' to 'REAL'. + +warning[E067]: Implicit downcast from 'TIME' to 'REAL'. + ┌─ :36:15 + │ +36 │ v_real := TIME#10h20m30s; // valid + │ ^^^^^^^^^^^^^^ Implicit downcast from 'TIME' to 'REAL'. + error[E037]: Invalid assignment: cannot assign 'STRING' to 'REAL' ┌─ :39:5 │ @@ -32,6 +50,18 @@ error[E037]: Invalid assignment: cannot assign 'CHAR' to 'REAL' 43 │ v_real := CHAR#'c'; // INVALID │ ^^^^^^^^^^^^^^^^^^ Invalid assignment: cannot assign 'CHAR' to 'REAL' +warning[E067]: Implicit downcast from 'TIME_OF_DAY' to 'REAL'. + ┌─ :44:15 + │ +44 │ v_real := v_tod; // valid + │ ^^^^^ Implicit downcast from 'TIME_OF_DAY' to 'REAL'. + +warning[E067]: Implicit downcast from 'TIME_OF_DAY' to 'REAL'. + ┌─ :45:15 + │ +45 │ v_real := TOD#15:36:30; // valid + │ ^^^^^^^^^^^^ Implicit downcast from 'TIME_OF_DAY' to 'REAL'. + error[E037]: Invalid assignment: cannot assign 'STRING' to 'REAL' ┌─ :47:5 │ @@ -43,5 +73,3 @@ error[E037]: Invalid assignment: cannot assign 'STRING' to 'REAL' │ 49 │ v_real := v_arr_string_3[0]; // INVALID │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid assignment: cannot assign 'STRING' to 'REAL' - - diff --git a/src/validation/tests/snapshots/rusty__validation__tests__builtin_validation_tests__arithmetic_builtins_allow_mixing_of_fp_and_int_params.snap b/src/validation/tests/snapshots/rusty__validation__tests__builtin_validation_tests__arithmetic_builtins_allow_mixing_of_fp_and_int_params.snap new file mode 100644 index 0000000000..20cdea0801 --- /dev/null +++ b/src/validation/tests/snapshots/rusty__validation__tests__builtin_validation_tests__arithmetic_builtins_allow_mixing_of_fp_and_int_params.snap @@ -0,0 +1,15 @@ +--- +source: src/validation/tests/builtin_validation_tests.rs +expression: diagnostics +--- +warning[E067]: Implicit downcast from 'LREAL' to 'DINT'. + ┌─ :9:22 + │ +9 │ res_i := ADD(i1, i2, f1, f2); + │ ^^^^^^^^^^^^^^^^^^^ Implicit downcast from 'LREAL' to 'DINT'. + +warning[E067]: Implicit downcast from 'LREAL' to 'DINT'. + ┌─ :11:22 + │ +11 │ res_i := SUB(i1, f2); + │ ^^^^^^^^^^^ Implicit downcast from 'LREAL' to 'DINT'. diff --git a/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__action_implicit_downcast.snap b/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__action_implicit_downcast.snap index 766289fba1..511b7e1951 100644 --- a/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__action_implicit_downcast.snap +++ b/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__action_implicit_downcast.snap @@ -2,16 +2,26 @@ source: src/validation/tests/statement_validation_tests.rs expression: "&diagnostics" --- +warning[E067]: Implicit downcast from 'LINT' to 'DINT'. + ┌─ :9:20 + │ +9 │ fb.foo(var_lint, var_wstr); // downcast, invalid + │ ^^^^^^^^ Implicit downcast from 'LINT' to 'DINT'. + error[E037]: Invalid assignment: cannot assign 'WSTRING' to 'STRING' ┌─ :9:30 │ 9 │ fb.foo(var_lint, var_wstr); // downcast, invalid │ ^^^^^^^^ Invalid assignment: cannot assign 'WSTRING' to 'STRING' +warning[E067]: Implicit downcast from 'LINT' to 'INT'. + ┌─ :10:22 + │ +10 │ prog.bar(var_lint, var_arr); // downcast, invalid + │ ^^^^^^^^ Implicit downcast from 'LINT' to 'INT'. + error[E037]: Invalid assignment: cannot assign 'ARRAY[1..3] OF LINT' to 'STRING' ┌─ :10:32 │ 10 │ prog.bar(var_lint, var_arr); // downcast, invalid │ ^^^^^^^ Invalid assignment: cannot assign 'ARRAY[1..3] OF LINT' to 'STRING' - - diff --git a/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__bit_access_with_incorrect_operator_causes_warning.snap b/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__bit_access_with_incorrect_operator_causes_warning.snap index f16cb4ac90..bcfc58f16c 100644 --- a/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__bit_access_with_incorrect_operator_causes_warning.snap +++ b/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__bit_access_with_incorrect_operator_causes_warning.snap @@ -2,6 +2,12 @@ source: src/validation/tests/statement_validation_tests.rs expression: diagnostics --- +warning[E067]: Implicit downcast from 'DWORD' to 'BOOL'. + ┌─ :11:43 + │ +11 │ Output.var1.%Wn1.%Bn1.%Xn1 := Input.var1; // OK + │ ^^^^^^^^^^ Implicit downcast from 'DWORD' to 'BOOL'. + error[E048]: Could not resolve reference to n1 ┌─ :12:25 │ @@ -13,5 +19,3 @@ note[E060]: If you meant to directly access a bit/byte/word/..., use %X/%B/%Wn1 │ 12 │ Output.var1.n1 := Input.var1; // bitaccess without %X -> Warning │ ^^ If you meant to directly access a bit/byte/word/..., use %X/%B/%Wn1 instead. - - diff --git a/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__function_block_implicit_downcast.snap b/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__function_block_implicit_downcast.snap index cc7dc3d07d..54fb892dd7 100644 --- a/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__function_block_implicit_downcast.snap +++ b/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__function_block_implicit_downcast.snap @@ -2,10 +2,38 @@ source: src/validation/tests/statement_validation_tests.rs expression: "&diagnostics" --- +warning[E067]: Implicit downcast from 'LINT' to 'INT'. + ┌─ :11:17 + │ +11 │ var1_lint, // downcast + │ ^^^^^^^^^ Implicit downcast from 'LINT' to 'INT'. + +warning[E067]: Implicit downcast from 'LWORD' to 'DWORD'. + ┌─ :12:17 + │ +12 │ var_lword, // downcast + │ ^^^^^^^^^ Implicit downcast from 'LWORD' to 'DWORD'. + +warning[E067]: Implicit downcast from 'INT' to 'SINT'. + ┌─ :14:17 + │ +14 │ INT#var1_lint, // downcast + │ ^^^^^^^^^^^^^ Implicit downcast from 'INT' to 'SINT'. + +warning[E067]: Implicit downcast from 'LINT' to 'INT'. + ┌─ :15:17 + │ +15 │ var2_lint, // downcast + │ ^^^^^^^^^ Implicit downcast from 'LINT' to 'INT'. + error[E037]: Invalid assignment: cannot assign 'WSTRING' to 'STRING' ┌─ :16:17 │ 16 │ var_wstr, // invalid │ ^^^^^^^^ Invalid assignment: cannot assign 'WSTRING' to 'STRING' - +warning[E067]: Implicit downcast from 'LINT' to 'DINT'. + ┌─ :17:17 + │ +17 │ var1_lint // downcast + │ ^^^^^^^^^ Implicit downcast from 'LINT' to 'DINT'. diff --git a/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__function_call_parameter_validation.snap b/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__function_call_parameter_validation.snap index e0ac09e1e5..47700cf136 100644 --- a/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__function_call_parameter_validation.snap +++ b/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__function_call_parameter_validation.snap @@ -32,6 +32,12 @@ error[E037]: Invalid assignment: cannot assign 'REF_TO WSTRING' to 'DINT' 25 │ foo(input1 := var2, inout1 := var3, output1 => var4); // invalid types assigned │ ^^^^^^^^^^^^^^ Invalid assignment: cannot assign 'REF_TO WSTRING' to 'DINT' +warning[E067]: Implicit downcast from 'REAL' to 'DINT'. + ┌─ :25:60 + │ +25 │ foo(input1 := var2, inout1 := var3, output1 => var4); // invalid types assigned + │ ^^^^ Implicit downcast from 'REAL' to 'DINT'. + error[E037]: Invalid assignment: cannot assign 'STRING' to 'DINT' ┌─ :27:17 │ @@ -50,4 +56,8 @@ error[E037]: Invalid assignment: cannot assign 'REF_TO WSTRING' to 'DINT' 27 │ foo(var2, var3, var4); // invalid types assigned │ ^^^^ Invalid assignment: cannot assign 'REF_TO WSTRING' to 'DINT' - +warning[E067]: Implicit downcast from 'REAL' to 'DINT'. + ┌─ :27:29 + │ +27 │ foo(var2, var3, var4); // invalid types assigned + │ ^^^^ Implicit downcast from 'REAL' to 'DINT'. diff --git a/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__implicit_param_downcast_in_function_call.snap b/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__implicit_param_downcast_in_function_call.snap index 57795d7afc..e9dfd83fda 100644 --- a/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__implicit_param_downcast_in_function_call.snap +++ b/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__implicit_param_downcast_in_function_call.snap @@ -2,10 +2,44 @@ source: src/validation/tests/statement_validation_tests.rs expression: "&diagnostics" --- +warning[E067]: Implicit downcast from 'LINT' to 'INT'. + ┌─ :12:17 + │ +12 │ var1_lint, // downcast + │ ^^^^^^^^^ Implicit downcast from 'LINT' to 'INT'. + +warning[E067]: Implicit downcast from 'LWORD' to 'DWORD'. + ┌─ :13:17 + │ +13 │ var_lword, // downcast + │ ^^^^^^^^^ Implicit downcast from 'LWORD' to 'DWORD'. + +warning[E067]: Implicit downcast from 'LREAL' to 'REAL'. + ┌─ :14:17 + │ +14 │ var_lreal, // downcast + │ ^^^^^^^^^ Implicit downcast from 'LREAL' to 'REAL'. + +warning[E067]: Implicit downcast from 'INT' to 'SINT'. + ┌─ :15:17 + │ +15 │ INT#var1_lint, // downcast + │ ^^^^^^^^^^^^^ Implicit downcast from 'INT' to 'SINT'. + +warning[E067]: Implicit downcast from 'LINT' to 'INT'. + ┌─ :16:17 + │ +16 │ var2_lint, // downcast + │ ^^^^^^^^^ Implicit downcast from 'LINT' to 'INT'. + error[E037]: Invalid assignment: cannot assign 'WSTRING' to 'STRING' ┌─ :17:17 │ 17 │ var_in_out_wstr, // invalid │ ^^^^^^^^^^^^^^^ Invalid assignment: cannot assign 'WSTRING' to 'STRING' - +warning[E067]: Implicit downcast from 'LINT' to 'DINT'. + ┌─ :18:17 + │ +18 │ var1_lint // downcast + │ ^^^^^^^^^ Implicit downcast from 'LINT' to 'DINT'. diff --git a/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__method_implicit_downcast.snap b/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__method_implicit_downcast.snap index c49875e165..e9fb62df16 100644 --- a/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__method_implicit_downcast.snap +++ b/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__method_implicit_downcast.snap @@ -2,10 +2,14 @@ source: src/validation/tests/statement_validation_tests.rs expression: "&diagnostics" --- +warning[E067]: Implicit downcast from 'LINT' to 'INT'. + ┌─ :8:23 + │ +8 │ cl.testMethod(var_lint, var_arr, ADR(var_arr)); // downcast, invalid, ok + │ ^^^^^^^^ Implicit downcast from 'LINT' to 'INT'. + error[E037]: Invalid assignment: cannot assign 'ARRAY[1..3] OF DINT' to 'ARRAY[1..3] OF SINT' ┌─ :8:33 │ 8 │ cl.testMethod(var_lint, var_arr, ADR(var_arr)); // downcast, invalid, ok │ ^^^^^^^ Invalid assignment: cannot assign 'ARRAY[1..3] OF DINT' to 'ARRAY[1..3] OF SINT' - - diff --git a/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__passing_compatible_numeric_types_to_functions_is_allowed.snap b/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__passing_compatible_numeric_types_to_functions_is_allowed.snap new file mode 100644 index 0000000000..6794ceb25a --- /dev/null +++ b/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__passing_compatible_numeric_types_to_functions_is_allowed.snap @@ -0,0 +1,9 @@ +--- +source: src/validation/tests/statement_validation_tests.rs +expression: diagnostics +--- +warning[E067]: Implicit downcast from 'LREAL' to 'LINT'. + ┌─ :8:13 + │ +8 │ bar(lreal_); + │ ^^^^^^ Implicit downcast from 'LREAL' to 'LINT'. diff --git a/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__program_call_parameter_validation.snap b/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__program_call_parameter_validation.snap index ccd2988c30..b6a9bb04c0 100644 --- a/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__program_call_parameter_validation.snap +++ b/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__program_call_parameter_validation.snap @@ -32,6 +32,12 @@ error[E037]: Invalid assignment: cannot assign 'REF_TO WSTRING' to 'DINT' 25 │ prog(input1 := var2, inout1 := var3, output1 => var4); // invalid types assigned │ ^^^^^^^^^^^^^^ Invalid assignment: cannot assign 'REF_TO WSTRING' to 'DINT' +warning[E067]: Implicit downcast from 'REAL' to 'DINT'. + ┌─ :25:61 + │ +25 │ prog(input1 := var2, inout1 := var3, output1 => var4); // invalid types assigned + │ ^^^^ Implicit downcast from 'REAL' to 'DINT'. + error[E037]: Invalid assignment: cannot assign 'STRING' to 'DINT' ┌─ :27:18 │ @@ -50,4 +56,8 @@ error[E037]: Invalid assignment: cannot assign 'REF_TO WSTRING' to 'DINT' 27 │ prog(var2, var3, var4); // invalid types assigned │ ^^^^ Invalid assignment: cannot assign 'REF_TO WSTRING' to 'DINT' - +warning[E067]: Implicit downcast from 'REAL' to 'DINT'. + ┌─ :27:30 + │ +27 │ prog(var2, var3, var4); // invalid types assigned + │ ^^^^ Implicit downcast from 'REAL' to 'DINT'. diff --git a/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__program_implicit_downcast.snap b/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__program_implicit_downcast.snap index cc7dc3d07d..54fb892dd7 100644 --- a/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__program_implicit_downcast.snap +++ b/src/validation/tests/snapshots/rusty__validation__tests__statement_validation_tests__program_implicit_downcast.snap @@ -2,10 +2,38 @@ source: src/validation/tests/statement_validation_tests.rs expression: "&diagnostics" --- +warning[E067]: Implicit downcast from 'LINT' to 'INT'. + ┌─ :11:17 + │ +11 │ var1_lint, // downcast + │ ^^^^^^^^^ Implicit downcast from 'LINT' to 'INT'. + +warning[E067]: Implicit downcast from 'LWORD' to 'DWORD'. + ┌─ :12:17 + │ +12 │ var_lword, // downcast + │ ^^^^^^^^^ Implicit downcast from 'LWORD' to 'DWORD'. + +warning[E067]: Implicit downcast from 'INT' to 'SINT'. + ┌─ :14:17 + │ +14 │ INT#var1_lint, // downcast + │ ^^^^^^^^^^^^^ Implicit downcast from 'INT' to 'SINT'. + +warning[E067]: Implicit downcast from 'LINT' to 'INT'. + ┌─ :15:17 + │ +15 │ var2_lint, // downcast + │ ^^^^^^^^^ Implicit downcast from 'LINT' to 'INT'. + error[E037]: Invalid assignment: cannot assign 'WSTRING' to 'STRING' ┌─ :16:17 │ 16 │ var_wstr, // invalid │ ^^^^^^^^ Invalid assignment: cannot assign 'WSTRING' to 'STRING' - +warning[E067]: Implicit downcast from 'LINT' to 'DINT'. + ┌─ :17:17 + │ +17 │ var1_lint // downcast + │ ^^^^^^^^^ Implicit downcast from 'LINT' to 'DINT'. diff --git a/src/validation/tests/statement_validation_tests.rs b/src/validation/tests/statement_validation_tests.rs index 30418a7679..db4302bd8c 100644 --- a/src/validation/tests/statement_validation_tests.rs +++ b/src/validation/tests/statement_validation_tests.rs @@ -1321,7 +1321,7 @@ fn passing_compatible_numeric_types_to_functions_is_allowed() { "#, ); - assert!(diagnostics.is_empty()); + assert_snapshot!(diagnostics); } #[test] diff --git a/tests/integration/data/json/simple_program.st b/tests/integration/data/json/simple_program.st index 4d45f7e3f6..3bd848ecf2 100644 --- a/tests/integration/data/json/simple_program.st +++ b/tests/integration/data/json/simple_program.st @@ -4,5 +4,5 @@ PROGRAM prg b : REAL; END_VAR b := 1.5; - a := b; + a := INT#b; END_PROGRAM