diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/RedefinedConstructorException.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/RedefinedConstructorException.java new file mode 100644 index 000000000000..51e4859fb9a6 --- /dev/null +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/RedefinedConstructorException.java @@ -0,0 +1,17 @@ +package org.enso.interpreter.runtime.error; + +import com.oracle.truffle.api.exception.AbstractTruffleException; +import org.enso.interpreter.runtime.Module; + +/** An exception thrown when the program tries to redefine an already-defined constructor */ +public class RedefinedConstructorException extends AbstractTruffleException { + + /** + * Creates a new error. + * + * @param atom the method of the atom on which {@code method} is being defined + */ + public RedefinedConstructorException(String atom, Module scope) { + super("Constructors cannot be overloaded, but you have tried to overload " + atom + " in scope " + scope.getName()); + } +} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/ModuleScope.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/ModuleScope.java index 88a5194da210..ad52574e7202 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/ModuleScope.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/ModuleScope.java @@ -8,6 +8,7 @@ import org.enso.interpreter.runtime.Module; import org.enso.interpreter.runtime.callable.atom.AtomConstructor; import org.enso.interpreter.runtime.callable.function.Function; +import org.enso.interpreter.runtime.error.RedefinedConstructorException; import org.enso.interpreter.runtime.error.RedefinedMethodException; import org.enso.interpreter.runtime.error.RedefinedConversionException; @@ -38,9 +39,17 @@ public ModuleScope(Module module) { * @param constructor the constructor to register */ public void registerConstructor(AtomConstructor constructor) { + var name = constructor.getName(); + if (constructors.containsKey(name)) + throw new RedefinedConstructorException(name, module); + constructors.put(name, constructor); + } + + public void forciblyRegisterConstructor(AtomConstructor constructor) { constructors.put(constructor.getName(), constructor); } + /** @return the associated type of this module. */ public AtomConstructor getAssociatedType() { return associatedType; diff --git a/engine/runtime/src/main/scala/org/enso/compiler/codegen/RuntimeStubsGenerator.scala b/engine/runtime/src/main/scala/org/enso/compiler/codegen/RuntimeStubsGenerator.scala index 4c023e7695f8..0c447691a78e 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/codegen/RuntimeStubsGenerator.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/codegen/RuntimeStubsGenerator.scala @@ -23,13 +23,13 @@ class RuntimeStubsGenerator(builtins: Builtins) { BindingAnalysis, "Non-parsed module used in stubs generator" ) - val constructors = localBindings.constructors.map { tp => + val constructors = localBindings.constructors./*distinctBy(_.name). */map { tp => if (tp.builtinType) { val builtinType = builtins.getBuiltinType(tp.name) if (builtinType == null) { throw new CompilerError("Unknown @BuiltinType " + tp.name) } - scope.registerConstructor(builtinType) + scope.forciblyRegisterConstructor(builtinType) builtinType.setShadowDefinitions(scope) (tp, builtinType) } else { diff --git a/engine/runtime/src/main/scala/org/enso/compiler/context/SuggestionBuilder.scala b/engine/runtime/src/main/scala/org/enso/compiler/context/SuggestionBuilder.scala index ddb67363a1ef..fa5f5b978a4d 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/context/SuggestionBuilder.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/context/SuggestionBuilder.scala @@ -344,6 +344,13 @@ final class SuggestionBuilder[A: IndexedSource](val source: A) { } } + /** Resolve a name to either an explicit sum type or a simple TypeArg. Used to link + * suggestions to concrete types, so the editor can know a fully qualified + * type name if possible. + * + * @param resolvedName the name to resolve + * @return how to present it to the suggestion engine + */ private def buildResolvedUnionTypeName( resolvedName: BindingsMap.ResolvedName ): Option[TypeArg] = resolvedName match {