ballerina-platform / ballerina-lang

The Ballerina Programming Language
https://ballerina.io/
Apache License 2.0
3.55k stars 736 forks source link

[Bug]: BIRGen crashes for error binding pattern in `on fail` with multiple `check` expressions #42477

Open MaryamZi opened 3 months ago

MaryamZi commented 3 months ago

Description

$title.

Steps to Reproduce

function f1(string str) {
    do {
        check f2();
        check f2();
    } on fail error error(message) {
    }
}

function f2() returns error? {
}
[2024-04-04 15:53:03,017] SEVERE {b7a.log.crash} - null 
java.lang.AssertionError
        at org.wso2.ballerinalang.compiler.tree.BLangNodeVisitor.visit(BLangNodeVisitor.java:626)
        at org.wso2.ballerinalang.compiler.tree.expressions.BLangSimpleVarRef.accept(BLangSimpleVarRef.java:65)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.createCall(BIRGen.java:1381)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.visit(BIRGen.java:1149)
        at org.wso2.ballerinalang.compiler.tree.expressions.BLangInvocation.accept(BLangInvocation.java:128)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.visit(BIRGen.java:1097)
        at org.wso2.ballerinalang.compiler.tree.statements.BLangSimpleVariableDef.accept(BLangSimpleVariableDef.java:50)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.visit(BIRGen.java:994)
        at org.wso2.ballerinalang.compiler.tree.statements.BLangBlockStmt.accept(BLangBlockStmt.java:65)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.visit(BIRGen.java:994)
        at org.wso2.ballerinalang.compiler.tree.statements.BLangBlockStmt.accept(BLangBlockStmt.java:65)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.visit(BIRGen.java:1159)
        at org.wso2.ballerinalang.compiler.tree.expressions.BLangStatementExpression.accept(BLangStatementExpression.java:53)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.visit(BIRGen.java:1056)
        at org.wso2.ballerinalang.compiler.tree.statements.BLangFail.accept(BLangFail.java:59)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.visit(BIRGen.java:994)
        at org.wso2.ballerinalang.compiler.tree.statements.BLangBlockStmt.accept(BLangBlockStmt.java:65)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.visit(BIRGen.java:1535)
        at org.wso2.ballerinalang.compiler.tree.statements.BLangIf.accept(BLangIf.java:60)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.visit(BIRGen.java:994)
        at org.wso2.ballerinalang.compiler.tree.statements.BLangBlockStmt.accept(BLangBlockStmt.java:65)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.visit(BIRGen.java:1159)
        at org.wso2.ballerinalang.compiler.tree.expressions.BLangStatementExpression.accept(BLangStatementExpression.java:53)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.visit(BIRGen.java:1137)
        at org.wso2.ballerinalang.compiler.tree.statements.BLangExpressionStmt.accept(BLangExpressionStmt.java:51)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.visit(BIRGen.java:994)
        at org.wso2.ballerinalang.compiler.tree.statements.BLangBlockStmt.accept(BLangBlockStmt.java:65)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.visit(BIRGen.java:744)
        at org.wso2.ballerinalang.compiler.tree.BLangBlockFunctionBody.accept(BLangBlockFunctionBody.java:60)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.visit(BIRGen.java:704)
        at org.wso2.ballerinalang.compiler.tree.BLangFunction.accept(BLangFunction.java:77)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.lambda$visit$5(BIRGen.java:352)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.visit(BIRGen.java:352)
        at org.wso2.ballerinalang.compiler.tree.BLangPackage.accept(BLangPackage.java:167)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.genBIR(BIRGen.java:292)
        at io.ballerina.projects.internal.CompilerPhaseRunner.birGen(CompilerPhaseRunner.java:216)
        at io.ballerina.projects.internal.CompilerPhaseRunner.performBirGenPhases(CompilerPhaseRunner.java:153)
        at io.ballerina.projects.ModuleContext.generateCodeInternal(ModuleContext.java:454)
        at io.ballerina.projects.ModuleCompilationState$4.generatePlatformSpecificCode(ModuleCompilationState.java:132)
        at io.ballerina.projects.ModuleContext.generatePlatformSpecificCode(ModuleContext.java:387)
        at io.ballerina.projects.JBallerinaBackend.performCodeGen(JBallerinaBackend.java:173)
        at io.ballerina.projects.JBallerinaBackend.<init>(JBallerinaBackend.java:142)
        at io.ballerina.projects.JBallerinaBackend.lambda$from$0(JBallerinaBackend.java:126)
        at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1220)
        at io.ballerina.projects.PackageCompilation.getCompilerBackend(PackageCompilation.java:176)
        at io.ballerina.projects.JBallerinaBackend.from(JBallerinaBackend.java:125)
        at io.ballerina.projects.JBallerinaBackend.from(JBallerinaBackend.java:113)
        at io.ballerina.cli.task.CompileTask.execute(CompileTask.java:217)
        at io.ballerina.cli.TaskExecutor.executeTasks(TaskExecutor.java:40)
        at io.ballerina.cli.cmd.RunCommand.execute(RunCommand.java:250)
        at java.base/java.util.Optional.ifPresent(Optional.java:178)
        at io.ballerina.cli.launcher.Main.main(Main.java:58)

