KT-3344 InternalError in compiler when type arguments are not specified

#KT-3344 fixed
This commit is contained in:
Svetlana Isakova
2013-02-20 13:21:29 +04:00
parent 6739f7ca24
commit 8ef067be77
6 changed files with 71 additions and 55 deletions
@@ -24,9 +24,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.context.CallCandidateResolutionContext; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.calls.context.ResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.context.TypeInfoForCall;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.JetTypeInfo; import org.jetbrains.jet.lang.types.JetTypeInfo;
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice; import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
@@ -284,34 +282,31 @@ public class BindingContextUtils {
}, false); }, false);
} }
public static void recordExpressionType(@NotNull JetExpression expression, @NotNull ResolutionContext context, @NotNull JetTypeInfo result) { public static void recordExpressionType(
@NotNull JetExpression expression, @NotNull BindingTrace trace,
@NotNull JetScope resolutionScope, @NotNull JetTypeInfo result
) {
JetType type = result.getType(); JetType type = result.getType();
if (type != null) { if (type != null) {
context.trace.record(BindingContext.EXPRESSION_TYPE, expression, type); trace.record(BindingContext.EXPRESSION_TYPE, expression, type);
} }
context.trace.record(BindingContext.PROCESSED, expression); trace.record(BindingContext.PROCESSED, expression);
if (result.getDataFlowInfo() != DataFlowInfo.EMPTY) { if (result.getDataFlowInfo() != DataFlowInfo.EMPTY) {
context.trace.record(BindingContext.EXPRESSION_DATA_FLOW_INFO, expression, result.getDataFlowInfo()); trace.record(BindingContext.EXPRESSION_DATA_FLOW_INFO, expression, result.getDataFlowInfo());
} }
if (!(expression instanceof JetReferenceExpression)) { if (!(expression instanceof JetReferenceExpression)) {
context.trace.record(BindingContext.RESOLUTION_SCOPE, expression, context.scope); trace.record(BindingContext.RESOLUTION_SCOPE, expression, resolutionScope);
} }
} }
@Nullable @Nullable
public static TypeInfoForCall getRecordedTypeInfoForCall( public static JetTypeInfo getRecordedTypeInfo(@NotNull JetExpression expression, @NotNull BindingContext context) {
@NotNull JetExpression expression, if (!context.get(BindingContext.PROCESSED, expression)) return null;
@NotNull ResolutionContext context DataFlowInfo dataFlowInfo = context.get(BindingContext.EXPRESSION_DATA_FLOW_INFO, expression);
) {
if (!context.trace.get(BindingContext.PROCESSED, expression)) return null;
JetType type = context.trace.get(BindingContext.EXPRESSION_TYPE, expression);
DataFlowInfo dataFlowInfo = context.trace.get(BindingContext.EXPRESSION_DATA_FLOW_INFO, expression);
if (dataFlowInfo == null) { if (dataFlowInfo == null) {
dataFlowInfo = DataFlowInfo.EMPTY; dataFlowInfo = DataFlowInfo.EMPTY;
} }
JetTypeInfo typeInfo = JetTypeInfo.create(context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression), dataFlowInfo); JetType type = context.get(BindingContext.EXPRESSION_TYPE, expression);
CallCandidateResolutionContext<FunctionDescriptor> callCandidateResolutionContext = return JetTypeInfo.create(type, dataFlowInfo);
context.trace.get(BindingContext.DEFERRED_COMPUTATION_FOR_CALL, expression);
return TypeInfoForCall.create(typeInfo, callCandidateResolutionContext);
} }
} }
@@ -48,7 +48,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.getRecordedTypeInfoForCall; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.getRecordedTypeInfo;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.recordExpressionType; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.recordExpressionType;
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.*; import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.*;
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS; import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS;
@@ -161,43 +161,48 @@ public class ArgumentTypeResolver {
} }
@NotNull @NotNull
public TypeInfoForCall getArgumentTypeInfo( public JetTypeInfo getArgumentTypeInfo(
@Nullable JetExpression expression, @Nullable JetExpression expression,
@NotNull CallResolutionContext context, @NotNull CallResolutionContext context,
@NotNull ResolveArgumentsMode resolveArgumentsMode @NotNull ResolveArgumentsMode resolveArgumentsMode,
@Nullable TemporaryBindingTrace traceToCommitForCall
) { ) {
if (expression == null) { if (expression == null) {
return TypeInfoForCall.create(null, context.dataFlowInfo); return JetTypeInfo.create(null, context.dataFlowInfo);
} }
if (expression instanceof JetFunctionLiteralExpression) { if (expression instanceof JetFunctionLiteralExpression) {
return TypeInfoForCall.create(getFunctionLiteralTypeInfo((JetFunctionLiteralExpression) expression, context, resolveArgumentsMode)); return getFunctionLiteralTypeInfo((JetFunctionLiteralExpression) expression, context, resolveArgumentsMode);
} }
TypeInfoForCall cachedTypeInfo = getRecordedTypeInfoForCall(expression, context); JetTypeInfo recordedTypeInfo = getRecordedTypeInfo(expression, context.trace.getBindingContext());
if (cachedTypeInfo != null) { if (recordedTypeInfo != null) {
return cachedTypeInfo; return recordedTypeInfo;
} }
//todo deparenthesize //todo deparenthesize
CallExpressionResolver callExpressionResolver = expressionTypingServices.getCallExpressionResolver(); CallExpressionResolver callExpressionResolver = expressionTypingServices.getCallExpressionResolver();
TypeInfoForCall result = null; if (!(expression instanceof JetCallExpression) && !(expression instanceof JetQualifiedExpression)) {
return expressionTypingServices.getTypeInfo(context.scope, expression, context.expectedType, context.dataFlowInfo, context.trace);
}
TypeInfoForCall result;
if (expression instanceof JetCallExpression) { if (expression instanceof JetCallExpression) {
result = callExpressionResolver.getCallExpressionTypeInfoForCall( result = callExpressionResolver.getCallExpressionTypeInfoForCall(
(JetCallExpression) expression, ReceiverValue.NO_RECEIVER, null, (JetCallExpression) expression, ReceiverValue.NO_RECEIVER, null,
context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE), ResolveMode.NESTED_CALL); context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE), ResolveMode.NESTED_CALL);
} }
if (expression instanceof JetQualifiedExpression) { else { // expression instanceof JetQualifiedExpression
result = callExpressionResolver.getQualifiedExpressionExtendedTypeInfo( result = callExpressionResolver.getQualifiedExpressionExtendedTypeInfo(
(JetQualifiedExpression) expression, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE), ResolveMode.NESTED_CALL); (JetQualifiedExpression) expression, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE), ResolveMode.NESTED_CALL);
} }
if (result != null) {
recordExpressionType(expression, context, result.getTypeInfo()); recordExpressionType(expression, context.trace, context.scope, result.getTypeInfo());
CallCandidateResolutionContext<FunctionDescriptor> deferredContext = result.getCallCandidateResolutionContext(); CallCandidateResolutionContext<FunctionDescriptor> deferredContext = result.getCallCandidateResolutionContext();
if (deferredContext != null) { if (deferredContext != null) {
context.trace.record(BindingContext.DEFERRED_COMPUTATION_FOR_CALL, expression, deferredContext); context.trace.record(BindingContext.DEFERRED_COMPUTATION_FOR_CALL, expression, deferredContext);
}
return result;
} }
return TypeInfoForCall.create( if (traceToCommitForCall != null) {
expressionTypingServices.getTypeInfo(context.scope, expression, context.expectedType, context.dataFlowInfo, context.trace)); traceToCommitForCall.commit();
}
return result.getTypeInfo();
} }
@NotNull @NotNull
@@ -32,7 +32,6 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.*;
import org.jetbrains.jet.lang.resolve.calls.context.CallCandidateResolutionContext; import org.jetbrains.jet.lang.resolve.calls.context.CallCandidateResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.context.CallResolutionContext; import org.jetbrains.jet.lang.resolve.calls.context.CallResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.context.ResolveMode; import org.jetbrains.jet.lang.resolve.calls.context.ResolveMode;
import org.jetbrains.jet.lang.resolve.calls.context.TypeInfoForCall;
import org.jetbrains.jet.lang.resolve.calls.inference.*; import org.jetbrains.jet.lang.resolve.calls.inference.*;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
@@ -49,7 +48,10 @@ import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.*; import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.jetbrains.jet.lang.diagnostics.Errors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT; import static org.jetbrains.jet.lang.diagnostics.Errors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT;
import static org.jetbrains.jet.lang.diagnostics.Errors.SUPER_IS_NOT_AN_EXPRESSION; import static org.jetbrains.jet.lang.diagnostics.Errors.SUPER_IS_NOT_AN_EXPRESSION;
@@ -448,13 +450,8 @@ public class CandidateResolver {
context.trace, "transient trace to resolve argument", argumentExpression); context.trace, "transient trace to resolve argument", argumentExpression);
JetType expectedType = substitutor.substitute(effectiveExpectedType, Variance.INVARIANT); JetType expectedType = substitutor.substitute(effectiveExpectedType, Variance.INVARIANT);
CallResolutionContext newContext = context.replaceBindingTrace(traceToResolveArgument).replaceExpectedType(expectedType); CallResolutionContext newContext = context.replaceBindingTrace(traceToResolveArgument).replaceExpectedType(expectedType);
TypeInfoForCall typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo(argumentExpression, newContext, JetTypeInfo typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo(argumentExpression, newContext,
resolveFunctionArgumentBodies); resolveFunctionArgumentBodies, traceToResolveArgument);
CallCandidateResolutionContext<FunctionDescriptor> contextForArgument = typeInfoForCall.getCallCandidateResolutionContext();
if (contextForArgument != null) {
//todo return JetTypeInfo instead of TypeInfoForCall, remove TypeInfoForCall
traceToResolveArgument.commit();
}
JetType type = typeInfoForCall.getType(); JetType type = typeInfoForCall.getType();
constraintSystem.addSubtypeConstraint(type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition( constraintSystem.addSubtypeConstraint(type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition(
valueParameterDescriptor.getIndex())); valueParameterDescriptor.getIndex()));
@@ -520,8 +517,8 @@ public class CandidateResolver {
} }
CallResolutionContext newContext = context.replaceDataFlowInfo(candidateCall.getDataFlowInfo()).replaceBindingTrace(trace) CallResolutionContext newContext = context.replaceDataFlowInfo(candidateCall.getDataFlowInfo()).replaceBindingTrace(trace)
.replaceExpectedType(expectedType); .replaceExpectedType(expectedType);
TypeInfoForCall typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo( JetTypeInfo typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo(
expression, newContext, resolveFunctionArgumentBodies); expression, newContext, resolveFunctionArgumentBodies, null);
JetType type = typeInfoForCall.getType(); JetType type = typeInfoForCall.getType();
candidateCall.addDataFlowInfo(typeInfoForCall.getDataFlowInfo()); candidateCall.addDataFlowInfo(typeInfoForCall.getDataFlowInfo());
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.types.DeferredType; import org.jetbrains.jet.lang.types.DeferredType;
@@ -104,12 +105,9 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor<JetTypeInfo, E
@NotNull @NotNull
private JetTypeInfo getTypeInfo(@NotNull JetExpression expression, ExpressionTypingContext context, JetVisitor<JetTypeInfo, ExpressionTypingContext> visitor) { private JetTypeInfo getTypeInfo(@NotNull JetExpression expression, ExpressionTypingContext context, JetVisitor<JetTypeInfo, ExpressionTypingContext> visitor) {
if (context.trace.get(BindingContext.PROCESSED, expression)) { JetTypeInfo recordedTypeInfo = BindingContextUtils.getRecordedTypeInfo(expression, context.trace.getBindingContext());
DataFlowInfo dataFlowInfo = context.trace.get(BindingContext.EXPRESSION_DATA_FLOW_INFO, expression); if (recordedTypeInfo != null) {
if (dataFlowInfo == null) { return recordedTypeInfo;
dataFlowInfo = DataFlowInfo.EMPTY;
}
return JetTypeInfo.create(context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression), dataFlowInfo);
} }
JetTypeInfo result; JetTypeInfo result;
try { try {
@@ -0,0 +1,16 @@
//KT-3344 InternalError in compiler when type arguments are not specified
package i
import java.util.HashMap
import java.util.ArrayList
class Foo(val attributes: Map<String, String>)
class Bar {
val foos = ArrayList<Foo>()
fun bar11(foo: Foo) {
foos.add(Foo(HashMap(foo.attributes))) // foo.attributes is unresolved but not marked
}
}
@@ -2338,6 +2338,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/inference/regressions/kt3301.kt"); doTest("compiler/testData/diagnostics/tests/inference/regressions/kt3301.kt");
} }
@TestMetadata("kt3344.kt")
public void testKt3344() throws Exception {
doTest("compiler/testData/diagnostics/tests/inference/regressions/kt3344.kt");
}
@TestMetadata("kt702.kt") @TestMetadata("kt702.kt")
public void testKt702() throws Exception { public void testKt702() throws Exception {
doTest("compiler/testData/diagnostics/tests/inference/regressions/kt702.kt"); doTest("compiler/testData/diagnostics/tests/inference/regressions/kt702.kt");