Index: test/samples/funwithtypes.dart |
diff --git a/test/samples/funwithtypes.dart b/test/samples/funwithtypes.dart |
deleted file mode 100644 |
index 40925ca4db611ebc3a6878a0c1c6ebbfb94c06fc..0000000000000000000000000000000000000000 |
--- a/test/samples/funwithtypes.dart |
+++ /dev/null |
@@ -1,124 +0,0 @@ |
-// 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. |
- |
-// Some examples of how the dart type system/checked mode interacts with dart type unsoundness. |
-// Suppose we were to "trust types" in the following sense: if the program passes the dart |
-// type checker, assume that all checks implied by checked mode would have passed, and |
-// compile under that assumption. What does that buy you? These examples are intended to |
-// illustrate why this is less than you might think. This file has no static errors or |
-// warnings, and runs fine in checked mode, but it demonstrates lots of ways in which |
-// nonetheless we can produce no such method errors, or sideways casts, etc. |
- |
-// A simple class |
-class A { |
- int x = 0; |
-} |
- |
-// Overriding x with an assignable type (supertype) is ok |
-class B extends A { |
- num x = 1.0; |
- int y = 1; |
-} |
- |
-// Contain a B |
-class S0 { |
- B field; |
-} |
- |
-// Override to an A |
-class S1 extends S0 { |
- A field; |
- S1(A this.field); |
-} |
- |
-// If we assume that s has type S0, can we assume that s.field has type B? No. |
-void nsm0(S0 s) { |
- // Dynamic dispatch required. |
- // With global subclass information, the compiler could potentially get rid |
- // of some of the checks here when bad overrides as above don't happen. |
- try { |
- s.field.y; |
- } on NoSuchMethodError catch (r) { |
- print("Oops, no field y in something of type B"); |
- } |
-} |
- |
-// If we assume that f returns a B, can we assume that B.y exists? No. |
-void nsm1(B f()) { |
- // Dynamic dispatch required. |
- // Even with global subclass info, the compiler can't do anything here, since |
- // this relies on screwy subtyping rather than screwy field overrides. |
- try { |
- f().y; |
- } on NoSuchMethodError catch (r) { |
- print("Oops, no field y in something of type B (extra badness)"); |
- } |
-} |
- |
-// If we assume that s is an S1, can we assume that s.field is an A? No. |
-void doubleForInt0(S1 s) { |
- // Dynamic dispatch required. |
- // With global subclass info we can possibly know when we need to emit careful code |
- // here, but we certainly can't just generate a simple unconditional primitive operation |
- // (even ignoring nulls) |
- s.field.x + 1; |
- if (s.field.x is double) { |
- print("Oops, got double for int"); |
- } |
-} |
- |
-// Can we assume that f returns an int (or a subtype of an int)? No. |
-// Can we assume that f returns an int (or subtype or a supertype of an int)? No. |
-void doubleForInt1(int f()) { |
- // Dynamic dispatch required. |
- // Here, even with global subclass info we're still stuck - we can't really |
- // ever trust the return types on closures. Note that int and double aren't |
- // even assignment compatible in this case. |
- f() + 1; |
- if (f() is double) { |
- print("Oops, got double for int (extra badness)"); |
- } |
-} |
- |
-class C extends A {} |
- |
-// Can we assume that f returns something on the same branch of the inheritance chain as B? No. |
-void sidewaysCast(B f()) { |
- // Just to emphasize the point, here's a more general case where the static type |
- // isn't even on the same branch of the subtype hierarchy as the dynamic type. |
- if (f() is C) { |
- print( |
- "Static type of expression is B, but runtime type is C (neither sub nor supertype)"); |
- } |
- if (f() is B) { |
- // Do something here. This code doesn't get reached.... unless the compiler optimizes |
- // based on trusting types and eliminates the is check, in which case we may suddenly |
- // execute different code. |
- } |
-} |
- |
-// If we assume that x has type List<B>, what can we assume about the type of the elements? Nothing. |
-void generic0(List<B> x) { |
- // What can we assume about the elements of this array if we trust types? |
- // Absolutely nothing, whatsoever. |
- if (x[0] is int) { |
- print( |
- "Parameter type is List<B> but actually contains an int (completely unrelated type)"); |
- } |
-} |
- |
-void main() { |
- nsm0(new S1(new A())); |
- nsm1(() => new A()); |
- doubleForInt0(new S1(new B())); |
- doubleForInt1(() { |
- num b = 1.0; |
- return b; |
- }); |
- sidewaysCast(() { |
- A a = new C(); |
- return a; |
- }); |
- generic0(<dynamic>[3]); |
-} |