Skip to content

Commit 58b6f40

Browse files
committed
Issue 42797. Understand in legacy libraries that a function returning Never (in Null Safety library) never returns. (reland)
Initial: https://dart-review.googlesource.com/c/sdk/+/155500 Reverted: https://dart-review.googlesource.com/c/sdk/+/155540 Bug: #42797 Change-Id: I5f0f1df594ac678718f347ee80b1764f971e42e1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/155541 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
1 parent fc8a6d9 commit 58b6f40

File tree

10 files changed

+35
-11
lines changed

10 files changed

+35
-11
lines changed

pkg/analysis_server/benchmark/benchmarks.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,6 @@ class RunCommand extends Command {
224224
benchmarks.firstWhere((b) => b.id == benchmarkId, orElse: () {
225225
print("Benchmark '$benchmarkId' not found.");
226226
exit(1);
227-
// Never reached.
228-
return null;
229227
});
230228

231229
var actualIterations = repeatCount;

pkg/analysis_server/test/stress/replay/replay.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ class Driver {
129129
server.printStatistics();
130130
}
131131
exit(0);
132-
return null;
133132
}
134133

135134
/// Create and return a parser that can be used to parse the command-line

pkg/analyzer/lib/src/dart/analysis/driver.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ typedef WorkToWaitAfterComputingResult = Future<void> Function(String path);
9191
/// TODO(scheglov) Clean up the list of implicitly analyzed files.
9292
class AnalysisDriver implements AnalysisDriverGeneric {
9393
/// The version of data format, should be incremented on every format change.
94-
static const int DATA_VERSION = 106;
94+
static const int DATA_VERSION = 108;
9595

9696
/// The length of the list returned by [_computeDeclaredVariablesSignature].
9797
static const int _declaredVariablesSignatureLength = 4;

pkg/analyzer/lib/src/dart/resolver/exit_detector.dart

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:analyzer/dart/ast/ast.dart';
66
import 'package:analyzer/dart/ast/token.dart';
77
import 'package:analyzer/dart/ast/visitor.dart';
88
import 'package:analyzer/dart/element/element.dart';
9+
import 'package:analyzer/src/dart/element/type.dart';
910

1011
/// Instances of the class `ExitDetector` determine whether the visited AST node
1112
/// is guaranteed to terminate by executing a `return` statement, `throw`
@@ -423,7 +424,7 @@ class ExitDetector extends GeneralizingAstVisitor<bool> {
423424
}
424425
}
425426
Element element = node.methodName.staticElement;
426-
if (element != null && element.hasAlwaysThrows) {
427+
if (_elementExits(element)) {
427428
return true;
428429
}
429430
return _nodeExits(node.argumentList);
@@ -660,4 +661,14 @@ class ExitDetector extends GeneralizingAstVisitor<bool> {
660661
static bool exits(AstNode node) {
661662
return ExitDetector()._nodeExits(node);
662663
}
664+
665+
static bool _elementExits(Element element) {
666+
if (element is ExecutableElement) {
667+
var declaration = element.declaration;
668+
return declaration.hasAlwaysThrows ||
669+
identical(declaration.returnType, NeverTypeImpl.instance);
670+
}
671+
672+
return false;
673+
}
663674
}

pkg/analyzer/test/src/diagnostics/missing_return_test.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import 'package:analyzer/src/test_utilities/package_mixin.dart';
77
import 'package:test_reflective_loader/test_reflective_loader.dart';
88

99
import '../dart/resolution/driver_resolution.dart';
10+
import '../dart/resolution/with_null_safety_mixin.dart';
1011

1112
main() {
1213
defineReflectiveSuite(() {
1314
defineReflectiveTests(MissingReturnTest);
15+
defineReflectiveTests(MissingReturnWithNullSafetyTest);
1416
});
1517
}
1618

@@ -213,3 +215,23 @@ class B extends A {
213215
]);
214216
}
215217
}
218+
219+
@reflectiveTest
220+
class MissingReturnWithNullSafetyTest extends DriverResolutionTest
221+
with WithNullSafetyMixin {
222+
test_returnNever() async {
223+
newFile('/test/lib/a.dart', content: r'''
224+
Never foo() {
225+
throw 0;
226+
}
227+
''');
228+
await assertNoErrorsInCode(r'''
229+
// @dart = 2.8
230+
import 'a.dart';
231+
232+
int f() {
233+
foo();
234+
}
235+
''');
236+
}
237+
}

pkg/front_end/tool/_fasta/command_line.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,6 @@ Future<T> runProtectedFromAbort<T>(Future<T> Function() action,
502502
// treat this as a crash which is signalled by exiting with 255.
503503
exit(255);
504504
}
505-
return failingValue;
506505
}
507506

508507
abstract class ValueSpecification {

pkg/kernel/lib/src/tool/command_line_util.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,5 @@ class CommandLineHelper {
4040
print(e);
4141
exit(1);
4242
}
43-
return null;
4443
}
4544
}

pkg/test_runner/lib/src/expectation_set.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ class ExpectationSet {
4949
} on SyntaxError catch (error) {
5050
stderr.writeln(error.toString());
5151
exit(1);
52-
53-
throw "unreachable";
5452
}
5553
}
5654

pkg/test_runner/lib/src/process_queue.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1186,7 +1186,6 @@ class BatchRunnerProcess {
11861186
// it will always fail. So rather than re-trying a 1000+ times, we
11871187
// exit.
11881188
io.exit(1);
1189-
return true;
11901189
});
11911190
}
11921191

pkg/test_runner/lib/src/test_suite.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,6 @@ class StandardTestSuite extends TestSuite {
749749
// Unreachable.
750750
print("Cannot create URL for path $file. Not in build or dart directory.");
751751
exit(1);
752-
return null;
753752
}
754753

755754
String _uriForBrowserTest(String pathComponent) {

0 commit comments

Comments
 (0)