Skip to content
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

Checking ascribed expression types for existence #7796

Merged
merged 21 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
2a161e8
Checking ascribed expression types for existance
JaroslavTulach Sep 12, 2023
b4652b7
Allow ascriptions of any expression
JaroslavTulach Sep 12, 2023
11b98ea
Requesting explicit runtime conversions with p:Plus & co.
JaroslavTulach Sep 12, 2023
2dd35b0
Avoid checking Expression.Binding signatures
JaroslavTulach Sep 12, 2023
a9424a9
Note in changelog
JaroslavTulach Sep 12, 2023
2bc7dd3
Methods of Any are dispatched for the whole EnsoMultiValue object
JaroslavTulach Sep 13, 2023
caf4427
Support == for TruffleObjects wrapping numbers
JaroslavTulach Sep 13, 2023
97fc8ef
Number interop for multi values
JaroslavTulach Sep 13, 2023
824ea0a
Supporting boolean interop for multi values
JaroslavTulach Sep 13, 2023
e415c91
Supporting string interop for multi values
JaroslavTulach Sep 13, 2023
340d76d
Supporting date and time interop for multi values
JaroslavTulach Sep 13, 2023
dad0fb1
Making integer AddNode work with foreign numbers
JaroslavTulach Sep 13, 2023
cc4ff63
Make all integer nodes extend common superclass
JaroslavTulach Sep 13, 2023
4614be2
Test to verify integer operation on foreign objects
JaroslavTulach Sep 13, 2023
0ab53f9
Using Parameterized instead of Theories
JaroslavTulach Sep 14, 2023
7cf503a
Let all integer operations accept foreign number as second argument
JaroslavTulach Sep 14, 2023
6678dd7
foreach rather than if
JaroslavTulach Sep 14, 2023
3d5b014
Make all nodes extend a shared node
JaroslavTulach Sep 14, 2023
634b25c
Support foreign number argument in double arithmetic nodes
JaroslavTulach Sep 14, 2023
04a1d14
Removing notes on \
JaroslavTulach Sep 14, 2023
8954f5c
Reusing Type from Pair returned by the resolveFor method
JaroslavTulach Sep 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,7 @@
projects next to each other][7634]
- [Support runtime checks of intersection types][7769]
- [Merge `Small_Integer` and `Big_Integer` types][7636]
- [Inline type ascriptions][7796]

[3227]: https://github.com/enso-org/enso/pull/3227
[3248]: https://github.com/enso-org/enso/pull/3248
Expand Down Expand Up @@ -1086,6 +1087,7 @@
[7634]: https://github.com/enso-org/enso/pull/7634
[7769]: https://github.com/enso-org/enso/pull/7769
[7636]: https://github.com/enso-org/enso/pull/7636
[7796]: https://github.com/enso-org/enso/pull/7796

# Enso 2.0.0-alpha.18 (2021-10-12)

