Skip to content

Commit

Permalink
Fix dart-lang#2546. Add constant context tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sgrekhov committed Feb 16, 2024
1 parent 5eb438e commit 9d85936
Show file tree
Hide file tree
Showing 10 changed files with 321 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2024, 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.

/// @assertion Let e be an expression; e occurs in a constant context iff one of
/// the following applies:
/// • e is an element of a list or set literal whose first token is const, or e
/// is a key or a value of an entry of a map literal whose first token is
/// const.
///
/// @description Checks that an expression `e` is a constant expression if `e`
/// is an element of a list whose first token is `const`. In this case `const`
/// modifier for `e` can be omitted
/// @author [email protected]
import '../../../../Utils/expect.dart';

class C {
final val;
const C(this.val);
}

main() {
var c1 = const [C(1)];
var c2 = const {C(2)};

Expect.identical(const C(1), c1[0]);
Expect.identical(const C(2), c2.lookup(const C(2)));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) 2024, 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.

/// @assertion Let e be an expression; e occurs in a constant context iff one of
/// the following applies:
/// • e is an element of a list or set literal whose first token is const, or e
/// is a key or a value of an entry of a map literal whose first token is
/// const.
///
/// @description Checks that an expression `e` is a constant expression if `e`
/// is an element of a map whose first token is `const`. In this case `const`
/// modifier for `e` can be omitted
/// @author [email protected]
import '../../../../Utils/expect.dart';

class C {
final val;
const C(this.val);
}

main() {
var c = const {C(1): C(2)};

Expect.identical(const C(2), c[const C(1)]);
Expect.identical(const C(1), c.keys.toList()[0]);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) 2024, 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.

/// @assertion Let e be an expression; e occurs in a constant context iff one of
/// the following applies:
/// • e is an element of a list or set literal whose first token is const, or e
/// is a key or a value of an entry of a map literal whose first token is
/// const.
///
/// @description Checks that it is a compile-time error if `e` is an element of
/// a list or set literal whose first token is `const`, or `e` is a key or a
/// value of an entry of a map literal whose first token is `const` but `e` is
/// not a constant expression.
/// @author [email protected]
class C {
final val;
C(this.val);
}

main() {
const c1 = const [C(1)];
// ^^^^
// [analyzer] unspecified
// [cfe] unspecified

const c2 = const {C(2)};
// ^^^^
// [analyzer] unspecified
// [cfe] unspecified

const c3 = const {C(3): 0};
// ^^^^
// [analyzer] unspecified
// [cfe] unspecified

const c4 = const {0: C(4)};
// ^^^^
// [analyzer] unspecified
// [cfe] unspecified
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2024, 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.

/// @assertion Let e be an expression; e occurs in a constant context iff one of
/// the following applies:
/// ...
/// • e occurs as @e in a construct derived from ⟨metadata⟩.
///
/// @description Checks that an expression `e` is a constant expression if `e`
/// occurs as `@e` in a construct derived from ⟨metadata⟩
/// @author [email protected]
import 'dart:mirrors';
import '../../../../Utils/expect.dart';

class C {
final val;
const C(this.val);
}

@C(1)
class A {}

main() {
Expect.identical(const C(1), reflectClass(A).metadata[0].reflectee);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) 2024, 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.

/// @assertion Let e be an expression; e occurs in a constant context iff one of
/// the following applies:
/// ...
/// • e is an actual argument in an expression derived from
/// ⟨constObjectExpression⟩.
///
/// @description Checks that an expression `e` is a constant expression if `e`
/// is an actual argument in an expression derived from ⟨constObjectExpression⟩
/// @author [email protected]
import '../../../../Utils/expect.dart';

class C {
final val;
const C(this.val);
}

main() {
const c = const C(1);
Expect.identical(c, const C(1));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) 2024, 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.

/// @assertion Let e be an expression; e occurs in a constant context iff one of
/// the following applies:
/// ...
/// • e is the initializing expression of a constant variable declaration
///
/// @description Checks that an expression `e` is a constant expression if `e`
/// is the initializing expression of a constant variable declaration
/// @author [email protected]
import '../../../../Utils/expect.dart';

class C {
final val;
const C(this.val);
}

main() {
const c = C(1);
Expect.identical(c, const C(1));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) 2024, 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.

/// @assertion Let e be an expression; e occurs in a constant context iff one of
/// the following applies:
/// ...
/// • e is an immediate subexpression of an expression e0 which occurs in a
/// constant context, where e0 is not a function literal
///
/// @description Checks that an expression `e` is a constant expression if `e`
/// is an immediate subexpression of an expression `e0` which occurs in a
/// constant context, where `e0` is not a function literal
/// @author [email protected]
import '../../../../Utils/expect.dart';

class C {
final val;
const C(this.val);
}

Object foo(Object o) => o;

main() {
var c1 = const C(C(1));
const c2 = 2 > 1 ? C(0) : C(1);
var c3 = identical(C(3), C(3));
const c4 = identical(C(3), C(3));

Expect.identical(const C(1), c1.val);
Expect.identical(const C(0), c2);
Expect.isFalse(c3);
Expect.isTrue(c4);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) 2024, 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.

/// @assertion Let e be an expression; e occurs in a constant context iff one of
/// the following applies:
/// ...
/// • e is an immediate subexpression of an expression e0 which occurs in a
/// constant context, where e0 is not a function literal
///
/// @description Checks that it is a compile-time error if `e` is an immediate
/// subexpression of an expression `e0` which occurs in a constant context but
/// `e0` is a function literal
/// @author [email protected]
class C {
final val;
const C(this.val);
}

main() {
const c1 = (){C(1);};
// ^^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

var c2 = const (){C(1);};
// ^^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

var c3 = const [(){C(1);}];
// ^^^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) 2024, 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.

/// @assertion A constant context is introduced in situations where an
/// expression is required to be constant. This is used to allow the const
/// modifier to be omitted in cases where it does not contribute any new
/// information.
///
/// @description Checks that an initializers list is not a constant context
/// @author [email protected]
class A {
const A();
}

class C {
final val;
const C.c1() : this.val = [];
// ^^
// [analyzer] unspecified
// [cfe] unspecified

const C.c2() : this.val = A();
// ^^^
// [analyzer] unspecified
// [cfe] unspecified
}

main() {
print(C);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) 2024, 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.

/// @assertion A constant context is introduced in situations where an
/// expression is required to be constant. This is used to allow the const
/// modifier to be omitted in cases where it does not contribute any new
/// information.
///
/// @description Checks that `when` part of a guard pattern is not a constant
/// context
/// @author [email protected]
import '../../../../Utils/expect.dart';

class C {
final val;
const C(this.val);
}

const c1 = C(1);

bool test(bool b) => switch(b) {
true when identical(c1, C(1)) => true,
_ => false
};

main() {
bool wasTrue = false;

if (2 > 1 case true when identical(c1, C(1))) {
wasTrue = true;
}
Expect.isFalse(wasTrue);

switch (true) {
case true when identical(c1, C(1)):
wasTrue = true;
default:
}
Expect.isFalse(wasTrue);
Expect.isFalse(test(true));
}

0 comments on commit 9d85936

Please sign in to comment.