Don't convert type to the same type (#11122)

This commit is contained in:
Jaroslav Tulach 2024-09-18 18:15:58 +02:00 committed by GitHub
parent 859b572242
commit 37688033c8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 83 additions and 3 deletions

View File

@ -0,0 +1,71 @@
package org.enso.interpreter.test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.core.AllOf.allOf;
import static org.junit.Assert.fail;
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.Source;
import org.graalvm.polyglot.Value;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class BinarySelfDispatchTest {
private static Context ctx;
private static Value module;
@BeforeClass
public static void initCtx() throws Exception {
ctx = ContextUtils.createDefaultContext();
var prelude =
Source.newBuilder(
"enso",
"""
from Standard.Base import all
type Delay
private Days n
type Datum
private On at delta
+ self (delta : Delay) -> Datum = Datum.On self.n delta.n
today_plus n =
delta = Delay.Days n
now = Datum.On 0 delta
now + now
""",
"error.enso")
.build();
module = ctx.eval(prelude);
}
@AfterClass
public static void closeCtx() {
module = null;
ctx.close();
ctx = null;
}
@Test
public void avoidSelfConversion() {
try {
var error = module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "today_plus 3");
fail("The code should yield a panic: " + error);
} catch (PolyglotException ex) {
assertThat(
"The error message is correct",
ex.getMessage(),
allOf(
containsString("expected `delta`"),
containsString("to be Delay"),
containsString("but got Datum")));
}
}
}

View File

@ -138,7 +138,7 @@ final class BinaryOperatorNode extends ExpressionNode {
@Shared("convert") @Cached InteropConversionCallNode convertNode,
@Shared("invoke") @Cached(allowUncached = true, value = "buildWithArity(2)")
InvokeFunctionNode invokeNode) {
return doDispatch(frame, self, that, thatType, symbolFn, convertNode, invokeNode);
return doDispatch(frame, self, that, selfType, thatType, symbolFn, convertNode, invokeNode);
}
@Specialization(replaces = "doThatConversionCached")
@ -151,12 +151,15 @@ final class BinaryOperatorNode extends ExpressionNode {
@Shared("convert") @Cached InteropConversionCallNode convertNode,
@Shared("invoke") @Cached(allowUncached = true, value = "buildWithArity(2)")
InvokeFunctionNode invokeNode) {
var selfType = findType(typeOfNode, self);
if (that instanceof EnsoMultiValue multi) {
for (var thatType : multi.allTypes()) {
var fn = findSymbol(symbol, thatType);
if (fn != null) {
var thatCasted = EnsoMultiValue.CastToNode.getUncached().executeCast(thatType, multi);
var result = doDispatch(frame, self, thatCasted, thatType, fn, convertNode, invokeNode);
var result =
doDispatch(
frame, self, thatCasted, selfType, thatType, fn, convertNode, invokeNode);
if (result != null) {
return result;
}
@ -167,7 +170,8 @@ final class BinaryOperatorNode extends ExpressionNode {
if (thatType != null) {
var fn = findSymbol(symbol, thatType);
if (fn != null) {
var result = doDispatch(frame, self, that, thatType, fn, convertNode, invokeNode);
var result =
doDispatch(frame, self, that, selfType, thatType, fn, convertNode, invokeNode);
if (result != null) {
return result;
}
@ -181,11 +185,16 @@ final class BinaryOperatorNode extends ExpressionNode {
VirtualFrame frame,
Object self,
Object that,
Type selfType,
Type thatType,
Function symbolFn,
InteropConversionCallNode convertNode,
InvokeFunctionNode invokeNode)
throws PanicException {
if (selfType == thatType) {
// conversions won't help
return null;
}
var convert = UnresolvedConversion.build(thatType.getDefinitionScope());
var ctx = EnsoContext.get(this);