mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 13:08:01 +00:00
[cfe] Don't cache constant in a lazy region
When unevaluated constants are found in conditions, a lazy region is created for evaluating the subexpression, ensure that constant locals are replaced within the subexpressions while still leaving the subexpressions themselves unevaluated. In these lazy regions, the result of evaluating the subexpressions should not be cached, since these subexpressions are not themselves unevaluated and should be evaluated if encountered elsewhere. This was previously not done, leading to constants not being evaluated even when these didn't contain any unevaluated constants. Closes #51823 Change-Id: Ibfc02fef3ecfcd2f1d2e9e1451f0eb71dde6fb42 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/290963 Reviewed-by: Chloe Stefantsova <cstefantsova@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
parent
6ef15e48bb
commit
290706f497
|
@ -2628,8 +2628,12 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
|
|||
if (evaluatedResult is AbortConstant) {
|
||||
nodeCache.remove(node);
|
||||
return evaluatedResult;
|
||||
} else {
|
||||
} else if (lazyDepth == 0) {
|
||||
nodeCache[node] = evaluatedResult;
|
||||
} else {
|
||||
// Don't cache nodes evaluated in a lazy region, since these are not
|
||||
// themselves unevaluated but just part of an unevaluated constant.
|
||||
nodeCache.remove(node);
|
||||
}
|
||||
result = evaluatedResult;
|
||||
}
|
||||
|
|
|
@ -87,9 +87,9 @@ Try correcting the name to the name of an existing getter, or defining a getter
|
|||
request.{core::Object::hashCode}{core::int};
|
||||
}
|
||||
static method main() → void {
|
||||
self::expect(false, #C1);
|
||||
self::expect(true, #C2);
|
||||
self::expect(false, #C1);
|
||||
self::expect(false, #C2);
|
||||
self::expect(true, #C4);
|
||||
self::expect(false, #C6);
|
||||
}
|
||||
static method expect(dynamic expected, dynamic actual) → dynamic {
|
||||
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
|
||||
|
@ -97,6 +97,10 @@ static method expect(dynamic expected, dynamic actual) → dynamic {
|
|||
}
|
||||
|
||||
constants {
|
||||
#C1 = false
|
||||
#C2 = true
|
||||
#C1 = "dart.library.io"
|
||||
#C2 = eval const core::bool::fromEnvironment(#C1)
|
||||
#C3 = "dart.library.html"
|
||||
#C4 = eval const core::bool::fromEnvironment(#C3)
|
||||
#C5 = "dart.library.foo"
|
||||
#C6 = eval const core::bool::fromEnvironment(#C5)
|
||||
}
|
||||
|
|
|
@ -87,9 +87,9 @@ Try correcting the name to the name of an existing getter, or defining a getter
|
|||
request.{core::Object::hashCode}{core::int};
|
||||
}
|
||||
static method main() → void {
|
||||
self::expect(false, #C1);
|
||||
self::expect(true, #C2);
|
||||
self::expect(false, #C1);
|
||||
self::expect(false, #C2);
|
||||
self::expect(true, #C4);
|
||||
self::expect(false, #C6);
|
||||
}
|
||||
static method expect(dynamic expected, dynamic actual) → dynamic {
|
||||
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
|
||||
|
@ -97,6 +97,16 @@ static method expect(dynamic expected, dynamic actual) → dynamic {
|
|||
}
|
||||
|
||||
constants {
|
||||
#C1 = false
|
||||
#C2 = true
|
||||
#C1 = "dart.library.io"
|
||||
#C2 = eval const core::bool::fromEnvironment(#C1)
|
||||
#C3 = "dart.library.html"
|
||||
#C4 = eval const core::bool::fromEnvironment(#C3)
|
||||
#C5 = "dart.library.foo"
|
||||
#C6 = eval const core::bool::fromEnvironment(#C5)
|
||||
}
|
||||
|
||||
Extra constant evaluation status:
|
||||
Evaluated with empty environment: ConstantExpression @ org-dartlang-testcase:///conditional_import.dart:41:23 -> BoolConstant(false)
|
||||
Evaluated with empty environment: ConstantExpression @ org-dartlang-testcase:///conditional_import.dart:42:22 -> BoolConstant(true)
|
||||
Evaluated with empty environment: ConstantExpression @ org-dartlang-testcase:///conditional_import.dart:43:23 -> BoolConstant(false)
|
||||
Extra constant evaluation: evaluated: 29, effectively constant: 3
|
||||
|
|
|
@ -87,9 +87,9 @@ Try correcting the name to the name of an existing getter, or defining a getter
|
|||
request.{core::Object::hashCode}{core::int};
|
||||
}
|
||||
static method main() → void {
|
||||
self::expect(false, #C1);
|
||||
self::expect(true, #C2);
|
||||
self::expect(false, #C1);
|
||||
self::expect(false, #C2);
|
||||
self::expect(true, #C4);
|
||||
self::expect(false, #C6);
|
||||
}
|
||||
static method expect(dynamic expected, dynamic actual) → dynamic {
|
||||
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
|
||||
|
@ -97,6 +97,10 @@ static method expect(dynamic expected, dynamic actual) → dynamic {
|
|||
}
|
||||
|
||||
constants {
|
||||
#C1 = false
|
||||
#C2 = true
|
||||
#C1 = "dart.library.io"
|
||||
#C2 = eval const core::bool::fromEnvironment(#C1)
|
||||
#C3 = "dart.library.html"
|
||||
#C4 = eval const core::bool::fromEnvironment(#C3)
|
||||
#C5 = "dart.library.foo"
|
||||
#C6 = eval const core::bool::fromEnvironment(#C5)
|
||||
}
|
||||
|
|
|
@ -87,9 +87,9 @@ Try correcting the name to the name of an existing getter, or defining a getter
|
|||
request.{core::Object::hashCode}{core::int};
|
||||
}
|
||||
static method main() → void {
|
||||
self::expect(false, #C1);
|
||||
self::expect(true, #C2);
|
||||
self::expect(false, #C1);
|
||||
self::expect(false, #C2);
|
||||
self::expect(true, #C4);
|
||||
self::expect(false, #C6);
|
||||
}
|
||||
static method expect(dynamic expected, dynamic actual) → dynamic {
|
||||
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
|
||||
|
@ -97,6 +97,10 @@ static method expect(dynamic expected, dynamic actual) → dynamic {
|
|||
}
|
||||
|
||||
constants {
|
||||
#C1 = false
|
||||
#C2 = true
|
||||
#C1 = "dart.library.io"
|
||||
#C2 = eval const core::bool::fromEnvironment(#C1)
|
||||
#C3 = "dart.library.html"
|
||||
#C4 = eval const core::bool::fromEnvironment(#C3)
|
||||
#C5 = "dart.library.foo"
|
||||
#C6 = eval const core::bool::fromEnvironment(#C5)
|
||||
}
|
||||
|
|
|
@ -87,9 +87,9 @@ Try correcting the name to the name of an existing getter, or defining a getter
|
|||
request.{core::Object::hashCode}{core::int};
|
||||
}
|
||||
static method main() → void {
|
||||
self::expect(false, #C1);
|
||||
self::expect(true, #C2);
|
||||
self::expect(false, #C1);
|
||||
self::expect(false, #C2);
|
||||
self::expect(true, #C4);
|
||||
self::expect(false, #C6);
|
||||
}
|
||||
static method expect(dynamic expected, dynamic actual) → dynamic {
|
||||
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
|
||||
|
@ -97,6 +97,16 @@ static method expect(dynamic expected, dynamic actual) → dynamic {
|
|||
}
|
||||
|
||||
constants {
|
||||
#C1 = false
|
||||
#C2 = true
|
||||
#C1 = "dart.library.io"
|
||||
#C2 = eval const core::bool::fromEnvironment(#C1)
|
||||
#C3 = "dart.library.html"
|
||||
#C4 = eval const core::bool::fromEnvironment(#C3)
|
||||
#C5 = "dart.library.foo"
|
||||
#C6 = eval const core::bool::fromEnvironment(#C5)
|
||||
}
|
||||
|
||||
Extra constant evaluation status:
|
||||
Evaluated with empty environment: ConstantExpression @ org-dartlang-testcase:///conditional_import.dart:41:23 -> BoolConstant(false)
|
||||
Evaluated with empty environment: ConstantExpression @ org-dartlang-testcase:///conditional_import.dart:42:22 -> BoolConstant(true)
|
||||
Evaluated with empty environment: ConstantExpression @ org-dartlang-testcase:///conditional_import.dart:43:23 -> BoolConstant(false)
|
||||
Extra constant evaluation: evaluated: 29, effectively constant: 3
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
--target=dart2js
|
||||
--target=dart2js
|
||||
--no-defines
|
||||
|
|
7
pkg/front_end/testcases/dart2js/issue51823.dart
Normal file
7
pkg/front_end/testcases/dart2js/issue51823.dart
Normal file
|
@ -0,0 +1,7 @@
|
|||
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'issue51823_lib.dart';
|
||||
|
||||
const a = const bool.fromEnvironment('foo') ? E.a : E.b;
|
|
@ -0,0 +1,59 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
import self as self;
|
||||
import "issue51823_lib.dart" as iss;
|
||||
|
||||
import "org-dartlang-testcase:///issue51823_lib.dart";
|
||||
|
||||
static const field iss::E a = #C9;
|
||||
|
||||
library /*isNonNullableByDefault*/;
|
||||
import self as iss;
|
||||
import "dart:core" as core;
|
||||
|
||||
class E extends core::_Enum /*isEnum*/ {
|
||||
static const field core::List<iss::E> values = #C12;
|
||||
enum-element static const field iss::E a = #C10;
|
||||
enum-element static const field iss::E b = #C11;
|
||||
const constructor •(core::int #index, core::String #name) → iss::E
|
||||
: super core::_Enum::•(#index, #name)
|
||||
;
|
||||
method _enumToString() → core::String
|
||||
return "E.${this.{core::_Enum::_name}{core::String}}";
|
||||
}
|
||||
static method method(iss::E e) → dynamic {
|
||||
#L1:
|
||||
switch(e) /*isExplicitlyExhaustive*/ {
|
||||
#L2:
|
||||
case #C10:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#L3:
|
||||
case #C11:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = "foo"
|
||||
#C2 = eval const core::bool::fromEnvironment(#C1)
|
||||
#C3 = 0.0
|
||||
#C4 = "a"
|
||||
#C5 = eval iss::E{index:#C3, _name:#C4}
|
||||
#C6 = 1.0
|
||||
#C7 = "b"
|
||||
#C8 = eval iss::E{index:#C6, _name:#C7}
|
||||
#C9 = eval #C2 ?{iss::E} #C5 : #C8
|
||||
#C10 = iss::E {index:#C3, _name:#C4}
|
||||
#C11 = iss::E {index:#C6, _name:#C7}
|
||||
#C12 = <iss::E>[#C10, #C11]
|
||||
}
|
||||
|
||||
|
||||
Constructor coverage from constants:
|
||||
org-dartlang-testcase:///issue51823_lib.dart:
|
||||
- E. (from org-dartlang-testcase:///issue51823_lib.dart:5:6)
|
||||
- _Enum. (from org-dartlang-sdk:///lib/core/enum.dart)
|
||||
- Object. (from org-dartlang-sdk:///lib/core/object.dart)
|
|
@ -0,0 +1,63 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
import self as self;
|
||||
import "issue51823_lib.dart" as iss;
|
||||
|
||||
import "org-dartlang-testcase:///issue51823_lib.dart";
|
||||
|
||||
static const field iss::E a = #C9;
|
||||
|
||||
library /*isNonNullableByDefault*/;
|
||||
import self as iss;
|
||||
import "dart:core" as core;
|
||||
|
||||
class E extends core::_Enum /*isEnum*/ {
|
||||
static const field core::List<iss::E> values = #C12;
|
||||
enum-element static const field iss::E a = #C10;
|
||||
enum-element static const field iss::E b = #C11;
|
||||
const constructor •(core::int #index, core::String #name) → iss::E
|
||||
: super core::_Enum::•(#index, #name)
|
||||
;
|
||||
method _enumToString() → core::String
|
||||
return "E.${this.{core::_Enum::_name}{core::String}}";
|
||||
}
|
||||
static method method(iss::E e) → dynamic {
|
||||
#L1:
|
||||
switch(e) /*isExplicitlyExhaustive*/ {
|
||||
#L2:
|
||||
case #C10:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#L3:
|
||||
case #C11:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = "foo"
|
||||
#C2 = eval const core::bool::fromEnvironment(#C1)
|
||||
#C3 = 0.0
|
||||
#C4 = "a"
|
||||
#C5 = eval iss::E{index:#C3, _name:#C4}
|
||||
#C6 = 1.0
|
||||
#C7 = "b"
|
||||
#C8 = eval iss::E{index:#C6, _name:#C7}
|
||||
#C9 = eval #C2 ?{iss::E} #C5 : #C8
|
||||
#C10 = iss::E {index:#C3, _name:#C4}
|
||||
#C11 = iss::E {index:#C6, _name:#C7}
|
||||
#C12 = <iss::E>[#C10, #C11]
|
||||
}
|
||||
|
||||
Extra constant evaluation status:
|
||||
Evaluated with empty environment: ConstantExpression @ org-dartlang-testcase:///issue51823.dart:7:45 -> InstanceConstant(const E{_Enum.index: 1.0, _Enum._name: "b"})
|
||||
Extra constant evaluation: evaluated: 7, effectively constant: 1
|
||||
|
||||
|
||||
Constructor coverage from constants:
|
||||
org-dartlang-testcase:///issue51823_lib.dart:
|
||||
- E. (from org-dartlang-testcase:///issue51823_lib.dart:5:6)
|
||||
- _Enum. (from org-dartlang-sdk:///lib/core/enum.dart)
|
||||
- Object. (from org-dartlang-sdk:///lib/core/object.dart)
|
|
@ -0,0 +1,3 @@
|
|||
import 'issue51823_lib.dart';
|
||||
|
||||
const a = const bool.fromEnvironment('foo') ? E.a : E.b;
|
|
@ -0,0 +1,3 @@
|
|||
import 'issue51823_lib.dart';
|
||||
|
||||
const a = const bool.fromEnvironment('foo') ? E.a : E.b;
|
63
pkg/front_end/testcases/dart2js/issue51823.dart.weak.expect
Normal file
63
pkg/front_end/testcases/dart2js/issue51823.dart.weak.expect
Normal file
|
@ -0,0 +1,63 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
import self as self;
|
||||
import "issue51823_lib.dart" as iss;
|
||||
|
||||
import "org-dartlang-testcase:///issue51823_lib.dart";
|
||||
|
||||
static const field iss::E a = #C9;
|
||||
|
||||
library /*isNonNullableByDefault*/;
|
||||
import self as iss;
|
||||
import "dart:core" as core;
|
||||
import "dart:_internal" as _in;
|
||||
|
||||
class E extends core::_Enum /*isEnum*/ {
|
||||
static const field core::List<iss::E> values = #C12;
|
||||
enum-element static const field iss::E a = #C10;
|
||||
enum-element static const field iss::E b = #C11;
|
||||
const constructor •(core::int #index, core::String #name) → iss::E
|
||||
: super core::_Enum::•(#index, #name)
|
||||
;
|
||||
method _enumToString() → core::String
|
||||
return "E.${this.{core::_Enum::_name}{core::String}}";
|
||||
}
|
||||
static method method(iss::E e) → dynamic {
|
||||
#L1:
|
||||
switch(e) /*isExplicitlyExhaustive*/ {
|
||||
#L2:
|
||||
case #C10:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#L3:
|
||||
case #C11:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#L4:
|
||||
default:
|
||||
throw new _in::ReachabilityError::•("`null` encountered as case in a switch statement with a non-nullable type.");
|
||||
}
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = "foo"
|
||||
#C2 = eval const core::bool::fromEnvironment(#C1)
|
||||
#C3 = 0.0
|
||||
#C4 = "a"
|
||||
#C5 = eval iss::E{index:#C3, _name:#C4}
|
||||
#C6 = 1.0
|
||||
#C7 = "b"
|
||||
#C8 = eval iss::E{index:#C6, _name:#C7}
|
||||
#C9 = eval #C2 ?{iss::E} #C5 : #C8
|
||||
#C10 = iss::E {index:#C3, _name:#C4}
|
||||
#C11 = iss::E {index:#C6, _name:#C7}
|
||||
#C12 = <iss::E*>[#C10, #C11]
|
||||
}
|
||||
|
||||
|
||||
Constructor coverage from constants:
|
||||
org-dartlang-testcase:///issue51823_lib.dart:
|
||||
- E. (from org-dartlang-testcase:///issue51823_lib.dart:5:6)
|
||||
- _Enum. (from org-dartlang-sdk:///lib/core/enum.dart)
|
||||
- Object. (from org-dartlang-sdk:///lib/core/object.dart)
|
|
@ -0,0 +1,63 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
import self as self;
|
||||
import "issue51823_lib.dart" as iss;
|
||||
|
||||
import "org-dartlang-testcase:///issue51823_lib.dart";
|
||||
|
||||
static const field iss::E a = #C9;
|
||||
|
||||
library /*isNonNullableByDefault*/;
|
||||
import self as iss;
|
||||
import "dart:core" as core;
|
||||
import "dart:_internal" as _in;
|
||||
|
||||
class E extends core::_Enum /*isEnum*/ {
|
||||
static const field core::List<iss::E> values = #C12;
|
||||
enum-element static const field iss::E a = #C10;
|
||||
enum-element static const field iss::E b = #C11;
|
||||
const constructor •(core::int #index, core::String #name) → iss::E
|
||||
: super core::_Enum::•(#index, #name)
|
||||
;
|
||||
method _enumToString() → core::String
|
||||
return "E.${this.{core::_Enum::_name}{core::String}}";
|
||||
}
|
||||
static method method(iss::E e) → dynamic {
|
||||
#L1:
|
||||
switch(e) /*isExplicitlyExhaustive*/ {
|
||||
#L2:
|
||||
case #C10:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#L3:
|
||||
case #C11:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#L4:
|
||||
default:
|
||||
throw new _in::ReachabilityError::•("`null` encountered as case in a switch statement with a non-nullable type.");
|
||||
}
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = "foo"
|
||||
#C2 = eval const core::bool::fromEnvironment(#C1)
|
||||
#C3 = 0.0
|
||||
#C4 = "a"
|
||||
#C5 = eval iss::E{index:#C3, _name:#C4}
|
||||
#C6 = 1.0
|
||||
#C7 = "b"
|
||||
#C8 = eval iss::E{index:#C6, _name:#C7}
|
||||
#C9 = eval #C2 ?{iss::E} #C5 : #C8
|
||||
#C10 = iss::E {index:#C3, _name:#C4}
|
||||
#C11 = iss::E {index:#C6, _name:#C7}
|
||||
#C12 = <iss::E*>[#C10, #C11]
|
||||
}
|
||||
|
||||
|
||||
Constructor coverage from constants:
|
||||
org-dartlang-testcase:///issue51823_lib.dart:
|
||||
- E. (from org-dartlang-testcase:///issue51823_lib.dart:5:6)
|
||||
- _Enum. (from org-dartlang-sdk:///lib/core/enum.dart)
|
||||
- Object. (from org-dartlang-sdk:///lib/core/object.dart)
|
|
@ -0,0 +1,36 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
import self as self;
|
||||
import "issue51823_lib.dart" as iss;
|
||||
import "dart:core" as core;
|
||||
|
||||
import "org-dartlang-testcase:///issue51823_lib.dart";
|
||||
|
||||
static const field iss::E a = const core::bool::fromEnvironment("foo") ?{iss::E} iss::E::a : iss::E::b;
|
||||
|
||||
library /*isNonNullableByDefault*/;
|
||||
import self as iss;
|
||||
import "dart:core" as core;
|
||||
|
||||
class E extends core::_Enum /*isEnum*/ {
|
||||
static const field core::List<iss::E> values = const <iss::E>[iss::E::a, iss::E::b];
|
||||
enum-element static const field iss::E a = const iss::E::•(0, "a");
|
||||
enum-element static const field iss::E b = const iss::E::•(1, "b");
|
||||
const constructor •(core::int #index, core::String #name) → iss::E
|
||||
: super core::_Enum::•(#index, #name)
|
||||
;
|
||||
method _enumToString() → core::String
|
||||
return "E.${this.{core::_Enum::_name}{core::String}}";
|
||||
}
|
||||
static method method(iss::E e) → dynamic
|
||||
;
|
||||
|
||||
|
||||
Extra constant evaluation status:
|
||||
Evaluated with empty environment: ConditionalExpression @ org-dartlang-testcase:///issue51823.dart:7:45 -> InstanceConstant(const E{_Enum.index: 1.0, _Enum._name: "b"})
|
||||
Evaluated with empty environment: FactoryConstructorInvocation @ org-dartlang-testcase:///issue51823.dart:7:17 -> BoolConstant(false)
|
||||
Evaluated: StaticGet @ org-dartlang-testcase:///issue51823.dart:7:49 -> InstanceConstant(const E{_Enum.index: 0.0, _Enum._name: "a"})
|
||||
Evaluated: StaticGet @ org-dartlang-testcase:///issue51823.dart:7:55 -> InstanceConstant(const E{_Enum.index: 1.0, _Enum._name: "b"})
|
||||
Evaluated: ListLiteral @ org-dartlang-testcase:///issue51823_lib.dart:5:6 -> ListConstant(const <E*>[const E{_Enum.index: 0.0, _Enum._name: "a"}, const E{_Enum.index: 1.0, _Enum._name: "b"}])
|
||||
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue51823_lib.dart:5:10 -> InstanceConstant(const E{_Enum.index: 0.0, _Enum._name: "a"})
|
||||
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue51823_lib.dart:5:13 -> InstanceConstant(const E{_Enum.index: 1.0, _Enum._name: "b"})
|
||||
Extra constant evaluation: evaluated: 12, effectively constant: 7
|
|
@ -0,0 +1,67 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
import self as self;
|
||||
import "issue51823_lib.dart" as iss;
|
||||
|
||||
import "org-dartlang-testcase:///issue51823_lib.dart";
|
||||
|
||||
static const field iss::E a = #C9;
|
||||
|
||||
library /*isNonNullableByDefault*/;
|
||||
import self as iss;
|
||||
import "dart:core" as core;
|
||||
import "dart:_internal" as _in;
|
||||
|
||||
class E extends core::_Enum /*isEnum*/ {
|
||||
static const field core::List<iss::E> values = #C12;
|
||||
enum-element static const field iss::E a = #C10;
|
||||
enum-element static const field iss::E b = #C11;
|
||||
const constructor •(core::int #index, core::String #name) → iss::E
|
||||
: super core::_Enum::•(#index, #name)
|
||||
;
|
||||
method _enumToString() → core::String
|
||||
return "E.${this.{core::_Enum::_name}{core::String}}";
|
||||
}
|
||||
static method method(iss::E e) → dynamic {
|
||||
#L1:
|
||||
switch(e) /*isExplicitlyExhaustive*/ {
|
||||
#L2:
|
||||
case #C10:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#L3:
|
||||
case #C11:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#L4:
|
||||
default:
|
||||
throw new _in::ReachabilityError::•("`null` encountered as case in a switch statement with a non-nullable type.");
|
||||
}
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = "foo"
|
||||
#C2 = eval const core::bool::fromEnvironment(#C1)
|
||||
#C3 = 0.0
|
||||
#C4 = "a"
|
||||
#C5 = eval iss::E{index:#C3, _name:#C4}
|
||||
#C6 = 1.0
|
||||
#C7 = "b"
|
||||
#C8 = eval iss::E{index:#C6, _name:#C7}
|
||||
#C9 = eval #C2 ?{iss::E} #C5 : #C8
|
||||
#C10 = iss::E {index:#C3, _name:#C4}
|
||||
#C11 = iss::E {index:#C6, _name:#C7}
|
||||
#C12 = <iss::E*>[#C10, #C11]
|
||||
}
|
||||
|
||||
Extra constant evaluation status:
|
||||
Evaluated with empty environment: ConstantExpression @ org-dartlang-testcase:///issue51823.dart:7:45 -> InstanceConstant(const E{_Enum.index: 1.0, _Enum._name: "b"})
|
||||
Extra constant evaluation: evaluated: 9, effectively constant: 1
|
||||
|
||||
|
||||
Constructor coverage from constants:
|
||||
org-dartlang-testcase:///issue51823_lib.dart:
|
||||
- E. (from org-dartlang-testcase:///issue51823_lib.dart:5:6)
|
||||
- _Enum. (from org-dartlang-sdk:///lib/core/enum.dart)
|
||||
- Object. (from org-dartlang-sdk:///lib/core/object.dart)
|
14
pkg/front_end/testcases/dart2js/issue51823_lib.dart
Normal file
14
pkg/front_end/testcases/dart2js/issue51823_lib.dart
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
enum E { a, b }
|
||||
|
||||
method(E e) {
|
||||
switch (e) {
|
||||
case E.a:
|
||||
return 0;
|
||||
case E.b:
|
||||
return 1;
|
||||
}
|
||||
}
|
|
@ -113,10 +113,8 @@ Evaluated: TypeLiteral @ org-dartlang-testcase:///various_2_lib.dart:17:27 -> Ty
|
|||
Evaluated: StaticTearOff @ org-dartlang-testcase:///various_2_lib.dart:18:12 -> StaticTearOffConstant(identical)
|
||||
Evaluated with empty environment: ConditionalExpression @ org-dartlang-testcase:///various_2_lib.dart:20:39 -> InstantiationConstant(id2<int*>)
|
||||
Evaluated with empty environment: FactoryConstructorInvocation @ org-dartlang-testcase:///various_2_lib.dart:20:11 -> BoolConstant(false)
|
||||
Evaluated with empty environment: Instantiation @ org-dartlang-testcase:///various_2_lib.dart:20:41 -> InstantiationConstant(id1<int*>)
|
||||
Evaluated: StaticTearOff @ org-dartlang-testcase:///various_2_lib.dart:20:41 -> StaticTearOffConstant(id1)
|
||||
Evaluated with empty environment: Instantiation @ org-dartlang-testcase:///various_2_lib.dart:20:47 -> InstantiationConstant(id2<int*>)
|
||||
Evaluated: StaticTearOff @ org-dartlang-testcase:///various_2_lib.dart:20:47 -> StaticTearOffConstant(id2)
|
||||
Evaluated: Instantiation @ org-dartlang-testcase:///various_2_lib.dart:20:41 -> InstantiationConstant(id1<int*>)
|
||||
Evaluated: Instantiation @ org-dartlang-testcase:///various_2_lib.dart:20:47 -> InstantiationConstant(id2<int*>)
|
||||
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///various_2_lib.dart:21:24 -> InstanceConstant(const Class<int*>{Class.field: 0})
|
||||
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///various_2_lib.dart:22:25 -> InstanceConstant(const Class<dynamic>{Class.field: const <int*>[42]})
|
||||
Evaluated: TypeLiteral @ org-dartlang-testcase:///various_2_lib.dart:23:29 -> TypeLiteralConstant(dynamic Function(dynamic)*)
|
||||
|
@ -130,4 +128,4 @@ Evaluated: MapLiteral @ org-dartlang-testcase:///various_2_lib.dart:34:39 -> Map
|
|||
Evaluated: ListConcatenation @ org-dartlang-testcase:///various_2_lib.dart:38:32 -> ListConstant(const <int*>[0])
|
||||
Evaluated: SetConcatenation @ org-dartlang-testcase:///various_2_lib.dart:39:31 -> SetConstant(const <int*>{0})
|
||||
Evaluated: MapConcatenation @ org-dartlang-testcase:///various_2_lib.dart:40:7 -> MapConstant(const <int*, String*>{0: "foo"})
|
||||
Extra constant evaluation: evaluated: 54, effectively constant: 53
|
||||
Extra constant evaluation: evaluated: 52, effectively constant: 51
|
||||
|
|
Loading…
Reference in a new issue