@@ -530,42 +530,50 @@ bool MissingOptionalUnwrapFailure::diagnose() {
530
530
}
531
531
532
532
bool RValueTreatedAsLValueFailure::diagnose () {
533
- if (auto callExpr = dyn_cast<ApplyExpr>(getAnchor ())) {
534
- Expr *argExpr = callExpr->getArg ();
535
-
536
- Diag<StringRef> subElementDiagID;
537
- Diag<Type> rvalueDiagID;
538
- Expr *diagExpr = nullptr ;
539
-
540
- if (isa<PrefixUnaryExpr>(callExpr) || isa<PostfixUnaryExpr>(callExpr)) {
541
- subElementDiagID = diag::cannot_apply_lvalue_unop_to_subelement;
542
- rvalueDiagID = diag::cannot_apply_lvalue_unop_to_rvalue;
543
- diagExpr = argExpr;
544
- } else if (isa<BinaryExpr>(callExpr)) {
545
- subElementDiagID = diag::cannot_apply_lvalue_binop_to_subelement;
546
- rvalueDiagID = diag::cannot_apply_lvalue_binop_to_rvalue;
547
- auto argTuple = dyn_cast<TupleExpr>(argExpr);
548
- diagExpr = argTuple->getElement (0 );
549
- } else {
550
- auto lastPathElement = getLocator ()->getPath ().back ();
551
- assert (lastPathElement.getKind () == ConstraintLocator::PathElementKind::ApplyArgToParam);
552
-
553
- subElementDiagID = diag::cannot_pass_rvalue_inout_subelement;
554
- rvalueDiagID = diag::cannot_pass_rvalue_inout;
555
- if (auto argTuple = dyn_cast<TupleExpr>(argExpr))
556
- diagExpr = argTuple->getElement (lastPathElement.getValue ());
557
- else if (auto parens = dyn_cast<ParenExpr>(argExpr))
558
- diagExpr = parens->getSubExpr ();
559
- }
533
+ Diag<StringRef> subElementDiagID;
534
+ Diag<Type> rvalueDiagID;
535
+ Expr *diagExpr = getLocator ()->getAnchor ();
536
+ SourceLoc loc;
537
+
538
+ auto callExpr = dyn_cast<ApplyExpr>(diagExpr);
539
+ if (!callExpr)
540
+ return false ; // currently only creating these for args, so should be
541
+ // unreachable
542
+
543
+ Expr *argExpr = callExpr->getArg ();
544
+ loc = callExpr->getFn ()->getLoc ();
545
+
546
+ if (isa<PrefixUnaryExpr>(callExpr) || isa<PostfixUnaryExpr>(callExpr)) {
547
+ subElementDiagID = diag::cannot_apply_lvalue_unop_to_subelement;
548
+ rvalueDiagID = diag::cannot_apply_lvalue_unop_to_rvalue;
549
+ diagExpr = argExpr;
550
+ } else if (isa<BinaryExpr>(callExpr)) {
551
+ subElementDiagID = diag::cannot_apply_lvalue_binop_to_subelement;
552
+ rvalueDiagID = diag::cannot_apply_lvalue_binop_to_rvalue;
553
+ auto argTuple = dyn_cast<TupleExpr>(argExpr);
554
+ diagExpr = argTuple->getElement (0 );
555
+ } else {
556
+ auto lastPathElement = getLocator ()->getPath ().back ();
557
+ assert (lastPathElement.getKind () ==
558
+ ConstraintLocator::PathElementKind::ApplyArgToParam);
559
+
560
+ subElementDiagID = diag::cannot_pass_rvalue_inout_subelement;
561
+ rvalueDiagID = diag::cannot_pass_rvalue_inout;
562
+ if (auto argTuple = dyn_cast<TupleExpr>(argExpr))
563
+ diagExpr = argTuple->getElement (lastPathElement.getValue ());
564
+ else if (auto parens = dyn_cast<ParenExpr>(argExpr))
565
+ diagExpr = parens->getSubExpr ();
566
+ }
560
567
561
- // FIXME: Would like for this to be unnecessary.
562
- getConstraintSystem ().TC .typeCheckExpression (diagExpr, getConstraintSystem ().DC );
568
+ // FIXME: Needed right now to apply correct overload choices to diagExpr for
569
+ // use by diagnoseSubElementFailure(). Once all callers are routed through
570
+ // here, that function can be rewritten to take the current Solution and use
571
+ // it for determining chosen decl bindings instead, making this extra
572
+ // typecheck unnecessary.
573
+ getConstraintSystem ().TC .typeCheckExpression (diagExpr,
574
+ getConstraintSystem ().DC );
563
575
564
- diagnoseSubElementFailure (diagExpr, callExpr->getFn ()->getLoc (),
565
- getConstraintSystem (),
566
- subElementDiagID, rvalueDiagID);
567
- return true ;
568
- }
569
- // These fixes are only being created for matching arg types right now, so this is unreachable.
570
- return false ;
576
+ diagnoseSubElementFailure (diagExpr, loc, getConstraintSystem (),
577
+ subElementDiagID, rvalueDiagID);
578
+ return true ;
571
579
}
0 commit comments