blob: 52cd2445142e660cc6288ac86cf56348bad1077b [file] [log] [blame]
// Copyright (c) 2023, 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 implicit generic function instantiations are inserted based on
/// the pattern's context type, but not when destructuring.
import "package:expect/expect.dart";
main() {
testRelational();
testValueExpression();
testDestructureRefutable();
}
T id<T>(T t) => t;
class Box<T> {
final T value;
Box(this.value);
}
typedef IntFn = int Function(int);
typedef TFn = T Function<T>(T);
class Compare {
operator <(IntFn f) => f is TFn;
}
void testRelational() {
const c = id;
// Instantiates based on the context type of the "<" method parameter type.
if (Compare() case < c) {
Expect.fail('"<" should receive instantiation, not generic function.');
} else {
// OK.
}
}
void testValueExpression() {
// Inserts instantiation in value expression.
var (IntFn a) = id;
Expect.isTrue(a is IntFn);
Expect.isFalse(a is TFn);
var (IntFn b,) = (id,);
Expect.isTrue(b is IntFn);
Expect.isFalse(b is TFn);
var [IntFn c] = [id];
Expect.isTrue(c is IntFn);
Expect.isFalse(c is TFn);
var {'x': IntFn d} = {'x': id};
Expect.isTrue(d is IntFn);
Expect.isFalse(d is TFn);
var Box<IntFn>(value: e) = Box(id);
Expect.isTrue(e is IntFn);
Expect.isFalse(e is TFn);
}
void testDestructureRefutable() {
// Does not instantiate during destructuring. In a refutable pattern, this
// means the value doesn't match the tested type.
(TFn,) record = (id,);
if (record case (IntFn b,)) {
Expect.fail('Should not match.');
}
List<TFn> list = [id];
if (list case [IntFn c]) {
Expect.fail('Should not match.');
}
Map<String, TFn> map = {'x': id};
if (map case {'x': IntFn d}) {
Expect.fail('Should not match.');
}
Box<TFn> box = Box(id);
if (box case Box(value: IntFn e)) {
Expect.fail('Should not match.');
}
}