blob: d2de3fb63e676ed2df8c89835af62289628ceb8b [file] [log] [blame]
// Copyright (c) 2020, 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.
// Test the static analysis of expressions of the form `e1 == e2`: Null is
// allowed on both the left and right hand side, but handled separately, so
// the instance member `operator ==` is only invoked with non-null receiver
// and argument.
import 'dart:async';
class A {}
class Covar1 {
// When `typeof(e1)` is `Covar1`, `e1 == e2` requires `typeof(e2) <: Covar1`.
operator ==(covariant Covar1 other) => identical(this, other);
}
abstract class AbstractCovar2 {
// When typeof(e1) is a subtype of `AbstractCovar2`, but not a subtype of
// `Covar2Impl`, `e1 == e2` requires `typeof(e2) <: AbstractCovar2`. We use
// `const` to make it statically known that the actual object for `e1` is a
// `Covar2Impl`, thus checking that the `==` check uses the specified static
// type rather than using knowledge about the constant expression directly.
operator ==(covariant AbstractCovar2 other);
const factory AbstractCovar2() = Covar2Impl;
}
class Covar2Impl implements AbstractCovar2 {
const Covar2Impl();
operator ==(Object other) => identical(this, other);
}
void main() {
num numVar = 2;
A aVar = A();
Covar1 covar1Var = Covar1();
A? aNullableVar = null;
Covar1? covar1NullableVar = null;
FutureOr<int?> futureOrNullableIntVar = null;
FutureOr<Covar1> futureOrCovar1Var = covar1Var;
List<void> voidListVar = [1];
var voidVar = voidListVar[0];
null == null;
null == true;
null == <int>{};
null == numVar;
null == aVar;
null == covar1Var;
null == aNullableVar;
null == covar1NullableVar;
null == futureOrNullableIntVar;
null == futureOrCovar1Var;
null == const AbstractCovar2();
null == voidListVar;
null == voidVar;
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] This expression has type 'void' and can't be used.
true == null;
true == true;
true == <int>{};
true == numVar;
true == aVar;
true == covar1Var;
true == aNullableVar;
true == covar1NullableVar;
true == futureOrNullableIntVar;
true == futureOrCovar1Var;
true == const AbstractCovar2();
true == voidListVar;
true == voidVar;
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] This expression has type 'void' and can't be used.
<int>{} == null;
<int>{} == true;
<int>{} == <int>{};
<int>{} == numVar;
<int>{} == aVar;
<int>{} == covar1Var;
<int>{} == aNullableVar;
<int>{} == covar1NullableVar;
<int>{} == futureOrNullableIntVar;
<int>{} == futureOrCovar1Var;
<int>{} == const AbstractCovar2();
<int>{} == voidListVar;
<int>{} == voidVar;
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] This expression has type 'void' and can't be used.
numVar == null;
numVar == true;
numVar == <int>{};
numVar == numVar;
numVar == aVar;
numVar == covar1Var;
numVar == aNullableVar;
numVar == covar1NullableVar;
numVar == futureOrNullableIntVar;
numVar == futureOrCovar1Var;
numVar == const AbstractCovar2();
numVar == voidListVar;
numVar == voidVar;
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] This expression has type 'void' and can't be used.
aVar == null;
aVar == true;
aVar == <int>{};
aVar == numVar;
aVar == aVar;
aVar == covar1Var;
aVar == aNullableVar;
aVar == covar1NullableVar;
aVar == futureOrNullableIntVar;
aVar == futureOrCovar1Var;
aVar == const AbstractCovar2();
aVar == voidListVar;
aVar == voidVar;
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] This expression has type 'void' and can't be used.
covar1Var == null;
covar1Var == true;
// ^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1Var == <int>{};
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1Var == numVar;
// ^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1Var == aVar;
// ^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1Var == covar1Var;
covar1Var == aNullableVar;
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1Var == covar1NullableVar;
covar1Var == futureOrNullableIntVar;
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1Var == futureOrCovar1Var;
// ^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1Var == const AbstractCovar2();
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1Var == voidListVar;
// ^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1Var == voidVar;
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] This expression has type 'void' and can't be used.
aNullableVar == null;
aNullableVar == true;
aNullableVar == <int>{};
aNullableVar == numVar;
aNullableVar == aVar;
aNullableVar == covar1Var;
aNullableVar == aNullableVar;
aNullableVar == covar1NullableVar;
aNullableVar == futureOrNullableIntVar;
aNullableVar == futureOrCovar1Var;
aNullableVar == const AbstractCovar2();
aNullableVar == voidListVar;
aNullableVar == voidVar;
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] This expression has type 'void' and can't be used.
covar1NullableVar == null;
covar1NullableVar == true;
// ^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1NullableVar == <int>{};
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1NullableVar == numVar;
// ^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1NullableVar == aVar;
// ^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1NullableVar == covar1Var;
covar1NullableVar == aNullableVar;
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1NullableVar == covar1NullableVar;
covar1NullableVar == futureOrNullableIntVar;
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1NullableVar == futureOrCovar1Var;
// ^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1NullableVar == const AbstractCovar2();
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1NullableVar == voidListVar;
// ^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1NullableVar == voidVar;
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] This expression has type 'void' and can't be used.
futureOrNullableIntVar == null;
futureOrNullableIntVar == true;
futureOrNullableIntVar == <int>{};
futureOrNullableIntVar == numVar;
futureOrNullableIntVar == aVar;
futureOrNullableIntVar == covar1Var;
futureOrNullableIntVar == aNullableVar;
futureOrNullableIntVar == covar1NullableVar;
futureOrNullableIntVar == futureOrNullableIntVar;
futureOrNullableIntVar == futureOrCovar1Var;
futureOrNullableIntVar == const AbstractCovar2();
futureOrNullableIntVar == voidListVar;
futureOrNullableIntVar == voidVar;
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] This expression has type 'void' and can't be used.
futureOrCovar1Var == null;
futureOrCovar1Var == true;
futureOrCovar1Var == <int>{};
futureOrCovar1Var == numVar;
futureOrCovar1Var == aVar;
futureOrCovar1Var == covar1Var;
futureOrCovar1Var == aNullableVar;
futureOrCovar1Var == covar1NullableVar;
futureOrCovar1Var == futureOrNullableIntVar;
futureOrCovar1Var == futureOrCovar1Var;
futureOrCovar1Var == const AbstractCovar2();
futureOrCovar1Var == voidListVar;
futureOrCovar1Var == voidVar;
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] This expression has type 'void' and can't be used.
const AbstractCovar2() == null;
const AbstractCovar2() == true;
// ^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
const AbstractCovar2() == <int>{};
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
const AbstractCovar2() == numVar;
// ^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
const AbstractCovar2() == aVar;
// ^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
const AbstractCovar2() == covar1Var;
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
const AbstractCovar2() == aNullableVar;
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
const AbstractCovar2() == covar1NullableVar;
// ^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
const AbstractCovar2() == futureOrNullableIntVar;
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
const AbstractCovar2() == futureOrCovar1Var;
// ^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
const AbstractCovar2() == const AbstractCovar2();
const AbstractCovar2() == voidListVar;
// ^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
const AbstractCovar2() == voidVar;
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] This expression has type 'void' and can't be used.
voidListVar == null;
voidListVar == true;
voidListVar == <int>{};
voidListVar == numVar;
voidListVar == aVar;
voidListVar == covar1Var;
voidListVar == aNullableVar;
voidListVar == covar1NullableVar;
voidListVar == futureOrNullableIntVar;
voidListVar == futureOrCovar1Var;
voidListVar == const AbstractCovar2();
voidListVar == voidListVar;
voidListVar == voidVar;
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] This expression has type 'void' and can't be used.
voidVar == null;
//^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] unspecified
voidVar == true;
//^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] unspecified
voidVar == <int>{};
//^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] unspecified
voidVar == numVar;
//^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] unspecified
voidVar == aVar;
//^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] unspecified
voidVar == covar1Var;
//^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] unspecified
voidVar == aNullableVar;
//^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] unspecified
voidVar == covar1NullableVar;
//^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] unspecified
voidVar == futureOrNullableIntVar;
//^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] unspecified
voidVar == futureOrCovar1Var;
//^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] unspecified
voidVar == voidListVar;
//^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] unspecified
voidVar == voidVar;
//^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] This expression has type 'void' and can't be used.
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] This expression has type 'void' and can't be used.
void fun<X extends Covar1, Y extends Covar1?, Z extends FutureOr<Covar1>>(
X covar1Var, Y covar1NullableVar, Z futureOrCovar1Var) {
covar1Var == null;
covar1Var == true;
// ^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1Var == <int>{};
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1Var == numVar;
// ^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1Var == aVar;
// ^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1Var == covar1Var;
covar1Var == aNullableVar;
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1Var == covar1NullableVar;
covar1Var == futureOrNullableIntVar;
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1Var == futureOrCovar1Var;
// ^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1Var == const AbstractCovar2();
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1Var == voidListVar;
// ^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1Var == voidVar;
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] This expression has type 'void' and can't be used.
covar1NullableVar == null;
covar1NullableVar == true;
// ^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1NullableVar == <int>{};
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1NullableVar == numVar;
// ^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1NullableVar == aVar;
// ^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1NullableVar == covar1Var;
covar1NullableVar == aNullableVar;
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1NullableVar == covar1NullableVar;
covar1NullableVar == futureOrNullableIntVar;
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1NullableVar == futureOrCovar1Var;
// ^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1NullableVar == const AbstractCovar2();
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1NullableVar == voidListVar;
// ^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] unspecified
covar1NullableVar == voidVar;
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] This expression has type 'void' and can't be used.
futureOrCovar1Var == null;
futureOrCovar1Var == true;
futureOrCovar1Var == <int>{};
futureOrCovar1Var == numVar;
futureOrCovar1Var == aVar;
futureOrCovar1Var == covar1Var;
futureOrCovar1Var == aNullableVar;
futureOrCovar1Var == covar1NullableVar;
futureOrCovar1Var == futureOrNullableIntVar;
futureOrCovar1Var == futureOrCovar1Var;
futureOrCovar1Var == const AbstractCovar2();
futureOrCovar1Var == voidListVar;
futureOrCovar1Var == voidVar;
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
// [cfe] This expression has type 'void' and can't be used.
}
}