@@ -634,7 +634,9 @@ abstract class FlowAnalysis<Node extends Object, Statement extends Node,
634
634
/// Call this method after visiting the initializer of a variable declaration.
635
635
void initialize (
636
636
Variable variable, Type initializerType, Expression initializerExpression,
637
- {required bool isFinal, required bool isLate});
637
+ {required bool isFinal,
638
+ required bool isLate,
639
+ required bool isImplicitlyTyped});
638
640
639
641
/// Return whether the [variable] is definitely assigned in the current state.
640
642
bool isAssigned (Variable variable);
@@ -724,11 +726,6 @@ abstract class FlowAnalysis<Node extends Object, Statement extends Node,
724
726
void parenthesizedExpression (
725
727
Expression outerExpression, Expression innerExpression);
726
728
727
- /// Attempt to promote [variable] to [type] . The client may use this to
728
- /// ensure that a variable declaration of the form `var x = expr;` promotes
729
- /// `x` to type `X&T` in the circumstance where the type of `expr` is `X&T` .
730
- void promote (Variable variable, Type type);
731
-
732
729
/// Retrieves the type that the [variable] is promoted to, if the [variable]
733
730
/// is currently promoted. Otherwise returns `null` .
734
731
Type ? promotedType (Variable variable);
@@ -1225,13 +1222,18 @@ class FlowAnalysisDebug<Node extends Object, Statement extends Node,
1225
1222
@override
1226
1223
void initialize (
1227
1224
Variable variable, Type initializerType, Expression initializerExpression,
1228
- {required bool isFinal, required bool isLate}) {
1225
+ {required bool isFinal,
1226
+ required bool isLate,
1227
+ required bool isImplicitlyTyped}) {
1229
1228
_wrap (
1230
1229
'initialize($variable , $initializerType , $initializerExpression , '
1231
- 'isFinal: $isFinal , isLate: $isLate )' ,
1230
+ 'isFinal: $isFinal , isLate: $isLate , '
1231
+ 'isImplicitlyTyped: $isImplicitlyTyped )' ,
1232
1232
() => _wrapped.initialize (
1233
1233
variable, initializerType, initializerExpression,
1234
- isFinal: isFinal, isLate: isLate));
1234
+ isFinal: isFinal,
1235
+ isLate: isLate,
1236
+ isImplicitlyTyped: isImplicitlyTyped));
1235
1237
}
1236
1238
1237
1239
@override
@@ -1340,11 +1342,6 @@ class FlowAnalysisDebug<Node extends Object, Statement extends Node,
1340
1342
_wrapped.parenthesizedExpression (outerExpression, innerExpression));
1341
1343
}
1342
1344
1343
- @override
1344
- void promote (Variable variable, Type type) {
1345
- _wrap ('promote($variable , $type ' , () => _wrapped.promote (variable, type));
1346
- }
1347
-
1348
1345
@override
1349
1346
Type ? promotedType (Variable variable) {
1350
1347
return _wrap (
@@ -2059,12 +2056,14 @@ class FlowModel<Variable extends Object, Type extends Object> {
2059
2056
Variable variable,
2060
2057
Type writtenType,
2061
2058
SsaNode <Variable , Type > newSsaNode,
2062
- TypeOperations <Variable , Type > typeOperations) {
2059
+ TypeOperations <Variable , Type > typeOperations,
2060
+ {bool promoteToTypeOfInterest = true }) {
2063
2061
VariableModel <Variable , Type >? infoForVar = variableInfo[variable];
2064
2062
if (infoForVar == null ) return this ;
2065
2063
2066
2064
VariableModel <Variable , Type > newInfoForVar = infoForVar.write (
2067
- nonPromotionReason, variable, writtenType, typeOperations, newSsaNode);
2065
+ nonPromotionReason, variable, writtenType, typeOperations, newSsaNode,
2066
+ promoteToTypeOfInterest: promoteToTypeOfInterest);
2068
2067
if (identical (newInfoForVar, infoForVar)) return this ;
2069
2068
2070
2069
return _updateVariableInfo (new VariableReference (variable), newInfoForVar);
@@ -2663,6 +2662,9 @@ abstract class TypeOperations<Variable extends Object, Type extends Object> {
2663
2662
/// Return `true` if the [leftType] is a subtype of the [rightType] .
2664
2663
bool isSubtypeOf (Type leftType, Type rightType);
2665
2664
2665
+ /// Returns `true` if [type] is a reference to a type parameter.
2666
+ bool isTypeParameterType (Type type);
2667
+
2666
2668
/// Returns the non-null promoted version of [type] .
2667
2669
///
2668
2670
/// Note that some types don't have a non-nullable version (e.g.
@@ -2819,7 +2821,8 @@ class VariableModel<Variable extends Object, Type extends Object> {
2819
2821
Variable variable,
2820
2822
Type writtenType,
2821
2823
TypeOperations <Variable , Type > typeOperations,
2822
- SsaNode <Variable , Type > newSsaNode) {
2824
+ SsaNode <Variable , Type > newSsaNode,
2825
+ {required bool promoteToTypeOfInterest}) {
2823
2826
if (writeCaptured) {
2824
2827
return new VariableModel <Variable , Type >(
2825
2828
promotedTypes: promotedTypes,
@@ -2834,8 +2837,10 @@ class VariableModel<Variable extends Object, Type extends Object> {
2834
2837
List <Type >? newPromotedTypes = demotionResult.promotedTypes;
2835
2838
2836
2839
Type declaredType = typeOperations.variableType (variable);
2837
- newPromotedTypes = _tryPromoteToTypeOfInterest (
2838
- typeOperations, declaredType, newPromotedTypes, writtenType);
2840
+ if (promoteToTypeOfInterest) {
2841
+ newPromotedTypes = _tryPromoteToTypeOfInterest (
2842
+ typeOperations, declaredType, newPromotedTypes, writtenType);
2843
+ }
2839
2844
// TODO(paulberry): remove demotions from demotionResult.nonPromotionHistory
2840
2845
// that are no longer in effect due to re-promotion.
2841
2846
if (identical (promotedTypes, newPromotedTypes) && assigned) {
@@ -3798,21 +3803,37 @@ class _FlowAnalysisImpl<Node extends Object, Statement extends Node,
3798
3803
@override
3799
3804
void initialize (
3800
3805
Variable variable, Type initializerType, Expression initializerExpression,
3801
- {required bool isFinal, required bool isLate}) {
3802
- ExpressionInfo <Variable , Type >? expressionInfo =
3803
- _getExpressionInfo (initializerExpression);
3804
- SsaNode <Variable , Type > newSsaNode = new SsaNode <Variable , Type >(isLate
3805
- ? null
3806
- : expressionInfo is _TrivialExpressionInfo
3807
- ? null
3808
- : expressionInfo);
3809
- if (isFinal) {
3810
- // We don't promote final variables on initialization, so pretend the
3811
- // written type is the variable's declared type.
3812
- initializerType = typeOperations.variableType (variable);
3806
+ {required bool isFinal,
3807
+ required bool isLate,
3808
+ required bool isImplicitlyTyped}) {
3809
+ ExpressionInfo <Variable , Type >? expressionInfo;
3810
+ if (isLate) {
3811
+ // Don't get expression info for late variables, since we don't know when
3812
+ // they'll be initialized.
3813
+ } else if (isImplicitlyTyped) {
3814
+ // We don't get expression info for implicitly typed variables yet (bug
3815
+ // https://github.com/dart-lang/language/issues/1785).
3816
+ // TODO(paulberry): fix this.
3817
+ } else {
3818
+ expressionInfo = _getExpressionInfo (initializerExpression);
3813
3819
}
3820
+ SsaNode <Variable , Type > newSsaNode = new SsaNode <Variable , Type >(
3821
+ expressionInfo is _TrivialExpressionInfo ? null : expressionInfo);
3814
3822
_current = _current.write (
3815
- null , variable, initializerType, newSsaNode, typeOperations);
3823
+ null , variable, initializerType, newSsaNode, typeOperations,
3824
+ promoteToTypeOfInterest: ! isImplicitlyTyped && ! isFinal);
3825
+ if (isImplicitlyTyped &&
3826
+ typeOperations.isTypeParameterType (initializerType)) {
3827
+ _current = _current
3828
+ .tryPromoteForTypeCheck (
3829
+ typeOperations,
3830
+ new ReferenceWithType <Variable , Type >(
3831
+ new VariableReference <Variable , Type >(variable),
3832
+ promotedType (variable) ??
3833
+ typeOperations.variableType (variable)),
3834
+ initializerType)
3835
+ .ifTrue;
3836
+ }
3816
3837
}
3817
3838
3818
3839
@override
@@ -3957,19 +3978,6 @@ class _FlowAnalysisImpl<Node extends Object, Statement extends Node,
3957
3978
forwardExpression (outerExpression, innerExpression);
3958
3979
}
3959
3980
3960
- @override
3961
- void promote (Variable variable, Type type) {
3962
- _current = _current
3963
- .tryPromoteForTypeCheck (
3964
- typeOperations,
3965
- new ReferenceWithType <Variable , Type >(
3966
- new VariableReference <Variable , Type >(variable),
3967
- promotedType (variable) ??
3968
- typeOperations.variableType (variable)),
3969
- type)
3970
- .ifTrue;
3971
- }
3972
-
3973
3981
@override
3974
3982
Type ? promotedType (Variable variable) {
3975
3983
return _current.infoFor (variable).promotedTypes? .last;
@@ -4544,7 +4552,9 @@ class _LegacyTypePromotion<Node extends Object, Statement extends Node,
4544
4552
@override
4545
4553
void initialize (
4546
4554
Variable variable, Type initializerType, Expression initializerExpression,
4547
- {required bool isFinal, required bool isLate}) {}
4555
+ {required bool isFinal,
4556
+ required bool isLate,
4557
+ required bool isImplicitlyTyped}) {}
4548
4558
4549
4559
@override
4550
4560
bool isAssigned (Variable variable) {
@@ -4703,11 +4713,6 @@ class _LegacyTypePromotion<Node extends Object, Statement extends Node,
4703
4713
forwardExpression (outerExpression, innerExpression);
4704
4714
}
4705
4715
4706
- @override
4707
- void promote (Variable variable, Type type) {
4708
- throw new UnimplementedError ('TODO(paulberry)' );
4709
- }
4710
-
4711
4716
@override
4712
4717
Type ? promotedType (Variable variable) {
4713
4718
return _knownTypes[variable];
0 commit comments