Browse Source

GDScript: Fix `await` type inference

Danil Alexeev 2 years ago
parent
commit
685db28e29

+ 10 - 13
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<GDScriptParser::CallNode *>(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

+ 4 - 0
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

+ 2 - 0
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.

+ 15 - 0
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)

+ 2 - 0
modules/gdscript/tests/scripts/analyzer/features/await_type_inference.out

@@ -0,0 +1,2 @@
+GDTEST_OK
+1 2 3