// 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 futureOrNullableIntVar = null; FutureOr futureOrCovar1Var = covar1Var; List voidListVar = [1]; var voidVar = voidListVar[0]; null == null; null == true; null == {}; 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 == {}; 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. {} == null; {} == true; {} == {}; {} == numVar; {} == aVar; {} == covar1Var; {} == aNullableVar; {} == covar1NullableVar; {} == futureOrNullableIntVar; {} == futureOrCovar1Var; {} == const AbstractCovar2(); {} == voidListVar; {} == 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 == {}; 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 == {}; 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 == {}; // ^^^^^^^ // [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 == {}; 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 == {}; // ^^^^^^^ // [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 == {}; 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 == {}; 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() == {}; // ^^^^^^^ // [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 == {}; 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 == {}; //^^^^^^^ // [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 covar1Var, Y covar1NullableVar, Z futureOrCovar1Var) { covar1Var == null; covar1Var == true; // ^^^^ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE // [cfe] unspecified covar1Var == {}; // ^^^^^^^ // [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 == {}; // ^^^^^^^ // [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 == {}; 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. } }