Issue 52409. Reading a Never typed getter makes the flow unreachable.

Bug: https://github.com/dart-lang/sdk/issues/52409
Change-Id: I675ed8f8cfa0d2e5327c2c6bc0fb1bda7bde038c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/303840
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Konstantin Shcheglov 2023-05-17 03:28:07 +00:00 committed by Commit Queue
parent 59bb1fce82
commit bd0e77c4fc
4 changed files with 61 additions and 0 deletions

View file

@ -1293,6 +1293,9 @@ mixin TypeAnalyzer<
receiverType: requiredType,
field: field,
);
if (operations.isNever(propertyType)) {
flow.handleExit();
}
flow.pushSubpattern(propertyType);
dispatchPattern(
context.withUnnecessaryWildcardKind(null),

View file

@ -8072,6 +8072,22 @@ main() {
]);
});
});
test('Read of Never typed getter makes unreachable', () {
h.addDownwardInfer(name: 'A', context: 'Object', result: 'A');
h.addMember('A', 'foo', 'Never');
h.run([
ifCase(
expr('Object'),
objectPattern(requiredType: 'A', fields: [
Var('foo').pattern().recordField('foo'),
]),
[
checkReachable(false),
],
),
]);
});
});
group('Pattern assignment:', () {

View file

@ -137,6 +137,20 @@ void f(int a) {
error(WarningCode.DEAD_CODE, 30, 7),
]);
}
test_objectPattern_neverTypedGetter() async {
await assertErrorsInCode(r'''
class A {
Never get foo => throw 0;
}
void f(Object x) {
if (x case A(foo: _)) {}
}
''', [
error(WarningCode.DEAD_CODE, 84, 2),
]);
}
}
@reflectiveTest

View file

@ -0,0 +1,28 @@
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
/// Regression test for https://github.com/dart-lang/sdk/issues/52409.
import 'package:expect/expect.dart';
import "../static_type_helper.dart";
class A {
Never get getterThatReturnsNever => throw 0;
}
void f(Object? x) {
int? y = 0; // implicitly promotes to `int`
switch (x) {
case A(getterThatReturnsNever: _):
y = null;
default:
}
// `y = null` was unreachable, so `y` should still be promoted to `int`
y.expectStaticType<Exactly<int>>();
}
void main() {
f(0);
}