K1: report swallowed diagnostic about upper bound violation
#KT-55055 Fixed
This commit is contained in:
committed by
Space Team
parent
b148df15a9
commit
930237b60e
+6
@@ -36426,6 +36426,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment_noReport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("upperBoundViolation.kt")
|
||||
public void testUpperBoundViolation() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/upperBoundViolation.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("useInferenceInformationFromExtension.kt")
|
||||
public void testUseInferenceInformationFromExtension() throws Exception {
|
||||
|
||||
+6
@@ -36426,6 +36426,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment_noReport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("upperBoundViolation.kt")
|
||||
public void testUpperBoundViolation() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/upperBoundViolation.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("useInferenceInformationFromExtension.kt")
|
||||
public void testUseInferenceInformationFromExtension() throws Exception {
|
||||
|
||||
+6
@@ -36426,6 +36426,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment_noReport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("upperBoundViolation.kt")
|
||||
public void testUpperBoundViolation() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/upperBoundViolation.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("useInferenceInformationFromExtension.kt")
|
||||
public void testUseInferenceInformationFromExtension() throws Exception {
|
||||
|
||||
+6
@@ -36522,6 +36522,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment_noReport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("upperBoundViolation.kt")
|
||||
public void testUpperBoundViolation() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/upperBoundViolation.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("useInferenceInformationFromExtension.kt")
|
||||
public void testUseInferenceInformationFromExtension() throws Exception {
|
||||
|
||||
@@ -884,6 +884,7 @@ public interface Errors {
|
||||
DiagnosticFactory4<PsiElement, KotlinType, String, String, BuilderLambdaLabelingInfo> STUB_TYPE_IN_RECEIVER_CAUSES_AMBIGUITY = DiagnosticFactory4.create(ERROR);
|
||||
DiagnosticFactory2<PsiElement, Name, Name> BUILDER_INFERENCE_MULTI_LAMBDA_RESTRICTION = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory2<PsiElement, Name, Name> BUILDER_INFERENCE_STUB_RECEIVER = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory4<KtElement, Name, Name, KotlinType, KotlinType> UPPER_BOUND_VIOLATION_IN_CONSTRAINT = DiagnosticFactory4.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<PsiElement, Collection<? extends ResolvedCall<?>>> NONE_APPLICABLE = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, Collection<? extends ResolvedCall<?>>> CANNOT_COMPLETE_RESOLVE = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
+1
@@ -1006,6 +1006,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(STUB_TYPE_IN_RECEIVER_CAUSES_AMBIGUITY, "The type of a receiver hasn''t been inferred yet. To disambiguate this call, explicitly cast it to `{0}` if you want the builder''s type parameter(s) `{1}` to be inferred to `{2}`.", RENDER_TYPE, STRING, STRING, null);
|
||||
MAP.put(BUILDER_INFERENCE_MULTI_LAMBDA_RESTRICTION, "Unstable inference behaviour with multiple lambdas. Please either specify the type argument for generic parameter `{0}` of `{1}` explicitly", TO_STRING, TO_STRING);
|
||||
MAP.put(BUILDER_INFERENCE_STUB_RECEIVER, "The type of a receiver hasn''t been inferred yet. Please specify type argument for generic parameter `{0}` of `{1}` explicitly", TO_STRING, TO_STRING);
|
||||
MAP.put(UPPER_BOUND_VIOLATION_IN_CONSTRAINT, "Upper bound violation for generic parameter `{0}` of `{1}`: {3} is not a subtype of {2}", TO_STRING, TO_STRING, RENDER_TYPE, RENDER_TYPE);
|
||||
MAP.put(NONE_APPLICABLE, "None of the following functions can be called with the arguments supplied: {0}", AMBIGUOUS_CALLS);
|
||||
MAP.put(CANNOT_COMPLETE_RESOLVE, "Cannot choose among the following candidates without completing type inference: {0}", AMBIGUOUS_CALLS);
|
||||
MAP.put(UNRESOLVED_REFERENCE_WRONG_RECEIVER, "Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: {0}", AMBIGUOUS_CALLS);
|
||||
|
||||
+14
-1
@@ -513,7 +513,20 @@ class DiagnosticReporterByTrackingStrategy(
|
||||
// some error reported later?
|
||||
}
|
||||
is CallableReferenceConstraintPosition<*> -> TODO()
|
||||
is DeclaredUpperBoundConstraintPosition<*> -> TODO()
|
||||
is DeclaredUpperBoundConstraintPosition<*> -> {
|
||||
val originalCall = (position as DeclaredUpperBoundConstraintPositionImpl).kotlinCall
|
||||
val typeParameterDescriptor = position.typeParameter
|
||||
val ownerDescriptor = typeParameterDescriptor.containingDeclaration
|
||||
trace.reportDiagnosticOnce(
|
||||
UPPER_BOUND_VIOLATION_IN_CONSTRAINT.on(
|
||||
(originalCall as PSIKotlinCall).psiCall.callElement,
|
||||
typeParameterDescriptor.name,
|
||||
ownerDescriptor.name,
|
||||
error.upperKotlinType,
|
||||
error.lowerKotlinType
|
||||
)
|
||||
)
|
||||
}
|
||||
is DelegatedPropertyConstraintPosition<*> -> {
|
||||
// DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE, reported later
|
||||
}
|
||||
|
||||
+1
@@ -39,6 +39,7 @@ class CallableReferenceArgumentResolver(val callableReferenceOverloadConflictRes
|
||||
if (chosenCandidate != null) {
|
||||
val toFreshSubstitutor = CreateFreshVariablesSubstitutor.createToFreshVariableSubstitutorAndAddInitialConstraints(
|
||||
chosenCandidate.candidate,
|
||||
resolvedAtom.atom.call,
|
||||
csBuilder
|
||||
)
|
||||
chosenCandidate.addConstraints(csBuilder, toFreshSubstitutor, callableReference = argument)
|
||||
|
||||
+4
-3
@@ -124,7 +124,7 @@ internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
|
||||
if (candidateDescriptor.typeParameters.isEmpty())
|
||||
FreshVariableNewTypeSubstitutor.Empty
|
||||
else
|
||||
createToFreshVariableSubstitutorAndAddInitialConstraints(candidateDescriptor, csBuilder)
|
||||
createToFreshVariableSubstitutorAndAddInitialConstraints(candidateDescriptor, resolvedCall.atom, csBuilder)
|
||||
|
||||
val knownTypeParametersSubstitutor = knownTypeParametersResultingSubstitutor?.let {
|
||||
createKnownParametersFromFreshVariablesSubstitutor(toFreshVariables, it)
|
||||
@@ -220,6 +220,7 @@ internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
|
||||
|
||||
fun createToFreshVariableSubstitutorAndAddInitialConstraints(
|
||||
candidateDescriptor: CallableDescriptor,
|
||||
kotlinCall: KotlinCall,
|
||||
csBuilder: ConstraintSystemOperation
|
||||
): FreshVariableNewTypeSubstitutor {
|
||||
val typeParameters = candidateDescriptor.typeParameters
|
||||
@@ -242,7 +243,7 @@ internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
|
||||
for (index in typeParameters.indices) {
|
||||
val typeParameter = typeParameters[index]
|
||||
val freshVariable = freshTypeVariables[index]
|
||||
val position = DeclaredUpperBoundConstraintPositionImpl(typeParameter)
|
||||
val position = DeclaredUpperBoundConstraintPositionImpl(typeParameter, kotlinCall)
|
||||
|
||||
for (upperBound in typeParameter.upperBounds) {
|
||||
freshVariable.addSubtypeConstraint(upperBound, position)
|
||||
@@ -263,7 +264,7 @@ internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
|
||||
// there can be null in case we already captured type parameter in outer class (in case of inner classes)
|
||||
// see test innerClassTypeAliasConstructor.kt
|
||||
val originalTypeParameter = originalTypeParameters.getOrNull(originalIndex) ?: continue
|
||||
val position = DeclaredUpperBoundConstraintPositionImpl(originalTypeParameter)
|
||||
val position = DeclaredUpperBoundConstraintPositionImpl(originalTypeParameter, kotlinCall)
|
||||
for (upperBound in originalTypeParameter.upperBounds) {
|
||||
freshVariable.addSubtypeConstraint(upperBound, position)
|
||||
}
|
||||
|
||||
+2
-1
@@ -28,7 +28,8 @@ class BuilderInferenceSubstitutionConstraintPositionImpl(
|
||||
class ExpectedTypeConstraintPositionImpl(topLevelCall: KotlinCall) : ExpectedTypeConstraintPosition<KotlinCall>(topLevelCall)
|
||||
|
||||
class DeclaredUpperBoundConstraintPositionImpl(
|
||||
typeParameter: TypeParameterDescriptor
|
||||
typeParameter: TypeParameterDescriptor,
|
||||
val kotlinCall: KotlinCall
|
||||
) : DeclaredUpperBoundConstraintPosition<TypeParameterDescriptor>(typeParameter) {
|
||||
override fun toString() = "DeclaredUpperBound ${typeParameter.name} from ${typeParameter.containingDeclaration}"
|
||||
}
|
||||
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
/upperBoundViolation.kt:9:9: error: upper bound violation for generic parameter `T` of `printGenericNumber`: String is not a subtype of Number
|
||||
printGenericNumber(this[0])
|
||||
^
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// !RENDER_DIAGNOSTICS_FULL_TEXT
|
||||
// ISSUE: KT-55055
|
||||
// FIR_DUMP
|
||||
fun <T : Number> printGenericNumber(t: T) = println("Number is $t")
|
||||
|
||||
fun main() {
|
||||
buildList { // inferred into MutableList<String>
|
||||
add("Boom")
|
||||
printGenericNumber(this[0])
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
FILE: upperBoundViolation.fir.kt
|
||||
public final fun <T : R|kotlin/Number|> printGenericNumber(t: R|T|): R|kotlin/Unit| {
|
||||
^printGenericNumber R|kotlin/io/println|(<strcat>(String(Number is ), R|<local>/t|))
|
||||
}
|
||||
public final fun main(): R|kotlin/Unit| {
|
||||
R|kotlin/collections/buildList|<R|kotlin/String|>(<L> = buildList@fun R|kotlin/collections/MutableList<kotlin/String>|.<anonymous>(): R|kotlin/Unit| <inline=Inline, kind=EXACTLY_ONCE> {
|
||||
this@R|special/anonymous|.R|SubstitutionOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(String(Boom))
|
||||
R|/printGenericNumber|<R|kotlin/String|>(this@R|special/anonymous|.R|SubstitutionOverride<kotlin/collections/MutableList.get: R|Stub (chain inference): TypeVariable(E)|>|(Int(0)))
|
||||
}
|
||||
)
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// !RENDER_DIAGNOSTICS_FULL_TEXT
|
||||
// ISSUE: KT-55055
|
||||
// FIR_DUMP
|
||||
fun <T : Number> printGenericNumber(t: T) = println("Number is $t")
|
||||
|
||||
fun main() {
|
||||
buildList { // inferred into MutableList<String>
|
||||
add("Boom")
|
||||
<!UPPER_BOUND_VIOLATION_IN_CONSTRAINT!>printGenericNumber(this[0])<!>
|
||||
}
|
||||
}
|
||||
Generated
+6
@@ -37258,6 +37258,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment_noReport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("upperBoundViolation.kt")
|
||||
public void testUpperBoundViolation() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/upperBoundViolation.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("useInferenceInformationFromExtension.kt")
|
||||
public void testUseInferenceInformationFromExtension() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user