Affected Version(s)

Current master (U9-snapshot)

OS, DB, other environment details and versions

No response

Related area

-> Compilation

Related issue(s) (optional)

No response

Suggested label(s) (optional)

No response

Suggested assignee(s) (optional)

No response

MaryamZi commented 3 months ago

Even with capture binding patterns, if we explicitly call a function like message() on the error value in a match statement, the backend crashes. This happens on U8 also.

function f1(string str) returns int {
    do {
        check f2(str);
        check f2(str);
    } on fail error e {
        match e.message() {
            "Error 1" => {
                return 1;
            }
        }
    }
    return 2;
}

function f2(string str) returns error? => ();
[2024-04-08 15:06:42,108] SEVERE {b7a.log.crash} - Cannot read field "kind" because "moveIns.rhsOp.variableDcl" is null 
java.lang.NullPointerException: Cannot read field "kind" because "moveIns.rhsOp.variableDcl" is null
        at org.wso2.ballerinalang.compiler.bir.optimizer.BIROptimizer$RHSTempVarOptimizer.visit(BIROptimizer.java:157)
        at org.wso2.ballerinalang.compiler.bir.model.BIRNode$BIRBasicBlock.accept(BIRNode.java:485)
        at org.wso2.ballerinalang.compiler.bir.optimizer.BIROptimizer$RHSTempVarOptimizer.lambda$visit$3(BIROptimizer.java:119)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
        at org.wso2.ballerinalang.compiler.bir.optimizer.BIROptimizer$RHSTempVarOptimizer.visit(BIROptimizer.java:119)
        at org.wso2.ballerinalang.compiler.bir.model.BIRNode$BIRFunction.accept(BIRNode.java:432)
        at org.wso2.ballerinalang.compiler.bir.optimizer.BIROptimizer$RHSTempVarOptimizer.lambda$visit$1(BIROptimizer.java:105)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
        at org.wso2.ballerinalang.compiler.bir.optimizer.BIROptimizer$RHSTempVarOptimizer.visit(BIROptimizer.java:105)
        at org.wso2.ballerinalang.compiler.bir.model.BIRNode$BIRPackage.accept(BIRNode.java:89)
        at org.wso2.ballerinalang.compiler.bir.optimizer.BIROptimizer.optimizePackage(BIROptimizer.java:82)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.genBIR(BIRGen.java:291)
        at io.ballerina.projects.internal.CompilerPhaseRunner.birGen(CompilerPhaseRunner.java:220)
        at io.ballerina.projects.internal.CompilerPhaseRunner.performBirGenPhases(CompilerPhaseRunner.java:157)
        at io.ballerina.projects.ModuleContext.generateCodeInternal(ModuleContext.java:454)
        at io.ballerina.projects.ModuleCompilationState$4.generatePlatformSpecificCode(ModuleCompilationState.java:132)
        at io.ballerina.projects.ModuleContext.generatePlatformSpecificCode(ModuleContext.java:387)
        at io.ballerina.projects.JBallerinaBackend.performCodeGen(JBallerinaBackend.java:174)
        at io.ballerina.projects.JBallerinaBackend.<init>(JBallerinaBackend.java:143)
        at io.ballerina.projects.JBallerinaBackend.lambda$from$0(JBallerinaBackend.java:121)
        at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1220)
        at io.ballerina.projects.PackageCompilation.getCompilerBackend(PackageCompilation.java:176)
        at io.ballerina.projects.JBallerinaBackend.from(JBallerinaBackend.java:120)
        at io.ballerina.cli.task.CompileTask.execute(CompileTask.java:201)
        at io.ballerina.cli.TaskExecutor.executeTasks(TaskExecutor.java:40)
        at io.ballerina.cli.cmd.RunCommand.execute(RunCommand.java:223)
        at java.base/java.util.Optional.ifPresent(Optional.java:178)
        at io.ballerina.cli.launcher.Main.main(Main.java:58)
MaryamZi commented 3 months ago

The error BP has been temporarily disallowed on the U9 branch via https://github.com/ballerina-platform/ballerina-lang/pull/42503.

Need to also address https://github.com/ballerina-platform/ballerina-lang/blob/2201.9.x/tests/jballerina-unit-test/src/test/resources/test-src/statements/onfail/on-fail-clause.bal#L591 when reverting the changes in that PR.

chiranSachintha commented 2 months ago

We have tried a few approaches:

  1. Generate a separate function for statements within the on-fail clause. This method allows to desugar only once for the on-fail clause, but creating this function is complex, due to that we move away from this approach.

  2. Clone the type binding and use it within the on-fail clause. While this seemed promising, we encountered some issues with this approach. The proposed solution is mentioned in the following doc.https://docs.google.com/document/d/1Dy7WLP7Ne8lqUKzIF89TYskf_8KmaBLLfb4XZypP7mw/edit?usp=sharing

chiranSachintha commented 2 months ago

With this task, we identified that the Do on-fail within the Query Action isn't desugared correctly. This needs to be addressed first to resolve the issue as well. https://github.com/ballerina-platform/ballerina-lang/issues/42632