From 6c9394f0b235dd4ea5a05d4d3032cd571ce6e1aa Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Wed, 8 May 2019 01:21:44 +0300 Subject: [PATCH] [NI] Use original implicit receiver for DSL violation check There is an inconsistency between old and new inference for storing receivers of resolved calls. In new inference, for captured types, receiver will be changed and to preserve behavior of the old inference, we use original one during important checks. This is more a workaround than a solution and should be revisited. #KT-31356 Fixed #KT-29948 Fixed #KT-31360 Fixed --- .../fir/FirDiagnosticsSmokeTestGenerated.java | 15 +++++++++++ .../checkers/DslScopeViolationCallChecker.kt | 7 +++++- .../tests/resolve/dslMarker/kt29948.kt | 19 ++++++++++++++ .../tests/resolve/dslMarker/kt29948.txt | 20 +++++++++++++++ .../tests/resolve/dslMarker/kt31360.kt | 25 +++++++++++++++++++ .../tests/resolve/dslMarker/kt31360.txt | 21 ++++++++++++++++ .../markedReceiverWithCapturedTypeArgument.kt | 11 ++++++++ ...markedReceiverWithCapturedTypeArgument.txt | 18 +++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 15 +++++++++++ .../DiagnosticsUsingJavacTestGenerated.java | 15 +++++++++++ 10 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/diagnostics/tests/resolve/dslMarker/kt29948.kt create mode 100644 compiler/testData/diagnostics/tests/resolve/dslMarker/kt29948.txt create mode 100644 compiler/testData/diagnostics/tests/resolve/dslMarker/kt31360.kt create mode 100644 compiler/testData/diagnostics/tests/resolve/dslMarker/kt31360.txt create mode 100644 compiler/testData/diagnostics/tests/resolve/dslMarker/markedReceiverWithCapturedTypeArgument.kt create mode 100644 compiler/testData/diagnostics/tests/resolve/dslMarker/markedReceiverWithCapturedTypeArgument.txt diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java index 5888511ff8c..be4f7c55b29 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java @@ -17470,6 +17470,21 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtensionAnnotatedType.kt"); } + @TestMetadata("kt29948.kt") + public void testKt29948() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/kt29948.kt"); + } + + @TestMetadata("kt31360.kt") + public void testKt31360() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/kt31360.kt"); + } + + @TestMetadata("markedReceiverWithCapturedTypeArgument.kt") + public void testMarkedReceiverWithCapturedTypeArgument() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/markedReceiverWithCapturedTypeArgument.kt"); + } + @TestMetadata("markersIntersection.kt") public void testMarkersIntersection() throws Exception { runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/markersIntersection.kt"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/DslScopeViolationCallChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/DslScopeViolationCallChecker.kt index 36570be692b..cde2286c2c5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/DslScopeViolationCallChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/DslScopeViolationCallChecker.kt @@ -31,7 +31,12 @@ object DslScopeViolationCallChecker : CallChecker { if (!context.languageVersionSettings.supportsFeature(LanguageFeature.DslMarkersSupport)) return val callImplicitReceivers = resolvedCall.getImplicitReceivers() - for (callImplicitReceiver in callImplicitReceivers) { + val originalReceivers = if (context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference)) + callImplicitReceivers.map { it.original } + else + callImplicitReceivers + + for (callImplicitReceiver in originalReceivers) { checkCallImplicitReceiver(callImplicitReceiver, resolvedCall, reportOn, context) } } diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/kt29948.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/kt29948.kt new file mode 100644 index 00000000000..7dd88e1b21c --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/kt29948.kt @@ -0,0 +1,19 @@ +@DslMarker +annotation class MyDsl + +@MyDsl +interface Foo { + val x: Int +} + +val Foo<*>.bad: Int get() = x + +fun Foo<*>.badFun(): Int = x + +val Foo.good: Int get() = x + +fun test(foo: Foo<*>) { + foo.apply { + x + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/kt29948.txt b/compiler/testData/diagnostics/tests/resolve/dslMarker/kt29948.txt new file mode 100644 index 00000000000..113b95d31bc --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/kt29948.txt @@ -0,0 +1,20 @@ +package + +public val Foo<*>.bad: kotlin.Int +public val Foo.good: kotlin.Int +public fun test(/*0*/ foo: Foo<*>): kotlin.Unit +public fun Foo<*>.badFun(): kotlin.Int + +@MyDsl public interface Foo { + public abstract val x: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.DslMarker public final annotation class MyDsl : kotlin.Annotation { + public constructor MyDsl() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/kt31360.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/kt31360.kt new file mode 100644 index 00000000000..9b3b0501a2b --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/kt31360.kt @@ -0,0 +1,25 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +@DslMarker +annotation class MyDsl + +@MyDsl +interface Scope { + val something: A + val value: B +} +fun scoped1(block: Scope.() -> Unit) {} +fun scoped2(block: Scope<*, String>.() -> Unit) {} + +val Scope<*, T>.property: T get() = value + +fun f() { + scoped1 { + value + property + } + scoped2 { + value + property + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/kt31360.txt b/compiler/testData/diagnostics/tests/resolve/dslMarker/kt31360.txt new file mode 100644 index 00000000000..d34221bc098 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/kt31360.txt @@ -0,0 +1,21 @@ +package + +public val Scope<*, T>.property: T +public fun f(): kotlin.Unit +public fun scoped1(/*0*/ block: Scope.() -> kotlin.Unit): kotlin.Unit +public fun scoped2(/*0*/ block: Scope<*, kotlin.String>.() -> kotlin.Unit): kotlin.Unit + +@kotlin.DslMarker public final annotation class MyDsl : kotlin.Annotation { + public constructor MyDsl() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@MyDsl public interface Scope { + public abstract val something: A + public abstract val value: B + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/markedReceiverWithCapturedTypeArgument.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/markedReceiverWithCapturedTypeArgument.kt new file mode 100644 index 00000000000..8349ec26541 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/markedReceiverWithCapturedTypeArgument.kt @@ -0,0 +1,11 @@ +@DslMarker +annotation class AnnMarker + +@AnnMarker +class Inv { + fun bar() {} +} + +fun Inv<*>.foo() { + bar() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/markedReceiverWithCapturedTypeArgument.txt b/compiler/testData/diagnostics/tests/resolve/dslMarker/markedReceiverWithCapturedTypeArgument.txt new file mode 100644 index 00000000000..55cb619f49b --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/markedReceiverWithCapturedTypeArgument.txt @@ -0,0 +1,18 @@ +package + +public fun Inv<*>.foo(): kotlin.Unit + +@kotlin.DslMarker public final annotation class AnnMarker : kotlin.Annotation { + public constructor AnnMarker() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@AnnMarker public final class Inv { + public constructor Inv() + public final fun bar(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 9bc42c1c969..c23c5d0de99 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -17482,6 +17482,21 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtensionAnnotatedType.kt"); } + @TestMetadata("kt29948.kt") + public void testKt29948() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/kt29948.kt"); + } + + @TestMetadata("kt31360.kt") + public void testKt31360() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/kt31360.kt"); + } + + @TestMetadata("markedReceiverWithCapturedTypeArgument.kt") + public void testMarkedReceiverWithCapturedTypeArgument() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/markedReceiverWithCapturedTypeArgument.kt"); + } + @TestMetadata("markersIntersection.kt") public void testMarkersIntersection() throws Exception { runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/markersIntersection.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index faef7d7e17c..b41e227c65e 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -17472,6 +17472,21 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtensionAnnotatedType.kt"); } + @TestMetadata("kt29948.kt") + public void testKt29948() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/kt29948.kt"); + } + + @TestMetadata("kt31360.kt") + public void testKt31360() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/kt31360.kt"); + } + + @TestMetadata("markedReceiverWithCapturedTypeArgument.kt") + public void testMarkedReceiverWithCapturedTypeArgument() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/markedReceiverWithCapturedTypeArgument.kt"); + } + @TestMetadata("markersIntersection.kt") public void testMarkersIntersection() throws Exception { runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/markersIntersection.kt");