| Index: pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
|
| diff --git a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
|
| index c2b3e416d62296f61ef30f48b417191b9deb13b3..6743561e173517646f5339630409d6a0476fd680 100644
|
| --- a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
|
| +++ b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
|
| @@ -150,6 +150,13 @@ class VariableScope<T> {
|
| ? null
|
| : new VariableScope<T>.deepCopyOf(other.parent);
|
|
|
| + VariableScope.topLevelCopyOf(VariableScope<T> other)
|
| + : variables = other.variables == null
|
| + ? null
|
| + : new Map<Local, T>.from(other.variables),
|
| + block = other.block,
|
| + parent = other.parent;
|
| +
|
| T operator [](Local variable) {
|
| T result;
|
| if (variables == null || (result = variables[variable]) == null) {
|
| @@ -401,6 +408,16 @@ class LocalsHandler<T> {
|
| inferrer = other.inferrer,
|
| compiler = other.compiler;
|
|
|
| + LocalsHandler.topLevelCopyOf(LocalsHandler<T> other)
|
| + : locals = new VariableScope<T>.topLevelCopyOf(other.locals),
|
| + fieldScope = new FieldInitializationScope<T>.from(other.fieldScope),
|
| + captured = other.captured,
|
| + capturedAndBoxed = other.capturedAndBoxed,
|
| + tryBlock = other.tryBlock,
|
| + types = other.types,
|
| + inferrer = other.inferrer,
|
| + compiler = other.compiler;
|
| +
|
| T use(Local local) {
|
| if (capturedAndBoxed.containsKey(local)) {
|
| return inferrer.typeOfElement(capturedAndBoxed[local]);
|
| @@ -906,11 +923,26 @@ abstract class InferrerVisitor
|
| LocalsHandler<T> saved = locals;
|
| locals = new LocalsHandler<T>.from(locals, node);
|
| updateIsChecks(isChecks, usePositive: true);
|
| - if (!oldAccumulateIsChecks) {
|
| + LocalsHandler<T> narrowed;
|
| + if (oldAccumulateIsChecks) {
|
| + narrowed = new LocalsHandler<T>.topLevelCopyOf(locals);
|
| + } else {
|
| accumulateIsChecks = false;
|
| isChecks = oldIsChecks;
|
| }
|
| visit(node.arguments.head);
|
| + if (oldAccumulateIsChecks) {
|
| +
|
| + bool invalidatedInRightHandSide (Send test) {
|
| + Element receiver = elements[test.receiver];
|
| + if (receiver is LocalElement) {
|
| + return narrowed.locals[receiver] != locals.locals[receiver];
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + isChecks.removeWhere(invalidatedInRightHandSide);
|
| + }
|
| saved.mergeDiamondFlow(locals, null);
|
| locals = saved;
|
| return types.boolType;
|
|
|