Chromium Code Reviews| 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); |
| } |
| } |