@@ -1990,8 +1990,10 @@ class FailureDiagnosis :public ASTVisitor<FailureDiagnosis, /*exprresult*/bool>{
1990
1990
TCCOptions options = TCCOptions(),
1991
1991
ExprTypeCheckListener *listener = nullptr,
1992
1992
bool allowFreeTypeVariables = true);
1993
- Expr *typeCheckChildIndependently (Expr *subExpr, TCCOptions options) {
1994
- return typeCheckChildIndependently (subExpr, Type (), CTP_Unused, options);
1993
+ Expr *typeCheckChildIndependently (Expr *subExpr, TCCOptions options,
1994
+ bool allowFreeTypeVariables = true ) {
1995
+ return typeCheckChildIndependently (subExpr, Type (), CTP_Unused, options,
1996
+ nullptr , allowFreeTypeVariables);
1995
1997
}
1996
1998
1997
1999
Type getTypeOfTypeCheckedChildIndependently (Expr *subExpr,
@@ -6052,13 +6054,21 @@ bool FailureDiagnosis::visitAssignExpr(AssignExpr *assignExpr) {
6052
6054
6053
6055
auto destType = destExpr->getType ();
6054
6056
if (destType->is <UnresolvedType>() || destType->hasTypeVariable ()) {
6055
- // If we have no useful type information from the destination, just type
6057
+ // Look closer into why destination has unresolved types since such
6058
+ // means that destination has diagnosible structural problems, and it's
6059
+ // better to diagnose destination (if possible) before moving on to
6060
+ // the source of the assignment.
6061
+ destExpr = typeCheckChildIndependently (
6062
+ destExpr, TCC_AllowLValue | TCC_ForceRecheck, false );
6063
+ if (!destExpr)
6064
+ return true ;
6065
+
6066
+ // If re-checking destination didn't produce diagnostic, let's just type
6056
6067
// check the source without contextual information. If it succeeds, then we
6057
6068
// win, but if it fails, we'll have to diagnose this another way.
6058
6069
return !typeCheckChildIndependently (assignExpr->getSrc ());
6059
6070
}
6060
-
6061
-
6071
+
6062
6072
// If the result type is a non-lvalue, then we are failing because it is
6063
6073
// immutable and that's not a great thing to assign to.
6064
6074
if (!destType->isLValueType ()) {
0 commit comments