Test of type variable bound printing

Tests that bounds are printed when printing a generic function type,
and that the printer correctly distinguishes between no specified bound
(no bound printed) and explicit Object bound (Object printed as bound).

Change-Id: I747743d902a9eaf66cf65c579051175216960c63
Reviewed-on: https://dart-review.googlesource.com/c/84606
Reviewed-by: Peter von der Ahé <ahe@google.com>
diff --git a/pkg/front_end/testcases/function_type_assignments.dart b/pkg/front_end/testcases/function_type_assignments.dart
new file mode 100644
index 0000000..f6249ea
--- /dev/null
+++ b/pkg/front_end/testcases/function_type_assignments.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2018, 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.
+
+T identity<T>(T t) => t;
+T identityObject<T extends Object>(T t) => t;
+T identityList<T extends List<T>>(T t) => t;
+
+// Test that error messages involving generic function types
+// print the type variable bounds correctly.
+String x = identity; // No bound
+String y = identityObject; // Object bound
+String z = identityList; // List<T> bound
+
+main() {}
diff --git a/pkg/front_end/testcases/function_type_assignments.dart.legacy.expect b/pkg/front_end/testcases/function_type_assignments.dart.legacy.expect
new file mode 100644
index 0000000..fa72575
--- /dev/null
+++ b/pkg/front_end/testcases/function_type_assignments.dart.legacy.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static field core::String x = self::identity;
+static field core::String y = self::identityObject;
+static field core::String z = self::identityList;
+static method identity<T extends core::Object = dynamic>(self::identity::T t) → self::identity::T
+  return t;
+static method identityObject<T extends core::Object = dynamic>(self::identityObject::T t) → self::identityObject::T
+  return t;
+static method identityList<T extends core::List<self::identityList::T> = dynamic>(self::identityList::T t) → self::identityList::T
+  return t;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/function_type_assignments.dart.legacy.transformed.expect b/pkg/front_end/testcases/function_type_assignments.dart.legacy.transformed.expect
new file mode 100644
index 0000000..fa72575
--- /dev/null
+++ b/pkg/front_end/testcases/function_type_assignments.dart.legacy.transformed.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static field core::String x = self::identity;
+static field core::String y = self::identityObject;
+static field core::String z = self::identityList;
+static method identity<T extends core::Object = dynamic>(self::identity::T t) → self::identity::T
+  return t;
+static method identityObject<T extends core::Object = dynamic>(self::identityObject::T t) → self::identityObject::T
+  return t;
+static method identityList<T extends core::List<self::identityList::T> = dynamic>(self::identityList::T t) → self::identityList::T
+  return t;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/function_type_assignments.dart.outline.expect b/pkg/front_end/testcases/function_type_assignments.dart.outline.expect
new file mode 100644
index 0000000..deb3a40
--- /dev/null
+++ b/pkg/front_end/testcases/function_type_assignments.dart.outline.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static field core::String x;
+static field core::String y;
+static field core::String z;
+static method identity<T extends core::Object = dynamic>(self::identity::T t) → self::identity::T
+  ;
+static method identityObject<T extends core::Object = dynamic>(self::identityObject::T t) → self::identityObject::T
+  ;
+static method identityList<T extends core::List<self::identityList::T> = dynamic>(self::identityList::T t) → self::identityList::T
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/function_type_assignments.dart.strong.expect b/pkg/front_end/testcases/function_type_assignments.dart.strong.expect
new file mode 100644
index 0000000..a7d04c0
--- /dev/null
+++ b/pkg/front_end/testcases/function_type_assignments.dart.strong.expect
@@ -0,0 +1,44 @@
+// Formatted problems:
+//
+// pkg/front_end/testcases/function_type_assignments.dart:11:12: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+// String x = identity; // No bound
+//            ^
+//
+// pkg/front_end/testcases/function_type_assignments.dart:12:12: Error: A value of type 'T Function<T extends Object>(T)' can't be assigned to a variable of type 'String'.
+//  - 'Object' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+// String y = identityObject; // Object bound
+//            ^
+//
+// pkg/front_end/testcases/function_type_assignments.dart:13:12: Error: A value of type 'T Function<T extends List<T>>(T)' can't be assigned to a variable of type 'String'.
+//  - 'List' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+// String z = identityList; // List<T> bound
+//            ^
+
+library;
+import self as self;
+import "dart:core" as core;
+
+static field core::String x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/function_type_assignments.dart:11:12: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+String x = identity; // No bound
+           ^" in self::identity as{TypeError} core::String;
+static field core::String y = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/function_type_assignments.dart:12:12: Error: A value of type 'T Function<T extends Object>(T)' can't be assigned to a variable of type 'String'.
+ - 'Object' is from 'dart:core'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+String y = identityObject; // Object bound
+           ^" in self::identityObject as{TypeError} core::String;
+static field core::String z = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/function_type_assignments.dart:13:12: Error: A value of type 'T Function<T extends List<T>>(T)' can't be assigned to a variable of type 'String'.
+ - 'List' is from 'dart:core'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+String z = identityList; // List<T> bound
+           ^" in self::identityList as{TypeError} core::String;
+static method identity<T extends core::Object = dynamic>(self::identity::T t) → self::identity::T
+  return t;
+static method identityObject<T extends core::Object = core::Object>(self::identityObject::T t) → self::identityObject::T
+  return t;
+static method identityList<T extends core::List<self::identityList::T> = core::List<dynamic>>(self::identityList::T t) → self::identityList::T
+  return t;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/function_type_assignments.dart.strong.transformed.expect b/pkg/front_end/testcases/function_type_assignments.dart.strong.transformed.expect
new file mode 100644
index 0000000..f945f65
--- /dev/null
+++ b/pkg/front_end/testcases/function_type_assignments.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static field core::String x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/function_type_assignments.dart:11:12: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+String x = identity; // No bound
+           ^" in self::identity as{TypeError} core::String;
+static field core::String y = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/function_type_assignments.dart:12:12: Error: A value of type 'T Function<T extends Object>(T)' can't be assigned to a variable of type 'String'.
+ - 'Object' is from 'dart:core'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+String y = identityObject; // Object bound
+           ^" in self::identityObject as{TypeError} core::String;
+static field core::String z = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/function_type_assignments.dart:13:12: Error: A value of type 'T Function<T extends List<T>>(T)' can't be assigned to a variable of type 'String'.
+ - 'List' is from 'dart:core'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+String z = identityList; // List<T> bound
+           ^" in self::identityList as{TypeError} core::String;
+static method identity<T extends core::Object = dynamic>(self::identity::T t) → self::identity::T
+  return t;
+static method identityObject<T extends core::Object = core::Object>(self::identityObject::T t) → self::identityObject::T
+  return t;
+static method identityList<T extends core::List<self::identityList::T> = core::List<dynamic>>(self::identityList::T t) → self::identityList::T
+  return t;
+static method main() → dynamic {}