diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java index 363f8cd67a7..c6b7c24f2a6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.resolve; import com.google.common.collect.ImmutableMap; +import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiElement; import kotlin.annotations.jvm.ReadOnly; import org.jetbrains.annotations.NotNull; @@ -15,7 +16,6 @@ import org.jetbrains.kotlin.cfg.LeakingThisDescriptor; import org.jetbrains.kotlin.cfg.TailRecursionKind; import org.jetbrains.kotlin.contracts.description.InvocationKind; import org.jetbrains.kotlin.contracts.model.Computation; -import org.jetbrains.kotlin.contracts.model.Functor; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.kotlin.name.FqName; @@ -264,6 +264,8 @@ public interface BindingContext { WritableSlice PRIMITIVE_NUMERIC_COMPARISON_INFO = Slices.createSimpleSlice(); + WritableSlice> NEW_INFERENCE_CATCH_EXCEPTION_PARAMETER = Slices.createSimpleSlice(); + @SuppressWarnings("UnusedDeclaration") @Deprecated // This field is needed only for the side effects of its initializer Void _static_initializer = BasicWritableSlice.initSliceDebugNames(BindingContext.class); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt index 38aafcf8458..f7fc1da4619 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.referenceExpression import org.jetbrains.kotlin.resolve.* +import org.jetbrains.kotlin.resolve.BindingContext.NEW_INFERENCE_CATCH_EXCEPTION_PARAMETER import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver import org.jetbrains.kotlin.resolve.calls.CallTransformer import org.jetbrains.kotlin.resolve.calls.KotlinCallResolver @@ -40,9 +41,7 @@ import org.jetbrains.kotlin.resolve.calls.util.CallMaker import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns -import org.jetbrains.kotlin.resolve.scopes.LexicalScope -import org.jetbrains.kotlin.resolve.scopes.MemberScope -import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes +import org.jetbrains.kotlin.resolve.scopes.* import org.jetbrains.kotlin.resolve.scopes.receivers.* import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.expressions.* @@ -632,6 +631,7 @@ class PSICallResolver( val context = outerCallContext.replaceContextDependency(ContextDependency.DEPENDENT) .replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceDataFlowInfo(startDataFlowInfo) + .expandContextForCatchClause(ktExpression) if (ktExpression is KtCallableReferenceExpression) { checkNoSpread(outerCallContext, valueArgument) @@ -683,4 +683,20 @@ class PSICallResolver( val typeInfo = expressionTypingServices.getTypeInfo(argumentExpression, context) return createSimplePSICallArgument(context, valueArgument, typeInfo) ?: parseErrorArgument } + + private fun BasicCallResolutionContext.expandContextForCatchClause(ktExpression: Any): BasicCallResolutionContext { + if (ktExpression !is KtExpression) return this + + val variableDescriptorHolder = trace.bindingContext[NEW_INFERENCE_CATCH_EXCEPTION_PARAMETER, ktExpression] ?: return this + val variableDescriptor = variableDescriptorHolder.get() ?: return this + variableDescriptorHolder.set(null) + + val redeclarationChecker = expressionTypingServices.createLocalRedeclarationChecker(trace) + + val catchScope = with(scope) { + LexicalWritableScope(this, ownerDescriptor, false, redeclarationChecker, LexicalScopeKind.CATCH) + } + catchScope.addVariableDescriptor(variableDescriptor) + return replaceScope(catchScope) + } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java index 82e9ee48c73..7f5cb9d0f8d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java @@ -22,6 +22,7 @@ import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Ref; import com.intellij.psi.util.PsiTreeUtil; +import kotlin.Pair; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; @@ -35,6 +36,7 @@ import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl; import org.jetbrains.kotlin.lexer.KtTokens; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.*; +import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.BindingContextUtils; import org.jetbrains.kotlin.resolve.BindingTrace; import org.jetbrains.kotlin.resolve.calls.CallResolver; @@ -67,7 +69,7 @@ public class ControlStructureTypingUtils { private static final Logger LOG = Logger.getInstance(ControlStructureTypingUtils.class); public enum ResolveConstruct { - IF("if"), ELVIS("elvis"), EXCL_EXCL("ExclExcl"), WHEN("when"); + IF("if"), ELVIS("elvis"), EXCL_EXCL("ExclExcl"), WHEN("when"), TRY("try"); private final String name; private final Name specialFunctionName; @@ -116,6 +118,39 @@ public class ControlStructureTypingUtils { ) { SimpleFunctionDescriptorImpl function = createFunctionDescriptorForSpecialConstruction( construct, argumentNames, isArgumentNullable); + return resolveSpecialConstructionAsCall(call, function, construct, context, dataFlowInfoForArguments); + } + + /*package*/ ResolvedCall resolveTryAsCall( + @NotNull Call call, + @NotNull KtTryExpression tryExpression, + @NotNull List> catchedExceptions, + @NotNull ExpressionTypingContext context, + @Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments + ) { + List argumentNames = Lists.newArrayList("tryBlock"); + List argumentsNullability = Lists.newArrayList(false); + for (int i = 0; i < tryExpression.getCatchClauses().size(); i++) { + argumentNames.add("catchBlock" + i); + argumentsNullability.add(false); + } + SimpleFunctionDescriptorImpl function = + createFunctionDescriptorForSpecialConstruction(ResolveConstruct.TRY, argumentNames, argumentsNullability); + for (Pair descriptorPair : catchedExceptions) { + KtExpression catchBlock = descriptorPair.getFirst(); + VariableDescriptor catchedExceptionDescriptor = descriptorPair.getSecond(); + context.trace.record(BindingContext.NEW_INFERENCE_CATCH_EXCEPTION_PARAMETER, catchBlock, Ref.create(catchedExceptionDescriptor)); + } + return resolveSpecialConstructionAsCall(call, function, ResolveConstruct.TRY, context, dataFlowInfoForArguments); + } + + private ResolvedCall resolveSpecialConstructionAsCall( + @NotNull Call call, + @NotNull SimpleFunctionDescriptorImpl function, + @NotNull ResolveConstruct construct, + @NotNull ExpressionTypingContext context, + @Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments + ) { TracingStrategy tracing = createTracingForSpecialConstruction(call, construct.getName(), context); TypeSubstitutor knownTypeParameterSubstitutor = createKnownTypeParameterSubstitutorForSpecialCall(construct, function, context.expectedType, context.languageVersionSettings); ResolutionCandidate resolutionCandidate = @@ -252,6 +287,20 @@ public class ControlStructureTypingUtils { return createIndependentDataFlowInfoForArgumentsForCall(subjectDataFlowInfo, dataFlowInfoForArgumentsMap); } + public static MutableDataFlowInfoForArguments createDataFlowInfoForArgumentsOfTryCall( + @NotNull Call callForTry, + @NotNull DataFlowInfo dataFlowInfoBeforeTry, + @NotNull DataFlowInfo dataFlowInfoAfterTry + ) { + Map dataFlowInfoForArgumentsMap = new HashMap<>(); + List valueArguments = callForTry.getValueArguments(); + dataFlowInfoForArgumentsMap.put(valueArguments.get(0), dataFlowInfoBeforeTry); + for (int i = 1; i < valueArguments.size(); i++) { + dataFlowInfoForArgumentsMap.put(valueArguments.get(i), dataFlowInfoAfterTry); + } + return createIndependentDataFlowInfoForArgumentsForCall(dataFlowInfoBeforeTry, dataFlowInfoForArgumentsMap); + } + /*package*/ static Call createCallForSpecialConstruction( @NotNull KtExpression expression, @NotNull KtExpression calleeExpression, diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java index be932fcb7f5..0d8c4fae9d9 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.types.expressions; import com.google.common.collect.Lists; import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; +import kotlin.collections.CollectionsKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; @@ -47,13 +48,13 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; import static org.jetbrains.kotlin.diagnostics.Errors.*; import static org.jetbrains.kotlin.resolve.BindingContext.*; import static org.jetbrains.kotlin.resolve.calls.context.ContextDependency.INDEPENDENT; import static org.jetbrains.kotlin.types.TypeUtils.*; -import static org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.createCallForSpecialConstruction; -import static org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.createDataFlowInfoForArgumentsForIfCall; +import static org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.*; import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*; public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { @@ -489,6 +490,9 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { @Override public KotlinTypeInfo visitTryExpression(@NotNull KtTryExpression expression, ExpressionTypingContext typingContext) { + if (typingContext.languageVersionSettings.supportsFeature(LanguageFeature.NewInference)) { + return resolveTryExpressionWithNewInference(expression, typingContext); + } ExpressionTypingContext context = typingContext.replaceContextDependency(INDEPENDENT); KtExpression tryBlock = expression.getTryBlock(); List catchClauses = expression.getCatchClauses(); @@ -500,15 +504,8 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { KtExpression catchBody = catchClause.getCatchBody(); boolean nothingInCatchBranch = false; if (catchParameter != null) { - checkCatchParameterDeclaration(catchParameter, context); + VariableDescriptor variableDescriptor = resolveAndCheckCatchParameter(catchParameter, context); - VariableDescriptor variableDescriptor = components.descriptorResolver.resolveLocalVariableDescriptor( - context.scope, catchParameter, context.trace); - KotlinType catchParameterType = variableDescriptor.getType(); - checkCatchParameterType(catchParameter, catchParameterType, context); - - KotlinType throwableType = components.builtIns.getThrowable().getDefaultType(); - components.dataFlowAnalyzer.checkType(catchParameterType, catchParameter, context.replaceExpectedType(throwableType)); if (catchBody != null) { LexicalWritableScope catchScope = newWritableScopeImpl(context, LexicalScopeKind.CATCH, components.overloadChecker); catchScope.addVariableDescriptor(variableDescriptor); @@ -527,15 +524,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { } KotlinTypeInfo tryResult = facade.getTypeInfo(tryBlock, context); - ExpressionTypingContext tryOutputContext = context.replaceExpectedType(NO_EXPECTED_TYPE); - if (!nothingInAllCatchBranches && - facade.getComponents().languageVersionSettings.supportsFeature(LanguageFeature.SoundSmartCastsAfterTry)) { - PreliminaryLoopVisitor tryVisitor = PreliminaryLoopVisitor.visitTryBlock(expression); - tryOutputContext = tryOutputContext.replaceDataFlowInfo( - tryVisitor.clearDataFlowInfoForAssignedLocalVariables(tryOutputContext.dataFlowInfo, - components.languageVersionSettings) - ); - } + ExpressionTypingContext tryOutputContext = getCleanedContextFromTryWithAssignmentsToVar(expression, nothingInAllCatchBranches, context); KotlinTypeInfo result = TypeInfoFactoryKt.noTypeInfo(tryOutputContext); if (finallyBlock != null) { @@ -557,6 +546,129 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { } } + private KotlinTypeInfo resolveTryExpressionWithNewInference(@NotNull KtTryExpression tryExpression, ExpressionTypingContext tryInputContext) { + // tryInputContext is an ExpressionTypingContext before try/catch expression + + KtBlockExpression tryBlock = tryExpression.getTryBlock(); + List catchClauses = tryExpression.getCatchClauses(); + KtFinallySection finallySection = tryExpression.getFinallyBlock(); + + DataFlowInfo dataFlowInfoBeforeTry = tryInputContext.dataFlowInfo; + + List catchBlocks = Lists.newArrayList(); + List> catchClausesBlocksAndParameters = Lists.newArrayList(); + + for (KtCatchClause catchClause : catchClauses) { + KtParameter catchParameter = catchClause.getCatchParameter(); + KtExpression catchBody = catchClause.getCatchBody(); + if (catchParameter != null) { + VariableDescriptor variableDescriptor = resolveAndCheckCatchParameter(catchParameter, tryInputContext); + if (catchBody != null) { + catchBlocks.add(catchBody); + catchClausesBlocksAndParameters.add(new kotlin.Pair<>(catchBody, variableDescriptor)); + } + } + } + + KtBlockExpression finallyBlock = null; + if (finallySection != null) { + finallyBlock = finallySection.getFinalExpression(); + } + + List arguments = Lists.newArrayList(tryBlock); + arguments.addAll(catchBlocks); + + Call callForTry = createCallForSpecialConstruction(tryExpression, tryExpression, arguments); + + MutableDataFlowInfoForArguments dataFlowInfoForArguments = createDataFlowInfoForArgumentsOfTryCall(callForTry, dataFlowInfoBeforeTry, dataFlowInfoBeforeTry); + ResolvedCall resolvedCall = components.controlStructureTypingUtils + .resolveTryAsCall(callForTry, tryExpression, catchClausesBlocksAndParameters, tryInputContext, dataFlowInfoForArguments); + KotlinType resultType = resolvedCall.getResultingDescriptor().getReturnType(); + + BindingContext bindingContext = tryInputContext.trace.getBindingContext(); + + return processTryBranches(tryExpression, tryBlock, tryInputContext, catchBlocks, finallyBlock, bindingContext, resultType); + } + + @NotNull + private KotlinTypeInfo processTryBranches( + @NotNull KtTryExpression tryExpression, + KtBlockExpression tryBlock, + ExpressionTypingContext context, + List catchBlocks, + KtBlockExpression finallyBlock, + BindingContext bindingContext, + KotlinType resultType + ) { + KotlinTypeInfo tryInfo = BindingContextUtils.getRecordedTypeInfo(tryBlock, bindingContext); + DataFlowInfo dataFlowInfoAfterTry; + if (tryInfo != null) { + dataFlowInfoAfterTry = tryInfo.getDataFlowInfo(); + } + else { + dataFlowInfoAfterTry = DataFlowInfo.Companion.getEMPTY(); + } + boolean nothingInAllCatchBranches = isCatchBranchesReturnsNothing(catchBlocks, bindingContext); + + // it is not actually correct way (#KT-28370) of computing context, but it's how was in OI + ExpressionTypingContext tryOutputContext = getCleanedContextFromTryWithAssignmentsToVar(tryExpression, nothingInAllCatchBranches, context); + + KotlinTypeInfo result = TypeInfoFactoryKt.createTypeInfo(resultType, tryOutputContext); + + if (finallyBlock != null) { + return facade.getTypeInfo(finallyBlock, tryOutputContext).replaceType(resultType); + } else if (!nothingInAllCatchBranches || tryInfo == null) { + return result; + } else { + return TypeInfoFactoryKt.createTypeInfo( + components.dataFlowAnalyzer.checkType(resultType, tryExpression, tryOutputContext), + dataFlowInfoAfterTry + ); + } + } + + private static boolean isCatchBranchesReturnsNothing(List catchBlocks, BindingContext bindingContext) { + return CollectionsKt.all(whichCatchBranchesReturnNothing(catchBlocks, bindingContext), it -> it); + } + + private static List whichCatchBranchesReturnNothing(List catchBlocks, BindingContext bindingContext) { + return catchBlocks.stream() + .map(catchBlock -> BindingContextUtils.getRecordedTypeInfo(catchBlock, bindingContext)) + .map(catchTypeInfo -> { + if (catchTypeInfo == null) return true; + KotlinType catchType = catchTypeInfo.getType(); + return catchType == null || KotlinBuiltIns.isNothing(catchType); + }) + .collect(Collectors.toList()); + } + + private VariableDescriptor resolveAndCheckCatchParameter(@NotNull KtParameter catchParameter, ExpressionTypingContext context) { + checkCatchParameterDeclaration(catchParameter, context); + + VariableDescriptor variableDescriptor = components.descriptorResolver + .resolveLocalVariableDescriptor(context.scope, catchParameter, context.trace); + KotlinType catchParameterType = variableDescriptor.getType(); + checkCatchParameterType(catchParameter, catchParameterType, context); + KotlinType throwableType = components.builtIns.getThrowable().getDefaultType(); + components.dataFlowAnalyzer.checkType(catchParameterType, catchParameter, context.replaceExpectedType(throwableType)); + return variableDescriptor; + } + + private ExpressionTypingContext getCleanedContextFromTryWithAssignmentsToVar( + KtTryExpression tryExpression, + boolean nothingInAllCatchBranches, + ExpressionTypingContext context + ) { + context = context.replaceExpectedType(NO_EXPECTED_TYPE); + if (!nothingInAllCatchBranches && facade.getComponents().languageVersionSettings.supportsFeature(LanguageFeature.SoundSmartCastsAfterTry)) { + PreliminaryLoopVisitor tryVisitor = PreliminaryLoopVisitor.visitTryBlock(tryExpression); + context = context.replaceDataFlowInfo( + tryVisitor.clearDataFlowInfoForAssignedLocalVariables(context.dataFlowInfo, components.languageVersionSettings) + ); + } + return context; + } + private static void checkCatchParameterType(KtParameter catchParameter, KotlinType catchParameterType, ExpressionTypingContext context) { TypeParameterDescriptor typeParameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(catchParameterType); if (typeParameterDescriptor != null) { @@ -679,7 +791,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { } else { KotlinTypeInfo result = facade .getTypeInfo(returnedExpression, context.replaceExpectedType(newInferenceLambdaInfo.getExpectedType()) - .replaceContextDependency(newInferenceLambdaInfo.getContextDependency())); + .replaceContextDependency(newInferenceLambdaInfo.getContextDependency())); contextInfo = new LambdaContextInfo(result, null, context.scope, context.trace); } newInferenceLambdaInfo.getReturnStatements().add(new kotlin.Pair<>(expression, contextInfo)); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java index 0342abe4db1..510f038c0b2 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java @@ -24,10 +24,7 @@ import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue; import org.jetbrains.kotlin.resolve.calls.tower.KotlinResolutionCallbacksImpl; -import org.jetbrains.kotlin.resolve.scopes.LexicalScope; -import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind; -import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope; -import org.jetbrains.kotlin.resolve.scopes.TraceBasedLocalRedeclarationChecker; +import org.jetbrains.kotlin.resolve.scopes.*; import org.jetbrains.kotlin.types.ErrorUtils; import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt; @@ -380,4 +377,8 @@ public class ExpressionTypingServices { return slice == BindingContext.EXPRESSION_EFFECTS; } } + + public LocalRedeclarationChecker createLocalRedeclarationChecker(BindingTrace trace) { + return new TraceBasedLocalRedeclarationChecker(trace, expressionTypingComponents.overloadChecker); + } } diff --git a/compiler/testData/diagnostics/tests/controlStructures/tryReturnType.kt b/compiler/testData/diagnostics/tests/controlStructures/tryReturnType.kt index bf6b56583a9..bbc53466ce3 100644 --- a/compiler/testData/diagnostics/tests/controlStructures/tryReturnType.kt +++ b/compiler/testData/diagnostics/tests/controlStructures/tryReturnType.kt @@ -14,15 +14,15 @@ fun foo() : Int { } fun bar() : Int = - try { - doSmth() + try { + doSmth() } catch (e: Exception) { - "" + "" } finally { "" - } + } fun doSmth() {} diff --git a/compiler/testData/diagnostics/testsWithStdLib/tryCatch/assignTry.kt b/compiler/testData/diagnostics/testsWithStdLib/tryCatch/assignTry.kt index 9c3cf9a5d41..e1e5ce1244f 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/tryCatch/assignTry.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/tryCatch/assignTry.kt @@ -5,15 +5,15 @@ class ExcA : Exception() class ExcB : Exception() fun test2() { - val s: String? = try { + val s: String? = try { "" } catch (e: ExcA) { null } catch (e: ExcB) { - 10 - } + 10 + } s.length } diff --git a/compiler/testData/diagnostics/testsWithStdLib/tryCatch/tryExpression.kt b/compiler/testData/diagnostics/testsWithStdLib/tryCatch/tryExpression.kt index f414096b90c..406bf9d4730 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/tryCatch/tryExpression.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/tryCatch/tryExpression.kt @@ -13,8 +13,8 @@ fun test0(): List = run { } } -fun test1(): Map = run { - try { +fun test1(): Map = run { + try { emptyMap() } catch (e: ExcA) { emptyMap() @@ -22,13 +22,13 @@ fun test1(): Map = run { e.map } finally { "" - } -} + } +} -fun test2(): Map = run { - try { +fun test2(): Map = run { + try { emptyMap() } catch (e: ExcA) { - mapOf("" to "") + mapOf("" to "") } -} \ No newline at end of file +} \ No newline at end of file