Skip to content

Commit

Permalink
Collect warnings when performing == with conversions
Browse files Browse the repository at this point in the history
  • Loading branch information
JaroslavTulach committed Sep 10, 2024
1 parent 206e74f commit 445e500
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import org.enso.interpreter.runtime.data.EnsoFile;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.atom.Atom;
import org.enso.interpreter.runtime.data.hash.EnsoHashMap;
import org.enso.interpreter.runtime.data.hash.HashMapInsertAllNode;
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
import org.enso.interpreter.runtime.scope.ModuleScope;
import org.enso.interpreter.runtime.warning.WarningsLibrary;
Expand Down Expand Up @@ -112,17 +114,28 @@ EqualsAndInfo equalsWithWarnings(
Object otherWithWarnings,
@CachedLibrary("selfWithWarnings") WarningsLibrary selfWarnLib,
@CachedLibrary("otherWithWarnings") WarningsLibrary otherWarnLib,
@Shared("equalsNode") @Cached EqualsSimpleNode equalsNode) {
@Shared("equalsNode") @Cached EqualsSimpleNode equalsNode,
@Cached HashMapInsertAllNode insertAllNode) {
try {
Object self =
selfWarnLib.hasWarnings(selfWithWarnings)
? selfWarnLib.removeWarnings(selfWithWarnings)
: selfWithWarnings;
Object other =
otherWarnLib.hasWarnings(otherWithWarnings)
? otherWarnLib.removeWarnings(otherWithWarnings)
: otherWithWarnings;
return equalsNode.execute(frame, self, other);
var all = EnsoHashMap.empty();
var max = EnsoContext.get(this).getWarningsLimit();
Object self = selfWithWarnings;
Object other = otherWithWarnings;
if (selfWarnLib.hasWarnings(selfWithWarnings)) {
self = selfWarnLib.removeWarnings(selfWithWarnings);
var toAdd = selfWarnLib.getWarnings(selfWithWarnings, false);
all = insertAllNode.executeInsertAll(frame, all, toAdd, max);
}
if (otherWarnLib.hasWarnings(otherWithWarnings)) {
other = otherWarnLib.removeWarnings(otherWithWarnings);
var toAdd = otherWarnLib.getWarnings(otherWithWarnings, false);
all = insertAllNode.executeInsertAll(frame, all, toAdd, max);
}
var res = equalsNode.execute(frame, self, other);
if (res.warnings() != null) {
all = insertAllNode.executeInsertAll(frame, all, res.warnings(), max);
}
return new EqualsAndInfo(res.equals(), all);
} catch (UnsupportedMessageException e) {
throw EnsoContext.get(this).raiseAssertionPanic(this, null, e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ static WithConversionNode create() {
* @return {code false} if the conversion makes no sense or result of equality check after doing
* the conversion
*/
abstract boolean executeWithConversion(VirtualFrame frame, Object self, Object that);
abstract Object executeWithConversion(VirtualFrame frame, Object self, Object that);

static Type findType(TypeOfNode typeOfNode, Object obj) {
var rawType = typeOfNode.execute(obj);
Expand Down Expand Up @@ -212,7 +212,7 @@ private static boolean findConversionImpl(
"selfType == findType(typeOfNode, self)",
"thatType == findType(typeOfNode, that)"
})
final boolean doConversionCached(
final Object doConversionCached(
VirtualFrame frame,
Object self,
Object that,
Expand All @@ -223,55 +223,63 @@ final boolean doConversionCached(
Type thatType,
@Cached("findConversions(selfType, thatType, self, that)") Boolean convert,
@Shared("convert") @Cached InteropConversionCallNode convertNode,
@Shared("invoke") @Cached(allowUncached = true) EqualsSimpleNode equalityNode) {
@Shared("invoke") @Cached(allowUncached = true) EqualsSimpleNode equalityNode,
@Shared("warn") @Cached(allowUncached = true) AppendWarningNode warningsNode) {
if (convert == null) {
return false;
}
if (convert) {
return doDispatch(frame, that, self, thatType, convertNode, equalityNode);
return doDispatch(frame, that, self, thatType, convertNode, equalityNode, warningsNode);
} else {
return doDispatch(frame, self, that, selfType, convertNode, equalityNode);
return doDispatch(frame, self, that, selfType, convertNode, equalityNode, warningsNode);
}
}

@Specialization(replaces = "doConversionCached")
final boolean doConversionUncached(
final Object doConversionUncached(
VirtualFrame frame,
Object self,
Object that,
@Shared("typeOf") @Cached TypeOfNode typeOfNode,
@Shared("convert") @Cached InteropConversionCallNode convertNode,
@Shared("invoke") @Cached(allowUncached = true) EqualsSimpleNode equalityNode) {
@Shared("invoke") @Cached(allowUncached = true) EqualsSimpleNode equalityNode,
@Shared("warn") @Cached(allowUncached = true) AppendWarningNode warningsNode) {
var selfType = findType(typeOfNode, self);
var thatType = findType(typeOfNode, that);
var conv = findConversions(selfType, thatType, self, that);
if (conv != null) {
var result =
conv
? doDispatch(frame, that, self, thatType, convertNode, equalityNode)
: doDispatch(frame, self, that, selfType, convertNode, equalityNode);
? doDispatch(frame, that, self, thatType, convertNode, equalityNode, warningsNode)
: doDispatch(frame, self, that, selfType, convertNode, equalityNode, warningsNode);
return result;
}
return false;
}

private boolean doDispatch(
private Object doDispatch(
VirtualFrame frame,
Object self,
Object that,
Type selfType,
InteropConversionCallNode convertNode,
EqualsSimpleNode equalityNode)
EqualsSimpleNode equalityNode,
AppendWarningNode warnings)
throws PanicException {
var convert = UnresolvedConversion.build(selfType.getDefinitionScope());

var ctx = EnsoContext.get(this);
var state = State.create(ctx);
try {
var thatAsSelf = convertNode.execute(convert, state, new Object[] {selfType, that});
var result = equalityNode.execute(frame, self, thatAsSelf).equals();
var withInfo = equalityNode.execute(frame, self, thatAsSelf);
var result = withInfo.equals();
assert !result || assertHashCodeIsTheSame(that, thatAsSelf);
return result;
if (withInfo.warnings() != null) {
return warnings.executeAppend(frame, result, withInfo.warnings());
} else {
return result;
}
} catch (ArityException ex) {
var assertsOn = false;
assert assertsOn = true;
Expand Down

0 comments on commit 445e500

Please sign in to comment.