// Copyright (c) 2016, 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.

// Check function subtyping of type arguments. These cases use typedefs as type
// arguments, and the typedefs have type parameters that are used more than
// once.

import 'package:expect/expect.dart';

typedef A F<A>(A arg1, A arg2);
typedef B G<A, B>(B arg1, B arg2);

typedef Set<A> FS<A>(Set<A> arg1, Set<A> arg2);

@NoInline()
@AssumeDynamic()
dyn(x) => x;

class CheckEnv<X, Y> {
  test(bool intX) {
    Expect.isTrue(<F<X>>[] is List<F>);
    Expect.isTrue(<F<X>>[] is List<F<X>>);
    Expect.isTrue(<F<X>>[] is List<G<Y, X>>);

    Expect.isTrue(dyn(<F<X>>[]) is List<F>);
    Expect.isTrue(dyn(<F<X>>[]) is List<F<X>>);
    Expect.isTrue(dyn(<F<X>>[]) is List<G<Y, X>>);

    Expect.isTrue(<F<X>>[] is! List<F<Y>>);
    Expect.isTrue(<F<X>>[] is! List<G<X, Y>>);

    Expect.isTrue(dyn(<F<X>>[]) is! List<F<Y>>);
    Expect.isTrue(dyn(<F<X>>[]) is! List<G<X, Y>>);

    Expect.isTrue(dyn(<FS<X>>[]) is List<FS>);
    Expect.isTrue(dyn(<FS<X>>[]) is List<FS<X>>);
    if (intX) {
      Expect.isTrue(dyn(<FS<X>>[]) is List<FS<int>>);
      Expect.isTrue(dyn(<FS<int>>[]) is List<FS<X>>);
      Expect.isTrue(dyn(<FS<Y>>[]) is! List<FS<int>>);
      Expect.isTrue(dyn(<FS<int>>[]) is! List<FS<Y>>);
    }
  }
}

main() {
  Expect.isTrue(<F<int>>[] is List<F<int>>);
  Expect.isTrue(dyn(<F<int>>[]) is List<F<int>>);
  Expect.isTrue(<F<int>>[] is List<G<bool, int>>);
  Expect.isTrue(dyn(<F<int>>[]) is List<G<bool, int>>);

  new CheckEnv<int, String>().test(true);
  new CheckEnv<String, int>().test(false);
}
