Closed radeusgd closed 10 months ago
I have a fix that properly reports the error from CLI. I am struggling to write a test in "IDE mode" - e.g. strict.errors=false
. I am afraid my idea to associate the error with Argument.defaultValue
neither Argument.ascribedType
isn't that great idea. Any advices @Akirathan or @hubertp?
diff --git engine/runtime-parser/src/main/scala/org/enso/compiler/core/ir/expression/errors/Redefined.scala engine/runtime-parser/src/main/scala/org/enso/compiler/core/ir/expression/errors/Redefined.scala
index 066711d86b..1e4739905c 100644
--- engine/runtime-parser/src/main/scala/org/enso/compiler/core/ir/expression/errors/Redefined.scala
+++ engine/runtime-parser/src/main/scala/org/enso/compiler/core/ir/expression/errors/Redefined.scala
@@ -564,6 +564,104 @@ object Redefined {
s"(Redefined (Atom $typeName))"
}
+ /** An error representing the redefinition of an atom in a given module.
+ *
+ * @param name the name of the atom being redefined
+ * @param location the location in the source to which this error
+ * corresponds
+ * @param passData the pass metadata for the error
+ * @param diagnostics any diagnostics associated with this error.
+ */
+ sealed case class Arg(
+ name: Name,
+ override val location: Option[IdentifiedLocation],
+ override val passData: MetadataStorage = MetadataStorage(),
+ override val diagnostics: DiagnosticStorage = DiagnosticStorage()
+ ) extends Redefined
+ with Diagnostic.Kind.Interactive
+ with module.scope.Definition
+ with IRKind.Primitive {
+ override protected var id: Identifier = randomId
+
+ /** Creates a copy of `this`.
+ *
+ * @param name the name of the atom the method was being redefined
+ * on
+ * @param location the location in the source to which this error
+ * corresponds
+ * @param passData the pass metadata for the error
+ * @param diagnostics any diagnostics associated with this error.
+ * @param id the identifier for the node
+ * @return a copy of `this`, updated with the specified values
+ */
+ def copy(
+ name: Name = name,
+ location: Option[IdentifiedLocation] = location,
+ passData: MetadataStorage = passData,
+ diagnostics: DiagnosticStorage = diagnostics,
+ id: Identifier = id
+ ): Arg = {
+ val res =
+ Arg(name, location, passData, diagnostics)
+ res.id = id
+ res
+ }
+
+ /** @inheritdoc */
+ override def duplicate(
+ keepLocations: Boolean = true,
+ keepMetadata: Boolean = true,
+ keepDiagnostics: Boolean = true,
+ keepIdentifiers: Boolean = false
+ ): Arg =
+ copy(
+ name = name.duplicate(
+ keepLocations,
+ keepMetadata,
+ keepDiagnostics,
+ keepIdentifiers
+ ),
+ location = if (keepLocations) location else None,
+ passData = if (keepMetadata) passData.duplicate else MetadataStorage(),
+ diagnostics =
+ if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
+ id = if (keepIdentifiers) id else randomId
+ )
+
+ /** @inheritdoc */
+ override def setLocation(location: Option[IdentifiedLocation]): Arg =
+ copy(location = location)
+
+ /** @inheritdoc */
+ override def message(source: Source): String =
+ s"Redefining arguments is not supported: ${name.name} is " +
+ s"defined multiple times."
+
+ override def diagnosticKeys(): Array[Any] = Array(name.name)
+
+ /** @inheritdoc */
+ override def mapExpressions(fn: Expression => Expression): Arg = this
+
+ /** @inheritdoc */
+ override def toString: String =
+ s"""
+ |Error.Redefined.Arg(
+ |name = $name,
+ |location = $location,
+ |passData = ${this.showPassData},
+ |diagnostics = $diagnostics,
+ |id = $id
+ |)
+ |""".stripMargin
+
+ /** @inheritdoc */
+ override def children: List[IR] = List(name)
+
+ /** @inheritdoc */
+ override def showCode(indent: Int): String =
+ s"(Redefined (Argument $name))"
+ }
+
/** An error representing the redefinition of a binding in a given scope.
*
* While bindings in child scopes are allowed to _shadow_ bindings in
diff --git engine/runtime/src/main/scala/org/enso/compiler/codegen/IrToTruffle.scala engine/runtime/src/main/scala/org/enso/compiler/codegen/IrToTruffle.scala
index 9ec93d7350..39e61b35fd 100644
--- engine/runtime/src/main/scala/org/enso/compiler/codegen/IrToTruffle.scala
+++ engine/runtime/src/main/scala/org/enso/compiler/codegen/IrToTruffle.scala
@@ -1764,6 +1764,10 @@ class IrToTruffle(
context.getBuiltins
.error()
.makeCompileError(Text.create(err.message(source)))
+ case err: errors.Redefined.Arg =>
+ context.getBuiltins
+ .error()
+ .makeCompileError(Text.create(err.message(source)))
case err: errors.Unexpected.TypeSignature =>
context.getBuiltins
.error()
diff --git engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/AliasAnalysis.scala engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/AliasAnalysis.scala
index 21e43a6a38..19deb594d0 100644
--- engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/AliasAnalysis.scala
+++ engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/AliasAnalysis.scala
@@ -26,6 +26,7 @@ import org.enso.compiler.core.ir.expression.{
Operator,
Section
}
+import org.enso.compiler.core.ir.expression.errors.Redefined
import org.enso.compiler.core.ir.`type`
import org.enso.compiler.pass.IRPass
import org.enso.compiler.pass.analyse.AliasAnalysis.Graph.{Occurrence, Scope}
@@ -554,12 +555,13 @@ case object AliasAnalysis extends IRPass {
)
.updateMetadata(this -->> Info.Occurrence(graph, occurrenceId))
} else {
- throw new CompilerError(
- s"""
- Arguments should never be redefined. This is a bug.
- ${}
- """
+ val f = scope.occurrences.collectFirst {
+ case x if x.symbol == name.name => x
+ }
+ arg.copy(
+ ascribedType = Some(new Redefined.Arg(name, arg.location))
)
+ .updateMetadata(this -->> Info.Occurrence(graph, f.get.id))
}
}
}
diff --git engine/runtime/src/test/java/org/enso/compiler/ExecCompilerTest.java engine/runtime/src/test/java/org/enso/compiler/ExecCompilerTest.java
index a41d9ffdc1..5865b038f6 100644
--- engine/runtime/src/test/java/org/enso/compiler/ExecCompilerTest.java
+++ engine/runtime/src/test/java/org/enso/compiler/ExecCompilerTest.java
@@ -72,6 +72,17 @@ public class ExecCompilerTest {
}
}
+ @Test
+ public void redefinedArgument() throws Exception {
+ var module = ctx.eval("enso", """
+ type My_Type
+ Value a b c a
+ """);
+ var run = module.invokeMember("eval_expression", "My_Type.Value");
+ var error = run.newInstance(1, 2, 3, 4);
+ assertTrue("We get an error value back: " + error, error.isException());
+ }
+
@Test
public void testSelfAssignment() throws Exception {
var module = ctx.eval("enso", """
@JaroslavTulach
I wouldn't put this IR error into ascribedType
field, but rather add it as a diagnostic, like so:
diff --git a/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/AliasAnalysis.scala b/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/AliasAnalysis.scala
index 21e43a6a3..e18285cda 100644
--- a/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/AliasAnalysis.scala
+++ b/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/AliasAnalysis.scala
@@ -26,6 +26,7 @@ import org.enso.compiler.core.ir.expression.{
Operator,
Section
}
+import org.enso.compiler.core.ir.expression.errors.Redefined
import org.enso.compiler.core.ir.`type`
import org.enso.compiler.pass.IRPass
import org.enso.compiler.pass.analyse.AliasAnalysis.Graph.{Occurrence, Scope}
@@ -554,11 +555,8 @@ case object AliasAnalysis extends IRPass {
)
.updateMetadata(this -->> Info.Occurrence(graph, occurrenceId))
} else {
- throw new CompilerError(
- s"""
- Arguments should never be redefined. This is a bug.
- ${}
- """
+ arg.copy().addDiagnostic(
+ Redefined.Arg(name, arg.location)
)
}
}
Jaroslav Tulach reports a new STANDUP for yesterday (2023-12-01):
Progress: - #7962 fixed by PR: https://github.com/enso-org/enso/pull/8438
Next Day: Bugfix something
DiscordDiscord is the easiest way to communicate over voice, video, and text. Chat, hang out, and stay close with your friends and communities.
Repro:
Actual behaviour
Compiler crash exposing an internal error, impossible to locate which part of the codebase the error refers to without running with a debugger
Expected behaviour
A friendly error like a syntax error telling the user about a duplicate definition and location of the issue (file, line number), like in most errors.