dart / co19 / 6186e8e037eb98568e0f829726544621c4e05445 / . / LanguageFeatures / Super-bounded-types / static_analysis_A01_t04.dart

/* | |

* Copyright (c) 2018, 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. | |

*/ | |

/** | |

* @assertion We say that the parameterized type G<T1..Tk> is regular-bounded | |

* when Tj <: [T1/X1 .. Tk/Xk]Bj for all j, 1 <= j <= k, where X1..Xk are the | |

* formal type parameters of G in declaration order, and B1..Bk are the | |

* corresponding upper bounds. | |

* This means that each actual type argument satisfies the declared upper bound | |

* for the corresponding formal type parameter. | |

* We extend covariance for generic class types such that it can be used also in | |

* cases where a type argument violates the corresponding bound. | |

* For instance, assuming the classes [C] and [D] as declared in the | |

* [Motivation] section, [C<D>] is a subtype of [C<Object>]. This is new because | |

* [C<Object>] used to be a compile-time error, which means that no questions | |

* could be asked about its properties. Note that this is a straightforward | |

* application of the usual covariance rule: [C<D> <: C<Object>] because | |

* [D <: Object]. We need this relaxation of the rules in order to be able to | |

* define which violations of the declared bounds are admissible. | |

* @description Checks that assigning [dynamic] as a bound of super-bounded type | |

* does not cause compile error in case of several type parameters. | |

* @author iarkh@unipro.ru | |

* @issue #32903 | |

*/ | |

class C<X extends C<X, int>, int> {} | |

class D extends C<D, int> {} | |

class E<String, X extends E<String, X, double, int>, double, int> {} | |

class F extends E<String, F, double, int> {} | |

main() { | |

D d = new D(); | |

C<dynamic, int> c = d; | |

C<dynamic, dynamic> c1 = d; | |

dynamic c2 = d; | |

F f = new F(); | |

E<String, dynamic, double, int> e = f; | |

E<dynamic, dynamic, dynamic, dynamic> e1 = f; | |

dynamic e2 = f; | |

} |