-
Notifications
You must be signed in to change notification settings - Fork 326
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Promote broken values instead of ignoring them #11777
Changes from 4 commits
1c2d007
49c628e
91f7497
1ed8505
7373304
00516f5
b0f71f8
ee7c81e
d703496
7901a25
ba16c47
6e0928a
bed6609
1647c53
ef80339
a8571c4
6551756
09fb17f
3b8c089
434ba8a
777c38b
8748349
b7430cb
fe5b9e1
3ce19c7
afedc71
bda76cf
0130601
5916204
5bfe082
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package org.enso.interpreter.test.semantic; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertFalse; | ||
import static org.junit.Assert.assertTrue; | ||
|
||
import org.enso.common.MethodNames; | ||
import org.enso.test.utils.ContextUtils; | ||
import org.graalvm.polyglot.Context; | ||
import org.graalvm.polyglot.PolyglotException; | ||
import org.graalvm.polyglot.Value; | ||
import org.junit.AfterClass; | ||
import org.junit.BeforeClass; | ||
import org.junit.Test; | ||
|
||
public class DataflowErrorPropagationTest { | ||
private static Context ctx; | ||
private static Value suppressError; | ||
private static Value suppressErrorWithAssign; | ||
|
||
@BeforeClass | ||
public static void prepareCtx() { | ||
ctx = ContextUtils.createDefaultContext(); | ||
var code = | ||
""" | ||
from Standard.Base import all | ||
|
||
private yield_error yes:Boolean -> Text = | ||
if yes then Error.throw "Yielding an error" else | ||
"OK" | ||
|
||
suppress_error yes:Boolean value = | ||
yield_error yes | ||
JaroslavTulach marked this conversation as resolved.
Show resolved
Hide resolved
|
||
value | ||
|
||
suppress_error_with_assign yes:Boolean value = | ||
_ = yield_error yes | ||
value | ||
"""; | ||
suppressError = | ||
ctx.eval("enso", code).invokeMember(MethodNames.Module.EVAL_EXPRESSION, "suppress_error"); | ||
suppressErrorWithAssign = | ||
ctx.eval("enso", code) | ||
.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "suppress_error_with_assign"); | ||
} | ||
|
||
@AfterClass | ||
public static void disposeCtx() { | ||
ctx.close(); | ||
ctx = null; | ||
} | ||
|
||
@Test | ||
public void noErrorReturnValue() { | ||
var value = suppressError.execute(false, 42); | ||
assertTrue("It is a number", value.isNumber()); | ||
assertEquals(42, value.asInt()); | ||
} | ||
|
||
@Test | ||
public void propagateErrorImmediatelly() { | ||
var value = suppressError.execute(true, 42); | ||
assertFalse("It is not a number", value.isNumber()); | ||
assertTrue("It is an error", value.isException()); | ||
try { | ||
throw value.throwException(); | ||
} catch (PolyglotException ex) { | ||
assertEquals("Yielding an error", ex.getMessage()); | ||
} | ||
} | ||
|
||
@Test | ||
public void noErrorReturnValueWithAssign() { | ||
var value = suppressErrorWithAssign.execute(false, 42); | ||
assertTrue("It is a number", value.isNumber()); | ||
assertEquals(42, value.asInt()); | ||
} | ||
|
||
@Test | ||
public void errorIsAssignedAndThatIsEnoughReturnValue() { | ||
var value = suppressErrorWithAssign.execute(true, 42); | ||
assertTrue("It is a number", value.isNumber()); | ||
assertFalse("Not an error", value.isException()); | ||
assertEquals(42, value.asInt()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,8 @@ | |
import com.oracle.truffle.api.source.SourceSection; | ||
import java.util.Set; | ||
import org.enso.interpreter.node.ExpressionNode; | ||
import org.enso.interpreter.runtime.EnsoContext; | ||
import org.enso.interpreter.runtime.error.DataflowError; | ||
|
||
/** | ||
* This node defines the body of a function for execution, as well as the protocol for executing the | ||
|
@@ -55,8 +57,15 @@ public static BlockNode buildSilent(ExpressionNode[] expressions, ExpressionNode | |
@Override | ||
@ExplodeLoop | ||
public Object executeGeneric(VirtualFrame frame) { | ||
var ctx = EnsoContext.get(this); | ||
var nothing = ctx.getBuiltins().nothing(); | ||
for (ExpressionNode statement : statements) { | ||
statement.executeGeneric(frame); | ||
var result = statement.executeGeneric(frame); | ||
if (result != nothing) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not get rid of this if statement and use simply just There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indeed this seems redundant, can we remove it, or is there some reason that we don't see here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason is the other part of #5430:
We don't need to solve it in this PR. Just my 2 Kč explanation of the |
||
if (result instanceof DataflowError err) { | ||
return err; | ||
JaroslavTulach marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
} | ||
return returnExpr.executeGeneric(frame); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is way easier of parse, we the function signature clearly stays unaffected.