diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index 1485bb0056b..03199499b0a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -232,6 +232,14 @@ public interface Errors { ParameterizedDiagnosticFactory1 RETURN_TYPE_MISMATCH = ParameterizedDiagnosticFactory1.create(ERROR, "This function must return a value of type {0}"); ParameterizedDiagnosticFactory1 EXPECTED_TYPE_MISMATCH = ParameterizedDiagnosticFactory1.create(ERROR, "Expected a value of type {0}"); ParameterizedDiagnosticFactory1 ASSIGNMENT_TYPE_MISMATCH = ParameterizedDiagnosticFactory1.create(ERROR, "Expected a value of type {0}. Assignment operation is not an expression, so it does not return any value"); + ParameterizedDiagnosticFactory1 IMPLICIT_CAST_TO_UNIT_OR_ANY = ParameterizedDiagnosticFactory1.create(WARNING, "Type was casted to ''{0}''. Please specify ''{0}'' as expected type, if you mean such cast"); + ParameterizedDiagnosticFactory1 EXPRESSION_EXPECTED = new ParameterizedDiagnosticFactory1(ERROR, "{0} is not an expression, and only expression are allowed here") { + @Override + protected String makeMessageFor(JetExpression expression) { + String expressionType = expression.toString(); + return expressionType.substring(0, 1) + expressionType.substring(1).toLowerCase(); + } + }; ParameterizedDiagnosticFactory1 UPPER_BOUND_VIOLATED = ParameterizedDiagnosticFactory1.create(ERROR, "An upper bound {0} is violated"); // TODO : Message ParameterizedDiagnosticFactory1 FINAL_CLASS_OBJECT_UPPER_BOUND = ParameterizedDiagnosticFactory1.create(ERROR, "{0} is a final type, and thus a class object cannot extend it"); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java index a6e120b1e8d..b795a4cea1e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java @@ -242,6 +242,11 @@ public class JetStandardClasses { public static JetType getAnyType() { return ANY_TYPE; } + + public static boolean isAny(JetType type) { + return !(type instanceof NamespaceType) && + type.getConstructor() == ANY_TYPE.getConstructor(); + } public static JetType getNullableAnyType() { return NULLABLE_ANY_TYPE; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index a2898afa2dd..a4b19717143 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -110,11 +110,15 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { @Override public JetType visitParenthesizedExpression(JetParenthesizedExpression expression, ExpressionTypingContext context) { + return visitParenthesizedExpression(expression, context, false); + } + + public JetType visitParenthesizedExpression(JetParenthesizedExpression expression, ExpressionTypingContext context, boolean isStatement) { JetExpression innerExpression = expression.getExpression(); if (innerExpression == null) { return null; } - return DataFlowUtils.checkType(facade.getType(innerExpression, context.replaceScope(context.scope)), expression, context); + return DataFlowUtils.checkType(facade.getType(innerExpression, context.replaceScope(context.scope), isStatement), expression, context); } @Override @@ -479,7 +483,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { @Override public JetType visitBlockExpression(JetBlockExpression expression, ExpressionTypingContext context) { - return context.getServices().getBlockReturnedType(context.scope, expression, CoercionStrategy.NO_COERCION, context); + return visitBlockExpression(expression, context, false); + } + + public JetType visitBlockExpression(JetBlockExpression expression, ExpressionTypingContext context, boolean isStatement) { + return context.getServices().getBlockReturnedType(context.scope, expression, isStatement ? CoercionStrategy.COERCION_TO_UNIT : CoercionStrategy.NO_COERCION, context); } @Override @@ -611,6 +619,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { @Override public JetType visitUnaryExpression(JetUnaryExpression expression, ExpressionTypingContext context) { + return visitUnaryExpression(expression, context, false); + } + + public JetType visitUnaryExpression(JetUnaryExpression expression, ExpressionTypingContext context, boolean isStatement) { JetExpression baseExpression = expression.getBaseExpression(); if (baseExpression == null) return null; JetSimpleNameExpression operationSign = expression.getOperationReference(); @@ -619,9 +631,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { referencedName = referencedName == null ? " " : referencedName; context.labelResolver.enterLabeledElement(referencedName.substring(1), baseExpression); // TODO : Some processing for the label? - JetType type = DataFlowUtils.checkType(facade.getType(baseExpression, context.replaceExpectedReturnType(context.expectedType)), expression, context); + ExpressionTypingContext newContext = context.replaceExpectedReturnType(context.expectedType); + JetType type = facade.getType(baseExpression, newContext, isStatement); context.labelResolver.exitLabeledElement(baseExpression); - return type; + return DataFlowUtils.checkType(type, expression, context); } IElementType operationType = operationSign.getReferencedNameElementType(); String name = OperatorConventions.UNARY_OPERATION_NAMES.get(operationType); @@ -835,6 +848,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } private JetType assignmentIsNotAnExpressionError(JetBinaryExpression expression, ExpressionTypingContext context) { + facade.checkStatementType(expression, context.replaceExpectedType(NO_EXPECTED_TYPE)); context.trace.report(ASSIGNMENT_IN_EXPRESSION_CONTEXT.on(expression)); return null; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java index f573e39e79a..4b258197df0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java @@ -12,8 +12,6 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.DescriptorUtils; -import org.jetbrains.jet.lang.resolve.calls.TaskPrioritizers; -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.JetScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; @@ -54,7 +52,11 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { @Override - public JetType visitIfExpression(JetIfExpression expression, ExpressionTypingContext contextWithExpectedType) { + public JetType visitIfExpression(JetIfExpression expression, ExpressionTypingContext context) { + return visitIfExpression(expression, context, false); + } + + public JetType visitIfExpression(JetIfExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); JetExpression condition = expression.getCondition(); checkCondition(context.scope, condition, context); @@ -73,7 +75,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { if (type != null && JetStandardClasses.isNothing(type)) { facade.setResultingDataFlowInfo(elseInfo); } - return DataFlowUtils.checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType); + return DataFlowUtils.checkImplicitCast(DataFlowUtils.checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType), expression, contextWithExpectedType, isStatement); } return null; } @@ -82,10 +84,11 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { if (type != null && JetStandardClasses.isNothing(type)) { facade.setResultingDataFlowInfo(thenInfo); } - return DataFlowUtils.checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType); + return DataFlowUtils.checkImplicitCast(DataFlowUtils.checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType), expression, contextWithExpectedType, isStatement); } - JetType thenType = context.getServices().getBlockReturnedTypeWithWritableScope(thenScope, Collections.singletonList(thenBranch), CoercionStrategy.NO_COERCION, contextWithExpectedType.replaceDataFlowInfo(thenInfo)); - JetType elseType = context.getServices().getBlockReturnedTypeWithWritableScope(elseScope, Collections.singletonList(elseBranch), CoercionStrategy.NO_COERCION, contextWithExpectedType.replaceDataFlowInfo(elseInfo)); + CoercionStrategy coercionStrategy = isStatement ? CoercionStrategy.COERCION_TO_UNIT : CoercionStrategy.NO_COERCION; + JetType thenType = context.getServices().getBlockReturnedTypeWithWritableScope(thenScope, Collections.singletonList(thenBranch), coercionStrategy, contextWithExpectedType.replaceDataFlowInfo(thenInfo)); + JetType elseType = context.getServices().getBlockReturnedTypeWithWritableScope(elseScope, Collections.singletonList(elseBranch), coercionStrategy, contextWithExpectedType.replaceDataFlowInfo(elseInfo)); JetType result; if (thenType == null) { @@ -107,11 +110,18 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { else if (jumpInElse && !jumpInThen) { facade.setResultingDataFlowInfo(thenInfo); } - return result; + if (result == null) return null; + return DataFlowUtils.checkImplicitCast(result, expression, contextWithExpectedType, isStatement); } @Override - public JetType visitWhileExpression(JetWhileExpression expression, ExpressionTypingContext contextWithExpectedType) { + public JetType visitWhileExpression(JetWhileExpression expression, ExpressionTypingContext context) { + return visitWhileExpression(expression, context, false); + } + + public JetType visitWhileExpression(JetWhileExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { + if (!isStatement) return DataFlowUtils.illegalStatementType(expression, contextWithExpectedType, facade); + ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); JetExpression condition = expression.getCondition(); checkCondition(context.scope, condition, context); @@ -152,7 +162,12 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { } @Override - public JetType visitDoWhileExpression(JetDoWhileExpression expression, ExpressionTypingContext contextWithExpectedType) { + public JetType visitDoWhileExpression(JetDoWhileExpression expression, ExpressionTypingContext context) { + return visitDoWhileExpression(expression, context, false); + } + public JetType visitDoWhileExpression(JetDoWhileExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { + if (!isStatement) return DataFlowUtils.illegalStatementType(expression, contextWithExpectedType, facade); + ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); JetExpression body = expression.getBody(); JetScope conditionScope = context.scope; @@ -181,7 +196,13 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { } @Override - public JetType visitForExpression(JetForExpression expression, ExpressionTypingContext contextWithExpectedType) { + public JetType visitForExpression(JetForExpression expression, ExpressionTypingContext context) { + return visitForExpression(expression, context, false); + } + + public JetType visitForExpression(JetForExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { + if (!isStatement) return DataFlowUtils.illegalStatementType(expression, contextWithExpectedType, facade); + ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); JetParameter loopParameter = expression.getLoopParameter(); JetExpression loopRange = expression.getLoopRange(); @@ -419,6 +440,4 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { context.labelResolver.recordLabel(expression, context); return DataFlowUtils.checkType(JetStandardClasses.getNothingType(), expression, context); } - - } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java index e8e4e992221..3ff9bd46936 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java @@ -11,6 +11,7 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValue; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValueFactory; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; +import org.jetbrains.jet.lang.types.JetStandardClasses; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.TypeUtils; @@ -18,8 +19,7 @@ import org.jetbrains.jet.lexer.JetTokens; import java.util.List; -import static org.jetbrains.jet.lang.diagnostics.Errors.AUTOCAST_IMPOSSIBLE; -import static org.jetbrains.jet.lang.diagnostics.Errors.TYPE_MISMATCH; +import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.resolve.BindingContext.AUTOCAST; /** @@ -154,4 +154,30 @@ public class DataFlowUtils { context.trace.report(TYPE_MISMATCH.on(expression, context.expectedType, expressionType)); return expressionType; } + + @Nullable + public static JetType checkStatementType(@NotNull JetExpression expression, @NotNull ExpressionTypingContext context) { + if (context.expectedType != TypeUtils.NO_EXPECTED_TYPE && !JetStandardClasses.isUnit(context.expectedType)) { + context.trace.report(EXPECTED_TYPE_MISMATCH.on(expression, context.expectedType)); + return null; + } + return JetStandardClasses.getUnitType(); + } + + @Nullable + public static JetType checkImplicitCast(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull ExpressionTypingContext context, boolean isStatement) { + if (expressionType != null && context.expectedType == TypeUtils.NO_EXPECTED_TYPE && !isStatement && + (JetStandardClasses.isUnit(expressionType) || JetStandardClasses.isAny(expressionType))) { + context.trace.report(IMPLICIT_CAST_TO_UNIT_OR_ANY.on(expression, expressionType)); + + } + return expressionType; + } + + @Nullable + public static JetType illegalStatementType(@NotNull JetExpression expression, @NotNull ExpressionTypingContext context, @NotNull ExpressionTypingInternals facade) { + facade.checkStatementType(expression, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE)); + context.trace.report(EXPRESSION_EXPECTED.on(expression, expression)); + return null; + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingFacade.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingFacade.java index cb51c922781..033d70d3578 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingFacade.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingFacade.java @@ -14,7 +14,7 @@ public interface ExpressionTypingFacade { @Nullable JetType getType(@NotNull JetExpression expression, ExpressionTypingContext context); - + @Nullable - JetType getTypeForStatement(@NotNull JetExpression expression, ExpressionTypingContext context); + JetType getType(@NotNull JetExpression expression, ExpressionTypingContext context, boolean isStatement); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingInternals.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingInternals.java index 200174c6bc5..dc80d0c61f8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingInternals.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingInternals.java @@ -24,4 +24,6 @@ import org.jetbrains.jet.lang.types.JetType; JetType getSelectorReturnType(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetExpression selectorExpression, @NotNull ExpressionTypingContext context); void checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @NotNull JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context); + + void checkStatementType(@NotNull JetExpression expression, ExpressionTypingContext context); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java index 66769cd0f6e..3ed6dc0304e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java @@ -133,7 +133,7 @@ public class ExpressionTypingServices { getBlockReturnedType(newContext.scope, blockExpression, CoercionStrategy.COERCION_TO_UNIT, context); } else { - expressionTypingFacade.getType(bodyExpression, newContext); + expressionTypingFacade.getType(bodyExpression, newContext, !blockBody); } } @@ -159,7 +159,7 @@ public class ExpressionTypingServices { assert bodyExpression != null; JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace); expressionTypingFacade.getType(bodyExpression, ExpressionTypingContext.newContext(semanticServices, new HashMap(), new HashMap>(), new LabelResolver(), - trace, functionInnerScope, DataFlowInfo.EMPTY, NO_EXPECTED_TYPE, FORBIDDEN, false)); + trace, functionInnerScope, DataFlowInfo.EMPTY, NO_EXPECTED_TYPE, FORBIDDEN, false), !function.hasBlockBody()); //todo function literals final Collection returnedExpressions = Lists.newArrayList(); if (function.hasBlockBody()) { @@ -225,13 +225,13 @@ public class ExpressionTypingServices { final boolean[] mismatch = new boolean[1]; ObservableBindingTrace errorInterceptingTrace = makeTraceInterceptingTypeMismatch(temporaryTraceExpectingUnit, statementExpression, mismatch); newContext = createContext(newContext, errorInterceptingTrace, scope, newContext.dataFlowInfo, context.expectedType, context.expectedReturnType); - result = blockLevelVisitor.getTypeForStatement(statementExpression, newContext); + result = blockLevelVisitor.getType(statementExpression, newContext, true); if (mismatch[0]) { TemporaryBindingTrace temporaryTraceNoExpectedType = TemporaryBindingTrace.create(trace); mismatch[0] = false; ObservableBindingTrace interceptingTrace = makeTraceInterceptingTypeMismatch(temporaryTraceNoExpectedType, statementExpression, mismatch); newContext = createContext(newContext, interceptingTrace, scope, newContext.dataFlowInfo, NO_EXPECTED_TYPE, context.expectedReturnType); - result = blockLevelVisitor.getTypeForStatement(statementExpression, newContext); + result = blockLevelVisitor.getType(statementExpression, newContext, true); if (mismatch[0]) { temporaryTraceExpectingUnit.commit(); } @@ -245,11 +245,11 @@ public class ExpressionTypingServices { } else { newContext = createContext(newContext, trace, scope, newContext.dataFlowInfo, context.expectedType, context.expectedReturnType); - result = blockLevelVisitor.getTypeForStatement(statementExpression, newContext); + result = blockLevelVisitor.getType(statementExpression, newContext, true); } } else { - result = blockLevelVisitor.getTypeForStatement(statementExpression, newContext); + result = blockLevelVisitor.getType(statementExpression, newContext, true); if (coercionStrategyForLastExpression == CoercionStrategy.COERCION_TO_UNIT) { boolean mightBeUnit = false; if (statementExpression instanceof JetDeclaration) { @@ -271,7 +271,7 @@ public class ExpressionTypingServices { } } else { - result = blockLevelVisitor.getTypeForStatement(statementExpression, newContext); + result = blockLevelVisitor.getType(statementExpression, newContext, true); } DataFlowInfo newDataFlowInfo = blockLevelVisitor.getResultingDataFlowInfo(); 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 36db4c054db..1edb38e0318 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 @@ -40,7 +40,7 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor) { + var i = 0 + when (i) { + 1 => i-- + 2 => i = 2 // i is surrounded by a black border + else => j = 2 + } + System.out?.println(i) +} + +//KT-351 Distinguish statement and expression positions +val w = while (true) {} + +fun foo() { + var z = 2 + val r = { // type fun(): Int is inferred + if (true) { + 2 + } + else { + z = 34 + } + } + val f: fun(): Int = r + val g: fun(): Any = r +} + +//KT-735 Statements without braces are prohibited on the right side of when entries. +fun box() : Int { + val d = 2 + var z = 0 + when(d) { + is 5, is 3 => z++ + else => z = -1000 + } + return z +} + +//More tests + +fun test1() = while(true) {} +fun test2(): Unit = while(true) {} + +fun testCoercionToUnit() { + val simple: fun(): Unit = { + 41 + } + val withIf: fun(): Unit = { + if (true) { + 3 + } else { + 45 + } + } + val i = 34 + val withWhen : fun() : Unit = { + when(i) { + is 1 => { + val d = 34 + "1" + doSmth(d) + + } + is 2 => '4' + else => true + } + } + + var x = 43 + val checkType = { + if (true) { + x = 4 + } else { + 45 + } + } + val f : fun() : String = checkType +} + +fun doSmth(i: Int) {} + +fun testImplicitCoercion() { + val d = 21 + var z = 0 + var i = when(d) { + is 3 => null + is 4 => { val z = 23 } + else => z = 20 + } + + var u = when(d) { + is 3 => { + z = 34 + } + else => z-- + } + + var iff = if (true) { + z = 34 + } + val g = if (true) 4 + val h = if (false) 4 else {} + + bar(if (true) { + 4 + } + else { + z = 342 + }) +} + +fun bar(a: Unit) {} + +fun testStatementInExpressionContext() { + var z = 34 + val a1: Unit = z = 334 + val a2: Unit = while(true) {} + val f = for (i in 1..10) {} + if (true) return z = 34 + return while (true) {} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/regressions/kt629.jet b/compiler/testData/diagnostics/tests/regressions/kt629.jet index 3d52542ad7f..f0c8780ad9a 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt629.jet +++ b/compiler/testData/diagnostics/tests/regressions/kt629.jet @@ -18,6 +18,6 @@ fun box() : Boolean { fun box2() : Boolean { - var c = A() + var c = A() return (c.p = "yeah") && true } \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java b/compiler/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java index e765cef474a..d9071141007 100644 --- a/compiler/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java +++ b/compiler/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java @@ -326,9 +326,9 @@ public class JetTypeCheckerTest extends JetLiteFixture { } public void testLoops() throws Exception { - assertType("while (1) {1}", "Unit"); - assertType("do {1} while(1)", "Unit"); - assertType("for (i in 1) {1}", "Unit"); + assertType("{ while (1) {1} }", "fun(): Unit"); + assertType("{ do {1} while(1) }", "fun(): Unit"); + assertType("{ for (i in 1) {1} }", "fun(): Unit"); } public void testFunctionLiterals() throws Exception {