Version 1.1.0-dev.5.9

svn merge -c 31467 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 31482 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

R=kasperl@google.com

Review URL: https://codereview.chromium.org//136753002

git-svn-id: http://dart.googlecode.com/svn/trunk@31736 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/sdk/lib/_internal/compiler/implementation/dart_types.dart b/sdk/lib/_internal/compiler/implementation/dart_types.dart
index a4603f0..5f14cc2 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart
@@ -60,6 +60,11 @@
    */
   DartType subst(Link<DartType> arguments, Link<DartType> parameters);
 
+  /// Performs the substitution of the type arguments of [type] for their
+  /// corresponding type variables in this type.
+  DartType substByContext(GenericType type) =>
+      subst(type.typeArguments, type.element.typeVariables);
+
   /**
    * Returns the unaliased type of this type.
    *
@@ -797,8 +802,7 @@
     compiler.resolveTypedef(element);
     element.checkCyclicReference(compiler);
     DartType definition = element.alias.unalias(compiler);
-    TypedefType declaration = element.computeType(compiler);
-    return definition.subst(typeArguments, declaration.typeArguments);
+    return definition.substByContext(this);
   }
 
   int get hashCode => super.hashCode;
@@ -889,10 +893,8 @@
         type = element.computeType(compiler);
       }
       if (!declarer.element.typeVariables.isEmpty) {
-        type = type.subst(declarer.typeArguments,
-                          declarer.element.typeVariables);
-        type = type.subst(receiver.typeArguments,
-                          receiver.element.typeVariables);
+        type = type.substByContext(declarer);
+        type = type.substByContext(receiver);
       }
       cachedType = type;
     }
@@ -1305,8 +1307,7 @@
     Link<DartType> typeVariables = element.typeVariables;
     while (!typeVariables.isEmpty && !typeArguments.isEmpty) {
       TypeVariableType typeVariable = typeVariables.head;
-      DartType bound = typeVariable.element.bound.subst(
-          type.typeArguments, element.typeVariables);
+      DartType bound = typeVariable.element.bound.substByContext(type);
       DartType typeArgument = typeArguments.head;
       checkTypeVariableBound(type, typeArgument, typeVariable, bound);
       typeVariables = typeVariables.tail;
@@ -1501,13 +1502,10 @@
 
     /// Returns the set of supertypes of [type] at depth [depth].
     Set<DartType> getSupertypesAtDepth(InterfaceType type, int depth) {
-      ClassElement cls = type.element;
-      OrderedTypeSet types = cls.allSupertypesAndSelf;
-      Link<DartType> typeVariables = cls.typeVariables;
-      Link<DartType> typeArguments = type.typeArguments;
+      OrderedTypeSet types = type.element.allSupertypesAndSelf;
       Set<DartType> set = new Set<DartType>();
-      types.forEach(depth, (DartType type) {
-        set.add(type.subst(typeArguments, typeVariables));
+      types.forEach(depth, (DartType supertype) {
+        set.add(supertype.substByContext(type));
       });
       return set;
     }
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index f72260c..78ad547 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -1518,8 +1518,7 @@
     assert(invariant(this, redirectionTargetType != null,
         message: 'Redirection target type has not yet been computed for '
                  '$this.'));
-    return redirectionTargetType.subst(newType.typeArguments,
-                                       newType.element.typeVariables);
+    return redirectionTargetType.substByContext(newType);
   }
 
   /**
@@ -1671,6 +1670,8 @@
       return functionSignature = compiler.objectClass.localLookup('')
           .computeSignature(compiler);
     }
+    // TODO(johnniwinther): Ensure that the function signature (and with it the
+    // function type) substitutes type variables correctly.
     return functionSignature = superMember.computeSignature(compiler);
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
index c3a33a5..688a7eb 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
@@ -413,9 +413,7 @@
 
     expressions.add(code);
 
-    // TODO(ahe): Remove comments from output.
-    List tearOffInfo =
-        [new jsAst.LiteralString('$callSelectorString /* tearOffInfo */')];
+    List tearOffInfo = [new jsAst.LiteralString('$callSelectorString')];
 
     if (needsStubs || canTearOff) {
       addParameterStubs(member, (Selector selector, jsAst.Fun function) {
@@ -447,8 +445,7 @@
             callSelectors.contains(callSelector)) {
           callSelectorString = '"${namer.invocationName(callSelector)}"';
         }
-        tearOffInfo.add(
-            new jsAst.LiteralString('$callSelectorString /* tearOffInfo */'));
+        tearOffInfo.add(new jsAst.LiteralString('$callSelectorString'));
       }, canTearOff);
     }
 
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index a396889..455a091 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -645,8 +645,7 @@
       InterfaceType factoryType =
           treeElements.getType(redirectionNode.expression);
 
