From 9d10832ffc38c4d3ef72ddb3898a29eefaaf213d Mon Sep 17 00:00:00 2001 From: Daniel Chao Date: Wed, 23 Oct 2024 14:38:30 -0700 Subject: [PATCH] Fix typecheck error on Listing/Mapping (#725) The addresses the following case: local l1: Listing = new { 1 } l2: Listing = (l1) { 2 } The member in `l1` should be checked against its owner; to check against `Listing`. --- .../java/org/pkl/core/runtime/VmUtils.java | 3 +++ .../input/errors/listingTypeCheckError6.pkl | 5 +++++ .../input/errors/listingTypeCheckError7.pkl | 2 ++ .../input/errors/mappingTypeCheckError10.pkl | 2 ++ .../input/errors/mappingTypeCheckError9.pkl | 5 +++++ .../output/errors/listingTypeCheckError6.err | 19 +++++++++++++++++++ .../output/errors/listingTypeCheckError7.err | 15 +++++++++++++++ .../output/errors/mappingTypeCheckError10.err | 15 +++++++++++++++ .../output/errors/mappingTypeCheckError9.err | 19 +++++++++++++++++++ 9 files changed, 85 insertions(+) create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/input/errors/listingTypeCheckError6.pkl create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/input/errors/listingTypeCheckError7.pkl create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/input/errors/mappingTypeCheckError10.pkl create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/input/errors/mappingTypeCheckError9.pkl create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/output/errors/listingTypeCheckError6.err create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/output/errors/listingTypeCheckError7.err create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/output/errors/mappingTypeCheckError10.err create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/output/errors/mappingTypeCheckError9.err diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmUtils.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmUtils.java index 9f5c4e55..46909071 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmUtils.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmUtils.java @@ -298,6 +298,9 @@ public final class VmUtils { } } } else if (receiver instanceof VmListingOrMapping vmListingOrMapping) { + if (owner != receiver && owner instanceof VmListingOrMapping vmListingOrMappingOwner) { + ret = vmListingOrMappingOwner.typecastObjectMember(member, ret, callNode); + } ret = vmListingOrMapping.typecastObjectMember(member, ret, callNode); } receiver.setCachedValue(memberKey, ret, member); diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/errors/listingTypeCheckError6.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/listingTypeCheckError6.pkl new file mode 100644 index 00000000..0e3d9203 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/listingTypeCheckError6.pkl @@ -0,0 +1,5 @@ +local listing1: Listing = new { 1 } +local listing2: Listing = listing1 +local listing3 = (listing2) { "2" } + +first = listing3[0] diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/errors/listingTypeCheckError7.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/listingTypeCheckError7.pkl new file mode 100644 index 00000000..15ddeb36 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/listingTypeCheckError7.pkl @@ -0,0 +1,2 @@ +foo: Listing = new { 1; 2; 3 } +bar: Listing = (foo) { "bar" } diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/errors/mappingTypeCheckError10.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/mappingTypeCheckError10.pkl new file mode 100644 index 00000000..d1a08682 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/mappingTypeCheckError10.pkl @@ -0,0 +1,2 @@ +foo: Mapping = new { ["foo"] = 1; ["bar"] = 2 } +bar: Mapping = (foo) { ["baz"] = "three" } diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/errors/mappingTypeCheckError9.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/mappingTypeCheckError9.pkl new file mode 100644 index 00000000..a7a93620 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/mappingTypeCheckError9.pkl @@ -0,0 +1,5 @@ +local mapping1: Mapping = new { ["foo"] = 1 } +local mapping2: Mapping = mapping1 +local mapping3 = (mapping2) { ["bar"] = "2" } + +first = mapping3["foo"] diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/errors/listingTypeCheckError6.err b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/listingTypeCheckError6.err new file mode 100644 index 00000000..acaded30 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/listingTypeCheckError6.err @@ -0,0 +1,19 @@ +–– Pkl Error –– +Expected value of type `String`, but got type `Int`. +Value: 1 + +x | local listing2: Listing = listing1 + ^^^^^^ +at listingTypeCheckError6#listing2 (file:///$snippetsDir/input/errors/listingTypeCheckError6.pkl) + +x | local listing1: Listing = new { 1 } + ^ +at listingTypeCheckError6#listing1[#1] (file:///$snippetsDir/input/errors/listingTypeCheckError6.pkl) + +x | first = listing3[0] + ^^^^^^^^^^^ +at listingTypeCheckError6#first (file:///$snippetsDir/input/errors/listingTypeCheckError6.pkl) + +xxx | text = renderer.renderDocument(value) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +at pkl.base#Module.output.text (pkl:base) diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/errors/listingTypeCheckError7.err b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/listingTypeCheckError7.err new file mode 100644 index 00000000..ddf0752a --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/listingTypeCheckError7.err @@ -0,0 +1,15 @@ +–– Pkl Error –– +Expected value of type `String`, but got type `Int`. +Value: 1 + +x | bar: Listing = (foo) { "bar" } + ^^^^^^ +at listingTypeCheckError7#bar (file:///$snippetsDir/input/errors/listingTypeCheckError7.pkl) + +x | foo: Listing = new { 1; 2; 3 } + ^ +at listingTypeCheckError7#foo[#1] (file:///$snippetsDir/input/errors/listingTypeCheckError7.pkl) + +xxx | text = renderer.renderDocument(value) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +at pkl.base#Module.output.text (pkl:base) diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/errors/mappingTypeCheckError10.err b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/mappingTypeCheckError10.err new file mode 100644 index 00000000..1f0a0577 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/mappingTypeCheckError10.err @@ -0,0 +1,15 @@ +–– Pkl Error –– +Expected value of type `String`, but got type `Int`. +Value: 1 + +x | bar: Mapping = (foo) { ["baz"] = "three" } + ^^^^^^ +at mappingTypeCheckError10#bar (file:///$snippetsDir/input/errors/mappingTypeCheckError10.pkl) + +x | foo: Mapping = new { ["foo"] = 1; ["bar"] = 2 } + ^ +at mappingTypeCheckError10#foo["foo"] (file:///$snippetsDir/input/errors/mappingTypeCheckError10.pkl) + +xxx | text = renderer.renderDocument(value) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +at pkl.base#Module.output.text (pkl:base) diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/errors/mappingTypeCheckError9.err b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/mappingTypeCheckError9.err new file mode 100644 index 00000000..78c49951 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/mappingTypeCheckError9.err @@ -0,0 +1,19 @@ +–– Pkl Error –– +Expected value of type `String`, but got type `Int`. +Value: 1 + +x | local mapping2: Mapping = mapping1 + ^^^^^^ +at mappingTypeCheckError9#mapping2 (file:///$snippetsDir/input/errors/mappingTypeCheckError9.pkl) + +x | local mapping1: Mapping = new { ["foo"] = 1 } + ^ +at mappingTypeCheckError9#mapping1["foo"] (file:///$snippetsDir/input/errors/mappingTypeCheckError9.pkl) + +x | first = mapping3["foo"] + ^^^^^^^^^^^^^^^ +at mappingTypeCheckError9#first (file:///$snippetsDir/input/errors/mappingTypeCheckError9.pkl) + +xxx | text = renderer.renderDocument(value) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +at pkl.base#Module.output.text (pkl:base)