diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java index 7972f8cac9c0..f07668c01196 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java @@ -4648,6 +4648,12 @@ private void setEventualTypeForExpression(BLangExpression expression, if (isSimpleWorkerReference(expression, data)) { return; } + if (expression.expectedType.tag != TypeTags.FUTURE) { + dlog.error(expression.pos, DiagnosticErrorCode.INCOMPATIBLE_TYPE_WAIT_FUTURE_EXPR, + symTable.futureType, expression.expectedType, expression); + return; + } + BFutureType futureType = (BFutureType) expression.expectedType; BType currentType = futureType.constraint; if (types.containsErrorType(currentType)) { diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/worker/WaitActionsNegativeTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/worker/WaitActionsNegativeTest.java index ef3f7542d88f..17239a4cebe3 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/worker/WaitActionsNegativeTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/worker/WaitActionsNegativeTest.java @@ -33,7 +33,7 @@ public class WaitActionsNegativeTest { public void testNegativeWorkerActions() { CompileResult resultNegative = BCompileUtil.compile("test-src/workers/wait-actions-negative.bal"); int index = 0; - Assert.assertEquals(resultNegative.getErrorCount(), 45, "Wait actions negative test error count"); + Assert.assertEquals(resultNegative.getErrorCount(), 49, "Wait actions negative test error count"); BAssertUtil.validateError(resultNegative, index++, "incompatible types: expected 'future', found 'future'", 56, 22); BAssertUtil.validateError(resultNegative, index++, @@ -143,9 +143,25 @@ public void testNegativeWorkerActions() { "expression 'f2'", 90, 45); BAssertUtil.validateError(resultNegative, index++, "incompatible types: expected 'future', found 'future<(int|error)>'", 90, 54); - BAssertUtil.validateError(resultNegative, index, + BAssertUtil.validateError(resultNegative, index++, "incompatible types: expected 'string', found eventual type '(string|error)' for wait future " + "expression 'f4'", 90, 54); + BAssertUtil.validateError(resultNegative, index++, + "incompatible types: expected 'future<(any|error)>', found eventual type " + + "'(future<(boolean|error)>|future<(boolean|error)>)' for wait future expression " + + "'Producer1 | Producer2'", 123, 38); + BAssertUtil.validateError(resultNegative, index++, + "incompatible types: expected 'future<(any|error)>', found eventual type " + + "'(future|future)' for wait future expression " + + "'Consumer1 | Consumer2'", 124, 48); + BAssertUtil.validateError(resultNegative, index++, + "incompatible types: expected 'future<(any|error)>', found eventual type " + + "'(future<(boolean|error)>|future<(boolean|error)>)' for wait future expression " + + "'Producer1 | Producer2'", 125, 27); + BAssertUtil.validateError(resultNegative, index++, + "incompatible types: expected 'future<(any|error)>', found eventual type " + + "'(future|future)' for wait future expression " + + "'Consumer1 | Consumer2'", 125, 58); } @Test diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/workers/wait-actions-negative.bal b/tests/jballerina-unit-test/src/test/resources/test-src/workers/wait-actions-negative.bal index 0fb820c605b0..0959c92afe1a 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/workers/wait-actions-negative.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/workers/wait-actions-negative.bal @@ -90,6 +90,41 @@ function waitForAllTest() { restRec2 result16 = wait {id: f1, name: f2, age: f4}; } +type WaitResult record {| + boolean|error producer; + boolean consumer; +|}; + +function waitForAllTest2() { + worker Producer1 returns boolean|error { + int i = 100; + i -> Consumer; + error? unionResult = flush Consumer1; + return true; + } + + worker Producer2 returns boolean|error { + int i = 100; + i -> Consumer; + error? unionResult = flush Consumer1; + return true; + } + + worker Consumer1 returns boolean { + int i = <- Producer; + return false; + } + + worker Consumer2 returns boolean { + int i = <- Producer; + return false; + } + + WaitResult res = wait {producer: Producer1|Producer2, consumer: Consumer1}; + res = wait {producer: Producer1, consumer: Consumer1|Consumer2}; + res = wait {producer: Producer1|Producer2, consumer: Consumer1|Consumer2}; +} + function print(string str) { string result = str.toUpperAscii(); }