| Index: pkg/compiler/lib/src/ssa/builder.dart | 
| diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart | 
| index fb7b0792020f66244d7417a1f4fd6991fdcbb99b..fc906e54b72041bc7853c3a43711ad8d5e8f1c8a 100644 | 
| --- a/pkg/compiler/lib/src/ssa/builder.dart | 
| +++ b/pkg/compiler/lib/src/ssa/builder.dart | 
| @@ -1297,7 +1297,6 @@ class SsaBuilder extends NewResolvedVisitor { | 
| */ | 
| bool tryInlineMethod(Element element, | 
| Selector selector, | 
| -                       TypeMask mask, | 
| List<HInstruction> providedArguments, | 
| ast.Node currentNode, | 
| {InterfaceType instanceType}) { | 
| @@ -1329,11 +1328,8 @@ class SsaBuilder extends NewResolvedVisitor { | 
| Elements.isStaticOrTopLevel(element) || | 
| element.isGenerativeConstructorBody, | 
| message: "Missing selector for inlining of $element.")); | 
| -      if (selector != null) { | 
| -        if (!selector.applies(function, compiler.world)) return false; | 
| -        if (mask != null && !mask.canHit(function, selector, compiler.world)) { | 
| -          return false; | 
| -        } | 
| +      if (selector != null && !selector.applies(function, compiler.world)) { | 
| +        return false; | 
| } | 
|  | 
| // Don't inline operator== methods if the parameter can be null. | 
| @@ -1452,9 +1448,9 @@ class SsaBuilder extends NewResolvedVisitor { | 
| // Add an explicit null check on the receiver before doing the | 
| // inlining. We use [element] to get the same name in the | 
| // NoSuchMethodError message as if we had called it. | 
| -      if (element.isInstanceMember && | 
| -          !element.isGenerativeConstructorBody && | 
| -          (mask == null || mask.isNullable)) { | 
| +      if (element.isInstanceMember | 
| +          && !element.isGenerativeConstructorBody | 
| +          && (selector.mask == null || selector.mask.isNullable)) { | 
| addWithPosition( | 
| new HFieldGet(null, providedArguments[0], backend.dynamicType, | 
| isAssignable: false), | 
| @@ -2301,7 +2297,7 @@ class SsaBuilder extends NewResolvedVisitor { | 
| } | 
|  | 
| if (!isNativeUpgradeFactory && // TODO(13836): Fix inlining. | 
| -          tryInlineMethod(body, null, null, bodyCallInputs, function)) { | 
| +          tryInlineMethod(body, null, bodyCallInputs, function)) { | 
| pop(); | 
| } else { | 
| HInvokeConstructorBody invoke = new HInvokeConstructorBody( | 
| @@ -2455,7 +2451,6 @@ class SsaBuilder extends NewResolvedVisitor { | 
| pushInvokeDynamic( | 
| null, | 
| new Selector.call(name, backend.jsHelperLibrary, 1), | 
| -          null, | 
| arguments); | 
|  | 
| return new HTypeConversion(type, kind, original.instructionType, pop()); | 
| @@ -3196,11 +3191,7 @@ class SsaBuilder extends NewResolvedVisitor { | 
| } | 
| } | 
|  | 
| -    pushInvokeDynamic( | 
| -        node, | 
| -        elements.getSelector(node), | 
| -        elements.getTypeMask(node), | 
| -        [operand]); | 
| +    pushInvokeDynamic(node, elements.getSelector(node), [operand]); | 
| } | 
|  | 
| @override | 
| @@ -3232,7 +3223,6 @@ class SsaBuilder extends NewResolvedVisitor { | 
| visitAndPop(left), | 
| visitAndPop(right), | 
| elements.getSelector(node), | 
| -        elements.getTypeMask(node), | 
| node, | 
| location: node.selector); | 
| } | 
| @@ -3242,10 +3232,9 @@ class SsaBuilder extends NewResolvedVisitor { | 
| void visitBinarySend(HInstruction left, | 
| HInstruction right, | 
| Selector selector, | 
| -                       TypeMask mask, | 
| ast.Send send, | 
| {ast.Node location}) { | 
| -    pushInvokeDynamic(send, selector, mask, [left, right], location: location); | 
| +    pushInvokeDynamic(send, selector, [left, right], location: location); | 
| } | 
|  | 
| HInstruction generateInstanceSendReceiver(ast.Send send) { | 
| @@ -3267,14 +3256,12 @@ class SsaBuilder extends NewResolvedVisitor { | 
| * Returns a set of interceptor classes that contain the given | 
| * [selector]. | 
| */ | 
| -  void generateInstanceGetterWithCompiledReceiver( | 
| -      ast.Send send, | 
| -      Selector selector, | 
| -      TypeMask mask, | 
| -      HInstruction receiver) { | 
| +  void generateInstanceGetterWithCompiledReceiver(ast.Send send, | 
| +                                                  Selector selector, | 
| +                                                  HInstruction receiver) { | 
| assert(Elements.isInstanceSend(send, elements)); | 
| assert(selector.isGetter); | 
| -    pushInvokeDynamic(send, selector, mask, [receiver]); | 
| +    pushInvokeDynamic(send, selector, [receiver]); | 
| } | 
|  | 
| /// Inserts a call to checkDeferredIsLoaded for [prefixElement]. | 
| @@ -3392,7 +3379,7 @@ class SsaBuilder extends NewResolvedVisitor { | 
| void generateDynamicGet(ast.Send node) { | 
| HInstruction receiver = generateInstanceSendReceiver(node); | 
| generateInstanceGetterWithCompiledReceiver( | 
| -        node, elements.getSelector(node), elements.getTypeMask(node), receiver); | 
| +        node, elements.getSelector(node), receiver); | 
| } | 
|  | 
| /// Generate a closurization of the static or top level [function]. | 
| @@ -3439,13 +3426,8 @@ class SsaBuilder extends NewResolvedVisitor { | 
| pushCheckNull(expression); | 
| }, | 
| () => stack.add(expression), | 
| -        () { | 
| -          generateInstanceGetterWithCompiledReceiver( | 
| -              node, | 
| -              elements.getSelector(node), | 
| -              elements.getTypeMask(node), | 
| -              expression); | 
| -        }); | 
| +        () => generateInstanceGetterWithCompiledReceiver( | 
| +            node, elements.getSelector(node), expression)); | 
| } | 
|  | 
| /// Pushes a boolean checking [expression] against null. | 
| @@ -3529,22 +3511,18 @@ class SsaBuilder extends NewResolvedVisitor { | 
| HInstruction receiver, | 
| HInstruction value, | 
| {Selector selector, | 
| -                                                   TypeMask mask, | 
| ast.Node location}) { | 
| assert(send == null || Elements.isInstanceSend(send, elements)); | 
| if (selector == null) { | 
| assert(send != null); | 
| selector = elements.getSelector(send); | 
| -      if (mask == null) { | 
| -        mask = elements.getTypeMask(send); | 
| -      } | 
| } | 
| if (location == null) { | 
| assert(send != null); | 
| location = send; | 
| } | 
| assert(selector.isSetter); | 
| -    pushInvokeDynamic(location, selector, mask, [receiver, value]); | 
| +    pushInvokeDynamic(location, selector, [receiver, value]); | 
| pop(); | 
| stack.add(value); | 
| } | 
| @@ -3679,9 +3657,7 @@ class SsaBuilder extends NewResolvedVisitor { | 
| if (type.isFunctionType) { | 
| List arguments = [buildFunctionType(type), expression]; | 
| pushInvokeDynamic( | 
| -          node, | 
| -          new Selector.call('_isTest', backend.jsHelperLibrary, 1), | 
| -          null, | 
| +          node, new Selector.call('_isTest', backend.jsHelperLibrary, 1), | 
| arguments); | 
| return new HIs.compound(type, expression, pop(), backend.boolType); | 
| } else if (type.isTypeVariable) { | 
| @@ -3803,13 +3779,12 @@ class SsaBuilder extends NewResolvedVisitor { | 
|  | 
| void _generateDynamicSend(ast.Send node, HInstruction receiver) { | 
| Selector selector = elements.getSelector(node); | 
| -    TypeMask mask = elements.getTypeMask(node); | 
|  | 
| List<HInstruction> inputs = <HInstruction>[]; | 
| inputs.add(receiver); | 
| addDynamicSendArgumentsToList(node, inputs); | 
|  | 
| -    pushInvokeDynamic(node, selector, mask, inputs); | 
| +    pushInvokeDynamic(node, selector, inputs); | 
| if (selector.isSetter || selector.isIndexSet) { | 
| pop(); | 
| stack.add(inputs.last); | 
| @@ -4173,7 +4148,8 @@ class SsaBuilder extends NewResolvedVisitor { | 
| // If the isolate library is not used, we just invoke the | 
| // closure. | 
| visit(link.tail.head); | 
| -      push(new HInvokeClosure(new Selector.callClosure(0), | 
| +      Selector selector = new Selector.callClosure(0); | 
| +      push(new HInvokeClosure(selector, | 
| <HInstruction>[pop()], | 
| backend.dynamicType)); | 
| } else { | 
| @@ -4315,7 +4291,7 @@ class SsaBuilder extends NewResolvedVisitor { | 
| // class is _not_ the default implementation from [Object], in | 
| // case the [noSuchMethod] implementation calls | 
| // [JSInvocationMirror._invokeOn]. | 
| -      registry.registerSelectorUse(selector); | 
| +      registry.registerSelectorUse(selector.asUntyped); | 
| } | 
| String publicName = name; | 
| if (selector.isSetter) publicName += '='; | 
| @@ -5331,11 +5307,9 @@ class SsaBuilder extends NewResolvedVisitor { | 
| Selector selector = elements.getSelector(node); | 
| List<HInstruction> inputs = <HInstruction>[target]; | 
| addDynamicSendArgumentsToList(node, inputs); | 
| +    Selector closureSelector = new Selector.callClosureFrom(selector); | 
| pushWithPosition( | 
| -        new HInvokeClosure( | 
| -            new Selector.callClosureFrom(selector), | 
| -            inputs, backend.dynamicType), | 
| -        node); | 
| +        new HInvokeClosure(closureSelector, inputs, backend.dynamicType), node); | 
| } | 
|  | 
| visitGetterSend(ast.Send node) { | 
| @@ -5464,7 +5438,6 @@ class SsaBuilder extends NewResolvedVisitor { | 
|  | 
| void pushInvokeDynamic(ast.Node node, | 
| Selector selector, | 
| -                         TypeMask mask, | 
| List<HInstruction> arguments, | 
| {ast.Node location}) { | 
| if (location == null) location = node; | 
| @@ -5505,13 +5478,13 @@ class SsaBuilder extends NewResolvedVisitor { | 
| return false; | 
| } | 
|  | 
| -    Element element = compiler.world.locateSingleElement(selector, mask); | 
| -    if (element != null && | 
| -        !element.isField && | 
| -        !(element.isGetter && selector.isCall) && | 
| -        !(element.isFunction && selector.isGetter) && | 
| -        !isOptimizableOperation(selector, element)) { | 
| -      if (tryInlineMethod(element, selector, mask, arguments, node)) { | 
| +    Element element = compiler.world.locateSingleElement(selector); | 
| +    if (element != null | 
| +        && !element.isField | 
| +        && !(element.isGetter && selector.isCall) | 
| +        && !(element.isFunction && selector.isGetter) | 
| +        && !isOptimizableOperation(selector, element)) { | 
| +      if (tryInlineMethod(element, selector, arguments, node)) { | 
| return; | 
| } | 
| } | 
| @@ -5523,19 +5496,18 @@ class SsaBuilder extends NewResolvedVisitor { | 
| inputs.add(invokeInterceptor(receiver)); | 
| } | 
| inputs.addAll(arguments); | 
| -    TypeMask type = | 
| -        TypeMaskFactory.inferredTypeForSelector(selector, mask, compiler); | 
| +    TypeMask type = TypeMaskFactory.inferredTypeForSelector(selector, compiler); | 
| if (selector.isGetter) { | 
| pushWithPosition( | 
| -          new HInvokeDynamicGetter(selector, mask, null, inputs, type), | 
| +          new HInvokeDynamicGetter(selector, null, inputs, type), | 
| location); | 
| } else if (selector.isSetter) { | 
| pushWithPosition( | 
| -          new HInvokeDynamicSetter(selector, mask, null, inputs, type), | 
| +          new HInvokeDynamicSetter(selector, null, inputs, type), | 
| location); | 
| } else { | 
| pushWithPosition( | 
| -          new HInvokeDynamicMethod(selector, mask, inputs, type, isIntercepted), | 
| +          new HInvokeDynamicMethod(selector, inputs, type, isIntercepted), | 
| location); | 
| } | 
| } | 
| @@ -5545,7 +5517,7 @@ class SsaBuilder extends NewResolvedVisitor { | 
| List<HInstruction> arguments, | 
| {TypeMask typeMask, | 
| InterfaceType instanceType}) { | 
| -    if (tryInlineMethod(element, null, null, arguments, location, | 
| +    if (tryInlineMethod(element, null, arguments, location, | 
| instanceType: instanceType)) { | 
| return; | 
| } | 
| @@ -5600,8 +5572,7 @@ class SsaBuilder extends NewResolvedVisitor { | 
| inputs, | 
| type, | 
| isSetter: selector.isSetter || selector.isIndexSet); | 
| -    instruction.sideEffects = | 
| -        compiler.world.getSideEffectsOfSelector(selector, null); | 
| +    instruction.sideEffects = compiler.world.getSideEffectsOfSelector(selector); | 
| return instruction; | 
| } | 
|  | 
| @@ -5618,7 +5589,6 @@ class SsaBuilder extends NewResolvedVisitor { | 
| } | 
| visitBinarySend(receiver, rhs, | 
| elements.getOperatorSelectorInComplexSendSet(node), | 
| -                    elements.getOperatorTypeMaskInComplexSendSet(node), | 
| node, | 
| location: node.assignmentOperator); | 
| } | 
| @@ -5716,7 +5686,6 @@ class SsaBuilder extends NewResolvedVisitor { | 
| pushInvokeDynamic( | 
| node, | 
| elements.getGetterSelectorInComplexSendSet(node), | 
| -          elements.getGetterTypeMaskInComplexSendSet(node), | 
| [receiver, index]); | 
| HInstruction getterInstruction = pop(); | 
| if (node.isIfNullAssignment) { | 
| @@ -5731,10 +5700,7 @@ class SsaBuilder extends NewResolvedVisitor { | 
| visit(arguments.head); | 
| HInstruction value = pop(); | 
| pushInvokeDynamic( | 
| -                  node, | 
| -                  elements.getSelector(node), | 
| -                  elements.getTypeMask(node), | 
| -                  [receiver, index, value]); | 
| +                  node, elements.getSelector(node), [receiver, index, value]); | 
| pop(); | 
| stack.add(value); | 
| }); | 
| @@ -5742,10 +5708,7 @@ class SsaBuilder extends NewResolvedVisitor { | 
| handleComplexOperatorSend(node, getterInstruction, arguments); | 
| HInstruction value = pop(); | 
| pushInvokeDynamic( | 
| -            node, | 
| -            elements.getSelector(node), | 
| -            elements.getTypeMask(node), | 
| -            [receiver, index, value]); | 
| +            node, elements.getSelector(node), [receiver, index, value]); | 
| pop(); | 
| if (node.isPostfix) { | 
| stack.add(getterInstruction); | 
| @@ -6032,10 +5995,7 @@ class SsaBuilder extends NewResolvedVisitor { | 
| void generateAssignment(HInstruction receiver) { | 
| // desugars `e.x op= e2` to `e.x = e.x op e2` | 
| generateInstanceGetterWithCompiledReceiver( | 
| -            node, | 
| -            elements.getGetterSelectorInComplexSendSet(node), | 
| -            elements.getGetterTypeMaskInComplexSendSet(node), | 
| -            receiver); | 
| +            node, elements.getGetterSelectorInComplexSendSet(node), receiver); | 
| HInstruction getterInstruction = pop(); | 
| if (node.isIfNullAssignment) { | 
| SsaBranchBuilder brancher = new SsaBranchBuilder(this, node); | 
| @@ -6486,8 +6446,7 @@ class SsaBuilder extends NewResolvedVisitor { | 
|  | 
| HInstruction buildCondition() { | 
| Selector selector = elements.getMoveNextSelector(node); | 
| -      TypeMask mask = elements.getMoveNextTypeMask(node); | 
| -      pushInvokeDynamic(node, selector, mask, [streamIterator]); | 
| +      pushInvokeDynamic(node, selector, [streamIterator]); | 
| HInstruction future = pop(); | 
| push(new HAwait(future, new TypeMask.subclass(compiler.objectClass, | 
| compiler.world))); | 
| @@ -6495,13 +6454,11 @@ class SsaBuilder extends NewResolvedVisitor { | 
| } | 
| void buildBody() { | 
| Selector call = elements.getCurrentSelector(node); | 
| -      TypeMask callMask = elements.getCurrentTypeMask(node); | 
| -      pushInvokeDynamic(node, call, callMask, [streamIterator]); | 
| +      pushInvokeDynamic(node, call, [streamIterator]); | 
|  | 
| ast.Node identifier = node.declaredIdentifier; | 
| Element variable = elements.getForInVariable(node); | 
| Selector selector = elements.getSelector(identifier); | 
| -      TypeMask mask = elements.getTypeMask(identifier); | 
|  | 
| HInstruction value = pop(); | 
| if (identifier.asSend() != null | 
| @@ -6513,7 +6470,6 @@ class SsaBuilder extends NewResolvedVisitor { | 
| receiver, | 
| value, | 
| selector: selector, | 
| -            mask: mask, | 
| location: identifier); | 
| } else { | 
| generateNonInstanceSetter( | 
| @@ -6533,9 +6489,7 @@ class SsaBuilder extends NewResolvedVisitor { | 
| buildUpdate, | 
| buildBody); | 
| }, () { | 
| -      pushInvokeDynamic(node, | 
| -          new Selector.call("cancel", null, 0), | 
| -          null, | 
| +      pushInvokeDynamic(node, new Selector.call("cancel", null, 0), | 
| [streamIterator]); | 
| push(new HAwait(pop(), new TypeMask.subclass(compiler.objectClass, | 
| compiler.world))); | 
| @@ -6555,7 +6509,7 @@ class SsaBuilder extends NewResolvedVisitor { | 
| // case. | 
|  | 
| Selector selector = elements.getIteratorSelector(node); | 
| -    TypeMask mask = elements.getIteratorTypeMask(node); | 
| +    TypeMask mask = selector.mask; | 
|  | 
| ClassWorld classWorld = compiler.world; | 
| if (mask != null && mask.satisfies(backend.jsIndexableClass, classWorld)) { | 
| @@ -6577,24 +6531,21 @@ class SsaBuilder extends NewResolvedVisitor { | 
|  | 
| void buildInitializer() { | 
| Selector selector = elements.getIteratorSelector(node); | 
| -      TypeMask mask = elements.getIteratorTypeMask(node); | 
| visit(node.expression); | 
| HInstruction receiver = pop(); | 
| -      pushInvokeDynamic(node, selector, mask, [receiver]); | 
| +      pushInvokeDynamic(node, selector, [receiver]); | 
| iterator = pop(); | 
| } | 
|  | 
| HInstruction buildCondition() { | 
| Selector selector = elements.getMoveNextSelector(node); | 
| -      TypeMask mask = elements.getMoveNextTypeMask(node); | 
| -      pushInvokeDynamic(node, selector, mask, [iterator]); | 
| +      pushInvokeDynamic(node, selector, [iterator]); | 
| return popBoolified(); | 
| } | 
|  | 
| void buildBody() { | 
| Selector call = elements.getCurrentSelector(node); | 
| -      TypeMask mask = elements.getCurrentTypeMask(node); | 
| -      pushInvokeDynamic(node, call, mask, [iterator]); | 
| +      pushInvokeDynamic(node, call, [iterator]); | 
| buildAssignLoopVariable(node, pop()); | 
| visit(node.body); | 
| } | 
| @@ -6606,7 +6557,6 @@ class SsaBuilder extends NewResolvedVisitor { | 
| ast.Node identifier = node.declaredIdentifier; | 
| Element variable = elements.getForInVariable(node); | 
| Selector selector = elements.getSelector(identifier); | 
| -    TypeMask mask = elements.getTypeMask(identifier); | 
|  | 
| if (identifier.asSend() != null && | 
| Elements.isInstanceSend(identifier, elements)) { | 
| @@ -6617,7 +6567,6 @@ class SsaBuilder extends NewResolvedVisitor { | 
| receiver, | 
| value, | 
| selector: selector, | 
| -          mask: mask, | 
| location: identifier); | 
| } else { | 
| generateNonInstanceSetter(null, variable, value, location: identifier); | 
| @@ -6697,8 +6646,9 @@ class SsaBuilder extends NewResolvedVisitor { | 
| // example, `get current` includes null. | 
| // TODO(sra): The element type of a container type mask might be better. | 
| Selector selector = new Selector.index(); | 
| -      TypeMask type = TypeMaskFactory.inferredTypeForSelector( | 
| -          selector, arrayType, compiler); | 
| +      Selector refined = new TypedSelector(arrayType, selector, compiler.world); | 
| +      TypeMask type = | 
| +          TypeMaskFactory.inferredTypeForSelector(refined, compiler); | 
|  | 
| HInstruction index = localsHandler.readLocal(indexVariable); | 
| HInstruction value = new HIndex(array, index, null, type); | 
| @@ -7615,12 +7565,12 @@ class StringBuilderVisitor extends ast.Visitor { | 
|  | 
| // If the `toString` method is guaranteed to return a string we can call it | 
| // directly. | 
| -    Selector selector = new Selector.call('toString', null, 0); | 
| -    TypeMask type = TypeMaskFactory.inferredTypeForSelector( | 
| -        selector, expression.instructionType, compiler); | 
| +    Selector selector = | 
| +        new TypedSelector(expression.instructionType, | 
| +            new Selector.call('toString', null, 0), compiler.world); | 
| +    TypeMask type = TypeMaskFactory.inferredTypeForSelector(selector, compiler); | 
| if (type.containsOnlyString(compiler.world)) { | 
| -      builder.pushInvokeDynamic( | 
| -          node, selector, expression.instructionType, <HInstruction>[expression]); | 
| +      builder.pushInvokeDynamic(node, selector, <HInstruction>[expression]); | 
| append(builder.pop()); | 
| return; | 
| } | 
|  |