Expand Down
4 changes: 0 additions & 4 deletions docs/syntax/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ working with types. These are listed below.
| `;` | `< :`, `> =` | -2 | Left | Concatenates the left and right operand typesets to create a new typeset. |
| `\|` | `> <:`, `> !`, `> in`, `> :` | 5 | Left | Computes the union of the left and right operand typesets. |
| `&` | `> \|` | 6 | Left | Computes the intersection of the left and right operand typesets. |
| `\` | `> &` | 7 | Left | Computes the subtraction of the right typeset from the left typeset. |
| `:=` | `< :`, `> =`, `> ;` | -1 | Left | Creates a typeset member by assigning a value to a label. |

<!-- prettier-ignore-end -->
Expand All @@ -108,7 +107,6 @@ bind (`=`) has a relative level of -3 in this ordering.
(declare-fun tsConcat () Int) ; `;`
(declare-fun tsUnion () Int) ; `|`
(declare-fun tsInter () Int) ; `&`
(declare-fun minus () Int) ; `\`
(declare-fun tsMember () Int) ; `:=`

(assert (> ascrip bind))
Expand Down Expand Up @@ -265,8 +263,6 @@ of typesets. Their syntax is as follows:
arguments.
- **Intersection - `&`:** The resultant typeset may contain values that are
members of _both_ its arguments.
- **Subtraction - `\`:** The resultant typeset may contain values that are in
the first argument's set but not in the second.

> The actionables for this section are:
>
Expand Down
4 changes: 1 addition & 3 deletions docs/types/hierarchy.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,8 @@ They are as follows:
product types.
- **Union - `|`:** This operator creates a typeset that contains the members in
the union of its operands.
- **Intersection - `|`:** This operator creates a typeset that contains the
- **Intersection - `&`:** This operator creates a typeset that contains the
members in the intersection of its operands.
- **Subtraction - `\`:** This operator creates a typeset that contains all of
the members in the left operand that do not occur in the right operand.

For information on the syntactic usage of these operators, please see the
section on [type operators](#../syntax/types.md#type-operators) in the syntax
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ Object doDataflowError(
@Shared("indirectInvokeFunctionNode") @Cached IndirectInvokeFunctionNode invokeFunctionNode,
@Cached ConditionProfile profile) {
Function function =
methodResolverNode.execute(EnsoContext.get(this).getBuiltins().dataflowError(), symbol);
methodResolverNode.executeResolution(
EnsoContext.get(this).getBuiltins().dataflowError(), symbol);
if (profile.profile(function == null)) {
return self;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.control.TailCallException;
import org.enso.interpreter.runtime.data.ArrayRope;
import org.enso.interpreter.runtime.data.EnsoMultiValue;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.error.DataflowError;
Expand Down Expand Up @@ -152,6 +153,27 @@ Object doPanicSentinel(
throw that;
}

@Specialization
Object doMultiValue(
VirtualFrame frame,
State state,
UnresolvedConversion conversion,
Object self,
EnsoMultiValue that,
Object[] arguments) {
var type = extractType(self);
var result = that.castTo(type);
if (result == null) {
throw new PanicException(
EnsoContext.get(this)
.getBuiltins()
.error()
.makeNoSuchConversion(type, self, conversion),
this);
}
return result;
}

@Specialization
Object doWarning(
VirtualFrame frame,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ Object doFunctionalDispatchCachedSymbol(

Function resolveFunction(
UnresolvedSymbol symbol, Type selfTpe, MethodResolverNode methodResolverNode) {
Function function = methodResolverNode.execute(selfTpe, symbol);
Function function = methodResolverNode.executeResolution(selfTpe, symbol);
if (function == null) {
return null;
}
Expand Down Expand Up @@ -288,10 +288,11 @@ Object doMultiValue(
var fnAndType = self.resolveSymbol(methodResolverNode, symbol);
if (fnAndType != null) {
var unwrapSelf = self.castTo(fnAndType.getRight());
assert unwrapSelf != null;
assert arguments[0] == self;
arguments[0] = unwrapSelf;
return execute(frame, state, symbol, unwrapSelf, arguments);
if (unwrapSelf != null) {
assert arguments[0] == self;
arguments[0] = unwrapSelf;
}
return invokeFunctionNode.execute(fnAndType.getLeft(), frame, state, arguments);
}
throw methodNotFound(symbol, self);
}
Expand All @@ -305,7 +306,7 @@ Object doDataflowError(
Object[] arguments,
@Shared("methodResolverNode") @Cached MethodResolverNode methodResolverNode) {
Function function =
methodResolverNode.execute(EnsoContext.get(this).getBuiltins().dataflowError(), symbol);
methodResolverNode.executeResolution(EnsoContext.get(this).getBuiltins().dataflowError(), symbol);
if (errorReceiverProfile.profile(function == null)) {
return self;
} else {
Expand Down Expand Up @@ -352,9 +353,10 @@ Function resolveWarningFunction(
e);
}

Type typeOfSymbol = symbol.resolveDeclaringType(this, types.getType(selfWithoutWarnings));
Builtins builtins = EnsoContext.get(this).getBuiltins();
if (typeOfSymbol == builtins.any()) {
var selfType = types.getType(selfWithoutWarnings);
var fnAndType = symbol.resolveFor(this, selfType);
var builtins = EnsoContext.get(this).getBuiltins();
if (fnAndType != null && fnAndType.getRight() == builtins.any()) {
return symbol
.getScope()
.lookupMethodDefinition(builtins.warning().getEigentype(), symbol.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.enso.interpreter.EnsoLanguage;
import org.enso.interpreter.node.BaseNode.TailStatus;
import org.enso.interpreter.node.EnsoRootNode;
import org.enso.interpreter.node.ExpressionNode;
import org.enso.interpreter.node.callable.ApplicationNode;
import org.enso.interpreter.node.callable.InvokeCallableNode.DefaultsExecutionMode;
import org.enso.interpreter.node.callable.thunk.ThunkExecutorNode;
Expand Down Expand Up @@ -55,6 +56,13 @@ public abstract class ReadArgumentCheckNode extends Node {
this.name = name;
}

/**
*
*/
public static ExpressionNode wrap(ExpressionNode original, ReadArgumentCheckNode check) {
return new TypeCheckExpressionNode(original, check);
}

/** Executes check or conversion of the value.abstract
* @param frame frame requesting the conversion
* @param value the value to convert
Expand Down Expand Up @@ -289,16 +297,28 @@ private Pair<Function, Type> findConversion(Type from) {
ApplicationNode findConversionNode(Type from) {
var convAndType = findConversion(from);

if (convAndType != null && NodeUtil.findParent(this, ReadArgumentNode.class) instanceof ReadArgumentNode ran) {
CompilerAsserts.neverPartOfCompilation();
var convNode = LiteralNode.build(convAndType.getLeft());
var intoNode = LiteralNode.build(convAndType.getRight());
var valueNode = ran.plainRead();
var args = new CallArgument[]{
new CallArgument(null, intoNode),
new CallArgument(null, valueNode)
};
return ApplicationNode.build(convNode, args, DefaultsExecutionMode.EXECUTE);
if (convAndType != null) {
if (NodeUtil.findParent(this, ReadArgumentNode.class) instanceof ReadArgumentNode ran) {
CompilerAsserts.neverPartOfCompilation();
var convNode = LiteralNode.build(convAndType.getLeft());
var intoNode = LiteralNode.build(convAndType.getRight());
var valueNode = ran.plainRead();
var args = new CallArgument[]{
new CallArgument(null, intoNode),
new CallArgument(null, valueNode)
};
return ApplicationNode.build(convNode, args, DefaultsExecutionMode.EXECUTE);
} else if (NodeUtil.findParent(this, TypeCheckExpressionNode.class) instanceof TypeCheckExpressionNode tcen) {
CompilerAsserts.neverPartOfCompilation();
var convNode = LiteralNode.build(convAndType.getLeft());
var intoNode = LiteralNode.build(convAndType.getRight());
var valueNode = tcen.original;
var args = new CallArgument[]{
new CallArgument(null, intoNode),
new CallArgument(null, valueNode)
};
return ApplicationNode.build(convNode, args, DefaultsExecutionMode.EXECUTE);
}
}
return null;
}
Expand Down Expand Up @@ -378,4 +398,29 @@ public Object execute(VirtualFrame frame) {
return result;
}
}

private static final class TypeCheckExpressionNode extends ExpressionNode {
@Child
private ExpressionNode original;
@Child
private ReadArgumentCheckNode check;

TypeCheckExpressionNode(ExpressionNode original, ReadArgumentCheckNode check) {
this.check = check;
this.original = original;
}

@Override
public Object executeGeneric(VirtualFrame frame) {
var value = original.executeGeneric(frame);
var result = check.handleCheckOrConversion(frame, value);
return result;
}

@Override
public boolean isInstrumentable() {
return false;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.error.PanicException;
import org.graalvm.collections.Pair;

@GenerateUncached
@ReportPolymorphism
Expand All @@ -22,15 +23,20 @@ EnsoContext getContext() {
return EnsoContext.get(this);
}

public abstract Function execute(Type type, UnresolvedSymbol symbol);
public abstract Pair<Function, Type> execute(Type type, UnresolvedSymbol symbol);

public Function expectNonNull(Object self, Type type, UnresolvedSymbol symbol) {
public final Function executeResolution(Type type, UnresolvedSymbol symbol) {
var pair = execute(type, symbol);
return pair == null ? null : pair.getLeft();
}

public final Function expectNonNull(Object self, Type type, UnresolvedSymbol symbol) {
var result = execute(type, symbol);
if (result == null) {
throw new PanicException(
EnsoContext.get(this).getBuiltins().error().makeNoSuchMethod(self, symbol), this);
}
return result;
return result.getLeft();
}

@Specialization(
Expand All @@ -40,17 +46,17 @@ public Function expectNonNull(Object self, Type type, UnresolvedSymbol symbol) {
"cachedType == type"
},
limit = "CACHE_SIZE")
Function resolveCached(
Pair<Function, Type> resolveCached(
Type type,
UnresolvedSymbol symbol,
@Cached("symbol") UnresolvedSymbol cachedSymbol,
@Cached("type") Type cachedType,
@Cached("resolveUncached(cachedType, cachedSymbol)") Function function) {
@Cached("resolveUncached(cachedType, cachedSymbol)") Pair<Function, Type> function) {
return function;
}

@Specialization(replaces = "resolveCached")
Function resolveUncached(Type self, UnresolvedSymbol symbol) {
Pair<Function, Type> resolveUncached(Type self, UnresolvedSymbol symbol) {
return symbol.resolveFor(this, self);
}
}
Loading
Loading