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

Side by Side Diff: pkg/analyzer/lib/src/generated/type_system.dart

Issue 2214833002: fix #26965, allow promotion from type param upper bound in strong mode (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fix Created 4 years, 4 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 unified diff | Download patch
« no previous file with comments | « CHANGELOG.md ('k') | pkg/analyzer/test/src/task/strong/checker_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analyzer.src.generated.type_system; 5 library analyzer.src.generated.type_system;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import 'dart:math' as math; 8 import 'dart:math' as math;
9 9
10 import 'package:analyzer/dart/ast/token.dart' show TokenType; 10 import 'package:analyzer/dart/ast/token.dart' show TokenType;
(...skipping 27 matching lines...) Expand all
38 38
39 StrongTypeSystemImpl( 39 StrongTypeSystemImpl(
40 {this.implicitCasts: true, 40 {this.implicitCasts: true,
41 this.nonnullableTypes: AnalysisOptionsImpl.NONNULLABLE_TYPES}); 41 this.nonnullableTypes: AnalysisOptionsImpl.NONNULLABLE_TYPES});
42 42
43 bool anyParameterType(FunctionType ft, bool predicate(DartType t)) { 43 bool anyParameterType(FunctionType ft, bool predicate(DartType t)) {
44 return ft.parameters.any((p) => predicate(p.type)); 44 return ft.parameters.any((p) => predicate(p.type));
45 } 45 }
46 46
47 @override 47 @override
48 bool canPromoteToType(DartType to, DartType from) => isSubtypeOf(to, from); 48 bool canPromoteToType(DartType to, DartType from) {
49 // Allow promoting to a subtype, for example:
50 //
51 // f(Base b) {
52 // if (b is SubTypeOfBase) {
53 // // promote `b` to SubTypeOfBase for this block
54 // }
55 // }
56 //
57 // This allows the variable to be used wherever the supertype (here `Base`)
58 // is expected, while gaining a more precise type.
59 if (isSubtypeOf(to, from)) {
60 return true;
61 }
62 // For a type parameter `T extends U`, allow promoting from the upper bound
63 // `U` to `S` where `S <: U`.
64 //
65 // This does restrict the variable, because `S </: T`, it can no longer be
66 // used as a `T` without another cast.
67 //
68 // However the members you could access from a variable of type `T`, were
69 // already those on the upper bound `U`. So all members on `U` will be
70 // accessible, as well as those on `S`. Pragmatically this feels like a
71 // useful enough trade-off to allow promotion.
72 //
73 // (In general we would need union types to support this feature precisely.)
74 if (from is TypeParameterType) {
75 return isSubtypeOf(to, from.resolveToBound(DynamicTypeImpl.instance));
76 }
77
78 return false;
79 }
49 80
50 @override 81 @override
51 FunctionType functionTypeToConcreteType( 82 FunctionType functionTypeToConcreteType(
52 TypeProvider typeProvider, FunctionType t) { 83 TypeProvider typeProvider, FunctionType t) {
53 // TODO(jmesserly): should we use a real "fuzzyArrow" bit on the function 84 // TODO(jmesserly): should we use a real "fuzzyArrow" bit on the function
54 // type? That would allow us to implement this in the subtype relation. 85 // type? That would allow us to implement this in the subtype relation.
55 // TODO(jmesserly): we'll need to factor this differently if we want to 86 // TODO(jmesserly): we'll need to factor this differently if we want to
56 // move CodeChecker's functionality into existing analyzer. Likely we can 87 // move CodeChecker's functionality into existing analyzer. Likely we can
57 // let the Expression have a strict arrow, then in places were we do 88 // let the Expression have a strict arrow, then in places were we do
58 // inference, convert back to a fuzzy arrow. 89 // inference, convert back to a fuzzy arrow.
(...skipping 1489 matching lines...) Expand 10 before | Expand all | Expand 10 after
1548 } 1579 }
1549 1580
1550 bool _isBottom(DartType t, {bool dynamicIsBottom: false}) { 1581 bool _isBottom(DartType t, {bool dynamicIsBottom: false}) {
1551 return (t.isDynamic && dynamicIsBottom) || t.isBottom; 1582 return (t.isDynamic && dynamicIsBottom) || t.isBottom;
1552 } 1583 }
1553 1584
1554 bool _isTop(DartType t, {bool dynamicIsBottom: false}) { 1585 bool _isTop(DartType t, {bool dynamicIsBottom: false}) {
1555 // TODO(leafp): Document the rules in play here 1586 // TODO(leafp): Document the rules in play here
1556 return (t.isDynamic && !dynamicIsBottom) || t.isObject; 1587 return (t.isDynamic && !dynamicIsBottom) || t.isObject;
1557 } 1588 }
OLDNEW
« no previous file with comments | « CHANGELOG.md ('k') | pkg/analyzer/test/src/task/strong/checker_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698