Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(198)

Unified Diff: editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/type/UnionTypeImpl.java

Issue 578643004: Redefine union-type subtyping to be more permissive. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/internal/type/UnionTypeImplTest.java » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/type/UnionTypeImpl.java
diff --git a/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/type/UnionTypeImpl.java b/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/type/UnionTypeImpl.java
index 27a3491bd6fe13a61f8c797e94b8838dde28f498..5970002acf70200514b0baf6099d986360eb75d4 100644
--- a/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/type/UnionTypeImpl.java
+++ b/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/type/UnionTypeImpl.java
@@ -148,49 +148,77 @@ public class UnionTypeImpl extends TypeImpl implements UnionType {
@Override
protected boolean internalIsMoreSpecificThan(Type type, boolean withDynamic,
Set<TypePair> visitedTypePairs) {
- // TODO(collinsn): what version of subtyping do we want?
+ // What version of subtyping do we want? See discussion below in [internalIsSubtypeOf].
//
// The more unsound version: any.
- /*
for (Type t : types) {
if (((TypeImpl) t).internalIsMoreSpecificThan(type, withDynamic, visitedTypePairs)) {
return true;
}
}
return false;
- */
// The less unsound version: all.
+ /*
for (Type t : types) {
if (!((TypeImpl) t).internalIsMoreSpecificThan(type, withDynamic, visitedTypePairs)) {
return false;
}
}
return true;
+ */
}
@Override
protected boolean internalIsSubtypeOf(Type type, Set<TypePair> visitedTypePairs) {
// Premature optimization opportunity: if [type] is also a union type, we could instead
- // do a subset test on the underlying element tests.
+ // do a subset test on the underlying element sets.
- // TODO(collinsn): what version of subtyping do we want?
+ // What version of union-type subtyping do we want? We choose the more unsound version,
+ // motivated by the following example. Suppose classes [A] and [B] are unrelated
+ // and that [C] extends [B]:
+ //
+ // A B
+ // |
+ // C
+ //
+ // If [ab : {A, B}] and [ac : {A, C}] then we'd intuitively expect either
+ // both or neither of the assignments
+ //
+ // B b1 = ab;
+ // B b2 = ac;
//
+ // to be allowed; they're both allowed under the more unsound subtyping rule.
+ //
+ // However, under the less unsound subtyping rule, the assignment to [b1] is
+ // allowed, but the assignment to [b2] is not. The reason is that assignment
+ // compatible [T1 <=> T1] for interface types is defined by [T1 <: T2] or
+ // [T2 <: T1]. So, in the [b1 = ab] case, the test [B <: {A, B}] always passes,
+ // for both definitions of union-type subtyping. On the other hand, the test
+ // [B <: {A, C}] always fails, leaving only [{A, C} <: B], which only passes
+ // for the more unsound rule.
+ //
+ // An interesting consequence: we usually think of [A <: B] meaning that
+ // knowing an expression has type [A] is more informative than knowing it has type [B].
+ // Of course, this intuition is already wrong once we have [dynamic], but it becomes
+ // more wrong when we define union-type subtyping in the more unsound way. We now e.g.
+ // have [{A, B} <: B], where the LHS is surely less informative than the RHS!
+
// The more unsound version: any.
- /*
for (Type t : types) {
if (((TypeImpl) t).internalIsSubtypeOf(type, visitedTypePairs)) {
return true;
}
}
return false;
- */
// The less unsound version: all.
+ /*
for (Type t : types) {
if (!((TypeImpl) t).internalIsSubtypeOf(type, visitedTypePairs)) {
return false;
}
}
return true;
+ */
}
/**
« no previous file with comments | « no previous file | editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/internal/type/UnionTypeImplTest.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698