| // Copyright (c) 2021, 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. |
| |
| // Checks that typeinference on arguments continues working after their order is |
| // changed. |
| |
| import "package:expect/expect.dart"; |
| |
| Type? argument = null; |
| |
| void registerTypeArgument<X>() { |
| argument = X; |
| } |
| |
| void runAndCheckForTypeArgument( |
| Type expectedArgument, void Function() functionToRun) { |
| argument = null; |
| functionToRun(); |
| Expect.equals(expectedArgument, argument); |
| } |
| |
| class BGeneric<X> { |
| const BGeneric(); |
| } |
| |
| void fooGeneric<X>(BGeneric<X> x, {required BGeneric<List<X>> y}) { |
| registerTypeArgument<X>(); |
| } |
| |
| void fooFunction(int x, {required double Function(double) y}) { |
| y(3.14); |
| } |
| |
| X bar<X>(X x) { |
| registerTypeArgument<X>(); |
| return x; |
| } |
| |
| void fooFunctionGeneric<X>(int x, {required void Function(X) y}) { |
| registerTypeArgument<X>(); |
| } |
| |
| void main() { |
| runAndCheckForTypeArgument(dynamic, () { |
| fooGeneric(const BGeneric(), y: const BGeneric()); |
| }); |
| runAndCheckForTypeArgument(dynamic, () { |
| fooGeneric(y: const BGeneric(), const BGeneric()); |
| }); |
| runAndCheckForTypeArgument(int, () { |
| fooGeneric(const BGeneric<int>(), y: const BGeneric<List<int>>()); |
| }); |
| runAndCheckForTypeArgument(String, () { |
| fooGeneric(y: const BGeneric<List<String>>(), const BGeneric<String>()); |
| }); |
| |
| runAndCheckForTypeArgument(double, () { |
| fooFunction(42, y: bar); |
| }); |
| runAndCheckForTypeArgument(double, () { |
| fooFunction(y: bar, 42); |
| }); |
| |
| runAndCheckForTypeArgument(String, () { |
| fooFunctionGeneric(42, y: (String x) {}); |
| }); |
| runAndCheckForTypeArgument(num, () { |
| fooFunctionGeneric(y: (num x) {}, 42); |
| }); |
| } |