blob: 10d064ea17ffa8e14f9f3009c61f90505edac417 [file] [log] [blame]
// Copyright (c) 2022, 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.
// Tests that when the feature is enabled, inferred types can flow
// "horizontally" from a non-closure argument of an invocation to a closure
// argument.
testLaterUnnamedParameter(void Function<T>(T, void Function(T)) f) {
f(0, (x) {
x;
});
}
/// This special case verifies that the implementations correctly associate the
/// zeroth positional parameter with the corresponding argument (even if that
/// argument isn't in the zeroth position at the call site).
testLaterUnnamedParameterDependsOnNamedParameter(
void Function<T>(void Function(T), {required T a}) f) {
f(a: 0, (x) {
x;
});
}
testEarlierUnnamedParameter(void Function<T>(void Function(T), T) f) {
f((x) {
x;
}, 0);
}
testLaterNamedParameter(
void Function<T>({required T a, required void Function(T) b}) f) {
f(
a: 0,
b: (x) {
x;
});
}
testEarlierNamedParameter(
void Function<T>({required void Function(T) a, required T b}) f) {
f(
a: (x) {
x;
},
b: 0);
}
/// This special case verifies that the implementations correctly associate the
/// zeroth positional parameter with the corresponding argument (even if that
/// argument isn't in the zeroth position at the call site).
testEarlierNamedParameterDependsOnUnnamedParameter(
void Function<T>(T b, {required void Function(T) a}) f) {
f(a: (x) {
x;
}, 0);
}
testPropagateToReturnType(U Function<T, U>(T, U Function(T)) f) {
f(0, (x) => [x]);
}
testFold(List<int> list) {
var a = list.fold(0, (x, y) => (x) + (y));
a;
}
// The test cases below exercise situations where there are multiple closures in
// the invocation, and they need to be inferred in the right order.
testClosureAsParameterType(U Function<T, U>(T, U Function(T)) f) {
f(() => 0, (h) => [h()]);
}
testPropagateToEarlierClosure(U Function<T, U>(U Function(T), T Function()) f) {
f((x) => [x], () => 0);
}
testPropagateToLaterClosure(U Function<T, U>(T Function(), U Function(T)) f) {
f(() => 0, (x) => [x]);
}
testLongDependencyChain(
V Function<T, U, V>(T Function(), U Function(T), V Function(U)) f) {
f(() => [0], (x) => x.single, (y) => {y});
}
testDependencyCycle(Map<T, U> Function<T, U>(T Function(U), U Function(T)) f) {
f((x) => [x], (y) => {y});
}
testNecessaryDueToWrongExplicitParameterType(List<int> list) {
var a = list.fold(0, (x, int y) => (x) + (y));
a;
}
testPropagateFromContravariantReturnType(
U Function<T, U>(void Function(T) Function(), U Function(T)) f) {
f(() => (int i) {}, (x) => [x]);
}
testPropagateToContravariantParameterType(
U Function<T, U>(T Function(), U Function(void Function(T))) f) {
f(() => 0, (x) => [x]);
}
testReturnTypeRefersToMultipleTypeVars(
void Function<T, U>(
Map<T, U> Function(), void Function(T), void Function(U))
f) {
f(() => {0: ''}, (k) {
k;
}, (v) {
v;
});
}
testUnnecessaryDueToNoDependency(T Function<T>(T Function(), T) f) {
f(() => 0, null);
}
testUnnecessaryDueToExplicitParameterType(List<int> list) {
var a = list.fold(null, (int? x, y) => (x ?? 0) + y);
a;
}
testUnnecessaryDueToExplicitParameterTypeNamed(
T Function<T>(T, T Function({required T x, required int y})) f) {
var a = f(null, ({int? x, required y}) => (x ?? 0) + y);
a;
}
testParenthesized(void Function<T>(T, void Function(T)) f) {
f(0, ((x) {
x;
}));
}
testParenthesizedNamed(
void Function<T>({required T a, required void Function(T) b}) f) {
f(
a: 0,
b: ((x) {
x;
}));
}
testParenthesizedTwice(void Function<T>(T, void Function(T)) f) {
f(0, (((x) {
x;
})));
}
testParenthesizedTwiceNamed(
void Function<T>({required T a, required void Function(T) b}) f) {
f(
a: 0,
b: (((x) {
x;
})));
}
main() {}