Add LanguageFeature prohibiting exposing function type parameter bound #KT-27112
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt index 46bfa4065..b6c8638 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt
@@ -77,7 +77,7 @@ private val modifiersChecker = modifiersChecker.withTrace(trace) - private val exposedChecker = ExposedVisibilityChecker(trace) + private val exposedChecker = ExposedVisibilityChecker(trace, languageVersionSettings) private val shadowedExtensionChecker = ShadowedExtensionChecker(typeSpecificityComparator, trace)
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ExposedVisibilityChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ExposedVisibilityChecker.kt index 8f4dee2..4193e45 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ExposedVisibilityChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ExposedVisibilityChecker.kt
@@ -16,6 +16,9 @@ package org.jetbrains.kotlin.resolve +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.DiagnosticSink.DO_NOTHING @@ -26,7 +29,10 @@ // Checker for all seven EXPOSED_* errors // All functions return true if everything is OK, or false in case of any errors -class ExposedVisibilityChecker(private val trace: DiagnosticSink = DO_NOTHING) { +class ExposedVisibilityChecker( + private val trace: DiagnosticSink = DO_NOTHING, + private val languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT +) { // NB: does not check any members fun checkClassHeader(klass: KtClassOrObject, classDescriptor: ClassDescriptor): Boolean { @@ -89,6 +95,14 @@ ) result = false } + + if (languageVersionSettings.supportsFeature(LanguageFeature.ProhibitExposingFunctionTypeParameterBound)) { + functionDescriptor.typeParameters.forEachIndexed { i, typeParameterDescriptor -> + if (!checkParameterBounds(function.typeParameters[i], typeParameterDescriptor, functionVisibility)) { + result = false + } + } + } } functionDescriptor.valueParameters.forEachIndexed { i, parameterDescriptor -> val restricting = parameterDescriptor.type.leastPermissiveDescriptor(functionVisibility) @@ -184,21 +198,30 @@ var result = true classDescriptor.declaredTypeParameters.forEachIndexed { i, typeParameterDescriptor -> if (i >= typeParameterList.size) return result - for (upperBound in typeParameterDescriptor.upperBounds) { - val restricting = upperBound.leastPermissiveDescriptor(classVisibility) - if (restricting != null) { - trace.report( - Errors.EXPOSED_TYPE_PARAMETER_BOUND.on( - typeParameterList[i], classVisibility, - restricting, restricting.effectiveVisibility() - ) - ) - result = false - break - } - } + val ktTypeParameter = typeParameterList[i] + if (!checkParameterBounds(ktTypeParameter, typeParameterDescriptor, classVisibility)) result = false } return result } + + private fun checkParameterBounds( + ktTypeParameter: KtTypeParameter, + typeParameterDescriptor: TypeParameterDescriptor, + ownerVisibility: EffectiveVisibility + ): Boolean { + for (upperBound in typeParameterDescriptor.upperBounds) { + val restricting = upperBound.leastPermissiveDescriptor(ownerVisibility) + if (restricting != null) { + trace.report( + Errors.EXPOSED_TYPE_PARAMETER_BOUND.on( + ktTypeParameter, ownerVisibility, + restricting, restricting.effectiveVisibility() + ) + ) + return false + } + } + return true + } }
diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 69eae3b..a72da3f 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt
@@ -115,6 +115,8 @@ InlineClasses(sinceVersion = KOTLIN_1_3, defaultState = State.ENABLED_WITH_WARNING, kind = UNSTABLE_FEATURE), + ProhibitExposingFunctionTypeParameterBound(sinceVersion = null, defaultState = State.DISABLED, kind = BUG_FIX), + ; val presentableName: String