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

import 'dart:async';

class Derived<T> implements Future<T> {
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

class FixedPoint<T> implements Future<FixedPoint<T>> {
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

class Divergent<T> implements Future<Divergent<Divergent<T>>> {
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}


test() async {
  // flatten(Derived<int>) = int
  int x = await new Derived<int>(); /// 01: runtime error
  Future<int> f() async => new Derived<int>(); /// 02: ok
  Future<int> f() async { return new Derived<int>(); } /// 03: ok
  Future<int> x = (() async => new Derived<int>())(); /// 04: runtime error

  // flatten(FixedPoint<int>) = FixedPoint<int>
  FixedPoint<int> x = await new FixedPoint<int>(); /// 05: runtime error
  Future<FixedPoint<int>> f() async => new FixedPoint<int>(); /// 06: ok
  Future<FixedPoint<int>> f() async { return new FixedPoint<int>(); } /// 07: ok
  Future<FixedPoint<int>> x = (() async => new FixedPoint<int>())(); /// 08: runtime error

  // flatten(Divergent<int>) = Divergent<Divergent<int>>
  Divergent<Divergent<int>> x = await new Divergent<int>(); /// 09: runtime error
  Future<Divergent<Divergent<int>>> f() async => new Divergent<int>(); /// 10: ok
  Future<Divergent<Divergent<int>>> f() async { return new Divergent<int>(); } /// 11: ok
  Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())(); /// 12: runtime error
}

main() {
  test();
}