Report MEMBER_PROJECTED_OUT on calls with smart cast receiver
#KT-10856 Fixed
This commit is contained in:
@@ -61,7 +61,9 @@ fun ResolutionContext<*>.reportTypeMismatchDueToTypeProjection(
|
||||
is CallPosition.Unknown -> return false
|
||||
}
|
||||
|
||||
val receiverType = resolvedCall.dispatchReceiver?.type ?: return false
|
||||
val receiverType = resolvedCall.smartCastDispatchReceiverType
|
||||
?: (resolvedCall.dispatchReceiver ?: return false).type
|
||||
|
||||
val callableDescriptor = resolvedCall.resultingDescriptor.original
|
||||
|
||||
val substitutedDescriptor =
|
||||
|
||||
@@ -436,7 +436,7 @@ class CandidateResolver(
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor> CallCandidateResolutionContext<D>.checkReceiver(
|
||||
candidateCall: ResolvedCall<D>,
|
||||
candidateCall: MutableResolvedCall<D>,
|
||||
receiverParameter: ReceiverParameterDescriptor?,
|
||||
receiverArgument: ReceiverValue?,
|
||||
isExplicitReceiver: Boolean,
|
||||
@@ -497,9 +497,12 @@ class CandidateResolver(
|
||||
if (smartCastResult == null) {
|
||||
reportUnsafeCall = true
|
||||
}
|
||||
else if (!smartCastResult.isCorrect) {
|
||||
// Error about unstable smart cast reported within checkAndRecordPossibleCast
|
||||
return OTHER_ERROR
|
||||
else {
|
||||
candidateCall.setSmartCastDispatchReceiverType(smartCastResult.resultType)
|
||||
if (!smartCastResult.isCorrect) {
|
||||
// Error about unstable smart cast reported within checkAndRecordPossibleCast
|
||||
return OTHER_ERROR
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
@@ -121,4 +121,10 @@ public abstract class DelegatingResolvedCall<D extends CallableDescriptor> imple
|
||||
public boolean isSafeCall() {
|
||||
return resolvedCall.isSafeCall();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public KotlinType getSmartCastDispatchReceiverType() {
|
||||
return resolvedCall.getSmartCastDispatchReceiverType();
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.resolve.DelegatingBindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem;
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus;
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor;
|
||||
|
||||
public interface MutableResolvedCall<D extends CallableDescriptor> extends ResolvedCall<D> {
|
||||
@@ -64,4 +65,6 @@ public interface MutableResolvedCall<D extends CallableDescriptor> extends Resol
|
||||
|
||||
//todo remove: use value to parameter map status
|
||||
boolean hasInferredReturnType();
|
||||
|
||||
void setSmartCastDispatchReceiverType(@NotNull KotlinType smartCastDispatchReceiverType);
|
||||
}
|
||||
|
||||
@@ -85,4 +85,7 @@ public interface ResolvedCall<D extends CallableDescriptor> {
|
||||
DataFlowInfoForArguments getDataFlowInfoForArguments();
|
||||
|
||||
boolean isSafeCall();
|
||||
|
||||
@Nullable
|
||||
KotlinType getSmartCastDispatchReceiverType();
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
|
||||
private ConstraintSystem constraintSystem = null;
|
||||
private Boolean hasInferredReturnType = null;
|
||||
private boolean completed = false;
|
||||
private KotlinType smartCastDispatchReceiverType = null;
|
||||
|
||||
private ResolvedCallImpl(
|
||||
@NotNull ResolutionCandidate<D> candidate,
|
||||
@@ -370,4 +371,15 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
|
||||
public TypeSubstitutor getKnownTypeParametersSubstitutor() {
|
||||
return knownTypeParametersSubstitutor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSmartCastDispatchReceiverType(@NotNull KotlinType smartCastDispatchReceiverType) {
|
||||
this.smartCastDispatchReceiverType = smartCastDispatchReceiverType;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public KotlinType getSmartCastDispatchReceiverType() {
|
||||
return smartCastDispatchReceiverType;
|
||||
}
|
||||
}
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
class Inv<E>
|
||||
class C<R> {
|
||||
fun bindTo(property: Inv<R>) {}
|
||||
}
|
||||
|
||||
fun foo(x: Any?, y: C<*>) {
|
||||
y.<!MEMBER_PROJECTED_OUT!>bindTo<!>("")
|
||||
|
||||
if (x is C<*>) {
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.<!MEMBER_PROJECTED_OUT!>bindTo<!>("")
|
||||
with(<!DEBUG_INFO_SMARTCAST!>x<!>) {
|
||||
<!MEMBER_PROJECTED_OUT!>bindTo<!>("")
|
||||
}
|
||||
}
|
||||
|
||||
with(x) {
|
||||
if (this is C<*>) {
|
||||
<!MEMBER_PROJECTED_OUT, DEBUG_INFO_IMPLICIT_RECEIVER_SMARTCAST!>bindTo<!>("")
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package
|
||||
|
||||
public fun foo(/*0*/ x: kotlin.Any?, /*1*/ y: C<*>): kotlin.Unit
|
||||
|
||||
public final class C</*0*/ R> {
|
||||
public constructor C</*0*/ R>()
|
||||
public final fun bindTo(/*0*/ property: Inv<R>): 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
|
||||
}
|
||||
|
||||
public final class Inv</*0*/ E> {
|
||||
public constructor Inv</*0*/ E>()
|
||||
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
|
||||
}
|
||||
@@ -7382,6 +7382,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("projectedOutSmartCast.kt")
|
||||
public void testProjectedOutSmartCast() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/projectionsScope/projectedOutSmartCast.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("recursiveUpperBoundStar.kt")
|
||||
public void testRecursiveUpperBoundStar() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/projectionsScope/recursiveUpperBoundStar.kt");
|
||||
|
||||
Reference in New Issue
Block a user