-      targetType = targetType.subst(factoryType.typeArguments,
-                                    factoryType.element.typeVariables);
+      targetType = targetType.substByContext(factoryType);
       factory.redirectionTarget = target;
       factory.redirectionTargetType = targetType;
     }
@@ -2738,7 +2737,7 @@
       } else if (target.modifiers.isFinal() ||
                  target.modifiers.isConst() ||
                  (target.isFunction() &&
-                  Elements.isStaticOrTopLevelFunction(target) && 
+                  Elements.isStaticOrTopLevelFunction(target) &&
                   !target.isSetter())) {
         if (target.isFunction()) {
           setter = warnAndCreateErroneousElement(
@@ -4166,17 +4165,14 @@
    */
   void addAllSupertypes(OrderedTypeSetBuilder allSupertypes,
                         InterfaceType type) {
-    Link<DartType> typeArguments = type.typeArguments;
     ClassElement classElement = type.element;
-    Link<DartType> typeVariables = classElement.typeVariables;
     Link<DartType> supertypes = classElement.allSupertypes;
     assert(invariant(element, supertypes != null,
         message: "Supertypes not computed on $classElement "
                  "during resolution of $element"));
     while (!supertypes.isEmpty) {
       DartType supertype = supertypes.head;
-      allSupertypes.add(compiler,
-                        supertype.subst(typeArguments, typeVariables));
+      allSupertypes.add(compiler, supertype.substByContext(type));
       supertypes = supertypes.tail;
     }
   }
diff --git a/sdk/lib/_internal/compiler/implementation/typechecker.dart b/sdk/lib/_internal/compiler/implementation/typechecker.dart
index 5dd026a..ff499fc 100644
--- a/sdk/lib/_internal/compiler/implementation/typechecker.dart
+++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart
@@ -1334,10 +1334,19 @@
     if (Elements.isUnresolved(constructor)) return types.dynamicType;
     DartType constructorType = constructor.computeType(compiler);
     if (identical(type.kind, TypeKind.INTERFACE)) {
-      InterfaceType interfaceType = type;
-      constructorType = constructorType.subst(
-          interfaceType.typeArguments,
-          interfaceType.element.typeVariables);
+      if (constructor.isSynthesized) {
+        // TODO(johnniwinther): Remove this when synthesized constructors handle
+        // type variables correctly.
+        InterfaceType interfaceType = type;
+        ClassElement receiverElement = interfaceType.element;
+        while (receiverElement.isMixinApplication) {
+          receiverElement = receiverElement.supertype.element;
+        }
+        constructorType = constructorType.substByContext(
+            interfaceType.asInstanceOf(receiverElement));
+      } else {
+        constructorType = constructorType.substByContext(type);
+      }
     }
     return constructorType;
   }
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart
index 9366565..c33e7f0 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -84,7 +84,7 @@
                       bool showDiagnostics: true}) {
   Uri script = currentDirectory.resolveUri(Platform.script);
   Uri libraryRoot = script.resolve('../../../sdk/');
-  Uri packageRoot = script.resolve('./packages/');
+  Uri packageRoot = currentDirectory.resolve('${Platform.packageRoot}/');
 
   MemorySourceFileProvider provider;
   var readStringFromUri;
diff --git a/tests/compiler/dart2js/mixin_language_test.dart b/tests/compiler/dart2js/mixin_language_test.dart
new file mode 100644
index 0000000..f4be3b2
--- /dev/null
+++ b/tests/compiler/dart2js/mixin_language_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file

+// for details. All rights reserved. Use of this source code is governed by a

+// BSD-style license that can be found in the LICENSE file.

+

+// Test that dart2js produces the expected static type warnings for these

+// language tests. This ensures that the analyzer and dart2js agrees on the

+// tests.

+

+import 'warnings_checker.dart';

+

+/// Map from test files to a map of their expected status. If the status map is

+/// `null` no warnings must be missing or unexpected, otherwise the status map

+/// can contain a list of line numbers for keys 'missing' and 'unexpected' for

+/// the warnings of each category.

+const Map<String, dynamic> TESTS = const {

+    'language/typevariable_substitution2_test.dart': null,

+};

+

+void main(List<String> arguments) {

+  checkWarnings(TESTS, arguments);

+}

diff --git a/tests/compiler/dart2js/warnings_checker.dart b/tests/compiler/dart2js/warnings_checker.dart
index 1105b38..aa84570 100644
--- a/tests/compiler/dart2js/warnings_checker.dart
+++ b/tests/compiler/dart2js/warnings_checker.dart
@@ -16,10 +16,11 @@
 import '../../../sdk/lib/_internal/compiler/implementation/util/uri_extras.dart';

 import 'dart:convert';

 

-void checkWarnings(Map<String, dynamic> tests) {

+void checkWarnings(Map<String, dynamic> tests, [List<String> arguments]) {

   bool isWindows = Platform.isWindows;

   Uri script = currentDirectory.resolveUri(Platform.script);

   bool warningsMismatch = false;

+  bool verbose = arguments != null && arguments.contains('-v');

   asyncTest(() => Future.forEach(tests.keys, (String test) {

     Uri uri = script.resolve('../../$test');

     String source = UTF8.decode(readAll(uriPathToNative(uri.path)));

@@ -38,7 +39,7 @@
     var compiler = compilerFor(const {},

          diagnosticHandler: collector,

          options: ['--analyze-only'],

-         showDiagnostics: false);

+         showDiagnostics: verbose);

     return compiler.run(uri).then((_) {

       Map<String, List<int>> statusMap = tests[test];

       // Line numbers with known unexpected warnings.

diff --git a/tests/language/checked_mode_helper.dart b/tests/language/checked_mode_helper.dart
new file mode 100644
index 0000000..695222d
--- /dev/null
+++ b/tests/language/checked_mode_helper.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library checked_mode_helper;
+
+import 'package:expect/expect.dart';
+
+/// Returns `true` if the program is running in checked mode.
+bool inCheckedMode() {
+  try {
+    var i = 42;
+    String s = i;
+  } on TypeError catch (e) {
+    return true;
+  }
+  return false;
+}
+
+/// Checks that a dynamic type error is thrown if and only if [f] is executed in
+/// checked mode and [expectTypeError] is `true`.
+void testDynamicTypeError(bool expectTypeError, f(), [String message]) {
+  if (expectTypeError) {
+    checkDynamicTypeError(f, message);
+  } else {
+    checkNoDynamicTypeError(f, message);
+  }
+}
+
+/// Checks that a dynamic type error is thrown if and only if [f] is executed in
+/// checked mode.
+void checkDynamicTypeError(f(), [String message]) {
+  message = message != null ? ': $message' : '';
+  try {
+    f();
+    Expect.isFalse(inCheckedMode(),
+      'Missing type error in checked mode$message.');
+  } on TypeError catch (e) {
+    Expect.isTrue(inCheckedMode(),
+      'Unexpected type error in production mode.');
+  }
+}
+
+/// Checks that no dynamic type error is thrown when [f] is executed regardless
+/// of execution mode.
+void checkNoDynamicTypeError(f(), [String message]) {
+  message = message != null ? ': $message' : '';
+  try {
+    f();
+  } on TypeError catch (e) {
+    String mode = inCheckedMode() ? 'checked mode' : 'production mode';
+    Expect.fail('Unexpected type error in $mode$message.');
+  }
+}
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index ee85f4c..b10f1a2 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -176,6 +176,9 @@
 proxy_test/05: StaticWarning # Issue 15467
 proxy_test/06: StaticWarning # Issue 15467
 
+# test issue 15714
+typevariable_substitution2_test/01: StaticWarning # Issue 15714
+
 abstract_exact_selector_test: StaticWarning
 abstract_getter_test: StaticWarning
 abstract_object_method_test: StaticWarning
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index e7da090..3ce7bcc 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -176,6 +176,9 @@
 proxy_test/05: StaticWarning # Issue 15467
 proxy_test/06: StaticWarning # Issue 15467
 
+# test issue 15714
+typevariable_substitution2_test/01: StaticWarning # Issue 15714
+
 abstract_exact_selector_test: StaticWarning
 abstract_getter_test: StaticWarning
 abstract_object_method_test: StaticWarning
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 1942eb0..18a5a57 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -50,6 +50,8 @@
 malbounded_type_test_test/03: Fail # Issue 14121
 malbounded_type_test_test/04: Fail # Issue 14121
 default_factory2_test/01: Fail # Issue 14121
+typevariable_substitution2_test/01: CompileTimeError # Issue 15875
+typevariable_substitution2_test/02: CompileTimeError # Issue 15875
 
 [ $compiler == dart2js && $unchecked ]
 type_checks_in_factory_method_test: RuntimeError # Issue 12746
diff --git a/tests/language/typevariable_substitution2_test.dart b/tests/language/typevariable_substitution2_test.dart
new file mode 100644
index 0000000..dffa913
--- /dev/null
+++ b/tests/language/typevariable_substitution2_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that mixins don't interfere with type variable substitution.
+
+import 'checked_mode_helper.dart';
+
+class B<T> {
+  B(T x);
+}
+
+class M {}
+
+class A<T> extends B<T> with M {
+  A(T x) : super(x);  // This line must be warning free.
+}
+
+class C<T> = B<T> with M;
+
+
+main() {
+  new A(null);
+  new C<String>(''); /// 01: ok
+  checkDynamicTypeError(() => new C<String>(0)); /// 02: static type warning
+}
diff --git a/tools/VERSION b/tools/VERSION
index 27e6014..6546847 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
 MINOR 1
 PATCH 0
 PRERELEASE 5
-PRERELEASE_PATCH 8
+PRERELEASE_PATCH 9