diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Meta.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Meta.enso index 119135d38c9c1..ae4b2b49d8c51 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Meta.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Meta.enso @@ -319,9 +319,9 @@ is_a value typ = if is_same_object value typ then True else if is_error value then typ == Base.Error else case value of _ : Vector.Vector -> typ.is_same_object_as Vector.Vector - _ : Array -> typ.is_same_object_as Base.Array - _ : Boolean -> if typ.is_same_object_as Base.Boolean then True else value.is_same_object_as typ - _ : Text -> typ.is_same_object_as Base.Text + _ : Array -> typ == Base.Array + _ : Boolean -> if typ == Base.Boolean then True else value == typ + _ : Text -> typ == Base.Text _ : Number -> if typ == Base.Number then True else case value of _ : Integer -> typ == Base.Integer _ : Decimal -> typ == Base.Decimal diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/controlflow/caseexpr/CatchTypeBranchNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/controlflow/caseexpr/CatchTypeBranchNode.java index fc1ee4a547291..98c93512cd422 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/controlflow/caseexpr/CatchTypeBranchNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/controlflow/caseexpr/CatchTypeBranchNode.java @@ -21,7 +21,7 @@ public abstract class CatchTypeBranchNode extends BranchNode { private final Type expectedType; - private final boolean isArrayExepctedType; + private final boolean isArrayType; private @Child TypeOfNode typeOfNode = TypeOfNode.build(); private @Child IsSameObjectNode isSameObject = IsSameObjectNode.build(); private final ConditionProfile profile = ConditionProfile.createCountingProfile(); @@ -29,7 +29,7 @@ public abstract class CatchTypeBranchNode extends BranchNode { CatchTypeBranchNode(Type tpe, RootCallTarget functionNode) { super(functionNode); this.expectedType = tpe; - this.isArrayExepctedType = Context.get(this).getBuiltins().array() == tpe; + this.isArrayType = Context.get(this).getBuiltins().array() == expectedType; } /** @@ -45,7 +45,7 @@ public static CatchTypeBranchNode build(Type tpe, RootCallTarget functionNode) { @Specialization( guards = { - "isArrayExepctedType()", + "isArrayExpectedType()", "interop.hasArrayElements(value)", "!types.hasType(value)", "interop.hasMetaObject(value)" @@ -59,8 +59,8 @@ public void doPolyglotArray( accept(frame, state, new Object[] {value}); } - boolean isArrayExepctedType() { - return isArrayExepctedType; + boolean isArrayExpectedType() { + return isArrayType; } @Specialization diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/controlflow/caseexpr/CatchPolyglotSymbolTypeBranchNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/controlflow/caseexpr/PolyglotSymbolTypeBranchNode.java similarity index 88% rename from engine/runtime/src/main/java/org/enso/interpreter/node/controlflow/caseexpr/CatchPolyglotSymbolTypeBranchNode.java rename to engine/runtime/src/main/java/org/enso/interpreter/node/controlflow/caseexpr/PolyglotSymbolTypeBranchNode.java index 9502a09fbca3e..ee581773a479d 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/controlflow/caseexpr/CatchPolyglotSymbolTypeBranchNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/controlflow/caseexpr/PolyglotSymbolTypeBranchNode.java @@ -19,7 +19,7 @@ /** An implementation of the case expression specialised to working on polyglot types. */ @NodeInfo(shortName = "PolyglotSymbolTypeMatch") -public abstract class CatchPolyglotSymbolTypeBranchNode extends BranchNode { +public abstract class PolyglotSymbolTypeBranchNode extends BranchNode { private final Object polyglotSymbol; private @Child TypeOfNode typeOfNode = TypeOfNode.build(); @@ -27,9 +27,9 @@ public abstract class CatchPolyglotSymbolTypeBranchNode extends BranchNode { private final ConditionProfile profile = ConditionProfile.createCountingProfile(); private final ConditionProfile subtypeProfile = ConditionProfile.createCountingProfile(); - CatchPolyglotSymbolTypeBranchNode(Object polyglotSymbolName, RootCallTarget functionNode) { + PolyglotSymbolTypeBranchNode(Object polyglotSymbol, RootCallTarget functionNode) { super(functionNode); - this.polyglotSymbol = polyglotSymbolName; + this.polyglotSymbol = polyglotSymbol; } /** @@ -39,9 +39,9 @@ public abstract class CatchPolyglotSymbolTypeBranchNode extends BranchNode { * @param functionNode the function to execute in this case * @return a catch-all node */ - public static CatchPolyglotSymbolTypeBranchNode build( + public static PolyglotSymbolTypeBranchNode build( Object polyglotSymbol, RootCallTarget functionNode) { - return CatchPolyglotSymbolTypeBranchNodeGen.create(polyglotSymbol, functionNode); + return PolyglotSymbolTypeBranchNodeGen.create(polyglotSymbol, functionNode); } @Specialization diff --git a/engine/runtime/src/main/scala/org/enso/compiler/codegen/IrToTruffle.scala b/engine/runtime/src/main/scala/org/enso/compiler/codegen/IrToTruffle.scala index 050135088f155..4be60b61ea2de 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/codegen/IrToTruffle.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/codegen/IrToTruffle.scala @@ -1087,39 +1087,38 @@ class IrToTruffle( BindingsMap.ResolvedPolyglotSymbol(mod, symbol) ) ) => - Option( + val polySymbol = mod .unsafeAsModule() .getScope .getPolyglotSymbols .get(symbol.name) - ) match { - case Some(polySymbol) => - val argOfType = List( - IR.DefinitionArgument.Specified( - varName, - None, - None, - suspended = false, - location, - passData = varName.passData, - diagnostics = varName.diagnostics - ) + if (polySymbol != null) { + val argOfType = List( + IR.DefinitionArgument.Specified( + varName, + None, + None, + suspended = false, + location, + passData = varName.passData, + diagnostics = varName.diagnostics ) + ) - val branchCodeNode = childProcessor.processFunctionBody( - argOfType, - branch.expression, - branch.location - ) - Right( - CatchPolyglotSymbolTypeBranchNode.build( - polySymbol, - branchCodeNode.getCallTarget - ) + val branchCodeNode = childProcessor.processFunctionBody( + argOfType, + branch.expression, + branch.location + ) + Right( + PolyglotSymbolTypeBranchNode.build( + polySymbol, + branchCodeNode.getCallTarget ) - case None => - Left(BadPatternMatch.NonVisiblePolyglotSymbol(tpeName.name)) + ) + } else { + Left(BadPatternMatch.NonVisiblePolyglotSymbol(tpeName.name)) } case Some(BindingsMap.Resolution(resolved)) => throw new CompilerError( diff --git a/engine/runtime/src/main/scala/org/enso/compiler/core/IR.scala b/engine/runtime/src/main/scala/org/enso/compiler/core/IR.scala index 45bfc2c1047ae..b86dbfe02c6c7 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/core/IR.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/core/IR.scala @@ -6186,7 +6186,7 @@ object IR { * * A type pattern matches on types. Type pattern is composed of two parts: * - a single identifier (e.g. `a` or `_`) - * - a fully qualified type name + * - a (potentially fully qualified) type name * E.g., `a : Foo -> ...` or `_ : Bar -> ...`` * * @param name the name of the bound variable, or wildcard diff --git a/engine/runtime/src/test/java/org/enso/interpreter/test/VectorTest.java b/engine/runtime/src/test/java/org/enso/interpreter/test/VectorTest.java index 04e7ffd4580b8..64a13ab89f3dc 100644 --- a/engine/runtime/src/test/java/org/enso/interpreter/test/VectorTest.java +++ b/engine/runtime/src/test/java/org/enso/interpreter/test/VectorTest.java @@ -133,7 +133,7 @@ public void passingListOrArrayToEnsoAsArray() throws Exception { import Standard.Base.Data.Array how_long array = case array of - arr -> arr.length + arr : Array.Array -> arr.length _ -> -1 """, "how_long.enso") .uri(uri) diff --git a/engine/runtime/src/test/scala/org/enso/interpreter/test/semantic/CaseTest.scala b/engine/runtime/src/test/scala/org/enso/interpreter/test/semantic/CaseTest.scala index ea196778f610e..7e83150dd24ea 100644 --- a/engine/runtime/src/test/scala/org/enso/interpreter/test/semantic/CaseTest.scala +++ b/engine/runtime/src/test/scala/org/enso/interpreter/test/semantic/CaseTest.scala @@ -44,5 +44,21 @@ class CaseTest extends InterpreterTest { "Compile error: Cannot match on List.Cons using 1 field (expecting 2)" the[InterpreterException] thrownBy eval(code) should have message msg } + + "result in an error when trying to pattern match on a module in a type position" in { + val code = + """ + |import Standard.Base.Data.Vector + | + |main = + | case [1,2,3] of + | _ : Vector -> 1 + | _ -> 2 + |""".stripMargin + + val msg = + "Compile error: Vector is not visible in this scope" + the[InterpreterException] thrownBy eval(code) should have message msg + } } } diff --git a/test/Tests/src/Semantic/Case_Spec.enso b/test/Tests/src/Semantic/Case_Spec.enso index 5628881e240e0..5784845abb64f 100644 --- a/test/Tests/src/Semantic/Case_Spec.enso +++ b/test/Tests/src/Semantic/Case_Spec.enso @@ -2,6 +2,7 @@ from Standard.Base import all import Standard.Base.Data.Array as ArrayMod import Standard.Base.Data.Text as TextMod +polyglot java import java.lang.Class polyglot java import java.lang.Object as JObject polyglot java import java.util.Random polyglot java import java.util.AbstractList @@ -17,13 +18,13 @@ spec = Test.group "Pattern Matches" <| Boolean -> Nothing _ -> Test.fail "Expected the Boolean constructor to match." case True of - Boolean -> Test.fail "Expected the Boolean type to match." + Boolean -> Test.fail "Expected True to match on a Boolean type check." _ : Boolean -> Nothing - _ -> Test.fail "Expected the Boolean type to match." + _ -> Test.fail "Expected True to match on a Boolean type check." case False of - Boolean -> Test.fail "Expected the Boolean type to match." + Boolean -> Test.fail "Expected False to match on a Boolean type check." _ : Boolean -> Nothing - _ -> Test.fail "Expected the Boolean type to match." + _ -> Test.fail "Expected False to match on a Boolean type check." Test.specify "should be able to match on the Integer type" <| case 1 of Integer -> Test.fail "Expected an integer to match." @@ -217,7 +218,6 @@ spec = Test.group "Pattern Matches" <| Test.specify "should be able to match on module rather than a type" <| case Vector of -# _ : Vector -> Test.fail "Expected to match on module." _ : Vector.Vector -> Test.fail "Expected to match on module." Vector.Vector -> Test.fail "Expected to match on module." Vector -> Nothing @@ -225,7 +225,6 @@ spec = Test.group "Pattern Matches" <| Test.specify "should be able to match on a type of a value rather tha module" <| case [1,2,3] of -# _ : Vector -> Test.fail "Expected to match on a type." Vector -> Test.fail "Expected to match on a type." Vector.Vector -> Test.fail "Expected to match on a type." _ : Vector.Vector -> Nothing @@ -249,15 +248,17 @@ spec = Test.group "Pattern Matches" <| _ -> Test.fail "Expected to match on ArrayList type." case Meta.type_of list of - _ : Vector.Vector -> Test.fail "Expected to match in catch-all case." - _ : Array -> Test.fail "Expected to match in catch-all case." - _ : ArrayList -> Test.fail "Expected to match in catch-all case." - _ -> Nothing + _ : Vector.Vector -> Test.fail "Expected to match in java.lang.Class case." + _ : Array -> Test.fail "Expected to match in java.lang.Class case." + _ : ArrayList -> Test.fail "Expected to match in java.lang.Class case." + _ : Class -> Nothing + _ : ArrayList -> Test.fail "Expected to match in java.lang.Class case." case Meta.type_of list of Vector.Vector -> Test.fail "Expected to match on a polyglot symbol." Array -> Test.fail "Expected to match on a polyglot symbol." ArrayList -> Nothing + Class -> Test.fail "Expected to match on a polyglot symbol." _ -> Test.fail "Expected to match on a polyglot symbol." Test.specify "should correctly pattern match on supertype" <|