@@ -3593,7 +3593,55 @@ checkImplicitPromotionsInCondition(const StmtConditionElement &cond,
3593
3593
.highlight (subExpr->getSourceRange ());
3594
3594
}
3595
3595
}
3596
-
3596
+
3597
+ static void diagnoseOptionalToAnyCoercion (TypeChecker &TC, const Expr *E,
3598
+ const DeclContext *DC) {
3599
+ if (!E || isa<ErrorExpr>(E) || !E->getType ())
3600
+ return ;
3601
+
3602
+ class OptionalToAnyCoercionWalker : public ASTWalker {
3603
+ TypeChecker &TC;
3604
+ SmallPtrSet<Expr *, 4 > ErasureCoercedToAny;
3605
+
3606
+ virtual std::pair<bool , Expr *> walkToExprPre (Expr *E) {
3607
+ if (!E || isa<ErrorExpr>(E) || !E->getType ())
3608
+ return { false , E };
3609
+
3610
+ if (auto *coercion = dyn_cast<CoerceExpr>(E)) {
3611
+ if (E->getType ()->isAny () && isa<ErasureExpr>(coercion->getSubExpr ()))
3612
+ ErasureCoercedToAny.insert (coercion->getSubExpr ());
3613
+ } else if (isa<ErasureExpr>(E) && !ErasureCoercedToAny.count (E) &&
3614
+ E->getType ()->isAny ()) {
3615
+ auto subExpr = cast<ErasureExpr>(E)->getSubExpr ();
3616
+ auto erasedTy = subExpr->getType ();
3617
+ if (erasedTy->getOptionalObjectType ()) {
3618
+ TC.diagnose (subExpr->getStartLoc (), diag::optional_to_any_coercion,
3619
+ erasedTy)
3620
+ .highlight (subExpr->getSourceRange ());
3621
+
3622
+ TC.diagnose (subExpr->getLoc (), diag::default_optional_to_any)
3623
+ .highlight (subExpr->getSourceRange ())
3624
+ .fixItInsertAfter (subExpr->getEndLoc (), " ?? <#default value#>" );
3625
+ TC.diagnose (subExpr->getLoc (), diag::force_optional_to_any)
3626
+ .highlight (subExpr->getSourceRange ())
3627
+ .fixItInsertAfter (subExpr->getEndLoc (), " !" );
3628
+ TC.diagnose (subExpr->getLoc (), diag::silence_optional_to_any)
3629
+ .highlight (subExpr->getSourceRange ())
3630
+ .fixItInsertAfter (subExpr->getEndLoc (), " as Any" );
3631
+ }
3632
+ }
3633
+
3634
+ return { true , E };
3635
+ }
3636
+
3637
+ public:
3638
+ OptionalToAnyCoercionWalker (TypeChecker &tc) : TC(tc) { }
3639
+ };
3640
+
3641
+ OptionalToAnyCoercionWalker Walker (TC);
3642
+ const_cast <Expr *>(E)->walk (Walker);
3643
+ }
3644
+
3597
3645
// ===----------------------------------------------------------------------===//
3598
3646
// High-level entry points.
3599
3647
// ===----------------------------------------------------------------------===//
@@ -3606,6 +3654,7 @@ void swift::performSyntacticExprDiagnostics(TypeChecker &TC, const Expr *E,
3606
3654
diagSyntacticUseRestrictions (TC, E, DC, isExprStmt);
3607
3655
diagRecursivePropertyAccess (TC, E, DC);
3608
3656
diagnoseImplicitSelfUseInClosure (TC, E, DC);
3657
+ diagnoseOptionalToAnyCoercion (TC, E, DC);
3609
3658
if (!TC.getLangOpts ().DisableAvailabilityChecking )
3610
3659
diagAvailability (TC, E, const_cast <DeclContext*>(DC));
3611
3660
if (TC.Context .LangOpts .EnableObjCInterop )
0 commit comments