diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index f67f4913c34..1c768006eed 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -2846,6 +2846,11 @@ void GDScriptAnalyzer::reduce_binary_op(GDScriptParser::BinaryOpNode *p_binary_o result.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT; result.kind = GDScriptParser::DataType::BUILTIN; result.builtin_type = Variant::BOOL; + } else if (p_binary_op->variant_op == Variant::OP_MODULE && left_type.builtin_type == Variant::STRING) { + // The modulo operator (%) on string acts as formatting and will always return a string. + result.type_source = left_type.type_source; + result.kind = GDScriptParser::DataType::BUILTIN; + result.builtin_type = Variant::STRING; } else if (left_type.is_variant() || right_type.is_variant()) { // Cannot infer type because one operand can be anything. result.kind = GDScriptParser::DataType::VARIANT; diff --git a/modules/gdscript/tests/scripts/analyzer/features/infer_type_on_string_format.gd b/modules/gdscript/tests/scripts/analyzer/features/infer_type_on_string_format.gd new file mode 100644 index 00000000000..c83a3a8a14e --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/infer_type_on_string_format.gd @@ -0,0 +1,6 @@ +# GH-88082 + +func test(): + var x = 1 + var message := "value: %s" % x + print(message) diff --git a/modules/gdscript/tests/scripts/analyzer/features/infer_type_on_string_format.out b/modules/gdscript/tests/scripts/analyzer/features/infer_type_on_string_format.out new file mode 100644 index 00000000000..cf6464a4c34 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/infer_type_on_string_format.out @@ -0,0 +1,2 @@ +GDTEST_OK +value: 1