K1: add separate TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_IN_AUGMENTED_ASSIGNMENT
This is made to have a correct error message for a problem described in KT-48546 #KT-48546 Fixed
This commit is contained in:
committed by
Space Team
parent
c5fe4b53cf
commit
bbee881b5b
+1
@@ -120,6 +120,7 @@ internal class KtFe10CallResolver(
|
|||||||
Errors.RESOLUTION_TO_PRIVATE_CONSTRUCTOR_OF_SEALED_CLASS,
|
Errors.RESOLUTION_TO_PRIVATE_CONSTRUCTOR_OF_SEALED_CLASS,
|
||||||
Errors.UNRESOLVED_REFERENCE,
|
Errors.UNRESOLVED_REFERENCE,
|
||||||
*Errors.TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM.factories,
|
*Errors.TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM.factories,
|
||||||
|
*Errors.TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_IN_AUGMENTED_ASSIGNMENT.factories,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val syntaxErrors = setOf(
|
private val syntaxErrors = setOf(
|
||||||
|
|||||||
@@ -830,6 +830,8 @@ public interface Errors {
|
|||||||
|
|
||||||
DiagnosticFactoryForDeprecation0<KtExpression> TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM =
|
DiagnosticFactoryForDeprecation0<KtExpression> TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM =
|
||||||
DiagnosticFactoryForDeprecation0.create(LanguageFeature.ForbidRecursiveDelegateExpressions);
|
DiagnosticFactoryForDeprecation0.create(LanguageFeature.ForbidRecursiveDelegateExpressions);
|
||||||
|
DiagnosticFactoryForDeprecation0<KtExpression> TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_IN_AUGMENTED_ASSIGNMENT =
|
||||||
|
DiagnosticFactoryForDeprecation0.create(LanguageFeature.ReportErrorsOnRecursiveTypeInsidePlusAssignment);
|
||||||
|
|
||||||
// Checking call arguments
|
// Checking call arguments
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -227,7 +227,9 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(REDUNDANT_MODIFIER_IN_GETTER, "Visibility modifiers are redundant in getter");
|
MAP.put(REDUNDANT_MODIFIER_IN_GETTER, "Visibility modifiers are redundant in getter");
|
||||||
MAP.put(TYPE_PARAMETERS_IN_ENUM, "Enum class cannot have type parameters");
|
MAP.put(TYPE_PARAMETERS_IN_ENUM, "Enum class cannot have type parameters");
|
||||||
MAP.put(TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM,
|
MAP.put(TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM,
|
||||||
"Type checking has run into a recursive problem. Easiest workaround: specify types of your declarations explicitly"); // TODO: message
|
"Type checking has run into a recursive problem. Easiest workaround: specify types of your declarations explicitly");
|
||||||
|
MAP.put(TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_IN_AUGMENTED_ASSIGNMENT,
|
||||||
|
"Type checking has run into a recursive problem. Easiest workaround: specify types of your declarations explicitly");
|
||||||
MAP.put(RETURN_NOT_ALLOWED, "'return' is not allowed here");
|
MAP.put(RETURN_NOT_ALLOWED, "'return' is not allowed here");
|
||||||
MAP.put(PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE, "Projections are not allowed for immediate arguments of a supertype");
|
MAP.put(PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE, "Projections are not allowed for immediate arguments of a supertype");
|
||||||
MAP.put(LABEL_NAME_CLASH, "There is more than one label with such a name in this scope");
|
MAP.put(LABEL_NAME_CLASH, "There is more than one label with such a name in this scope");
|
||||||
|
|||||||
+14
-3
@@ -16,10 +16,12 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticFactory2
|
|||||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.BadNamedArgumentsTarget.*
|
import org.jetbrains.kotlin.diagnostics.Errors.BadNamedArgumentsTarget.*
|
||||||
import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnce
|
import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnce
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.SpecialNames
|
import org.jetbrains.kotlin.name.SpecialNames
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.isNull
|
import org.jetbrains.kotlin.psi.psiUtil.isNull
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.lastBlockStatementOrThis
|
import org.jetbrains.kotlin.psi.psiUtil.lastBlockStatementOrThis
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.BuilderInferenceExpectedTypeConstraintPosition
|
import org.jetbrains.kotlin.resolve.calls.inference.BuilderInferenceExpectedTypeConstraintPosition
|
||||||
@@ -78,9 +80,18 @@ class DiagnosticReporterByTrackingStrategy(
|
|||||||
is VisibilityError -> tracingStrategy.invisibleMember(trace, diagnostic.invisibleMember)
|
is VisibilityError -> tracingStrategy.invisibleMember(trace, diagnostic.invisibleMember)
|
||||||
is NoValueForParameter -> tracingStrategy.noValueForParameter(trace, diagnostic.parameterDescriptor)
|
is NoValueForParameter -> tracingStrategy.noValueForParameter(trace, diagnostic.parameterDescriptor)
|
||||||
is TypeCheckerHasRanIntoRecursion -> {
|
is TypeCheckerHasRanIntoRecursion -> {
|
||||||
val shouldReportErrorsOnRecursiveTypeInsidePlusAssignment =
|
// Note: we have two similar diagnostics here
|
||||||
context.languageVersionSettings.supportsFeature(LanguageFeature.ReportErrorsOnRecursiveTypeInsidePlusAssignment)
|
// - TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM (error starting from 1.7)
|
||||||
tracingStrategy.recursiveType(trace, shouldReportErrorsOnRecursiveTypeInsidePlusAssignment)
|
// - TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_IN_AUGMENTED_ASSIGNMENT (error starting from 1.9)
|
||||||
|
// however they have different deprecation cycle, and thus it's better to distinguish them.
|
||||||
|
// This 'insideAugmentedAssignment' is just a heuristics (approximate) to do it.
|
||||||
|
// It cannot turn red code to green or green to red; the worst thing we can get here
|
||||||
|
// is replacing red code with yellow, if e.g. LV is set to 1.8 explicitly,
|
||||||
|
// and we have chosen the second diagnostics instead of the first one.
|
||||||
|
val insideAugmentedAssignment = call.callElement.parents.any {
|
||||||
|
it is KtBinaryExpression && it.operationToken in KtTokens.AUGMENTED_ASSIGNMENTS
|
||||||
|
}
|
||||||
|
tracingStrategy.recursiveType(trace, context.languageVersionSettings, insideAugmentedAssignment)
|
||||||
}
|
}
|
||||||
is InstantiationOfAbstractClass -> tracingStrategy.instantiationOfAbstractClass(trace)
|
is InstantiationOfAbstractClass -> tracingStrategy.instantiationOfAbstractClass(trace)
|
||||||
is AbstractSuperCall -> {
|
is AbstractSuperCall -> {
|
||||||
|
|||||||
+5
-6
@@ -20,6 +20,7 @@ import com.intellij.lang.ASTNode;
|
|||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0;
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0;
|
||||||
@@ -139,16 +140,14 @@ public abstract class AbstractTracingStrategy implements TracingStrategy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recursiveType(@NotNull BindingTrace trace, boolean shouldReportErrorsOnRecursiveTypeInsidePlusAssignment) {
|
public void recursiveType(@NotNull BindingTrace trace, @NotNull LanguageVersionSettings languageVersionSettings, boolean insideAugmentedAssignment) {
|
||||||
KtExpression expression = call.getCalleeExpression();
|
KtExpression expression = call.getCalleeExpression();
|
||||||
if (expression == null) return;
|
if (expression == null) return;
|
||||||
DiagnosticFactory0<KtExpression> factory;
|
if (insideAugmentedAssignment) {
|
||||||
if (shouldReportErrorsOnRecursiveTypeInsidePlusAssignment) {
|
trace.report(TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_IN_AUGMENTED_ASSIGNMENT.on(languageVersionSettings, expression));
|
||||||
factory = TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM.getErrorFactory();
|
|
||||||
} else {
|
} else {
|
||||||
factory = TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM.getWarningFactory();
|
trace.report(TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM.on(languageVersionSettings, expression));
|
||||||
}
|
}
|
||||||
trace.report(factory.on(expression));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ public interface TracingStrategy {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recursiveType(@NotNull BindingTrace trace, boolean shouldReportErrorsOnRecursiveTypeInsidePlusAssignment) {}
|
public void recursiveType(@NotNull BindingTrace trace, @NotNull LanguageVersionSettings languageVersionSettings, boolean insideAugmentedAssignment) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void instantiationOfAbstractClass(@NotNull BindingTrace trace) {}
|
public void instantiationOfAbstractClass(@NotNull BindingTrace trace) {}
|
||||||
@@ -148,7 +148,7 @@ public interface TracingStrategy {
|
|||||||
@NotNull Collection<? extends ResolvedCall<D>> descriptors
|
@NotNull Collection<? extends ResolvedCall<D>> descriptors
|
||||||
);
|
);
|
||||||
|
|
||||||
void recursiveType(@NotNull BindingTrace trace, boolean shouldReportErrorsOnRecursiveTypeInsidePlusAssignment);
|
void recursiveType(@NotNull BindingTrace trace, @NotNull LanguageVersionSettings languageVersionSettings, boolean insideAugmentedAssignment);
|
||||||
|
|
||||||
void instantiationOfAbstractClass(@NotNull BindingTrace trace);
|
void instantiationOfAbstractClass(@NotNull BindingTrace trace);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -599,7 +599,7 @@ public class ControlStructureTypingUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recursiveType(@NotNull BindingTrace trace, boolean shouldReportErrorsOnRecursiveTypeInsidePlusAssignment) {
|
public void recursiveType(@NotNull BindingTrace trace, @NotNull LanguageVersionSettings languageVersionSettings, boolean insideAugmentedAssignment) {
|
||||||
logError();
|
logError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// !LANGUAGE: -ReportErrorsOnRecursiveTypeInsidePlusAssignment
|
||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
// FIR: KT-51648
|
// FIR: KT-51648
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
|
// !LANGUAGE: -ReportErrorsOnRecursiveTypeInsidePlusAssignment
|
||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
// FIR: KT-51648
|
// FIR: KT-51648
|
||||||
|
|
||||||
object DelegateTest {
|
object DelegateTest {
|
||||||
var result = ""
|
var result = ""
|
||||||
val f by lazy {
|
val f by lazy {
|
||||||
result += <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE, TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_ERROR!>f<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>toString<!>() // Compiler crash
|
result += <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE, TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_IN_AUGMENTED_ASSIGNMENT_WARNING!>f<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>toString<!>() // Compiler crash
|
||||||
"hello"
|
"hello"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,7 +13,7 @@ object DelegateTest {
|
|||||||
object DelegateTest2 {
|
object DelegateTest2 {
|
||||||
var result = ""
|
var result = ""
|
||||||
val f by lazy {
|
val f by lazy {
|
||||||
result += <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_ERROR!>f<!>
|
result += <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_IN_AUGMENTED_ASSIGNMENT_WARNING!>f<!>
|
||||||
"hello"
|
"hello"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
object DelegateTest {
|
object DelegateTest {
|
||||||
var result = ""
|
var result = ""
|
||||||
val f by lazy {
|
val f by lazy {
|
||||||
result += <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE, TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_ERROR!>f<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>toString<!>() // Compiler crash
|
result += <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE, TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_IN_AUGMENTED_ASSIGNMENT_ERROR!>f<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>toString<!>() // Compiler crash
|
||||||
"hello"
|
"hello"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,29 +13,29 @@ object DelegateTest {
|
|||||||
object DelegateTest2 {
|
object DelegateTest2 {
|
||||||
var result = ""
|
var result = ""
|
||||||
val f by lazy {
|
val f by lazy {
|
||||||
result += <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_ERROR!>f<!>
|
result += <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_IN_AUGMENTED_ASSIGNMENT_ERROR!>f<!>
|
||||||
"hello"
|
"hello"
|
||||||
}
|
}
|
||||||
|
|
||||||
var intResult = 0
|
var intResult = 0
|
||||||
val i1 by lazy {
|
val i1 by lazy {
|
||||||
intResult <!OVERLOAD_RESOLUTION_AMBIGUITY!>+=<!> <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_ERROR!>i1<!>
|
intResult <!OVERLOAD_RESOLUTION_AMBIGUITY!>+=<!> <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_IN_AUGMENTED_ASSIGNMENT_ERROR!>i1<!>
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
val i2 by lazy {
|
val i2 by lazy {
|
||||||
intResult <!OVERLOAD_RESOLUTION_AMBIGUITY!>-=<!> <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_ERROR!>i2<!>
|
intResult <!OVERLOAD_RESOLUTION_AMBIGUITY!>-=<!> <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_IN_AUGMENTED_ASSIGNMENT_ERROR!>i2<!>
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
val i3 by lazy {
|
val i3 by lazy {
|
||||||
intResult <!OVERLOAD_RESOLUTION_AMBIGUITY!>*=<!> <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_ERROR!>i3<!>
|
intResult <!OVERLOAD_RESOLUTION_AMBIGUITY!>*=<!> <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_IN_AUGMENTED_ASSIGNMENT_ERROR!>i3<!>
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
val i4 by lazy {
|
val i4 by lazy {
|
||||||
intResult <!OVERLOAD_RESOLUTION_AMBIGUITY!>/=<!> <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_ERROR!>i4<!>
|
intResult <!OVERLOAD_RESOLUTION_AMBIGUITY!>/=<!> <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_IN_AUGMENTED_ASSIGNMENT_ERROR!>i4<!>
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
val i5 by lazy {
|
val i5 by lazy {
|
||||||
intResult <!OVERLOAD_RESOLUTION_AMBIGUITY!>%=<!> <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_ERROR!>i5<!>
|
intResult <!OVERLOAD_RESOLUTION_AMBIGUITY!>%=<!> <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_IN_AUGMENTED_ASSIGNMENT_ERROR!>i5<!>
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
object DelegateTest {
|
object DelegateTest {
|
||||||
var result = ""
|
var result = ""
|
||||||
val f by lazy {
|
val f by lazy {
|
||||||
result += <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE, TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_ERROR!>f<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>toString<!>() // Compiler crash
|
result += <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE, TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_IN_AUGMENTED_ASSIGNMENT_ERROR!>f<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>toString<!>() // Compiler crash
|
||||||
"hello"
|
"hello"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user