Flag additional code as unreachable due to types Null and Never.

Several unusual constructs that lead to unreachable code are now
recognized by flow analysis:

- Control flow after an expression of the form `e ?? other` or `e ??=
  other`, where `e` has static type `Null` and `other` has static type
  `Never`, is considered unreachable.

- Control flow predicated on an expression of the form `e is Never`
  evaluating to `true` is considered unreachable.

- Control flow predicated on an expression of the form `e is! Never`
  evaluating to `false` is considered unreachable.

- Control flow on the RHS of a null-aware access such as
  `e?.property...`, `e?.property = ...` or `e?.method(...)`, where `e`
  has static type `Null`, is considered unreachable (Note: this can
  arise in the presence of extension methods).

Previously, these behaviors only took effect if `e` was a reference to
a local variable.

Note: the change to `regress/issue_31180` is because I’ve corrected
the behavior of implicit temporary variables to not undergo a type
change from `Null` to `dynamic`, so the dead code part of `null?[1]`
is now erroneous.  (I had to make this change in order for the last
bullet above to work properly; without it, the type change to
`dynamic` prevents flow analysis from recognizing that the code to the
right of `?.` is unreachable.)  There's no behavioral change to
correct code, but I've captured the behavioral change to incorrect
code in
`tests/language_2/null_aware/null_aware_index_on_null_error_test.dart`.

Bug: https://github.com/dart-lang/sdk/issues/49635
Change-Id: I8b24b3b040a34f897c0b61dcb9bd105be6d0af6d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/251280
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Paul Berry 2022-08-22 16:50:19 +00:00 committed by Commit Bot
parent 8bd77bc510
commit b7567b1799
30 changed files with 576 additions and 293 deletions

View file

