@@ -3593,7 +3593,56 @@ checkImplicitPromotionsInCondition(const StmtConditionElement &cond,
35933593 .highlight (subExpr->getSourceRange ());
35943594 }
35953595}
3596-
3596+
3597+ static void diagnoseOptionalToAnyCoercion (TypeChecker &TC, const Expr *E,
3598+ const DeclContext *DC) {
3599+ if (E == nullptr || 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 ()->getDesugaredType ()->isAny () &&
3612+ isa<ErasureExpr>(coercion->getSubExpr ()))
3613+ ErasureCoercedToAny.insert (coercion->getSubExpr ());
3614+ } else if (isa<ErasureExpr>(E) && !ErasureCoercedToAny.count (E) &&
3615+ E->getType ()->getDesugaredType ()->isAny ()) {
3616+ auto subExpr = cast<ErasureExpr>(E)->getSubExpr ();
3617+ auto erasedTy = subExpr->getType ()->getDesugaredType ();
3618+ if (erasedTy->getOptionalObjectType ()) {
3619+ TC.diagnose (subExpr->getStartLoc (), diag::optional_to_any_coercion,
3620+ erasedTy)
3621+ .highlight (subExpr->getSourceRange ());
3622+
3623+ TC.diagnose (subExpr->getLoc (), diag::default_optional_to_any)
3624+ .highlight (subExpr->getSourceRange ())
3625+ .fixItInsertAfter (subExpr->getEndLoc (), " ?? <#default value#>" );
3626+ TC.diagnose (subExpr->getLoc (), diag::force_optional_to_any)
3627+ .highlight (subExpr->getSourceRange ())
3628+ .fixItInsertAfter (subExpr->getEndLoc (), " !" );
3629+ TC.diagnose (subExpr->getLoc (), diag::silence_optional_to_any)
3630+ .highlight (subExpr->getSourceRange ())
3631+ .fixItInsertAfter (subExpr->getEndLoc (), " as Any" );
3632+ }
3633+ }
3634+
3635+ return { true , E };
3636+ }
3637+
3638+ public:
3639+ OptionalToAnyCoercionWalker (TypeChecker &tc) : TC(tc) { }
3640+ };
3641+
3642+ OptionalToAnyCoercionWalker Walker (TC);
3643+ const_cast <Expr *>(E)->walk (Walker);
3644+ }
3645+
35973646// ===----------------------------------------------------------------------===//
35983647// High-level entry points.
35993648// ===----------------------------------------------------------------------===//
@@ -3606,6 +3655,7 @@ void swift::performSyntacticExprDiagnostics(TypeChecker &TC, const Expr *E,
36063655 diagSyntacticUseRestrictions (TC, E, DC, isExprStmt);
36073656 diagRecursivePropertyAccess (TC, E, DC);
36083657 diagnoseImplicitSelfUseInClosure (TC, E, DC);
3658+ diagnoseOptionalToAnyCoercion (TC, E, DC);
36093659 if (!TC.getLangOpts ().DisableAvailabilityChecking )
36103660 diagAvailability (TC, E, const_cast <DeclContext*>(DC));
36113661 if (TC.Context .LangOpts .EnableObjCInterop )
0 commit comments