@@ -355,7 +355,7 @@ class InferenceVisitor
355355 for (Expression expression in node.expressions) {
356356 expressionResults.add (inferrer.inferExpression (
357357 expression, const UnknownType (), ! inferrer.isTopLevel,
358- isVoidAllowed: true ));
358+ isVoidAllowed: true , forEffect : true ));
359359 }
360360 List <Statement > body = [];
361361 for (int index = 0 ; index < expressionResults.length; index++ ) {
@@ -711,7 +711,7 @@ class InferenceVisitor
711711 StatementInferenceResult visitExpressionStatement (ExpressionStatement node) {
712712 ExpressionInferenceResult result = inferrer.inferExpression (
713713 node.expression, const UnknownType (), ! inferrer.isTopLevel,
714- isVoidAllowed: true );
714+ isVoidAllowed: true , forEffect : true );
715715 node.expression = result.expression..parent = node;
716716 return const StatementInferenceResult ();
717717 }
@@ -5083,7 +5083,11 @@ class InferenceVisitor
50835083 @override
50845084 ExpressionInferenceResult visitRethrow (Rethrow node, DartType typeContext) {
50855085 inferrer.flowAnalysis.handleExit ();
5086- return new ExpressionInferenceResult (const BottomType (), node);
5086+ return new ExpressionInferenceResult (
5087+ inferrer.isNonNullableByDefault
5088+ ? const NeverType (Nullability .nonNullable)
5089+ : const BottomType (),
5090+ node);
50875091 }
50885092
50895093 @override
@@ -5375,6 +5379,7 @@ class InferenceVisitor
53755379 inferrer.flowAnalysis.switchStatement_expressionEnd (node);
53765380
53775381 bool hasDefault = false ;
5382+ bool lastCaseTerminates = true ;
53785383 for (int caseIndex = 0 ; caseIndex < node.cases.length; ++ caseIndex) {
53795384 SwitchCaseImpl switchCase = node.cases[caseIndex];
53805385 hasDefault = hasDefault || switchCase.isDefault;
@@ -5441,19 +5446,56 @@ class InferenceVisitor
54415446 switchCase.body = bodyResult.statement..parent = switchCase;
54425447 }
54435448
5444- if (! inferrer.isTopLevel && inferrer.isNonNullableByDefault) {
5445- // The last case block is allowed to complete normally.
5446- if (caseIndex < node.cases.length - 1 &&
5447- inferrer.flowAnalysis.isReachable) {
5448- inferrer.library.addProblem (messageSwitchCaseFallThrough,
5449- switchCase.fileOffset, noLength, inferrer.helper.uri);
5449+ if (inferrer.isNonNullableByDefault) {
5450+ lastCaseTerminates = ! inferrer.flowAnalysis.isReachable;
5451+ if (! inferrer.isTopLevel) {
5452+ // The last case block is allowed to complete normally.
5453+ if (caseIndex < node.cases.length - 1 &&
5454+ inferrer.flowAnalysis.isReachable) {
5455+ inferrer.library.addProblem (messageSwitchCaseFallThrough,
5456+ switchCase.fileOffset, noLength, inferrer.helper.uri);
5457+ }
54505458 }
54515459 }
54525460 }
54535461 bool isExhaustive =
54545462 hasDefault || (enumFields != null && enumFields.isEmpty);
54555463 inferrer.flowAnalysis.switchStatement_end (isExhaustive);
5456- return const StatementInferenceResult ();
5464+ Statement replacement;
5465+ if (isExhaustive &&
5466+ ! hasDefault &&
5467+ inferrer.shouldThrowUnsoundnessException) {
5468+ if (! lastCaseTerminates) {
5469+ LabeledStatement breakTarget;
5470+ if (node.parent is LabeledStatement ) {
5471+ breakTarget = node.parent;
5472+ } else {
5473+ replacement = breakTarget = new LabeledStatement (node);
5474+ }
5475+
5476+ SwitchCase lastCase = node.cases.last;
5477+ Statement body = lastCase.body;
5478+ if (body is Block ) {
5479+ body.statements.add (new BreakStatementImpl (isContinue: false )
5480+ ..target = breakTarget
5481+ ..targetStatement = node
5482+ ..fileOffset = node.fileOffset);
5483+ }
5484+ }
5485+ node.cases.add (new SwitchCase (
5486+ [],
5487+ [],
5488+ _createExpressionStatement (inferrer.createReachabilityError (
5489+ node.fileOffset,
5490+ messageNeverReachableSwitchDefaultError,
5491+ messageNeverReachableSwitchDefaultWarning)),
5492+ isDefault: true )
5493+ ..fileOffset = node.fileOffset
5494+ ..parent = node);
5495+ }
5496+ return replacement != null
5497+ ? new StatementInferenceResult .single (replacement)
5498+ : const StatementInferenceResult ();
54575499 }
54585500
54595501 @override
0 commit comments