From 685db28e2920150737bc53d5c86dcc64cc42bb60 Mon Sep 17 00:00:00 2001 From: Danil Alexeev Date: Fri, 3 Feb 2023 20:51:00 +0300 Subject: [PATCH] GDScript: Fix `await` type inference --- modules/gdscript/gdscript_analyzer.cpp | 23 ++++++++----------- .../analyzer/errors/await_signal_no_infer.gd | 4 ++++ .../analyzer/errors/await_signal_no_infer.out | 2 ++ .../analyzer/features/await_type_inference.gd | 15 ++++++++++++ .../features/await_type_inference.out | 2 ++ 5 files changed, 33 insertions(+), 13 deletions(-) create mode 100644 modules/gdscript/tests/scripts/analyzer/errors/await_signal_no_infer.gd create mode 100644 modules/gdscript/tests/scripts/analyzer/errors/await_signal_no_infer.out create mode 100644 modules/gdscript/tests/scripts/analyzer/features/await_type_inference.gd create mode 100644 modules/gdscript/tests/scripts/analyzer/features/await_type_inference.out diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index cafc7328e02..cd1dcf9a78b 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -2471,30 +2471,27 @@ void GDScriptAnalyzer::reduce_await(GDScriptParser::AwaitNode *p_await) { return; } - GDScriptParser::DataType awaiting_type; - if (p_await->to_await->type == GDScriptParser::Node::CALL) { reduce_call(static_cast(p_await->to_await), true); - awaiting_type = p_await->to_await->get_datatype(); } else { reduce_expression(p_await->to_await); } - if (p_await->to_await->is_constant) { + GDScriptParser::DataType await_type = p_await->to_await->get_datatype(); + // We cannot infer the type of the result of waiting for a signal. + if (await_type.is_hard_type() && await_type.kind == GDScriptParser::DataType::BUILTIN && await_type.builtin_type == Variant::SIGNAL) { + await_type.kind = GDScriptParser::DataType::VARIANT; + await_type.type_source = GDScriptParser::DataType::UNDETECTED; + } else if (p_await->to_await->is_constant) { p_await->is_constant = p_await->to_await->is_constant; p_await->reduced_value = p_await->to_await->reduced_value; - - awaiting_type = p_await->to_await->get_datatype(); - } else { - awaiting_type.kind = GDScriptParser::DataType::VARIANT; - awaiting_type.type_source = GDScriptParser::DataType::UNDETECTED; } - - p_await->set_datatype(awaiting_type); + await_type.is_coroutine = false; + p_await->set_datatype(await_type); #ifdef DEBUG_ENABLED - awaiting_type = p_await->to_await->get_datatype(); - if (!(awaiting_type.has_no_type() || awaiting_type.is_coroutine || awaiting_type.builtin_type == Variant::SIGNAL)) { + GDScriptParser::DataType to_await_type = p_await->to_await->get_datatype(); + if (!(to_await_type.has_no_type() || to_await_type.is_coroutine || to_await_type.builtin_type == Variant::SIGNAL)) { parser->push_warning(p_await, GDScriptWarning::REDUNDANT_AWAIT); } #endif diff --git a/modules/gdscript/tests/scripts/analyzer/errors/await_signal_no_infer.gd b/modules/gdscript/tests/scripts/analyzer/errors/await_signal_no_infer.gd new file mode 100644 index 00000000000..c787d9e50e8 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/await_signal_no_infer.gd @@ -0,0 +1,4 @@ +signal my_signal() + +func test(): + var _a := await my_signal diff --git a/modules/gdscript/tests/scripts/analyzer/errors/await_signal_no_infer.out b/modules/gdscript/tests/scripts/analyzer/errors/await_signal_no_infer.out new file mode 100644 index 00000000000..8f8744ad7e8 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/await_signal_no_infer.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Cannot infer the type of "_a" variable because the value doesn't have a set type. diff --git a/modules/gdscript/tests/scripts/analyzer/features/await_type_inference.gd b/modules/gdscript/tests/scripts/analyzer/features/await_type_inference.gd new file mode 100644 index 00000000000..9d8cfc7f99b --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/await_type_inference.gd @@ -0,0 +1,15 @@ +func coroutine() -> int: + @warning_ignore("redundant_await") + await 0 + return 1 + +func not_coroutine() -> int: + return 2 + +func test(): + var a := await coroutine() + @warning_ignore("redundant_await") + var b := await not_coroutine() + @warning_ignore("redundant_await") + var c := await 3 + prints(a, b, c) diff --git a/modules/gdscript/tests/scripts/analyzer/features/await_type_inference.out b/modules/gdscript/tests/scripts/analyzer/features/await_type_inference.out new file mode 100644 index 00000000000..2920e2ce9c3 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/await_type_inference.out @@ -0,0 +1,2 @@ +GDTEST_OK +1 2 3