diff --git a/pkg/front_end/lib/src/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/kernel/constant_evaluator.dart index 1f1aa25a040..7239370f13e 100644 --- a/pkg/front_end/lib/src/kernel/constant_evaluator.dart +++ b/pkg/front_end/lib/src/kernel/constant_evaluator.dart @@ -3380,19 +3380,23 @@ class ConstantEvaluator implements ExpressionVisitor { if (condition is AbortConstant) return condition; if (shouldBeUnevaluated) { - // Coverage-ignore-block(suite): Not run. - Expression? message = null; - if (statement.message != null) { - enterLazy(); - Constant constant = _evaluateSubexpression(statement.message!); - if (constant is AbortConstant) return constant; - message = _wrap(constant); - leaveLazy(); + if (instanceBuilder != null) { + Expression? message = null; + if (statement.message != null) { + enterLazy(); + Constant constant = _evaluateSubexpression(statement.message!); + if (constant is AbortConstant) return constant; + message = _wrap(constant); + leaveLazy(); + } + instanceBuilder!.asserts.add(new AssertStatement(_wrap(condition), + message: message, + conditionStartOffset: statement.conditionStartOffset, + conditionEndOffset: statement.conditionEndOffset)); + } else { + assert(inExtensionTypeConstConstructor); + return null; } - instanceBuilder!.asserts.add(new AssertStatement(_wrap(condition), - message: message, - conditionStartOffset: statement.conditionStartOffset, - conditionEndOffset: statement.conditionEndOffset)); } else if (condition is BoolConstant) { if (!condition.value) { if (statement.message == null) { @@ -4543,6 +4547,13 @@ class ConstantEvaluator implements ExpressionVisitor { Constant result = _handleFunctionInvocation( node.target.function, typeArguments, positional, named); inExtensionTypeConstConstructor = oldInExtensionTypeConstructor; + if (shouldBeUnevaluated) { + return unevaluated( + node, + new StaticInvocation(target, + unevaluatedArguments(positional, named, arguments.types), + isConst: node.isConst)); + } return result; } else { return createEvaluationErrorConstant( diff --git a/pkg/front_end/testcases/dart2js/issue56803.dart b/pkg/front_end/testcases/dart2js/issue56803.dart new file mode 100644 index 00000000000..8100aeff21e --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue56803.dart @@ -0,0 +1,14 @@ +// 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. + +const String? maybe = bool.fromEnvironment("not there") ? "string" : null; +extension type const Ext._(String _) implements String { + const Ext() + : assert(maybe != null, "Must not be null"), + _ = "OK"; +} +void main() { + var c = const Ext(); + print(c); +} diff --git a/pkg/front_end/testcases/dart2js/issue56803.dart.strong.expect b/pkg/front_end/testcases/dart2js/issue56803.dart.strong.expect new file mode 100644 index 00000000000..b8303d9949b --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue56803.dart.strong.expect @@ -0,0 +1,38 @@ +library; +import self as self; +import "dart:core" as core; + +extension type Ext(core::String _) implements core::String { + abstract extension-type-member representation-field get _() → core::String; + constructor _ = self::Ext|constructor#_; + constructor tearoff _ = self::Ext|constructor#_#_#tearOff; + constructor • = self::Ext|constructor#; + constructor tearoff • = self::Ext|constructor#_#new#tearOff; +} +static const field core::String? maybe = #C5; +static extension-type-member method Ext|constructor#_(core::String _) → self::Ext /* erasure=core::String */ { + lowered final self::Ext /* erasure=core::String */ #this = _; + return #this; +} +static extension-type-member method Ext|constructor#_#_#tearOff(core::String _) → self::Ext /* erasure=core::String */ + return self::Ext|constructor#_(_); +static extension-type-member method Ext|constructor#() → self::Ext /* erasure=core::String */ { + lowered final self::Ext /* erasure=core::String */ #this = "OK"; + assert(!(#C5 == null), "Must not be null"); + return #this; +} +static extension-type-member method Ext|constructor#_#new#tearOff() → self::Ext /* erasure=core::String */ + return self::Ext|constructor#(); +static method main() → void { + self::Ext /* erasure=core::String */ c = #C6; + core::print(c); +} + +constants { + #C1 = "not there" + #C2 = eval /* from org-dartlang-testcase:///issue56803.dart */ const core::bool::fromEnvironment(#C1) + #C3 = "string" + #C4 = null + #C5 = eval /* from org-dartlang-testcase:///issue56803.dart */ #C2 ?{core::String?} #C3 : #C4 + #C6 = eval /* from org-dartlang-testcase:///issue56803.dart */ const self::Ext|constructor#() +} diff --git a/pkg/front_end/testcases/dart2js/issue56803.dart.strong.modular.expect b/pkg/front_end/testcases/dart2js/issue56803.dart.strong.modular.expect new file mode 100644 index 00000000000..b8303d9949b --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue56803.dart.strong.modular.expect @@ -0,0 +1,38 @@ +library; +import self as self; +import "dart:core" as core; + +extension type Ext(core::String _) implements core::String { + abstract extension-type-member representation-field get _() → core::String; + constructor _ = self::Ext|constructor#_; + constructor tearoff _ = self::Ext|constructor#_#_#tearOff; + constructor • = self::Ext|constructor#; + constructor tearoff • = self::Ext|constructor#_#new#tearOff; +} +static const field core::String? maybe = #C5; +static extension-type-member method Ext|constructor#_(core::String _) → self::Ext /* erasure=core::String */ { + lowered final self::Ext /* erasure=core::String */ #this = _; + return #this; +} +static extension-type-member method Ext|constructor#_#_#tearOff(core::String _) → self::Ext /* erasure=core::String */ + return self::Ext|constructor#_(_); +static extension-type-member method Ext|constructor#() → self::Ext /* erasure=core::String */ { + lowered final self::Ext /* erasure=core::String */ #this = "OK"; + assert(!(#C5 == null), "Must not be null"); + return #this; +} +static extension-type-member method Ext|constructor#_#new#tearOff() → self::Ext /* erasure=core::String */ + return self::Ext|constructor#(); +static method main() → void { + self::Ext /* erasure=core::String */ c = #C6; + core::print(c); +} + +constants { + #C1 = "not there" + #C2 = eval /* from org-dartlang-testcase:///issue56803.dart */ const core::bool::fromEnvironment(#C1) + #C3 = "string" + #C4 = null + #C5 = eval /* from org-dartlang-testcase:///issue56803.dart */ #C2 ?{core::String?} #C3 : #C4 + #C6 = eval /* from org-dartlang-testcase:///issue56803.dart */ const self::Ext|constructor#() +} diff --git a/pkg/front_end/testcases/dart2js/issue56803.dart.strong.outline.expect b/pkg/front_end/testcases/dart2js/issue56803.dart.strong.outline.expect new file mode 100644 index 00000000000..66031b47ffc --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue56803.dart.strong.outline.expect @@ -0,0 +1,36 @@ +library; +import self as self; +import "dart:core" as core; + +extension type Ext(core::String _) implements core::String { + abstract extension-type-member representation-field get _() → core::String; + constructor _ = self::Ext|constructor#_; + constructor tearoff _ = self::Ext|constructor#_#_#tearOff; + constructor • = self::Ext|constructor#; + constructor tearoff • = self::Ext|constructor#_#new#tearOff; +} +static const field core::String? maybe = const core::bool::fromEnvironment("not there") ?{core::String?} "string" : null; +static extension-type-member method Ext|constructor#_(core::String _) → self::Ext /* erasure=core::String */ { + lowered final self::Ext /* erasure=core::String */ #this = _; + return #this; +} +static extension-type-member method Ext|constructor#_#_#tearOff(core::String _) → self::Ext /* erasure=core::String */ + return self::Ext|constructor#_(_); +static extension-type-member method Ext|constructor#() → self::Ext /* erasure=core::String */ { + lowered final self::Ext /* erasure=core::String */ #this = "OK"; + assert(!(self::maybe == null), "Must not be null"); + return #this; +} +static extension-type-member method Ext|constructor#_#new#tearOff() → self::Ext /* erasure=core::String */ + return self::Ext|constructor#(); +static method main() → void + ; + + +Extra constant evaluation status: +Evaluated with empty environment: Not @ org-dartlang-testcase:///issue56803.dart:8:22 -> BoolConstant(false) +Evaluated with empty environment: EqualsNull @ org-dartlang-testcase:///issue56803.dart:8:22 -> BoolConstant(true) +Evaluated with empty environment: StaticGet @ org-dartlang-testcase:///issue56803.dart:8:16 -> NullConstant(null) +Evaluated with empty environment: ConditionalExpression @ org-dartlang-testcase:///issue56803.dart:5:57 -> NullConstant(null) +Evaluated with empty environment: FactoryConstructorInvocation @ org-dartlang-testcase:///issue56803.dart:5:28 -> BoolConstant(false) +Extra constant evaluation: evaluated: 11, effectively constant: 5 diff --git a/pkg/front_end/testcases/dart2js/issue56803.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/issue56803.dart.strong.transformed.expect new file mode 100644 index 00000000000..9b8c26f083d --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue56803.dart.strong.transformed.expect @@ -0,0 +1,45 @@ +library; +import self as self; +import "dart:core" as core; + +extension type Ext(core::String _) implements core::String { + abstract extension-type-member representation-field get _() → core::String; + constructor _ = self::Ext|constructor#_; + constructor tearoff _ = self::Ext|constructor#_#_#tearOff; + constructor • = self::Ext|constructor#; + constructor tearoff • = self::Ext|constructor#_#new#tearOff; +} +static const field core::String? maybe = #C5; +static extension-type-member method Ext|constructor#_(core::String _) → self::Ext /* erasure=core::String */ { + lowered final self::Ext /* erasure=core::String */ #this = _; + return #this; +} +static extension-type-member method Ext|constructor#_#_#tearOff(core::String _) → self::Ext /* erasure=core::String */ + return self::Ext|constructor#_(_); +static extension-type-member method Ext|constructor#() → self::Ext /* erasure=core::String */ { + lowered final self::Ext /* erasure=core::String */ #this = "OK"; + assert(!(#C5 == null), "Must not be null"); + return #this; +} +static extension-type-member method Ext|constructor#_#new#tearOff() → self::Ext /* erasure=core::String */ + return self::Ext|constructor#(); +static method main() → void { + self::Ext /* erasure=core::String */ c = #C6; + core::print(c); +} + +constants { + #C1 = "not there" + #C2 = eval /* from org-dartlang-testcase:///issue56803.dart */ const core::bool::fromEnvironment(#C1) + #C3 = "string" + #C4 = null + #C5 = eval /* from org-dartlang-testcase:///issue56803.dart */ #C2 ?{core::String?} #C3 : #C4 + #C6 = eval /* from org-dartlang-testcase:///issue56803.dart */ const self::Ext|constructor#() +} + +Extra constant evaluation status: +Evaluated with empty environment: Not @ org-dartlang-testcase:///issue56803.dart:8:22 -> BoolConstant(false) +Evaluated with empty environment: EqualsNull @ org-dartlang-testcase:///issue56803.dart:8:22 -> BoolConstant(true) +Evaluated with empty environment: ConstantExpression @ org-dartlang-testcase:///issue56803.dart:8:16 -> NullConstant(null) +Evaluated with empty environment: ConstantExpression @ org-dartlang-testcase:///issue56803.dart:5:57 -> NullConstant(null) +Extra constant evaluation: evaluated: 13, effectively constant: 4 diff --git a/pkg/front_end/testcases/dart2js/issue56803.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/issue56803.dart.textual_outline.expect new file mode 100644 index 00000000000..c43f36cd3d0 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue56803.dart.textual_outline.expect @@ -0,0 +1,9 @@ +const String? maybe = bool.fromEnvironment("not there") ? "string" : null; + +extension type const Ext._(String _) implements String { + const Ext() + : assert(maybe != null, "Must not be null"), + _ = "OK"; +} + +void main() {} diff --git a/pkg/front_end/testcases/dart2js/issue56803.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/issue56803.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..c43f36cd3d0 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue56803.dart.textual_outline_modelled.expect @@ -0,0 +1,9 @@ +const String? maybe = bool.fromEnvironment("not there") ? "string" : null; + +extension type const Ext._(String _) implements String { + const Ext() + : assert(maybe != null, "Must not be null"), + _ = "OK"; +} + +void main() {} diff --git a/pkg/front_end/testcases/dart2js/issue56803.dart.weak.expect b/pkg/front_end/testcases/dart2js/issue56803.dart.weak.expect new file mode 100644 index 00000000000..b8303d9949b --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue56803.dart.weak.expect @@ -0,0 +1,38 @@ +library; +import self as self; +import "dart:core" as core; + +extension type Ext(core::String _) implements core::String { + abstract extension-type-member representation-field get _() → core::String; + constructor _ = self::Ext|constructor#_; + constructor tearoff _ = self::Ext|constructor#_#_#tearOff; + constructor • = self::Ext|constructor#; + constructor tearoff • = self::Ext|constructor#_#new#tearOff; +} +static const field core::String? maybe = #C5; +static extension-type-member method Ext|constructor#_(core::String _) → self::Ext /* erasure=core::String */ { + lowered final self::Ext /* erasure=core::String */ #this = _; + return #this; +} +static extension-type-member method Ext|constructor#_#_#tearOff(core::String _) → self::Ext /* erasure=core::String */ + return self::Ext|constructor#_(_); +static extension-type-member method Ext|constructor#() → self::Ext /* erasure=core::String */ { + lowered final self::Ext /* erasure=core::String */ #this = "OK"; + assert(!(#C5 == null), "Must not be null"); + return #this; +} +static extension-type-member method Ext|constructor#_#new#tearOff() → self::Ext /* erasure=core::String */ + return self::Ext|constructor#(); +static method main() → void { + self::Ext /* erasure=core::String */ c = #C6; + core::print(c); +} + +constants { + #C1 = "not there" + #C2 = eval /* from org-dartlang-testcase:///issue56803.dart */ const core::bool::fromEnvironment(#C1) + #C3 = "string" + #C4 = null + #C5 = eval /* from org-dartlang-testcase:///issue56803.dart */ #C2 ?{core::String?} #C3 : #C4 + #C6 = eval /* from org-dartlang-testcase:///issue56803.dart */ const self::Ext|constructor#() +} diff --git a/pkg/front_end/testcases/dart2js/issue56803.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/issue56803.dart.weak.transformed.expect new file mode 100644 index 00000000000..9b8c26f083d --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue56803.dart.weak.transformed.expect @@ -0,0 +1,45 @@ +library; +import self as self; +import "dart:core" as core; + +extension type Ext(core::String _) implements core::String { + abstract extension-type-member representation-field get _() → core::String; + constructor _ = self::Ext|constructor#_; + constructor tearoff _ = self::Ext|constructor#_#_#tearOff; + constructor • = self::Ext|constructor#; + constructor tearoff • = self::Ext|constructor#_#new#tearOff; +} +static const field core::String? maybe = #C5; +static extension-type-member method Ext|constructor#_(core::String _) → self::Ext /* erasure=core::String */ { + lowered final self::Ext /* erasure=core::String */ #this = _; + return #this; +} +static extension-type-member method Ext|constructor#_#_#tearOff(core::String _) → self::Ext /* erasure=core::String */ + return self::Ext|constructor#_(_); +static extension-type-member method Ext|constructor#() → self::Ext /* erasure=core::String */ { + lowered final self::Ext /* erasure=core::String */ #this = "OK"; + assert(!(#C5 == null), "Must not be null"); + return #this; +} +static extension-type-member method Ext|constructor#_#new#tearOff() → self::Ext /* erasure=core::String */ + return self::Ext|constructor#(); +static method main() → void { + self::Ext /* erasure=core::String */ c = #C6; + core::print(c); +} + +constants { + #C1 = "not there" + #C2 = eval /* from org-dartlang-testcase:///issue56803.dart */ const core::bool::fromEnvironment(#C1) + #C3 = "string" + #C4 = null + #C5 = eval /* from org-dartlang-testcase:///issue56803.dart */ #C2 ?{core::String?} #C3 : #C4 + #C6 = eval /* from org-dartlang-testcase:///issue56803.dart */ const self::Ext|constructor#() +} + +Extra constant evaluation status: +Evaluated with empty environment: Not @ org-dartlang-testcase:///issue56803.dart:8:22 -> BoolConstant(false) +Evaluated with empty environment: EqualsNull @ org-dartlang-testcase:///issue56803.dart:8:22 -> BoolConstant(true) +Evaluated with empty environment: ConstantExpression @ org-dartlang-testcase:///issue56803.dart:8:16 -> NullConstant(null) +Evaluated with empty environment: ConstantExpression @ org-dartlang-testcase:///issue56803.dart:5:57 -> NullConstant(null) +Extra constant evaluation: evaluated: 13, effectively constant: 4 diff --git a/pkg/front_end/testcases/dart2js/issue56803b.dart b/pkg/front_end/testcases/dart2js/issue56803b.dart new file mode 100644 index 00000000000..47d9c696dc7 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue56803b.dart @@ -0,0 +1,18 @@ +// 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. + +const String? maybe = bool.fromEnvironment("not there") ? "string" : null; + +class Ext { + final String _; + + const Ext() + : assert(maybe != null, "Must not be null"), + _ = "OK"; +} + +void main() { + var c = const Ext(); + print(c); +} diff --git a/pkg/front_end/testcases/dart2js/issue56803b.dart.strong.expect b/pkg/front_end/testcases/dart2js/issue56803b.dart.strong.expect new file mode 100644 index 00000000000..24c148afaf3 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue56803b.dart.strong.expect @@ -0,0 +1,36 @@ +library; +import self as self; +import "dart:core" as core; + +class Ext extends core::Object /*hasConstConstructor*/ { + final field core::String _; + const constructor •() → self::Ext + : assert(!(#C5 == null), "Must not be null"), self::Ext::_ = "OK", super core::Object::•() + ; + static method _#new#tearOff() → self::Ext + return new self::Ext::•(); +} +static const field core::String? maybe = #C5; +static method main() → void { + self::Ext c = #C10; + core::print(c); +} + +constants { + #C1 = "not there" + #C2 = eval /* from org-dartlang-testcase:///issue56803b.dart */ const core::bool::fromEnvironment(#C1) + #C3 = "string" + #C4 = null + #C5 = eval /* from org-dartlang-testcase:///issue56803b.dart */ #C2 ?{core::String?} #C3 : #C4 + #C6 = "OK" + #C7 = eval /* from org-dartlang-testcase:///issue56803b.dart */ #C5 == null + #C8 = eval /* from org-dartlang-testcase:///issue56803b.dart */!#C7 + #C9 = "Must not be null" + #C10 = eval /* from org-dartlang-testcase:///issue56803b.dart */ self::Ext{_:#C6, assert(#C8, #C9)} +} + + +Constructor coverage from constants: +org-dartlang-testcase:///issue56803b.dart: +- Ext. (from org-dartlang-testcase:///issue56803b.dart:10:9) +- Object. (from org-dartlang-sdk:///lib/core/object.dart) diff --git a/pkg/front_end/testcases/dart2js/issue56803b.dart.strong.modular.expect b/pkg/front_end/testcases/dart2js/issue56803b.dart.strong.modular.expect new file mode 100644 index 00000000000..24c148afaf3 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue56803b.dart.strong.modular.expect @@ -0,0 +1,36 @@ +library; +import self as self; +import "dart:core" as core; + +class Ext extends core::Object /*hasConstConstructor*/ { + final field core::String _; + const constructor •() → self::Ext + : assert(!(#C5 == null), "Must not be null"), self::Ext::_ = "OK", super core::Object::•() + ; + static method _#new#tearOff() → self::Ext + return new self::Ext::•(); +} +static const field core::String? maybe = #C5; +static method main() → void { + self::Ext c = #C10; + core::print(c); +} + +constants { + #C1 = "not there" + #C2 = eval /* from org-dartlang-testcase:///issue56803b.dart */ const core::bool::fromEnvironment(#C1) + #C3 = "string" + #C4 = null + #C5 = eval /* from org-dartlang-testcase:///issue56803b.dart */ #C2 ?{core::String?} #C3 : #C4 + #C6 = "OK" + #C7 = eval /* from org-dartlang-testcase:///issue56803b.dart */ #C5 == null + #C8 = eval /* from org-dartlang-testcase:///issue56803b.dart */!#C7 + #C9 = "Must not be null" + #C10 = eval /* from org-dartlang-testcase:///issue56803b.dart */ self::Ext{_:#C6, assert(#C8, #C9)} +} + + +Constructor coverage from constants: +org-dartlang-testcase:///issue56803b.dart: +- Ext. (from org-dartlang-testcase:///issue56803b.dart:10:9) +- Object. (from org-dartlang-sdk:///lib/core/object.dart) diff --git a/pkg/front_end/testcases/dart2js/issue56803b.dart.strong.outline.expect b/pkg/front_end/testcases/dart2js/issue56803b.dart.strong.outline.expect new file mode 100644 index 00000000000..b7465b87a18 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue56803b.dart.strong.outline.expect @@ -0,0 +1,24 @@ +library; +import self as self; +import "dart:core" as core; + +class Ext extends core::Object /*hasConstConstructor*/ { + final field core::String _; + const constructor •() → self::Ext + : assert(!(self::maybe == null), "Must not be null"), self::Ext::_ = "OK", super core::Object::•() + ; + static method _#new#tearOff() → self::Ext + return new self::Ext::•(); +} +static const field core::String? maybe = const core::bool::fromEnvironment("not there") ?{core::String?} "string" : null; +static method main() → void + ; + + +Extra constant evaluation status: +Evaluated with empty environment: Not @ org-dartlang-testcase:///issue56803b.dart:11:22 -> BoolConstant(false) +Evaluated with empty environment: EqualsNull @ org-dartlang-testcase:///issue56803b.dart:11:22 -> BoolConstant(true) +Evaluated with empty environment: StaticGet @ org-dartlang-testcase:///issue56803b.dart:11:16 -> NullConstant(null) +Evaluated with empty environment: ConditionalExpression @ org-dartlang-testcase:///issue56803b.dart:5:57 -> NullConstant(null) +Evaluated with empty environment: FactoryConstructorInvocation @ org-dartlang-testcase:///issue56803b.dart:5:28 -> BoolConstant(false) +Extra constant evaluation: evaluated: 6, effectively constant: 5 diff --git a/pkg/front_end/testcases/dart2js/issue56803b.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/issue56803b.dart.strong.transformed.expect new file mode 100644 index 00000000000..9210ccfbd89 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue56803b.dart.strong.transformed.expect @@ -0,0 +1,43 @@ +library; +import self as self; +import "dart:core" as core; + +class Ext extends core::Object /*hasConstConstructor*/ { + final field core::String _; + const constructor •() → self::Ext + : assert(!(#C5 == null), "Must not be null"), self::Ext::_ = "OK", super core::Object::•() + ; + static method _#new#tearOff() → self::Ext + return new self::Ext::•(); +} +static const field core::String? maybe = #C5; +static method main() → void { + self::Ext c = #C10; + core::print(c); +} + +constants { + #C1 = "not there" + #C2 = eval /* from org-dartlang-testcase:///issue56803b.dart */ const core::bool::fromEnvironment(#C1) + #C3 = "string" + #C4 = null + #C5 = eval /* from org-dartlang-testcase:///issue56803b.dart */ #C2 ?{core::String?} #C3 : #C4 + #C6 = "OK" + #C7 = eval /* from org-dartlang-testcase:///issue56803b.dart */ #C5 == null + #C8 = eval /* from org-dartlang-testcase:///issue56803b.dart */!#C7 + #C9 = "Must not be null" + #C10 = eval /* from org-dartlang-testcase:///issue56803b.dart */ self::Ext{_:#C6, assert(#C8, #C9)} +} + +Extra constant evaluation status: +Evaluated with empty environment: Not @ org-dartlang-testcase:///issue56803b.dart:11:22 -> BoolConstant(false) +Evaluated with empty environment: EqualsNull @ org-dartlang-testcase:///issue56803b.dart:11:22 -> BoolConstant(true) +Evaluated with empty environment: ConstantExpression @ org-dartlang-testcase:///issue56803b.dart:11:16 -> NullConstant(null) +Evaluated with empty environment: ConstantExpression @ org-dartlang-testcase:///issue56803b.dart:5:57 -> NullConstant(null) +Extra constant evaluation: evaluated: 8, effectively constant: 4 + + +Constructor coverage from constants: +org-dartlang-testcase:///issue56803b.dart: +- Ext. (from org-dartlang-testcase:///issue56803b.dart:10:9) +- Object. (from org-dartlang-sdk:///lib/core/object.dart) diff --git a/pkg/front_end/testcases/dart2js/issue56803b.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/issue56803b.dart.textual_outline.expect new file mode 100644 index 00000000000..e7ad3cce97d --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue56803b.dart.textual_outline.expect @@ -0,0 +1,10 @@ +const String? maybe = bool.fromEnvironment("not there") ? "string" : null; + +class Ext { + final String _; + const Ext() + : assert(maybe != null, "Must not be null"), + _ = "OK"; +} + +void main() {} diff --git a/pkg/front_end/testcases/dart2js/issue56803b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/issue56803b.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..d0b3fb7134f --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue56803b.dart.textual_outline_modelled.expect @@ -0,0 +1,10 @@ +class Ext { + const Ext() + : assert(maybe != null, "Must not be null"), + _ = "OK"; + final String _; +} + +const String? maybe = bool.fromEnvironment("not there") ? "string" : null; + +void main() {} diff --git a/pkg/front_end/testcases/dart2js/issue56803b.dart.weak.expect b/pkg/front_end/testcases/dart2js/issue56803b.dart.weak.expect new file mode 100644 index 00000000000..24c148afaf3 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue56803b.dart.weak.expect @@ -0,0 +1,36 @@ +library; +import self as self; +import "dart:core" as core; + +class Ext extends core::Object /*hasConstConstructor*/ { + final field core::String _; + const constructor •() → self::Ext + : assert(!(#C5 == null), "Must not be null"), self::Ext::_ = "OK", super core::Object::•() + ; + static method _#new#tearOff() → self::Ext + return new self::Ext::•(); +} +static const field core::String? maybe = #C5; +static method main() → void { + self::Ext c = #C10; + core::print(c); +} + +constants { + #C1 = "not there" + #C2 = eval /* from org-dartlang-testcase:///issue56803b.dart */ const core::bool::fromEnvironment(#C1) + #C3 = "string" + #C4 = null + #C5 = eval /* from org-dartlang-testcase:///issue56803b.dart */ #C2 ?{core::String?} #C3 : #C4 + #C6 = "OK" + #C7 = eval /* from org-dartlang-testcase:///issue56803b.dart */ #C5 == null + #C8 = eval /* from org-dartlang-testcase:///issue56803b.dart */!#C7 + #C9 = "Must not be null" + #C10 = eval /* from org-dartlang-testcase:///issue56803b.dart */ self::Ext{_:#C6, assert(#C8, #C9)} +} + + +Constructor coverage from constants: +org-dartlang-testcase:///issue56803b.dart: +- Ext. (from org-dartlang-testcase:///issue56803b.dart:10:9) +- Object. (from org-dartlang-sdk:///lib/core/object.dart) diff --git a/pkg/front_end/testcases/dart2js/issue56803b.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/issue56803b.dart.weak.transformed.expect new file mode 100644 index 00000000000..9210ccfbd89 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue56803b.dart.weak.transformed.expect @@ -0,0 +1,43 @@ +library; +import self as self; +import "dart:core" as core; + +class Ext extends core::Object /*hasConstConstructor*/ { + final field core::String _; + const constructor •() → self::Ext + : assert(!(#C5 == null), "Must not be null"), self::Ext::_ = "OK", super core::Object::•() + ; + static method _#new#tearOff() → self::Ext + return new self::Ext::•(); +} +static const field core::String? maybe = #C5; +static method main() → void { + self::Ext c = #C10; + core::print(c); +} + +constants { + #C1 = "not there" + #C2 = eval /* from org-dartlang-testcase:///issue56803b.dart */ const core::bool::fromEnvironment(#C1) + #C3 = "string" + #C4 = null + #C5 = eval /* from org-dartlang-testcase:///issue56803b.dart */ #C2 ?{core::String?} #C3 : #C4 + #C6 = "OK" + #C7 = eval /* from org-dartlang-testcase:///issue56803b.dart */ #C5 == null + #C8 = eval /* from org-dartlang-testcase:///issue56803b.dart */!#C7 + #C9 = "Must not be null" + #C10 = eval /* from org-dartlang-testcase:///issue56803b.dart */ self::Ext{_:#C6, assert(#C8, #C9)} +} + +Extra constant evaluation status: +Evaluated with empty environment: Not @ org-dartlang-testcase:///issue56803b.dart:11:22 -> BoolConstant(false) +Evaluated with empty environment: EqualsNull @ org-dartlang-testcase:///issue56803b.dart:11:22 -> BoolConstant(true) +Evaluated with empty environment: ConstantExpression @ org-dartlang-testcase:///issue56803b.dart:11:16 -> NullConstant(null) +Evaluated with empty environment: ConstantExpression @ org-dartlang-testcase:///issue56803b.dart:5:57 -> NullConstant(null) +Extra constant evaluation: evaluated: 8, effectively constant: 4 + + +Constructor coverage from constants: +org-dartlang-testcase:///issue56803b.dart: +- Ext. (from org-dartlang-testcase:///issue56803b.dart:10:9) +- Object. (from org-dartlang-sdk:///lib/core/object.dart) diff --git a/tests/web/extension_type_assert_error_test.dart b/tests/web/extension_type_assert_error_test.dart new file mode 100644 index 00000000000..34bd65071e3 --- /dev/null +++ b/tests/web/extension_type_assert_error_test.dart @@ -0,0 +1,21 @@ +// 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. + +// dart2jsOptions=--enable-asserts + +import "package:expect/expect.dart"; + +const String? maybe = bool.fromEnvironment("not there") ? "string" : null; + +extension type const Ext._(String _) implements String { + const Ext() + : assert(maybe != null, "Must not be null"), + _ = "OK"; +} + +void main() { + const Ext(); + // ^ + // [cfe] Constant evaluation error: +}