| Index: pkg/compiler/lib/src/cps_ir/type_propagation.dart
|
| diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
|
| index 6c896e1cf8ed4b40384b44a0be12474687650798..80cf38814f5cd85cae6c3eea583cf76bf9cac224 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
|
| @@ -1931,20 +1931,10 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| // the error message when the receiver is null, but we accept this.
|
| node.receiver.changeTo(node.dartReceiver);
|
|
|
| - // Check if any of the possible targets depend on the extra receiver
|
| - // argument. Mixins do this, and tear-offs always needs the extra receiver
|
| - // argument because BoundClosure uses it for equality and hash code.
|
| - // TODO(15933): Make automatically generated property extraction
|
| - // closures work with the dummy receiver optimization.
|
| - bool needsReceiver(Element target) {
|
| - if (target is! FunctionElement) return false;
|
| - FunctionElement function = target;
|
| - return typeSystem.methodUsesReceiverArgument(function) ||
|
| - node.selector.isGetter && !function.isGetter;
|
| - }
|
| - if (!getAllTargets(receiverType, node.selector).any(needsReceiver)) {
|
| - // Replace the extra receiver argument with a dummy value if the
|
| - // target definitely does not use it.
|
| + // Replace the extra receiver argument with a dummy value if the
|
| + // target definitely does not use it.
|
| + if (typeSystem.targetIgnoresReceiverArgument(receiverType,
|
| + node.selector)) {
|
| Constant dummy = makeConstantPrimitive(new IntConstantValue(0));
|
| new LetPrim(dummy).insertAbove(node.parent);
|
| node.arguments[0].changeTo(dummy);
|
| @@ -2492,7 +2482,7 @@ class TypePropagationVisitor implements Visitor {
|
| // change the abstract value.
|
| if (node.thisParameter != null && getValue(node.thisParameter).isNothing) {
|
| if (isIntercepted &&
|
| - typeSystem.methodUsesReceiverArgument(node.element)) {
|
| + !typeSystem.methodIgnoresReceiverArgument(node.element)) {
|
| setValue(node.thisParameter, nonConstant(typeSystem.nonNullType));
|
| } else {
|
| setValue(node.thisParameter,
|
| @@ -2500,11 +2490,11 @@ class TypePropagationVisitor implements Visitor {
|
| }
|
| }
|
| if (isIntercepted && getValue(node.parameters[0]).isNothing) {
|
| - if (typeSystem.methodUsesReceiverArgument(node.element)) {
|
| + if (typeSystem.methodIgnoresReceiverArgument(node.element)) {
|
| + setValue(node.parameters[0], nonConstant());
|
| + } else {
|
| setValue(node.parameters[0],
|
| nonConstant(typeSystem.getReceiverType(node.element)));
|
| - } else {
|
| - setValue(node.parameters[0], nonConstant());
|
| }
|
| }
|
| bool hasParameterWithoutValue = false;
|
| @@ -3135,8 +3125,15 @@ class TypePropagationVisitor implements Visitor {
|
| } else if (value.isConstant) {
|
| setValue(node, value);
|
| } else {
|
| - setValue(node,
|
| - nonConstant(value.type.intersection(node.refineType, classWorld)));
|
| + TypeMask type = value.type.intersection(node.refineType, classWorld);
|
| + if (!value.type.containsMask(type, classWorld)) {
|
| + // Ensure type does not degrade.
|
| + // TODO(asgerf): We need a biased intersection operation which
|
| + // guarantees the result is never worse than the first argument.
|
| + setValue(node, value);
|
| + } else {
|
| + setValue(node, nonConstant(type));
|
| + }
|
| }
|
| }
|
|
|
|
|