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

class A {}

class B extends A {}

late List<B> xs;
late List<List<B>> xss;

class Class<T extends A> {
  void method1a(T t) {
    if (t is B) {
      // `t` is now promoted to T & B

      // The list literal has type List<T>, not List<T & B>
      var ys = [t];
      xs = ys;
    }
  }

  void method1b(T t) {
    if (t is B) {
      // `t` is now promoted to T & B

      // The list literal has type List<List<T>>, not List<List<T & B>>
      var yss = [
        [t]
      ];
      xss = yss;
    }
  }

  void method2a(T t) {
    dynamic alias;
    if (t is B) {
      // `t` is now promoted to T & B

      // The list literal has type List<T>, not List<T & B>
      var ys = [t];
      alias = ys;
      xs = alias;
    }
  }

  void method2b(T t) {
    dynamic alias;
    if (t is B) {
      // `t` is now promoted to T & B

      // The list literal has type List<List<T>>, not List<List<T & B>>
      var yss = [
        [t]
      ];
      alias = yss;
      xss = alias;
    }
  }
}

void main() {
  throws(() {
    Class<A>().method2a(B());
    print(xs.runtimeType); // 'List<A>'.
  });
  throws(() {
    Class<A>().method2b(B());
    print(xs.runtimeType); // 'List<A>'.
  });
}

void errors() {
  Class<A>().method1a(B());
  Class<A>().method1b(B());
}

void throws(void Function() f) {
  try {
    f();
  } catch (e) {
    print(e);
    return;
  }
  throw 'Expected throws';
}
