diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Errors/Common.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Errors/Common.enso
index 372eb5bd8b..a5617b5b16 100644
--- a/distribution/lib/Standard/Base/0.0.0-dev/src/Errors/Common.enso
+++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Errors/Common.enso
@@ -59,8 +59,9 @@ type Type_Error
Arguments:
- expected: The expected type at the error location.
- actual: The actual type at the error location.
- - name: The name of the argument whose type is mismatched.
- Error expected actual name
+ - comment: Description of the value that was being checked,
+ e.g. function argument, result or an arbitrary expression.
+ Error expected actual comment
## PRIVATE
Convert the Type_Error error to a human-readable format.
@@ -78,7 +79,7 @@ type Type_Error
_ -> ". Try to apply " + (missing_args.join ", ") + " arguments"
_ -> tpe.to_text
- "Type error: expected `"+self.name+"` to be "+self.expected.to_display_text+", but got "+type_of_actual+"."
+ "Type error: expected "+self.comment+" to be "+self.expected.to_display_text+", but got "+type_of_actual+"."
@Builtin_Type
type Compile_Error
diff --git a/engine/runtime-compiler/src/main/java/org/enso/compiler/pass/analyse/PassPersistance.java b/engine/runtime-compiler/src/main/java/org/enso/compiler/pass/analyse/PassPersistance.java
index bd939c45c5..aa45e20925 100644
--- a/engine/runtime-compiler/src/main/java/org/enso/compiler/pass/analyse/PassPersistance.java
+++ b/engine/runtime-compiler/src/main/java/org/enso/compiler/pass/analyse/PassPersistance.java
@@ -30,7 +30,7 @@ import scala.Option;
@Persistable(clazz = GatherDiagnostics.DiagnosticsMeta.class, id = 1114)
@Persistable(clazz = DocumentationComments.Doc.class, id = 1115)
@Persistable(clazz = AliasAnalysis$Info$Occurrence.class, id = 1116)
-@Persistable(clazz = TypeSignatures.Signature.class, id = 1117)
+@Persistable(clazz = TypeSignatures.Signature.class, id = 2117)
@Persistable(clazz = ModuleAnnotations.Annotations.class, id = 1118)
@Persistable(clazz = AliasAnalysis$Info$Scope$Root.class, id = 1120)
@Persistable(clazz = DataflowAnalysis$DependencyInfo$Type$Static.class, id = 1121)
diff --git a/engine/runtime-compiler/src/main/scala/org/enso/compiler/context/SuggestionBuilder.scala b/engine/runtime-compiler/src/main/scala/org/enso/compiler/context/SuggestionBuilder.scala
index b797458a4a..7d7ed10b49 100644
--- a/engine/runtime-compiler/src/main/scala/org/enso/compiler/context/SuggestionBuilder.scala
+++ b/engine/runtime-compiler/src/main/scala/org/enso/compiler/context/SuggestionBuilder.scala
@@ -488,7 +488,7 @@ final class SuggestionBuilder[A: IndexedSource](
typeSignature: Option[TypeSignatures.Metadata]
): Vector[TypeArg] =
typeSignature match {
- case Some(TypeSignatures.Signature(typeExpr)) =>
+ case Some(TypeSignatures.Signature(typeExpr, _)) =>
buildTypeSignature(typeExpr)
case _ =>
Vector()
diff --git a/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/analyse/DataflowAnalysis.scala b/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/analyse/DataflowAnalysis.scala
index e9ea22902e..4e470d1e1c 100644
--- a/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/analyse/DataflowAnalysis.scala
+++ b/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/analyse/DataflowAnalysis.scala
@@ -393,7 +393,7 @@ case object DataflowAnalysis extends IRPass {
*/
def analyseType(typ: Type, info: DependencyInfo): Type = {
typ match {
- case asc @ Type.Ascription(typed, signature, _, _, _) =>
+ case asc @ Type.Ascription(typed, signature, _, _, _, _) =>
val ascrDep = asStatic(asc)
val typedDep = asStatic(typed)
val sigDep = asStatic(signature)
diff --git a/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/desugar/ComplexType.scala b/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/desugar/ComplexType.scala
index ee2fce97e8..f29e8f4155 100644
--- a/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/desugar/ComplexType.scala
+++ b/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/desugar/ComplexType.scala
@@ -166,7 +166,7 @@ case object ComplexType extends IRPass {
): List[Definition] = {
var unusedSig: Option[Type.Ascription] = None
val sig = lastSignature match {
- case Some(Type.Ascription(typed, _, _, _, _)) =>
+ case Some(Type.Ascription(typed, _, _, _, _, _)) =>
typed match {
case literal: Name.Literal =>
if (name.name == literal.name) {
diff --git a/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/SuspendedArguments.scala b/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/SuspendedArguments.scala
index 1b8a6b6e06..9d78457ca4 100644
--- a/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/SuspendedArguments.scala
+++ b/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/SuspendedArguments.scala
@@ -115,7 +115,7 @@ case object SuspendedArguments extends IRPass {
method.body match {
case lam @ Function.Lambda(args, body, _, _, _, _) =>
method.getMetadata(TypeSignatures) match {
- case Some(Signature(signature)) =>
+ case Some(Signature(signature, _)) =>
val newArgs = computeSuspensions(args.drop(1), signature)
if (newArgs.head.suspended) {
errors.Conversion(
@@ -163,7 +163,7 @@ case object SuspendedArguments extends IRPass {
body match {
case lam @ Function.Lambda(args, lamBody, _, _, _, _) =>
explicit.getMetadata(TypeSignatures) match {
- case Some(Signature(signature)) =>
+ case Some(Signature(signature, _)) =>
val newArgs = computeSuspensions(
args.drop(1),
signature
@@ -214,7 +214,7 @@ case object SuspendedArguments extends IRPass {
expression.transformExpressions {
case bind @ Expression.Binding(_, expr, _, _, _) =>
val newExpr = bind.getMetadata(TypeSignatures) match {
- case Some(Signature(signature)) =>
+ case Some(Signature(signature, _)) =>
expr match {
case lam @ Function.Lambda(args, body, _, _, _, _) =>
lam.copy(
@@ -229,7 +229,7 @@ case object SuspendedArguments extends IRPass {
bind.copy(expression = newExpr)
case lam @ Function.Lambda(args, body, _, _, _, _) =>
lam.getMetadata(TypeSignatures) match {
- case Some(Signature(signature)) =>
+ case Some(Signature(signature, _)) =>
lam.copy(
arguments = computeSuspensions(args, signature),
body = resolveExpression(body)
diff --git a/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/TypeFunctions.scala b/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/TypeFunctions.scala
index 499364a8aa..45c40a4587 100644
--- a/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/TypeFunctions.scala
+++ b/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/TypeFunctions.scala
@@ -186,7 +186,7 @@ case object TypeFunctions extends IRPass {
name.name match {
case Type.Ascription.name =>
- Type.Ascription(leftArg, rightArg, location)
+ Type.Ascription(leftArg, rightArg, None, location)
case Type.Context.name =>
Type.Context(leftArg, rightArg, location)
case Type.Error.name =>
diff --git a/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/TypeNames.scala b/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/TypeNames.scala
index 8161dff91c..8272b7c198 100644
--- a/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/TypeNames.scala
+++ b/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/TypeNames.scala
@@ -111,7 +111,8 @@ case object TypeNames extends IRPass {
new MetadataPair(
TypeSignatures,
TypeSignatures.Signature(
- resolveSignature(typeParams, bindingsMap, s.signature)
+ resolveSignature(typeParams, bindingsMap, s.signature),
+ s.comment
)
)
)
diff --git a/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/TypeSignatures.scala b/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/TypeSignatures.scala
index 1d10387eee..eca3016942 100644
--- a/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/TypeSignatures.scala
+++ b/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/TypeSignatures.scala
@@ -97,7 +97,7 @@ case object TypeSignatures extends IRPass {
case _ =>
}
val res = lastSignature match {
- case Some(asc @ Type.Ascription(typed, sig, _, _, _)) =>
+ case Some(asc @ Type.Ascription(typed, sig, comment, _, _, _)) =>
val methodRef = meth.methodReference
val newMethodWithDoc = asc
.getMetadata(DocumentationComments)
@@ -121,7 +121,7 @@ case object TypeSignatures extends IRPass {
if (ref isSameReferenceAs methodRef) {
Some(
newMethodWithAnnotations.updateMetadata(
- new MetadataPair(this, Signature(sig))
+ new MetadataPair(this, Signature(sig, comment))
)
)
} else {
@@ -246,7 +246,9 @@ case object TypeSignatures extends IRPass {
private def resolveAscription(sig: Type.Ascription): Expression = {
val newTyped = sig.typed.mapExpressions(resolveExpression)
val newSig = sig.signature.mapExpressions(resolveExpression)
- newTyped.updateMetadata(new MetadataPair(this, Signature(newSig)))
+ newTyped.updateMetadata(
+ new MetadataPair(this, Signature(newSig, sig.comment))
+ )
}
/** Resolves type signatures in a block.
@@ -271,7 +273,7 @@ case object TypeSignatures extends IRPass {
case binding: Expression.Binding =>
val newBinding = binding.mapExpressions(resolveExpression)
val res = lastSignature match {
- case Some(asc @ Type.Ascription(typed, sig, _, _, _)) =>
+ case Some(asc @ Type.Ascription(typed, sig, comment, _, _, _)) =>
val name = binding.name
val newBindingWithDoc = asc
.getMetadata(DocumentationComments)
@@ -287,7 +289,7 @@ case object TypeSignatures extends IRPass {
if (typedName.name == name.name) {
Some(
newBindingWithDoc.updateMetadata(
- new MetadataPair(this, Signature(sig))
+ new MetadataPair(this, Signature(sig, comment))
)
)
} else {
@@ -321,8 +323,10 @@ case object TypeSignatures extends IRPass {
/** A representation of a type signature.
*
* @param signature the expression for the type signature
+ * @param comment an optional comment from which the potential error message will be derived
*/
- case class Signature(signature: Expression) extends IRPass.IRMetadata {
+ case class Signature(signature: Expression, comment: Option[String] = None)
+ extends IRPass.IRMetadata {
override val metadataName: String = "TypeSignatures.Signature"
/** @inheritdoc */
@@ -345,6 +349,6 @@ case object TypeSignatures extends IRPass {
/** @inheritdoc */
override def duplicate(): Option[IRPass.IRMetadata] =
- Some(this.copy(signature = signature.duplicate()))
+ Some(this.copy(signature = signature.duplicate(), comment = comment))
}
}
diff --git a/engine/runtime-parser/src/main/java/org/enso/compiler/core/TreeToIr.java b/engine/runtime-parser/src/main/java/org/enso/compiler/core/TreeToIr.java
index 0f78bc4055..3f96a90b55 100644
--- a/engine/runtime-parser/src/main/java/org/enso/compiler/core/TreeToIr.java
+++ b/engine/runtime-parser/src/main/java/org/enso/compiler/core/TreeToIr.java
@@ -96,7 +96,7 @@ final class TreeToIr {
methodReference = translateExpression(sig.getVariable());
}
var signature = translateType(sig.getType());
- var ascription = new Type.Ascription(methodReference, signature, getIdentifiedLocation(sig), meta(), diag());
+ var ascription = new Type.Ascription(methodReference, signature, Option.empty(), getIdentifiedLocation(sig), meta(), diag());
yield ascription;
}
default -> translateExpression(exprTree);
@@ -250,7 +250,8 @@ final class TreeToIr {
yield join(error, appendTo);
}
- var ascribedBody = addTypeAscription(body, returnSignature, loc);
+ String functionName = fn.getName().codeRepr();
+ var ascribedBody = addTypeAscription(functionName, body, returnSignature, loc);
var binding = new Method.Binding(
methodRef,
args,
@@ -317,7 +318,7 @@ final class TreeToIr {
case Tree.TypeSignature sig -> {
var methodReference = translateMethodReference(sig.getVariable(), true);
var signature = translateType(sig.getType());
- var ascription = new Type.Ascription(methodReference, signature, getIdentifiedLocation(sig), meta(), diag());
+ var ascription = new Type.Ascription(methodReference, signature, Option.empty(), getIdentifiedLocation(sig), meta(), diag());
yield join(ascription, appendTo);
}
@@ -507,6 +508,7 @@ final class TreeToIr {
var loc = getIdentifiedLocation(fun);
var body = translateExpression(treeBody);
+ String functionName = name.name();
if (args.isEmpty()) {
if (body instanceof Expression.Block block) {
// suspended block has a name and no arguments
@@ -524,14 +526,14 @@ final class TreeToIr {
body = translateSyntaxError(fun, Syntax.UnexpectedExpression$.MODULE$);
}
- var ascribedBody = addTypeAscription(body, returnType, loc);
+ var ascribedBody = addTypeAscription(functionName, body, returnType, loc);
return new Expression.Binding(name, ascribedBody, loc, meta(), diag());
} else {
if (body == null) {
return translateSyntaxError(fun, Syntax.UnexpectedDeclarationInType$.MODULE$);
}
- var ascribedBody = addTypeAscription(body, returnType, loc);
+ var ascribedBody = addTypeAscription(functionName, body, returnType, loc);
return new Function.Binding(name, args, ascribedBody, loc, true, meta(), diag());
}
}
@@ -551,17 +553,18 @@ final class TreeToIr {
*
* If the type is {@code null}, the body is returned unchanged.
*/
- private Expression addTypeAscription(Expression body, Expression type, Option loc) {
+ private Expression addTypeAscription(String functionName, Expression body, Expression type, Option loc) {
if (type == null) {
return body;
}
- return new Type.Ascription(body, type, loc, meta(), diag());
+ String comment = "the result of `" + functionName + "`";
+ return new Type.Ascription(body, type, Option.apply(comment), loc, meta(), diag());
}
private Type.Ascription translateTypeSignature(Tree sig, Tree type, Expression typeName) {
var fn = translateType(type);
- return new Type.Ascription(typeName, fn, getIdentifiedLocation(sig), meta(), diag());
+ return new Type.Ascription(typeName, fn, Option.empty(), getIdentifiedLocation(sig), meta(), diag());
}
diff --git a/engine/runtime-parser/src/main/scala/org/enso/compiler/core/ir/Type.scala b/engine/runtime-parser/src/main/scala/org/enso/compiler/core/ir/Type.scala
index 6b79b44a77..28c94690e4 100644
--- a/engine/runtime-parser/src/main/scala/org/enso/compiler/core/ir/Type.scala
+++ b/engine/runtime-parser/src/main/scala/org/enso/compiler/core/ir/Type.scala
@@ -122,6 +122,7 @@ object Type {
*
* @param typed the expression being ascribed a type
* @param signature the signature being ascribed to `typed`
+ * @param comment a comment that may be used to add context to the type error
* @param location the source location that the node corresponds to
* @param passData the pass metadata associated with this node
* @param diagnostics compiler diagnostics for this node
@@ -129,6 +130,7 @@ object Type {
sealed case class Ascription(
typed: Expression,
signature: Expression,
+ comment: Option[String],
override val location: Option[IdentifiedLocation],
override val passData: MetadataStorage = new MetadataStorage(),
override val diagnostics: DiagnosticStorage = DiagnosticStorage()
@@ -141,6 +143,7 @@ object Type {
*
* @param typed the expression being ascribed a type
* @param signature the signature being ascribed to `typed`
+ * @param comment a comment that may be used to add context to the type error
* @param location the source location that the node corresponds to
* @param passData the pass metadata associated with this node
* @param diagnostics compiler diagnostics for this node
@@ -150,12 +153,14 @@ object Type {
def copy(
typed: Expression = typed,
signature: Expression = signature,
+ comment: Option[String] = comment,
location: Option[IdentifiedLocation] = location,
passData: MetadataStorage = passData,
diagnostics: DiagnosticStorage = diagnostics,
id: UUID @Identifier = id
): Ascription = {
- val res = Ascription(typed, signature, location, passData, diagnostics)
+ val res =
+ Ascription(typed, signature, comment, location, passData, diagnostics)
res.id = id
res
}
@@ -205,6 +210,7 @@ object Type {
s"""Type.Ascription(
|typed = $typed,
|signature = $signature,
+ |comment = $comment,
|location = $location,
|passData = ${this.showPassData},
|diagnostics = $diagnostics,
diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/callable/argument/ReadArgumentCheckNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/callable/argument/ReadArgumentCheckNode.java
index 86e203cb18..17dcbf79eb 100644
--- a/engine/runtime/src/main/java/org/enso/interpreter/node/callable/argument/ReadArgumentCheckNode.java
+++ b/engine/runtime/src/main/java/org/enso/interpreter/node/callable/argument/ReadArgumentCheckNode.java
@@ -19,7 +19,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import org.enso.compiler.core.ir.Name;
import org.enso.interpreter.EnsoLanguage;
import org.enso.interpreter.node.BaseNode.TailStatus;
import org.enso.interpreter.node.EnsoRootNode;
@@ -49,11 +48,11 @@ import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
import org.graalvm.collections.Pair;
public abstract class ReadArgumentCheckNode extends Node {
- private final String name;
+ private final String comment;
@CompilerDirectives.CompilationFinal private String expectedTypeMessage;
- ReadArgumentCheckNode(String name) {
- this.name = name;
+ ReadArgumentCheckNode(String comment) {
+ this.comment = comment;
}
/** */
@@ -62,7 +61,7 @@ public abstract class ReadArgumentCheckNode extends Node {
}
/**
- * Executes check or conversion of the value.abstract
+ * Executes check or conversion of the value.
*
* @param frame frame requesting the conversion
* @param value the value to convert
@@ -89,12 +88,12 @@ public abstract class ReadArgumentCheckNode extends Node {
expectedTypeMessage = expectedTypeMessage();
}
var ctx = EnsoContext.get(this);
- var msg = name == null ? "expression" : name;
- var err = ctx.getBuiltins().error().makeTypeError(expectedTypeMessage, v, msg);
+ var msg = comment == null ? "expression" : comment;
+ var err = ctx.getBuiltins().error().makeTypeErrorOfComment(expectedTypeMessage, v, msg);
throw new PanicException(err, this);
}
- public static ReadArgumentCheckNode allOf(Name argumentName, ReadArgumentCheckNode... checks) {
+ public static ReadArgumentCheckNode allOf(String argumentName, ReadArgumentCheckNode... checks) {
var list = Arrays.asList(checks);
var flatten =
list.stream()
@@ -105,27 +104,25 @@ public abstract class ReadArgumentCheckNode extends Node {
return switch (arr.length) {
case 0 -> null;
case 1 -> arr[0];
- default -> new AllOfNode(argumentName.name(), arr);
+ default -> new AllOfNode(argumentName, arr);
};
}
- public static ReadArgumentCheckNode oneOf(Name argumentName, List checks) {
+ public static ReadArgumentCheckNode oneOf(String comment, List checks) {
var arr = toArray(checks);
return switch (arr.length) {
case 0 -> null;
case 1 -> arr[0];
- default -> new OneOfNode(argumentName.name(), arr);
+ default -> new OneOfNode(comment, arr);
};
}
- public static ReadArgumentCheckNode build(Name argumentName, Type expectedType) {
- var n = argumentName == null ? null : argumentName.name();
- return ReadArgumentCheckNodeFactory.TypeCheckNodeGen.create(n, expectedType);
+ public static ReadArgumentCheckNode build(String comment, Type expectedType) {
+ return ReadArgumentCheckNodeFactory.TypeCheckNodeGen.create(comment, expectedType);
}
- public static ReadArgumentCheckNode meta(Name argumentName, Object metaObject) {
- var n = argumentName == null ? null : argumentName.name();
- return ReadArgumentCheckNodeFactory.MetaCheckNodeGen.create(n, metaObject);
+ public static ReadArgumentCheckNode meta(String comment, Object metaObject) {
+ return ReadArgumentCheckNodeFactory.MetaCheckNodeGen.create(comment, metaObject);
}
public static boolean isWrappedThunk(Function fn) {
diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/TypeError.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/TypeError.java
index e49ff6999a..54c84a6ac1 100644
--- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/TypeError.java
+++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/TypeError.java
@@ -13,6 +13,6 @@ public class TypeError extends UniquelyConstructibleBuiltin {
@Override
protected List getConstructorParamNames() {
- return List.of("expected", "actual", "name");
+ return List.of("expected", "actual", "comment");
}
}
diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/Error.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/Error.java
index fb2798e001..783dff4ee7 100644
--- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/Error.java
+++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/Error.java
@@ -176,11 +176,24 @@ public final class Error {
*
* @param expected the expected type
* @param actual the actual type
- * @param name the name of the variable that is a type error
+ * @param name name of the argument that was being checked
* @return a runtime representation of the error.
*/
+ @CompilerDirectives.TruffleBoundary
public Atom makeTypeError(Object expected, Object actual, String name) {
- return typeError.newInstance(expected, actual, Text.create(name));
+ return typeError.newInstance(expected, actual, Text.create("`" + name + "`"));
+ }
+
+ /**
+ * Creates an instance of the runtime representation of a {@code Type_Error}.
+ *
+ * @param expected the expected type
+ * @param actual the actual type
+ * @param comment description of the value that was being checked
+ * @return a runtime representation of the error.
+ */
+ public Atom makeTypeErrorOfComment(Object expected, Object actual, String comment) {
+ return typeError.newInstance(expected, actual, Text.create(comment));
}
/**
diff --git a/engine/runtime/src/main/scala/org/enso/interpreter/runtime/IrToTruffle.scala b/engine/runtime/src/main/scala/org/enso/interpreter/runtime/IrToTruffle.scala
index 0b2bbb4577..aa2bd354a9 100644
--- a/engine/runtime/src/main/scala/org/enso/interpreter/runtime/IrToTruffle.scala
+++ b/engine/runtime/src/main/scala/org/enso/interpreter/runtime/IrToTruffle.scala
@@ -713,24 +713,24 @@ class IrToTruffle(
// ==========================================================================
private def extractAscribedType(
- name: Name,
+ comment: String,
t: Expression
): ReadArgumentCheckNode = t match {
case u: `type`.Set.Union =>
ReadArgumentCheckNode.oneOf(
- name,
- u.operands.map(extractAscribedType(name, _)).asJava
+ comment,
+ u.operands.map(extractAscribedType(comment, _)).asJava
)
case i: `type`.Set.Intersection =>
ReadArgumentCheckNode.allOf(
- name,
- extractAscribedType(name, i.left),
- extractAscribedType(name, i.right)
+ comment,
+ extractAscribedType(comment, i.left),
+ extractAscribedType(comment, i.right)
)
- case p: Application.Prefix => extractAscribedType(name, p.function)
+ case p: Application.Prefix => extractAscribedType(comment, p.function)
case _: Tpe.Function =>
ReadArgumentCheckNode.build(
- name,
+ comment,
context.getTopScope().getBuiltins().function()
)
case t => {
@@ -740,7 +740,7 @@ class IrToTruffle(
.Resolution(BindingsMap.ResolvedType(mod, tpe))
) =>
ReadArgumentCheckNode.build(
- name,
+ comment,
asScope(
mod
.unsafeAsModule()
@@ -753,7 +753,7 @@ class IrToTruffle(
.Resolution(BindingsMap.ResolvedPolyglotSymbol(mod, symbol))
) =>
ReadArgumentCheckNode.meta(
- name,
+ comment,
asScope(
mod
.unsafeAsModule()
@@ -768,7 +768,8 @@ class IrToTruffle(
private def checkAsTypes(
arg: DefinitionArgument
): ReadArgumentCheckNode = {
- arg.ascribedType.map(extractAscribedType(arg.name, _)).getOrElse(null)
+ val comment = "`" + arg.name.name + "`"
+ arg.ascribedType.map(extractAscribedType(comment, _)).getOrElse(null)
}
/** Checks if the expression has a @Builtin_Method annotation
@@ -1074,9 +1075,11 @@ class IrToTruffle(
ir match {
case _: Expression.Binding =>
case _ =>
- val types = ir.getMetadata(TypeSignatures)
+ val types: Option[TypeSignatures.Signature] =
+ ir.getMetadata(TypeSignatures)
types.foreach { tpe =>
- val checkNode = extractAscribedType(null, tpe.signature);
+ val checkNode =
+ extractAscribedType(tpe.comment.orNull, tpe.signature);
if (checkNode != null) {
runtimeExpression =
ReadArgumentCheckNode.wrap(runtimeExpression, checkNode)
diff --git a/engine/runtime/src/test/java/org/enso/interpreter/test/SignaturePolyglotTest.java b/engine/runtime/src/test/java/org/enso/interpreter/test/SignaturePolyglotTest.java
index e56e46d9d5..9e8ba06ab2 100644
--- a/engine/runtime/src/test/java/org/enso/interpreter/test/SignaturePolyglotTest.java
+++ b/engine/runtime/src/test/java/org/enso/interpreter/test/SignaturePolyglotTest.java
@@ -66,7 +66,8 @@ public class SignaturePolyglotTest extends TestBase {
var ret = fn.execute(new StringBuilder("Hi"));
fail("Should fail, but got: " + ret);
} catch (PolyglotException e) {
- assertTypeError("`x`", "java.time.format.DateTimeFormatter", "StringBuilder", e.getMessage());
+ assertTypeError(
+ "`x`", "java.time.format.DateTimeFormatter", "java.lang.StringBuilder", e.getMessage());
}
}
diff --git a/engine/runtime/src/test/java/org/enso/interpreter/test/SignatureTest.java b/engine/runtime/src/test/java/org/enso/interpreter/test/SignatureTest.java
index 808b072f72..9cf7c20070 100644
--- a/engine/runtime/src/test/java/org/enso/interpreter/test/SignatureTest.java
+++ b/engine/runtime/src/test/java/org/enso/interpreter/test/SignatureTest.java
@@ -506,7 +506,7 @@ public class SignatureTest extends TestBase {
var v = module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "Bin.Zero One");
fail("Expecting an error, not " + v);
} catch (PolyglotException ex) {
- assertTypeError("`v`", "Zero", "Zero", ex.getMessage());
+ assertTypeError("`v`", "Zero", "One", ex.getMessage());
}
}
@@ -639,7 +639,7 @@ public class SignatureTest extends TestBase {
var v = module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "Bin.Vec 'Hi'");
fail("Expecting an error, not " + v);
} catch (PolyglotException ex) {
- assertTypeError("`v`", "Integer | Range | Vector", "Integer", ex.getMessage());
+ assertTypeError("`v`", "Integer | Range | Vector", "Text", ex.getMessage());
}
var ok2 = module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "Bin.Either Zero");
assertEquals("binary.Bin", ok2.getMetaObject().getMetaQualifiedName());
@@ -872,7 +872,8 @@ public class SignatureTest extends TestBase {
var res = plusChecked.execute("a", "b");
fail("Expecting an exception, not: " + res);
} catch (PolyglotException e) {
- assertContains("expected `expression` to be Integer, but got Text", e.getMessage());
+ assertContains(
+ "expected the result of `plusChecked` to be Integer, but got Text", e.getMessage());
}
}
@@ -923,7 +924,8 @@ public class SignatureTest extends TestBase {
var res = plusChecked.execute(2, 3);
fail("Expecting an exception, not: " + res);
} catch (PolyglotException e) {
- assertContains("expected `expression` to be Integer, but got Text", e.getMessage());
+ assertContains(
+ "expected the result of `constant` to be Integer, but got Text", e.getMessage());
}
}
@@ -944,13 +946,13 @@ public class SignatureTest extends TestBase {
.buildLiteral();
var module = ctx.eval(src);
- var plusChecked = module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "foo");
- assertEquals(8, plusChecked.execute(2).asInt());
+ var foo = module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "foo");
+ assertEquals(8, foo.execute(2).asInt());
try {
- var res = plusChecked.execute(".");
+ var res = foo.execute(".");
fail("Expecting an exception, not: " + res);
} catch (PolyglotException e) {
- assertContains("expected `expression` to be Integer, but got Text", e.getMessage());
+ assertContains("expected the result of `x` to be Integer, but got Text", e.getMessage());
}
}
@@ -978,7 +980,7 @@ public class SignatureTest extends TestBase {
var res = plusChecked.execute(".");
fail("Expecting an exception, not: " + res);
} catch (PolyglotException e) {
- assertContains("expected `expression` to be Integer, but got Text", e.getMessage());
+ assertContains("expected the result of `x` to be Integer, but got Text", e.getMessage());
}
}
@@ -1008,7 +1010,7 @@ public class SignatureTest extends TestBase {
var res = foo.execute(2);
fail("Expecting an exception, not: " + res);
} catch (PolyglotException e) {
- assertContains("expected `expression` to be Integer, but got Text", e.getMessage());
+ assertContains("expected the result of `foo` to be Integer, but got Text", e.getMessage());
}
var res = foo.execute(3);
@@ -1043,8 +1045,7 @@ public class SignatureTest extends TestBase {
var res = factorial.execute(20);
fail("Expecting an exception, not: " + res);
} catch (PolyglotException e) {
- // TODO we may want to change `expression` to 'the return type' or something
- assertContains("expected `expression` to be Integer, but got Text", e.getMessage());
+ assertContains("expected the result of `go` to be Integer, but got Text", e.getMessage());
}
}
@@ -1080,7 +1081,7 @@ public class SignatureTest extends TestBase {
var res = foo.execute(n, 1);
fail("Expecting an exception, not: " + res);
} catch (PolyglotException e) {
- assertContains("expected `expression` to be Integer, but got Text", e.getMessage());
+ assertContains("expected the result of `go` to be Integer, but got Text", e.getMessage());
}
}
@@ -1113,20 +1114,16 @@ public class SignatureTest extends TestBase {
var res = foo_bad.execute(n);
fail("Expecting an exception, not: " + res);
} catch (PolyglotException e) {
- assertContains("expected `expression` to be Integer, but got Text", e.getMessage());
+ assertEquals(
+ "Type error: expected the result of `foo_bad` to be Integer, but got Text.",
+ e.getMessage());
}
}
static void assertTypeError(String expArg, String expType, String realType, String msg) {
- if (!msg.contains(expArg)) {
- fail("Expecting value " + expArg + " in " + msg);
- }
- if (!msg.contains(expType)) {
- fail("Expecting value " + expType + " in " + msg);
- }
- if (!msg.contains(realType)) {
- fail("Expecting value " + realType + " in " + msg);
- }
+ assertEquals(
+ "Type error: expected " + expArg + " to be " + expType + ", but got " + realType + ".",
+ msg);
}
private static void assertContains(String exp, String msg) {
diff --git a/engine/runtime/src/test/scala/org/enso/interpreter/test/semantic/TextTest.scala b/engine/runtime/src/test/scala/org/enso/interpreter/test/semantic/TextTest.scala
index b18dc73ce1..b405e7cd56 100644
--- a/engine/runtime/src/test/scala/org/enso/interpreter/test/semantic/TextTest.scala
+++ b/engine/runtime/src/test/scala/org/enso/interpreter/test/semantic/TextTest.scala
@@ -117,7 +117,7 @@ class TextTest extends InterpreterTest {
|main =
| IO.println (List.Cons Nothing Nothing).to_display_text
| IO.println (Syntax_Error.Error "foo").to_display_text
- | IO.println (Type_Error.Error Nothing List.Nil "myvar").to_display_text
+ | IO.println (Type_Error.Error Nothing List.Nil "`myvar`").to_display_text
| IO.println (Compile_Error.Error "error :(").to_display_text
| IO.println (Inexhaustive_Pattern_Match.Error 32).to_display_text
| IO.println (Arithmetic_Error.Error "cannot frobnicate quaternions").to_display_text
diff --git a/test/micro-distribution/lib/Standard/Base/0.0.0-dev/src/Errors/Common.enso b/test/micro-distribution/lib/Standard/Base/0.0.0-dev/src/Errors/Common.enso
index 205a654c70..9ba09260e4 100644
--- a/test/micro-distribution/lib/Standard/Base/0.0.0-dev/src/Errors/Common.enso
+++ b/test/micro-distribution/lib/Standard/Base/0.0.0-dev/src/Errors/Common.enso
@@ -17,13 +17,13 @@ type Arithmetic_Error
@Builtin_Type
type Type_Error
- Error expected actual name
+ Error expected actual comment
type_of_actual self =
tpe = Meta.type_of self.actual
if tpe.is_error then self.actual.to_display_text else tpe.to_display_text
- to_display_text self = "Type error: expected `"+self.name+"` to be "+self.expected.to_display_text+", but got "+self.type_of_actual+"."
+ to_display_text self = "Type error: expected "+self.comment+" to be "+self.expected.to_display_text+", but got "+self.type_of_actual+"."
@Builtin_Type
type Not_Invokable