Index: pkg/analyzer/lib/src/task/strong/checker.dart |
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart |
index d0b55fed93a80bdca1f0ba935f98e22dae82274d..245443683ee7574c5b5325a891233bd9eccb1c96 100644 |
--- a/pkg/analyzer/lib/src/task/strong/checker.dart |
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart |
@@ -186,9 +186,7 @@ class CodeChecker extends RecursiveAstVisitor { |
// so no need to insert an error for this here. |
continue; |
} |
- DartType expectedType = _elementType(element); |
- if (expectedType == null) expectedType = DynamicTypeImpl.instance; |
- checkArgument(arg, expectedType); |
+ checkArgument(arg, _elementType(element)); |
} |
} |
@@ -701,34 +699,28 @@ class CodeChecker extends RecursiveAstVisitor { |
assert(functionType.namedParameterTypes.isEmpty); |
assert(functionType.optionalParameterTypes.isEmpty); |
- // Check the LHS type. |
+ // Refine the return type. |
var rhsType = _getDefiniteType(expr.rightHandSide); |
var lhsType = _getDefiniteType(expr.leftHandSide); |
var returnType = rules.refineBinaryExpressionType( |
typeProvider, lhsType, op, rhsType, functionType.returnType); |
- if (!rules.isSubtypeOf(returnType, lhsType)) { |
- final numType = typeProvider.numType; |
- // TODO(jmesserly): this seems to duplicate logic in StaticTypeAnalyzer. |
- // Try to fix up the numerical case if possible. |
- if (rules.isSubtypeOf(lhsType, numType) && |
- rules.isSubtypeOf(lhsType, rhsType)) { |
- // This is also slightly different from spec, but allows us to keep |
- // compound operators in the int += num and num += dynamic cases. |
- _recordImplicitCast(expr.rightHandSide, rhsType, lhsType); |
- } else { |
- // TODO(jmesserly): this results in a duplicate error, because |
- // ErrorVerifier also reports it. |
- _recordMessage(expr, StrongModeCode.STATIC_TYPE_ERROR, |
- [expr, returnType, lhsType]); |
- } |
- } else { |
- // Check the RHS type. |
- // |
- // This is only needed if we didn't already need a cast, and avoids |
- // emitting two messages for the same expression. |
- _checkDowncast(expr.rightHandSide, paramTypes.first); |
- } |
+ // Check the argument for an implicit cast. |
+ _checkDowncast(expr.rightHandSide, paramTypes[0], from: rhsType); |
Jennifer Messerly
2016/08/25 22:27:15
this is my attempt to fix by simplification :)
Leaf
2016/08/25 22:35:34
:)
|
+ |
+ // Check the return type for an implicit cast. |
+ // |
+ // If needed, mark the left size to indicate a down cast when we assign |
Leaf
2016/08/25 22:35:34
size -> side?
|
+ // back to it. so these two implicit casts are equivalent: |
+ // |
+ // y = /*implicit cast*/(y + 42); |
+ // y/*implicit cast*/ += 42; |
+ // |
+ // TODO(jmesserly): this is an unambiguous way to represent it, but it's |
Jennifer Messerly
2016/08/25 22:27:15
https://github.com/dart-lang/dev_compiler/issues/6
|
+ // a bit sneaky. We can't use the rightHandSide because that could be a |
+ // downcast on its own, and we can't use the entire expression because its |
+ // result value could used and then implicitly downcast. |
+ _checkDowncast(expr.leftHandSide, lhsType, from: returnType); |
} |
} |