diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index e1efe46d047..d09ce59ba07 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -727,6 +727,7 @@ public interface Errors { DiagnosticFactory2 INCOMPATIBLE_TYPES = DiagnosticFactory2.create(ERROR); DiagnosticFactory0 IMPLICIT_NOTHING_RETURN_TYPE = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 IMPLICIT_NOTHING_PROPERTY_TYPE = DiagnosticFactory0.create(WARNING); DiagnosticFactory1 IMPLICIT_INTERSECTION_TYPE = DiagnosticFactory1.create(ERROR); // Context tracking diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index dad0aabcc94..afc752469fe 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -527,6 +527,7 @@ public class DefaultErrorMessages { MAP.put(TYPE_MISMATCH_IN_CONDITION, "Condition must be of type kotlin.Boolean, but is of type {0}", RENDER_TYPE); MAP.put(INCOMPATIBLE_TYPES, "Incompatible types: {0} and {1}", RENDER_TYPE, RENDER_TYPE); MAP.put(IMPLICIT_NOTHING_RETURN_TYPE, "''Nothing'' return type needs to be specified explicitly"); + MAP.put(IMPLICIT_NOTHING_PROPERTY_TYPE, "Deprecated: ''Nothing'' property type needs to be specified explicitly"); MAP.put(IMPLICIT_INTERSECTION_TYPE, "Inferred type {0} is an intersection, please specify the required type explicitly", RENDER_TYPE); MAP.put(EXPECTED_CONDITION, "Expected condition of type kotlin.Boolean"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt index afefe3d8d70..dc4fda7d906 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt @@ -435,13 +435,7 @@ class DeclarationsChecker( checkTypeParameterConstraints(property) checkPropertyExposedType(property, propertyDescriptor) checkPropertyTypeParametersAreUsedInReceiverType(propertyDescriptor) - propertyDescriptor.returnType?.let { - if (property.typeReference == null) { - if (it.constructor is IntersectionTypeConstructor) { - trace.report(IMPLICIT_INTERSECTION_TYPE.on(property.nameIdentifier ?: property, it)) - } - } - } + checkImplicitCallableType(property, propertyDescriptor) } private fun checkPropertyTypeParametersAreUsedInReceiverType(descriptor: PropertyDescriptor) { @@ -656,19 +650,25 @@ class DeclarationsChecker( if (!function.hasBody() && !hasAbstractModifier && !hasExternalModifier) { trace.report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor)) } - functionDescriptor.returnType?.let { - if (!function.hasDeclaredReturnType()) { + checkImplicitCallableType(function, functionDescriptor) + checkFunctionExposedType(function, functionDescriptor) + checkVarargParameters(trace, functionDescriptor) + } + + private fun checkImplicitCallableType(declaration: KtCallableDeclaration, descriptor: CallableDescriptor) { + descriptor.returnType?.let { + if (declaration.typeReference == null) { + val target = declaration.nameIdentifier ?: declaration if (it.isNothing()) { - trace.report(IMPLICIT_NOTHING_RETURN_TYPE.on(nameIdentifier ?: function)) + trace.report( + (if (declaration is KtProperty) IMPLICIT_NOTHING_PROPERTY_TYPE else IMPLICIT_NOTHING_RETURN_TYPE).on(target) + ) } if (it.constructor is IntersectionTypeConstructor) { - trace.report(IMPLICIT_INTERSECTION_TYPE.on(nameIdentifier ?: function, it)) + trace.report(IMPLICIT_INTERSECTION_TYPE.on(target, it)) } } } - - checkFunctionExposedType(function, functionDescriptor) - checkVarargParameters(trace, functionDescriptor) } private fun checkFunctionExposedType(function: KtFunction, functionDescriptor: FunctionDescriptor) { diff --git a/compiler/testData/diagnostics/tests/implicitNothing.kt b/compiler/testData/diagnostics/tests/implicitNothing.kt index 1ce9bda8b32..f0fdce761a3 100644 --- a/compiler/testData/diagnostics/tests/implicitNothing.kt +++ b/compiler/testData/diagnostics/tests/implicitNothing.kt @@ -5,3 +5,14 @@ fun bar() = null!! fun baz() = bar() fun gav(): Any = null!! + +val x = null!! + +val y: Nothing = throw Exception() + +fun check() { + // Error: KT-10449 + fun local() = bar() + // Unreachable / unused, but not implicit Nothing + val x = null!! +} diff --git a/compiler/testData/diagnostics/tests/implicitNothing.txt b/compiler/testData/diagnostics/tests/implicitNothing.txt index 4f04b063b85..185cac036d7 100644 --- a/compiler/testData/diagnostics/tests/implicitNothing.txt +++ b/compiler/testData/diagnostics/tests/implicitNothing.txt @@ -1,6 +1,9 @@ package +public val x: kotlin.Nothing +public val y: kotlin.Nothing public fun bar(): kotlin.Nothing public fun baz(): kotlin.Nothing +public fun check(): kotlin.Unit public fun foo(): kotlin.Nothing public fun gav(): kotlin.Any diff --git a/compiler/testData/diagnostics/testsWithStdLib/resolve/javaPackageMembers.kt b/compiler/testData/diagnostics/testsWithStdLib/resolve/javaPackageMembers.kt index 95ee62372b4..26068f65a79 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/resolve/javaPackageMembers.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/resolve/javaPackageMembers.kt @@ -1,6 +1,6 @@ fun fn(): Nothing = throw java.lang.RuntimeException("oops") -val x = throw java.lang.RuntimeException("oops") +val x: Nothing = throw java.lang.RuntimeException("oops") class SomeClass { fun method() {