@ -2,6 +2,30 @@
### Language
- **Breaking change** [#49635][]: Flag additional code as unreachable due to
types `Null` and `Never`. Several unusual constructs that lead to unreachable
code are now recognized by flow analysis:
- Control flow after an expression of the form `e ?? other` or `e ??= other`,
where `e` has static type `Null` and `other` has static type `Never`, is
considered unreachable.
- Control flow predicated on an expression of the form `e is Never` evaluating
to `true` is considered unreachable.
- Control flow predicated on an expression of the form `e is! Never`
evaluating to `false` is considered unreachable.
- Control flow on the RHS of a null-aware access such as `e?.property...`,
`e?.property = ...` or `e?.method(...)`, where `e` has static type `Null`,
is considered unreachable (Note: this can arise in the presence of extension
methods).
Previously, these behaviors only took effect if `e` was a reference to a local
variable.
[#49635]: https://github.com/dart-lang/sdk/issues/49635
### Libraries
#### `dart:convert`

View file

@ -1923,19 +1923,13 @@ class FlowModel<Type extends Object> {
}
List<Type>? newPromotedTypes = info.promotedTypes;
Reachability newReachable = reachable;
if (promotedType != null) {
newPromotedTypes =
VariableModel._addToPromotedTypes(info.promotedTypes, promotedType);
if (reference.isPromotable &&
helper.typeOperations.isNever(promotedType)) {
newReachable = reachable.setUnreachable();
}
}
return identical(newTested, info.tested) &&
identical(newPromotedTypes, info.promotedTypes) &&
newReachable == reachable
identical(newPromotedTypes, info.promotedTypes)
? this
: _updateVariableInfo(
reference.promotionKey,
@ -1946,7 +1940,7 @@ class FlowModel<Type extends Object> {
unassigned: info.unassigned,
ssaNode: info.ssaNode,
nonPromotionHistory: info.nonPromotionHistory),
reachable: newReachable);
reachable: reachable);
}
/// Gets the info for [promotionKey] reference, creating it if it doesn't
@ -3423,6 +3417,10 @@ class _FlowAnalysisImpl<Node extends Object, Statement extends Node,
} else {
shortcutState = _current;
}
if (operations.classifyType(leftHandSideType) ==
TypeClassification.nullOrEquivalent) {
shortcutState = shortcutState.setUnreachable();
}
_stack.add(new _IfNullExpressionContext<Type>(shortcutState));
// Note: we are now on the RHS of the `??`, and so at this point in the
// flow, it is known that the LHS evaluated to `null`. It's tempting to
@ -3516,13 +3514,17 @@ class _FlowAnalysisImpl<Node extends Object, Statement extends Node,
@override
void isExpression_end(Expression isExpression, Expression subExpression,
bool isNot, Type type) {
ReferenceWithType<Type>? subExpressionReference =
_getExpressionReference(subExpression);
if (subExpressionReference != null) {
ExpressionInfo<Type> expressionInfo =
_current.tryPromoteForTypeCheck(this, subExpressionReference, type);
_storeExpressionInfo(
isExpression, isNot ? expressionInfo.invert() : expressionInfo);
if (operations.isNever(type)) {
booleanLiteral(isExpression, isNot);
} else {
ReferenceWithType<Type>? subExpressionReference =
_getExpressionReference(subExpression);
if (subExpressionReference != null) {
ExpressionInfo<Type> expressionInfo =
_current.tryPromoteForTypeCheck(this, subExpressionReference, type);
_storeExpressionInfo(
isExpression, isNot ? expressionInfo.invert() : expressionInfo);
}
}
}
@ -3629,14 +3631,16 @@ class _FlowAnalysisImpl<Node extends Object, Statement extends Node,
@override
void nullAwareAccess_rightBegin(Expression? target, Type targetType) {
// ignore:unnecessary_null_comparison
assert(targetType != null);
_current = _current.split();
_stack.add(new _NullAwareAccessContext<Type>(_current));
ReferenceWithType<Type>? targetReference = _getExpressionReference(target);
if (targetReference != null) {
_current = _current.tryMarkNonNullable(this, targetReference).ifTrue;
}
if (operations.classifyType(targetType) ==
TypeClassification.nullOrEquivalent) {
_current = _current.setUnreachable();
}
}
@override

View file

@ -36,6 +36,18 @@ main() {
]);
});
test("asExpression_end() sets reachability for Never", () {
// Note: this is handled by the general mechanism that marks control flow
// as reachable after any expression with static type `Never`. This is
// implemented in the flow analysis client, but we test it here anyway as
// a validation of the "mini AST" logic.
h.run([
checkReachable(true),
expr('int').as_('Never').stmt,
checkReachable(false),
]);
});
test('assert_afterCondition promotes', () {
var x = Var('x', 'int?');
h.run([
@ -1144,6 +1156,28 @@ main() {
]);
});
test(
'ifNullExpression sets shortcut reachability correctly for `Null` type',
() {
h.run([
expr('Null')
.ifNull(checkReachable(true).thenExpr(throw_(expr('Object'))))
.thenStmt(checkReachable(false))
.stmt,
]);
});
test(
'ifNullExpression sets shortcut reachability correctly for non-null '
'type', () {
h.run([
expr('Object')
.ifNull(checkReachable(true).thenExpr(throw_(expr('Object'))))
.thenStmt(checkReachable(true))
.stmt,
]);
});
test('ifStatement with early exit promotes in unreachable code', () {
var x = Var('x', 'int?');
h.run([
@ -1511,27 +1545,27 @@ main() {
]);
});
test('isExpression_end() does not set reachability for `this`', () {
test('isExpression_end() sets reachability for `this`', () {
h.thisType = 'C';
h.addSubtype('Never', 'C', true);
h.addFactor('C', 'Never', 'C');
h.run([
if_(this_.is_('Never'), [
checkReachable(true),
checkReachable(false),
], [
checkReachable(true),
]),
]);
});
group('isExpression_end() does not set reachability for property gets', () {
group('isExpression_end() sets reachability for property gets', () {
test('on a variable', () {
h.addMember('C', 'f', 'Object?');
var x = Var('x', 'C');
h.run([
declare(x, initialized: true),
if_(x.expr.property('f').is_('Never'), [
checkReachable(true),
checkReachable(false),
], [
checkReachable(true),
]),
@ -1542,7 +1576,7 @@ main() {
h.addMember('C', 'f', 'Object?');
h.run([
if_(expr('C').property('f').is_('Never'), [
checkReachable(true),
checkReachable(false),
], [
checkReachable(true),
]),
@ -1554,7 +1588,7 @@ main() {
h.addMember('C', 'f', 'Object?');
h.run([
if_(this_.property('f').is_('Never'), [
checkReachable(true),
checkReachable(false),
], [
checkReachable(true),
]),
@ -1566,7 +1600,7 @@ main() {
h.addMember('C', 'f', 'Object?');
h.run([
if_(thisOrSuperProperty('f').is_('Never'), [
checkReachable(true),
checkReachable(false),
], [
checkReachable(true),
]),
@ -1574,6 +1608,16 @@ main() {
});
});
test('isExpression_end() sets reachability for arbitrary exprs', () {
h.run([
if_(expr('int').is_('Never'), [
checkReachable(false),
], [
checkReachable(true),
]),
]);
});
test('labeledBlock without break', () {
var x = Var('x', 'int?');
h.run([
@ -1710,6 +1754,16 @@ main() {
]);
});
test('nonNullAssert_end sets reachability if type is `Null`', () {
// Note: this is handled by the general mechanism that marks control flow
// as reachable after any expression with static type `Never`. This is
// implemented in the flow analysis client, but we test it here anyway as
// a validation of the "mini AST" logic.
h.run([
expr('Null').nonNullAssert.thenStmt(checkReachable(false)).stmt,
]);
});
test('nullAwareAccess temporarily promotes', () {
var x = Var('x', 'int?');
late SsaNode<Type> ssaBeforePromotion;
@ -1759,6 +1813,17 @@ main() {
]);
});
test('nullAwareAccess sets reachability correctly for `Null` type', () {
h.run([
expr('Null')
.nullAwareAccess(block([
checkReachable(false),
]).thenExpr(expr('Object?')))
.thenStmt(checkReachable(true))
.stmt,
]);
});
test('nullAwareAccess_end ignores shorting if target is non-nullable', () {
var x = Var('x', 'int?');
h.run([
@ -3932,7 +3997,7 @@ main() {
test('promote to Never', () {
var s1 = FlowModel<Type>(Reachability.initial);
var s2 = s1._tryMarkNonNullable(h, nullVar).ifTrue;
expect(s2.reachable.overallReachable, false);
expect(s2.reachable.overallReachable, true);
expect(s2._infoFor(h, nullVar),
_matchVariableModel(chain: ['Never'], ofInterest: []));
});

View file

@ -0,0 +1,59 @@
// Copyright (c) 2022, 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.
/// This test verifies that various constructs involving an expression of type
/// `Never` are properly treated by flow analysis as belonging to unreachable
/// code paths.
/*member: asExpression:doesNotComplete*/
void asExpression(int i) {
i as Never;
/*stmt: unreachable*/ 1;
}
/*member: ifNullExpression:doesNotComplete*/
void ifNullExpression(Null Function() f) {
f() ?? (throw '');
// Since `f()` has static type `Null`, it must always evaluate to `null`,
// hence the shortcut branch of `f() ?? throw ''` is unreachable. This means
// that the code path after the whole expression `f() ?? throw ''` should be
// unreachable.
/*stmt: unreachable*/ 1;
}
/*member: ifNullAssignment:doesNotComplete*/
void ifNullAssignment(int? x, Null n) {
n ??= throw '';
// Since `n` has static type `Null`, it must always be `null`, hence the
// shortcut branch of `n ??= throw ''` is unreachable. This means that the
// code path after the whole expression `n ??= throw ''` should be
// unreachable.
/*stmt: unreachable*/ 1;
}
void ifExpression(Object? Function() f) {
if (f() is Never) /*unreachable*/ {
/*stmt: unreachable*/ 1;
} else {
2;
}
}
/*member: nonNullAssert:doesNotComplete*/
void nonNullAssert(Null Function() f) {
f()!;
// Since `f()` has static type `Null`, it must always evaluate to `null`,
// hence the non-null assertion always fails. This means that the code path
// after the whole expression `f()!` should be unreachable.
/*stmt: unreachable*/ 1;
}
void nullAwareAccess(Null Function() f, Object? Function() g) {
f()?.extensionMethod(/*unreachable*/ 1);
g()?.extensionMethod(2);
}
extension on Object? {
void extensionMethod(Object? o) {}
}

View file

@ -1660,7 +1660,13 @@ class _MiniAstTypeAnalyzer {
}
Type dispatchExpression(Expression expression, Type context) =>
_irBuilder.guard(expression, () => expression.visit(_harness, context));
_irBuilder.guard(expression, () {
var type = expression.visit(_harness, context);
if (flow.operations.isNever(type)) {
flow.handleExit();
}
return type;
});
void dispatchStatement(Statement statement) =>
_irBuilder.guard(statement, () => statement.visit(_harness));

View file

@ -1409,16 +1409,15 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
/// [initializerType].
DartType inferDeclarationType(DartType initializerType,
{bool forSyntheticVariable: false}) {
if (initializerType is NullType) {
if (forSyntheticVariable) {
return normalizeNullabilityInLibrary(
initializerType, libraryBuilder.library);
} else if (initializerType is NullType) {
// If the initializer type is Null or bottom, the inferred type is
// dynamic.
// TODO(paulberry): this rule is inherited from analyzer behavior but is
// not spec'ed anywhere.
return const DynamicType();
}
if (forSyntheticVariable) {
return normalizeNullabilityInLibrary(
initializerType, libraryBuilder.library);
} else {
return demoteTypeInLibrary(initializerType, libraryBuilder.library);
}

View file

@ -81,6 +81,4 @@ nnbd_mixed/inheritance_from_opt_in: TypeCheckError
nnbd_mixed/issue41567: TypeCheckError
nnbd_mixed/messages_with_types_opt_in: TypeCheckError
nnbd_mixed/messages_with_types_opt_out: TypeCheckError
regress/issue_31180: TypeCheckError
regress/issue_31180_2: TypeCheckError
runtime_checks_new/mixin_forwarding_stub_getter: TypeCheckError

View file

@ -2,31 +2,27 @@
// 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.
void test(var x) {
if (x is Never) {
Never n1 = x.toString();
Never n2 = x.runtimeType;
Never n3 = x.someGetter;
Never n4 = x.someMethod();
Never n5 = x + x;
Never n6 = x[x];
Never n7 = x();
Never n8 = x.runtimeType();
Never n9 = x.toString;
x.runtimeType = Object;
x.toString = () => '';
var v1 = x.toString();
var v2 = x.runtimeType;
var v3 = x.someGetter;
var v4 = x.someMethod();
var v5 = x + x;
var v6 = x[x];
var v7 = x();
var v8 = x.runtimeType();
var v9 = x.toString;
}
void test(Never x) {
Never n1 = x.toString();
Never n2 = x.runtimeType;
Never n3 = x.someGetter;
Never n4 = x.someMethod();
Never n5 = x + x;
Never n6 = x[x];
Never n7 = x();
Never n8 = x.runtimeType();
Never n9 = x.toString;
x.runtimeType = Object;
x.toString = () => '';
var v1 = x.toString();
var v2 = x.runtimeType;
var v3 = x.someGetter;
var v4 = x.someMethod();
var v5 = x + x;
var v6 = x[x];
var v7 = x();
var v8 = x.runtimeType();
var v9 = x.toString;
}
main() {
test(null);
}
main() {}

View file

@ -2,33 +2,29 @@ library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
static method test(dynamic x) → void {
if(x is{ForNonNullableByDefault} Never) {
Never n1 = x{Never}{Never}.toString();
Never n2 = x{Never}{Never}.runtimeType;
Never n3 = x{Never}{Never}.someGetter;
Never n4 = x{Never}{Never}.someMethod();
Never n5 = x{Never}{Never}.+(x{Never});
Never n6 = x{Never}{Never}.[](x{Never});
Never n7 = x{Never}{Never}.call();
Never n8 = x{Never}{Never}.runtimeType();
Never n9 = x{Never}{Never}.toString;
x{Never}{Never}.runtimeType = #C1;
x{Never}{Never}.toString = () → core::String => "";
Never v1 = x{Never}{Never}.toString();
Never v2 = x{Never}{Never}.runtimeType;
Never v3 = x{Never}{Never}.someGetter;
Never v4 = x{Never}{Never}.someMethod();
Never v5 = x{Never}{Never}.+(x{Never});
Never v6 = x{Never}{Never}.[](x{Never});
Never v7 = x{Never}{Never}.call();
Never v8 = x{Never}{Never}.runtimeType();
Never v9 = x{Never}{Never}.toString;
}
}
static method main() → dynamic {
self::test(null);
static method test(Never x) → void {
Never n1 = x{Never}.toString();
Never n2 = x{Never}.runtimeType;
Never n3 = x{Never}.someGetter;
Never n4 = x{Never}.someMethod();
Never n5 = x{Never}.+(x);
Never n6 = x{Never}.[](x);
Never n7 = x{Never}.call();
Never n8 = x{Never}.runtimeType();
Never n9 = x{Never}.toString;
x{Never}.runtimeType = #C1;
x{Never}.toString = () → core::String => "";
Never v1 = x{Never}.toString();
Never v2 = x{Never}.runtimeType;
Never v3 = x{Never}.someGetter;
Never v4 = x{Never}.someMethod();
Never v5 = x{Never}.+(x);
Never v6 = x{Never}.[](x);
Never v7 = x{Never}.call();
Never v8 = x{Never}.runtimeType();
Never v9 = x{Never}.toString;
}
static method main() → dynamic {}
constants {
#C1 = TypeLiteralConstant(core::Object)

View file

@ -2,33 +2,29 @@ library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
static method test(dynamic x) → void {
if(x is{ForNonNullableByDefault} Never) {
Never n1 = x{Never}{Never}.toString();
Never n2 = x{Never}{Never}.runtimeType;
Never n3 = x{Never}{Never}.someGetter;
Never n4 = x{Never}{Never}.someMethod();
Never n5 = x{Never}{Never}.+(x{Never});
Never n6 = x{Never}{Never}.[](x{Never});
Never n7 = x{Never}{Never}.call();
Never n8 = x{Never}{Never}.runtimeType();
Never n9 = x{Never}{Never}.toString;
x{Never}{Never}.runtimeType = #C1;
x{Never}{Never}.toString = () → core::String => "";
Never v1 = x{Never}{Never}.toString();
Never v2 = x{Never}{Never}.runtimeType;
Never v3 = x{Never}{Never}.someGetter;
Never v4 = x{Never}{Never}.someMethod();
Never v5 = x{Never}{Never}.+(x{Never});
Never v6 = x{Never}{Never}.[](x{Never});
Never v7 = x{Never}{Never}.call();
Never v8 = x{Never}{Never}.runtimeType();
Never v9 = x{Never}{Never}.toString;
}
}
static method main() → dynamic {
self::test(null);
static method test(Never x) → void {
Never n1 = x{Never}.toString();
Never n2 = x{Never}.runtimeType;
Never n3 = x{Never}.someGetter;
Never n4 = x{Never}.someMethod();
Never n5 = x{Never}.+(x);
Never n6 = x{Never}.[](x);
Never n7 = x{Never}.call();
Never n8 = x{Never}.runtimeType();
Never n9 = x{Never}.toString;
x{Never}.runtimeType = #C1;
x{Never}.toString = () → core::String => "";
Never v1 = x{Never}.toString();
Never v2 = x{Never}.runtimeType;
Never v3 = x{Never}.someGetter;
Never v4 = x{Never}.someMethod();
Never v5 = x{Never}.+(x);
Never v6 = x{Never}.[](x);
Never v7 = x{Never}.call();
Never v8 = x{Never}.runtimeType();
Never v9 = x{Never}.toString;
}
static method main() → dynamic {}
constants {
#C1 = TypeLiteralConstant(core::Object)

View file

@ -1,2 +1,2 @@
void test(var x) {}
void test(Never x) {}
main() {}

View file

@ -1,2 +1,2 @@
main() {}
void test(var x) {}
void test(Never x) {}

View file

@ -3,33 +3,29 @@ import self as self;
import "dart:_internal" as _in;
import "dart:core" as core;
static method test(dynamic x) → void {
if(x is{ForNonNullableByDefault} Never) {
Never n1 = let final Never #t1 = (let final Never #t2 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n2 = let final Never #t3 = (let final Never #t4 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n3 = let final Never #t5 = (let final Never #t6 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someGetter in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n4 = let final Never #t7 = (let final Never #t8 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n5 = let final Never #t9 = (let final Never #t10 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.+(let final Never #t11 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n6 = let final Never #t12 = (let final Never #t13 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.[](let final Never #t14 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n7 = let final Never #t15 = (let final Never #t16 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n8 = let final Never #t17 = (let final Never #t18 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n9 = let final Never #t19 = (let final Never #t20 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
(let final Never #t21 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType = #C1;
(let final Never #t22 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString = () → core::String => "";
Never v1 = let final Never #t23 = (let final Never #t24 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v2 = let final Never #t25 = (let final Never #t26 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v3 = let final Never #t27 = (let final Never #t28 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someGetter in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v4 = let final Never #t29 = (let final Never #t30 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v5 = let final Never #t31 = (let final Never #t32 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.+(let final Never #t33 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v6 = let final Never #t34 = (let final Never #t35 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.[](let final Never #t36 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v7 = let final Never #t37 = (let final Never #t38 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v8 = let final Never #t39 = (let final Never #t40 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v9 = let final Never #t41 = (let final Never #t42 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
}
}
static method main() → dynamic {
self::test(null);
static method test(Never x) → void {
Never n1 = let final Never #t1 = (let final Never #t2 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n2 = let final Never #t3 = (let final Never #t4 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n3 = let final Never #t5 = (let final Never #t6 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someGetter in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n4 = let final Never #t7 = (let final Never #t8 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n5 = let final Never #t9 = (let final Never #t10 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.+(let final Never #t11 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n6 = let final Never #t12 = (let final Never #t13 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.[](let final Never #t14 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n7 = let final Never #t15 = (let final Never #t16 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n8 = let final Never #t17 = (let final Never #t18 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n9 = let final Never #t19 = (let final Never #t20 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
(let final Never #t21 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType = #C1;
(let final Never #t22 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString = () → core::String => "";
Never v1 = let final Never #t23 = (let final Never #t24 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v2 = let final Never #t25 = (let final Never #t26 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v3 = let final Never #t27 = (let final Never #t28 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someGetter in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v4 = let final Never #t29 = (let final Never #t30 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v5 = let final Never #t31 = (let final Never #t32 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.+(let final Never #t33 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v6 = let final Never #t34 = (let final Never #t35 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.[](let final Never #t36 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v7 = let final Never #t37 = (let final Never #t38 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v8 = let final Never #t39 = (let final Never #t40 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v9 = let final Never #t41 = (let final Never #t42 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
}
static method main() → dynamic {}
constants {
#C1 = TypeLiteralConstant(core::Object*)

View file

@ -3,33 +3,29 @@ import self as self;
import "dart:_internal" as _in;
import "dart:core" as core;
static method test(dynamic x) → void {
if(x is{ForNonNullableByDefault} Never) {
Never n1 = let final Never #t1 = (let final Never #t2 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n2 = let final Never #t3 = (let final Never #t4 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n3 = let final Never #t5 = (let final Never #t6 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someGetter in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n4 = let final Never #t7 = (let final Never #t8 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n5 = let final Never #t9 = (let final Never #t10 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.+(let final Never #t11 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n6 = let final Never #t12 = (let final Never #t13 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.[](let final Never #t14 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n7 = let final Never #t15 = (let final Never #t16 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n8 = let final Never #t17 = (let final Never #t18 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n9 = let final Never #t19 = (let final Never #t20 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
(let final Never #t21 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType = #C1;
(let final Never #t22 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString = () → core::String => "";
Never v1 = let final Never #t23 = (let final Never #t24 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v2 = let final Never #t25 = (let final Never #t26 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v3 = let final Never #t27 = (let final Never #t28 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someGetter in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v4 = let final Never #t29 = (let final Never #t30 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v5 = let final Never #t31 = (let final Never #t32 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.+(let final Never #t33 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v6 = let final Never #t34 = (let final Never #t35 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.[](let final Never #t36 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v7 = let final Never #t37 = (let final Never #t38 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v8 = let final Never #t39 = (let final Never #t40 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v9 = let final Never #t41 = (let final Never #t42 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
}
}
static method main() → dynamic {
self::test(null);
static method test(Never x) → void {
Never n1 = let final Never #t1 = (let final Never #t2 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n2 = let final Never #t3 = (let final Never #t4 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n3 = let final Never #t5 = (let final Never #t6 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someGetter in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n4 = let final Never #t7 = (let final Never #t8 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n5 = let final Never #t9 = (let final Never #t10 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.+(let final Never #t11 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n6 = let final Never #t12 = (let final Never #t13 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.[](let final Never #t14 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n7 = let final Never #t15 = (let final Never #t16 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n8 = let final Never #t17 = (let final Never #t18 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n9 = let final Never #t19 = (let final Never #t20 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
(let final Never #t21 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType = #C1;
(let final Never #t22 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString = () → core::String => "";
Never v1 = let final Never #t23 = (let final Never #t24 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v2 = let final Never #t25 = (let final Never #t26 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v3 = let final Never #t27 = (let final Never #t28 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someGetter in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v4 = let final Never #t29 = (let final Never #t30 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v5 = let final Never #t31 = (let final Never #t32 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.+(let final Never #t33 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v6 = let final Never #t34 = (let final Never #t35 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.[](let final Never #t36 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v7 = let final Never #t37 = (let final Never #t38 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v8 = let final Never #t39 = (let final Never #t40 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v9 = let final Never #t41 = (let final Never #t42 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
}
static method main() → dynamic {}
constants {
#C1 = TypeLiteralConstant(core::Object*)

View file

@ -1,7 +1,7 @@
library /*isNonNullableByDefault*/;
import self as self;
static method test(dynamic x) → void
static method test(Never x) → void
;
static method main() → dynamic
;

View file

@ -3,33 +3,29 @@ import self as self;
import "dart:_internal" as _in;
import "dart:core" as core;
static method test(dynamic x) → void {
if(x is{ForNonNullableByDefault} Never) {
Never n1 = let final Never #t1 = (let final Never #t2 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n2 = let final Never #t3 = (let final Never #t4 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n3 = let final Never #t5 = (let final Never #t6 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someGetter in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n4 = let final Never #t7 = (let final Never #t8 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n5 = let final Never #t9 = (let final Never #t10 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.+(let final Never #t11 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n6 = let final Never #t12 = (let final Never #t13 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.[](let final Never #t14 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n7 = let final Never #t15 = (let final Never #t16 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n8 = let final Never #t17 = (let final Never #t18 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n9 = let final Never #t19 = (let final Never #t20 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
(let final Never #t21 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType = #C1;
(let final Never #t22 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString = () → core::String => "";
Never v1 = let final Never #t23 = (let final Never #t24 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v2 = let final Never #t25 = (let final Never #t26 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v3 = let final Never #t27 = (let final Never #t28 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someGetter in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v4 = let final Never #t29 = (let final Never #t30 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v5 = let final Never #t31 = (let final Never #t32 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.+(let final Never #t33 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v6 = let final Never #t34 = (let final Never #t35 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.[](let final Never #t36 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v7 = let final Never #t37 = (let final Never #t38 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v8 = let final Never #t39 = (let final Never #t40 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v9 = let final Never #t41 = (let final Never #t42 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
}
}
static method main() → dynamic {
self::test(null);
static method test(Never x) → void {
Never n1 = let final Never #t1 = (let final Never #t2 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n2 = let final Never #t3 = (let final Never #t4 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n3 = let final Never #t5 = (let final Never #t6 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someGetter in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n4 = let final Never #t7 = (let final Never #t8 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n5 = let final Never #t9 = (let final Never #t10 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.+(let final Never #t11 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n6 = let final Never #t12 = (let final Never #t13 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.[](let final Never #t14 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n7 = let final Never #t15 = (let final Never #t16 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n8 = let final Never #t17 = (let final Never #t18 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never n9 = let final Never #t19 = (let final Never #t20 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
(let final Never #t21 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType = #C1;
(let final Never #t22 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString = () → core::String => "";
Never v1 = let final Never #t23 = (let final Never #t24 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v2 = let final Never #t25 = (let final Never #t26 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v3 = let final Never #t27 = (let final Never #t28 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someGetter in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v4 = let final Never #t29 = (let final Never #t30 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.someMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v5 = let final Never #t31 = (let final Never #t32 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.+(let final Never #t33 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v6 = let final Never #t34 = (let final Never #t35 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.[](let final Never #t36 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v7 = let final Never #t37 = (let final Never #t38 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v8 = let final Never #t39 = (let final Never #t40 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.runtimeType() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
Never v9 = let final Never #t41 = (let final Never #t42 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.toString in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
}
static method main() → dynamic {}
constants {
#C1 = TypeLiteralConstant(core::Object*)

View file

@ -10,9 +10,17 @@ library;
// // @dart=2.9
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/regress/issue_31180.dart:8:15: Error: The operator '[]' isn't defined for the class 'Null'.
// Try correcting the operator to an existing operator, or defining a '[]' operator.
// return null?[1];
// ^
//
import self as self;
static method bad() → dynamic {
return let final has-declared-initializer dynamic #t1 = null in #t1 == null ?{dynamic} null : #t1{dynamic}.[](1);
return let final has-declared-initializer Null #t1 = null in #t1 == null ?{dynamic} null : invalid-expression "pkg/front_end/testcases/regress/issue_31180.dart:8:15: Error: The operator '[]' isn't defined for the class 'Null'.
Try correcting the operator to an existing operator, or defining a '[]' operator.
return null?[1];
^" in #t1{<unresolved>}.[](1);
}
static method main() → dynamic {}

View file

@ -10,9 +10,17 @@ library;
// // @dart=2.9
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/regress/issue_31180.dart:8:15: Error: The operator '[]' isn't defined for the class 'Null'.
// Try correcting the operator to an existing operator, or defining a '[]' operator.
// return null?[1];
// ^
//
import self as self;
static method bad() → dynamic {
return let final has-declared-initializer dynamic #t1 = null in #t1 == null ?{dynamic} null : #t1{dynamic}.[](1);
return let final has-declared-initializer Null #t1 = null in #t1 == null ?{dynamic} null : invalid-expression "pkg/front_end/testcases/regress/issue_31180.dart:8:15: Error: The operator '[]' isn't defined for the class 'Null'.
Try correcting the operator to an existing operator, or defining a '[]' operator.
return null?[1];
^" in #t1{<unresolved>}.[](1);
}
static method main() → dynamic {}

View file

@ -2,23 +2,30 @@ library;
//
// Problems in library:
//
// pkg/front_end/testcases/regress/issue_31180.dart:6:15: Error: Null safety features are disabled for this library.
// pkg/front_end/testcases/regress/issue_31180.dart:8:15: Error: Null safety features are disabled for this library.
// Try removing the `@dart=` annotation or setting the language version to 2.12 or higher.
// return null?[1];
// ^
// pkg/front_end/testcases/regress/issue_31180.dart:4:1: Context: This is the annotation that opts out this library from null safety features.
// pkg/front_end/testcases/regress/issue_31180.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
// // @dart=2.9
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/regress/issue_31180.dart:8:15: Error: The operator '[]' isn't defined for the class 'Null'.
// Try correcting the operator to an existing operator, or defining a '[]' operator.
// return null?[1];
// ^
//
import self as self;
import "dart:core" as core;
static method bad() → dynamic {
return let final<BottomType> #t1 = null in #t1.{core::Object::==}(null) ?{dynamic} null : #t1.[](1);
return let final has-declared-initializer Null #t1 = null in #t1 == null ?{dynamic} null : invalid-expression "pkg/front_end/testcases/regress/issue_31180.dart:8:15: Error: The operator '[]' isn't defined for the class 'Null'.
Try correcting the operator to an existing operator, or defining a '[]' operator.
return null?[1];
^" in #t1{<unresolved>}.[](1);
}
static method main() → dynamic {}
Extra constant evaluation status:
Evaluated: Let @ org-dartlang-testcase:///issue_31180.dart:6:10 -> NullConstant(null)
Evaluated: Let @ org-dartlang-testcase:///issue_31180.dart:8:10 -> NullConstant(null)
Extra constant evaluation: evaluated: 1, effectively constant: 1

View file

@ -1,7 +1,8 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:_internal" as _in;
static method bad() → dynamic {
return let final has-declared-initializer dynamic #t1 = null in #t1 == null ?{dynamic} null : #t1{dynamic}.[](1);
return let final has-declared-initializer Null #t1 = null in #t1 == null ?{Null} null : let final Never #t2 = (let final Never #t3 = #t1{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.[](1) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
}
static method main() → dynamic {}

View file

@ -1,7 +1,8 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:_internal" as _in;
static method bad() → dynamic {
return let final has-declared-initializer dynamic #t1 = null in #t1 == null ?{dynamic} null : #t1{dynamic}.[](1);
return let final has-declared-initializer Null #t1 = null in #t1 == null ?{Null} null : let final Never #t2 = (let final Never #t3 = #t1{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.[](1) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
}
static method main() → dynamic {}

View file

@ -0,0 +1,13 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:_internal" as _in;
static method bad() → dynamic {
return let final has-declared-initializer Null #t1 = null in #t1 == null ?{Null} null : let final Never #t2 = (let final Never #t3 = #t1{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){Never}.[](1) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
}
static method main() → dynamic {}
Extra constant evaluation status:
Evaluated: Let @ org-dartlang-testcase:///issue_31180_2.dart:6:10 -> NullConstant(null)
Extra constant evaluation: evaluated: 1, effectively constant: 1

View file

@ -248,8 +248,6 @@ rasta/unresolved_constructor: RuntimeError
rasta/unresolved_for_in: RuntimeError
regress/issue_29976: RuntimeError # Tests runtime behavior of error recovery.
regress/issue_29982: RuntimeError # Tests runtime behavior of error recovery.
regress/issue_31180: TypeCheckError
regress/issue_31180_2: TypeCheckError
regress/issue_32972: RuntimeError
regress/issue_33452: RuntimeError # Test has an intentional error
regress/issue_34225: RuntimeError

View file

@ -59,9 +59,9 @@ void isSimple(int? x, int? y, C Function() f) {
} else {
y = null;
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type `int?`
// now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -76,9 +76,9 @@ void isWithBogusPromotion(int? x, int? y, C Function() f) {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type `int?`
// now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -128,9 +128,9 @@ void isSimplePrivate(int? x, int? y, _C Function() f) {
} else {
y = null;
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type `int?`
// now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -145,9 +145,9 @@ void isWithBogusPromotionPrivate(int? x, int? y, _C Function() f) {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type `int?`
// now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}

View file

@ -0,0 +1,93 @@
// Copyright (c) 2022, 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.
/// This test verifies that various constructs involving an expression of type
/// `Never` are properly treated by flow analysis as belonging to unreachable
/// code paths.
import '../../static_type_helper.dart';
void asExpression(int? x, int i) {
if (x == null) {
i as Never;
}
// Since no runtime object can have type `Never`, the code path after `i as
// Never` should be unreachable. Hence, `x` is promoted to static type `int`.
x.expectStaticType<Exactly<int>>();
}
void ifNullExpression(int? x, Null Function() f) {
if (x == null) {
f() ?? (throw '');
}
// Since `f()` has static type `Null`, it must always evaluate to `null`,
// hence the shortcut branch of `f() ?? throw ''` is unreachable. This means
// that the code path after the whole expression `f() ?? throw ''` should be
// unreachable. Hence, `x` is promoted to static type `int`.
x.expectStaticType<Exactly<int>>();
}
void ifNullAssignment(int? x, Null n) {
if (x == null) {
n ??= throw '';
}
// Since `n` has static type `Null`, it must always be `null`, hence the
// shortcut branch of `n ??= throw ''` is unreachable. This means that the
// code path after the whole expression `n ??= throw ''` should be
// unreachable. Hence, `x` is promoted to static type `int`.
x.expectStaticType<Exactly<int>>();
}
void ifExpression(int? x, int? y, Object? Function() f) {
if (x == null || y == null) return;
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int>>();
if (f() is Never) {
x = null;
} else {
y = null;
}
// Since the assignment to y was reachable, it should have static type `int?`
// now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
void nonNullAssert(int? x, Null Function() f) {
if (x == null) {
f()!;
}
// Since `f()` has static type `Null`, it must always evaluate to `null`,
// hence the non-null assertion always fails. This means that the code path
// after the whole expression `f()!` should be unreachable. Hence, `x` is
// promoted to static type `int`.
x.expectStaticType<Exactly<int>>();
}
void nullAwareAccess(int? x, int? y, Null Function() f, Object? Function() g) {
if (x == null || y == null) return;
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int>>();
f()?.extensionMethod(x = null);
g()?.extensionMethod(y = null);
// Since `f()` has static type `Null`, it must always evaluate to `null`,
// hence the assignment to x should be unreachable.
// Since the assignment to y was reachable, it should have static type `int?`
// now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
extension on Object? {
void extensionMethod(Object? o) {}
}
main() {
asExpression(1, 1);
ifNullExpression(1, () => null);
ifNullAssignment(1, null);
ifExpression(1, 1, () => 1);
nonNullAssert(1, () => null);
nullAwareAccess(1, 1, () => null, () => 1);
}

View file

@ -92,9 +92,9 @@ class C extends B {
} else {
y = null;
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -107,9 +107,9 @@ class C extends B {
} else {
y = null;
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -124,9 +124,9 @@ class C extends B {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -141,9 +141,9 @@ class C extends B {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
}
@ -224,9 +224,9 @@ extension on D {
} else {
y = null;
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -239,9 +239,9 @@ extension on D {
} else {
y = null;
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -256,9 +256,9 @@ extension on D {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -273,9 +273,9 @@ extension on D {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
}
@ -359,9 +359,9 @@ class _C extends _B {
} else {
y = null;
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -374,9 +374,9 @@ class _C extends _B {
} else {
y = null;
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -391,9 +391,9 @@ class _C extends _B {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -408,9 +408,9 @@ class _C extends _B {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
}
@ -491,9 +491,9 @@ extension on _D {
} else {
y = null;
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -506,9 +506,9 @@ extension on _D {
} else {
y = null;
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -523,9 +523,9 @@ extension on _D {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -540,9 +540,9 @@ extension on _D {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
}

View file

@ -51,9 +51,9 @@ class C {
} else {
y = null;
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -68,9 +68,9 @@ class C {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
}
@ -119,9 +119,9 @@ extension on D {
} else {
y = null;
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -136,9 +136,9 @@ extension on D {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
}
@ -187,9 +187,9 @@ extension on E? {
} else {
y = null;
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -204,9 +204,9 @@ extension on E? {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type
// `int?` now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
}

View file

@ -59,9 +59,9 @@ void isSimple(int? x, int? y, C c) {
} else {
y = null;
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type `int?`
// now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -76,9 +76,9 @@ void isWithBogusPromotion(int? x, int? y, C c) {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type `int?`
// now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -128,9 +128,9 @@ void isSimplePrivate(int? x, int? y, _C c) {
} else {
y = null;
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type `int?`
// now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}
@ -145,9 +145,9 @@ void isWithBogusPromotionPrivate(int? x, int? y, _C c) {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
// Since the assignment to y was reachable, it should have static type `int?`
// now. But x should still have static type `int`.
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int?>>();
}

View file

@ -0,0 +1,9 @@
// Copyright (c) 2022, 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.
import "package:expect/expect.dart";
main() {
Expect.isNull(null?[0]);
}

View file

@ -0,0 +1,14 @@
// Copyright (c) 2022, 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.
// @dart = 2.9
main() {
null?[0];
// ^
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
// ^
// [cfe] Null safety features are disabled for this library.
// [cfe] The operator '[]' isn't defined for the class 'Null'.
}