Index: pkg/compiler/lib/src/elements/modelx.dart |
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart |
index e2588fc24fb1a419e139ce03e57f2399ec836445..bb331d96027f82fb2e26338ecc1b4130fdc95288 100644 |
--- a/pkg/compiler/lib/src/elements/modelx.dart |
+++ b/pkg/compiler/lib/src/elements/modelx.dart |
@@ -1425,11 +1425,22 @@ abstract class ConstantVariableMixin implements VariableElement { |
// constant for a variable already known to be erroneous. |
return; |
} |
- assert(invariant(this, constantCache == null || constantCache == value, |
- message: "Constant has already been computed for $this. " |
- "Existing constant: " |
- "${constantCache != null ? constantCache.toStructuredText() : ''}, " |
- "New constant: ${value != null ? value.toStructuredText() : ''}.")); |
+ if (constantCache != null && constantCache != value) { |
+ // Allow setting the constant as erroneous. Constants computed during |
+ // resolution are locally valid but might be effectively erroneous. For |
+ // instance `a ? true : false` where a is `const a = m()`. Since `a` is |
+ // declared to be constant, the conditional is assumed valid, but when |
+ // computing the value we see that it isn't. |
+ // TODO(johnniwinther): Remove this exception when all constant |
+ // expressions are computed during resolution. |
+ assert(invariant( |
+ this, value == null || value.kind == ConstantExpressionKind.ERRONEOUS, |
+ message: "Constant has already been computed for $this. " |
+ "Existing constant: " |
+ "${constantCache != null ? constantCache.toStructuredText() : ''}" |
+ ", New constant: " |
+ "${value != null ? value.toStructuredText() : ''}.")); |
+ } |
constantCache = value; |
} |
} |