Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit b430570

Browse files
sigmundchcommit-bot@chromium.org
authored andcommitted
dart2js: handle constant casts with type variable substitutions
Closes dart-lang/sdk#32811 Change-Id: Ibf108405a3a36092a42902e5be806310a34c067c Reviewed-on: https://dart-review.googlesource.com/49835 Reviewed-by: Stephen Adams <[email protected]> Commit-Queue: Sigmund Cherem <[email protected]>
1 parent 3575b81 commit b430570

File tree

4 files changed

+50
-11
lines changed

4 files changed

+50
-11
lines changed

pkg/compiler/lib/src/constants/evaluation.dart

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ abstract class EvaluationEnvironment {
2020

2121
DartTypes get types;
2222

23+
/// Type in the enclosing constructed
24+
InterfaceType get enclosingConstructedType;
25+
2326
/// Read environments string passed in using the '-Dname=value' option.
2427
String readFromEnvironment(String name);
2528

@@ -45,8 +48,8 @@ abstract class EvaluationEnvironment {
4548
void reportError(
4649
ConstantExpression expression, MessageKind kind, Map arguments);
4750

48-
ConstantValue evaluateConstructor(
49-
ConstructorEntity constructor, ConstantValue evaluate());
51+
ConstantValue evaluateConstructor(ConstructorEntity constructor,
52+
InterfaceType type, ConstantValue evaluate());
5053

5154
ConstantValue evaluateField(FieldEntity field, ConstantValue evaluate());
5255

@@ -56,6 +59,7 @@ abstract class EvaluationEnvironment {
5659

5760
abstract class EvaluationEnvironmentBase implements EvaluationEnvironment {
5861
Link<Spannable> _spannableStack = const Link<Spannable>();
62+
InterfaceType enclosingConstructedType;
5963
final Set<FieldEntity> _currentlyEvaluatedFields = new Set<FieldEntity>();
6064
final bool constantRequired;
6165

@@ -96,10 +100,13 @@ abstract class EvaluationEnvironmentBase implements EvaluationEnvironment {
96100
}
97101

98102
@override
99-
ConstantValue evaluateConstructor(
100-
ConstructorEntity constructor, ConstantValue evaluate()) {
103+
ConstantValue evaluateConstructor(ConstructorEntity constructor,
104+
InterfaceType type, ConstantValue evaluate()) {
101105
_spannableStack = _spannableStack.prepend(constructor);
106+
var old = enclosingConstructedType;
107+
enclosingConstructedType = type;
102108
ConstantValue result = evaluate();
109+
enclosingConstructedType = old;
103110
_spannableStack = _spannableStack.tail;
104111
return result;
105112
}

pkg/compiler/lib/src/constants/expressions.dart

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,8 @@ class ConstructedConstantExpression extends ConstantExpression {
581581
@override
582582
ConstantValue evaluate(
583583
EvaluationEnvironment environment, ConstantSystem constantSystem) {
584-
return environment.evaluateConstructor(target, () {
584+
InterfaceType instanceType = computeInstanceType(environment);
585+
return environment.evaluateConstructor(target, instanceType, () {
585586
InstanceData instanceData = computeInstanceData(environment);
586587
if (instanceData == null) {
587588
return new NonConstantValue();
@@ -608,8 +609,7 @@ class ConstructedConstantExpression extends ConstantExpression {
608609
}
609610
}
610611
if (isValidAsConstant) {
611-
return new ConstructedConstantValue(
612-
computeInstanceType(environment), fieldValues);
612+
return new ConstructedConstantValue(instanceType, fieldValues);
613613
} else {
614614
return new NonConstantValue();
615615
}
@@ -851,7 +851,12 @@ class AsConstantExpression extends ConstantExpression {
851851
expression.evaluate(environment, constantSystem);
852852
DartType expressionType =
853853
expressionValue.getType(environment.commonElements);
854-
if (!constantSystem.isSubtype(environment.types, expressionType, type)) {
854+
DartType enclosingType = environment.enclosingConstructedType;
855+
DartType superType = enclosingType != null
856+
? environment.substByContext(type, enclosingType)
857+
: type;
858+
if (!constantSystem.isSubtype(
859+
environment.types, expressionType, superType)) {
855860
// TODO(sigmund): consider reporting different messages and error
856861
// locations for implicit vs explicit casts.
857862
environment.reportError(expression, MessageKind.INVALID_CONSTANT_CAST,

tests/compiler/dart2js/model/constant_expression_evaluate_test.dart

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ class MemoryEnvironment implements EvaluationEnvironment {
9797
@override
9898
DartTypes get types => _environment.types;
9999

100+
@override
101+
InterfaceType get enclosingConstructedType =>
102+
_environment.enclosingConstructedType;
103+
100104
void reportWarning(
101105
ConstantExpression expression, MessageKind kind, Map arguments) {
102106
errors.add(new EvaluationError(kind, arguments));
@@ -109,9 +113,10 @@ class MemoryEnvironment implements EvaluationEnvironment {
109113
_environment.reportError(expression, kind, arguments);
110114
}
111115

112-
ConstantValue evaluateConstructor(
113-
ConstructorEntity constructor, ConstantValue evaluate()) {
114-
return _environment.evaluateConstructor(constructor, evaluate);
116+
@override
117+
ConstantValue evaluateConstructor(ConstructorEntity constructor,
118+
InterfaceType type, ConstantValue evaluate()) {
119+
return _environment.evaluateConstructor(constructor, type, evaluate);
115120
}
116121

117122
ConstantValue evaluateField(FieldEntity field, ConstantValue evaluate()) {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// Casts in constants correctly substitute type variables.
6+
7+
class A {
8+
const A();
9+
}
10+
11+
class B implements A {
12+
const B();
13+
}
14+
15+
class M<T extends A> {
16+
final T a;
17+
const M(dynamic t) : a = t; // adds implicit cast `as T`
18+
}
19+
20+
main() {
21+
print(const M<B>(const B()));
22+
}

0 commit comments

Comments
 (0)