diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java index 97e5af06ac9..df7b1e48962 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java @@ -24,9 +24,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; -import org.jetbrains.jet.lang.resolve.calls.context.CallCandidateResolutionContext; -import org.jetbrains.jet.lang.resolve.calls.context.ResolutionContext; -import org.jetbrains.jet.lang.resolve.calls.context.TypeInfoForCall; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetTypeInfo; import org.jetbrains.jet.util.slicedmap.ReadOnlySlice; @@ -284,34 +282,31 @@ public class BindingContextUtils { }, 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(); 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) { - 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)) { - context.trace.record(BindingContext.RESOLUTION_SCOPE, expression, context.scope); + trace.record(BindingContext.RESOLUTION_SCOPE, expression, resolutionScope); } } @Nullable - public static TypeInfoForCall getRecordedTypeInfoForCall( - @NotNull JetExpression expression, - @NotNull ResolutionContext context - ) { - 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); + public static JetTypeInfo getRecordedTypeInfo(@NotNull JetExpression expression, @NotNull BindingContext context) { + if (!context.get(BindingContext.PROCESSED, expression)) return null; + DataFlowInfo dataFlowInfo = context.get(BindingContext.EXPRESSION_DATA_FLOW_INFO, expression); if (dataFlowInfo == null) { dataFlowInfo = DataFlowInfo.EMPTY; } - JetTypeInfo typeInfo = JetTypeInfo.create(context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression), dataFlowInfo); - CallCandidateResolutionContext callCandidateResolutionContext = - context.trace.get(BindingContext.DEFERRED_COMPUTATION_FOR_CALL, expression); - return TypeInfoForCall.create(typeInfo, callCandidateResolutionContext); + JetType type = context.get(BindingContext.EXPRESSION_TYPE, expression); + return JetTypeInfo.create(type, dataFlowInfo); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java index c2fbe10bfea..785aa08b403 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java @@ -48,7 +48,7 @@ import java.util.List; import java.util.Map; 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.calls.CallResolverUtil.*; import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS; @@ -161,43 +161,48 @@ public class ArgumentTypeResolver { } @NotNull - public TypeInfoForCall getArgumentTypeInfo( + public JetTypeInfo getArgumentTypeInfo( @Nullable JetExpression expression, @NotNull CallResolutionContext context, - @NotNull ResolveArgumentsMode resolveArgumentsMode + @NotNull ResolveArgumentsMode resolveArgumentsMode, + @Nullable TemporaryBindingTrace traceToCommitForCall ) { if (expression == null) { - return TypeInfoForCall.create(null, context.dataFlowInfo); + return JetTypeInfo.create(null, context.dataFlowInfo); } if (expression instanceof JetFunctionLiteralExpression) { - return TypeInfoForCall.create(getFunctionLiteralTypeInfo((JetFunctionLiteralExpression) expression, context, resolveArgumentsMode)); + return getFunctionLiteralTypeInfo((JetFunctionLiteralExpression) expression, context, resolveArgumentsMode); } - TypeInfoForCall cachedTypeInfo = getRecordedTypeInfoForCall(expression, context); - if (cachedTypeInfo != null) { - return cachedTypeInfo; + JetTypeInfo recordedTypeInfo = getRecordedTypeInfo(expression, context.trace.getBindingContext()); + if (recordedTypeInfo != null) { + return recordedTypeInfo; } //todo deparenthesize 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) { result = callExpressionResolver.getCallExpressionTypeInfoForCall( (JetCallExpression) expression, ReceiverValue.NO_RECEIVER, null, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE), ResolveMode.NESTED_CALL); } - if (expression instanceof JetQualifiedExpression) { + else { // expression instanceof JetQualifiedExpression result = callExpressionResolver.getQualifiedExpressionExtendedTypeInfo( (JetQualifiedExpression) expression, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE), ResolveMode.NESTED_CALL); } - if (result != null) { - recordExpressionType(expression, context, result.getTypeInfo()); - CallCandidateResolutionContext deferredContext = result.getCallCandidateResolutionContext(); - if (deferredContext != null) { - context.trace.record(BindingContext.DEFERRED_COMPUTATION_FOR_CALL, expression, deferredContext); - } - return result; + + recordExpressionType(expression, context.trace, context.scope, result.getTypeInfo()); + CallCandidateResolutionContext deferredContext = result.getCallCandidateResolutionContext(); + if (deferredContext != null) { + context.trace.record(BindingContext.DEFERRED_COMPUTATION_FOR_CALL, expression, deferredContext); } - return TypeInfoForCall.create( - expressionTypingServices.getTypeInfo(context.scope, expression, context.expectedType, context.dataFlowInfo, context.trace)); + if (traceToCommitForCall != null) { + traceToCommitForCall.commit(); + } + return result.getTypeInfo(); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java index 257ab9d490f..d8bc8ae38bb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java @@ -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.CallResolutionContext; 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.model.ResolvedCall; 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 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.SUPER_IS_NOT_AN_EXPRESSION; @@ -448,13 +450,8 @@ public class CandidateResolver { context.trace, "transient trace to resolve argument", argumentExpression); JetType expectedType = substitutor.substitute(effectiveExpectedType, Variance.INVARIANT); CallResolutionContext newContext = context.replaceBindingTrace(traceToResolveArgument).replaceExpectedType(expectedType); - TypeInfoForCall typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo(argumentExpression, newContext, - resolveFunctionArgumentBodies); - CallCandidateResolutionContext contextForArgument = typeInfoForCall.getCallCandidateResolutionContext(); - if (contextForArgument != null) { - //todo return JetTypeInfo instead of TypeInfoForCall, remove TypeInfoForCall - traceToResolveArgument.commit(); - } + JetTypeInfo typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo(argumentExpression, newContext, + resolveFunctionArgumentBodies, traceToResolveArgument); JetType type = typeInfoForCall.getType(); constraintSystem.addSubtypeConstraint(type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition( valueParameterDescriptor.getIndex())); @@ -520,8 +517,8 @@ public class CandidateResolver { } CallResolutionContext newContext = context.replaceDataFlowInfo(candidateCall.getDataFlowInfo()).replaceBindingTrace(trace) .replaceExpectedType(expectedType); - TypeInfoForCall typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo( - expression, newContext, resolveFunctionArgumentBodies); + JetTypeInfo typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo( + expression, newContext, resolveFunctionArgumentBodies, null); JetType type = typeInfoForCall.getType(); candidateCall.addDataFlowInfo(typeInfoForCall.getDataFlowInfo()); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java index 62ce3acb959..26866f6bc70 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java @@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.*; 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.scopes.WritableScope; import org.jetbrains.jet.lang.types.DeferredType; @@ -104,12 +105,9 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor visitor) { - if (context.trace.get(BindingContext.PROCESSED, expression)) { - DataFlowInfo dataFlowInfo = context.trace.get(BindingContext.EXPRESSION_DATA_FLOW_INFO, expression); - if (dataFlowInfo == null) { - dataFlowInfo = DataFlowInfo.EMPTY; - } - return JetTypeInfo.create(context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression), dataFlowInfo); + JetTypeInfo recordedTypeInfo = BindingContextUtils.getRecordedTypeInfo(expression, context.trace.getBindingContext()); + if (recordedTypeInfo != null) { + return recordedTypeInfo; } JetTypeInfo result; try { diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt3344.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt3344.kt new file mode 100644 index 00000000000..5202a4dcf65 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt3344.kt @@ -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) + +class Bar { + val foos = ArrayList() + + fun bar11(foo: Foo) { + foos.add(Foo(HashMap(foo.attributes))) // foo.attributes is unresolved but not marked + } +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index dd9540a289a..a46bee6ff6f 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -2338,6 +2338,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage 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") public void testKt702() throws Exception { doTest("compiler/testData/diagnostics/tests/inference/regressions/kt702.kt");