@@ -3672,12 +3672,12 @@ checkImplicitPromotionsInCondition(const StmtConditionElement &cond,
3672
3672
}
3673
3673
}
3674
3674
3675
- static void diagnoseOptionalToAnyCoercion (TypeChecker &TC, const Expr *E,
3676
- const DeclContext *DC) {
3675
+ static void diagnoseUnintendedOptionalBehavior (TypeChecker &TC, const Expr *E,
3676
+ const DeclContext *DC) {
3677
3677
if (!E || isa<ErrorExpr>(E) || !E->getType ())
3678
3678
return ;
3679
3679
3680
- class OptionalToAnyCoercionWalker : public ASTWalker {
3680
+ class UnintendedOptionalBehaviorWalker : public ASTWalker {
3681
3681
TypeChecker &TC;
3682
3682
SmallPtrSet<Expr *, 4 > ErasureCoercedToAny;
3683
3683
@@ -3711,37 +3711,45 @@ static void diagnoseOptionalToAnyCoercion(TypeChecker &TC, const Expr *E,
3711
3711
// Warn about interpolated segments that contain optionals.
3712
3712
for (auto &segment : literal->getSegments ()) {
3713
3713
// Allow explicit casts.
3714
- if (isa<ExplicitCastExpr>(segment)) {
3715
- continue ;
3714
+ if (auto paren = dyn_cast<ParenExpr>(segment)) {
3715
+ if (isa<ExplicitCastExpr>(paren->getSubExpr ())) {
3716
+ continue ;
3717
+ }
3716
3718
}
3717
3719
3718
- auto segmentTy = segment->getType ();
3719
- if (segmentTy && !segmentTy->getOptionalObjectType ().isNull ()) {
3720
- TC.diagnose (segment->getStartLoc (),
3721
- diag::optional_in_string_interpolation_segment)
3722
- .highlight (segment->getSourceRange ());
3723
-
3724
- TC.diagnose (segment->getLoc (),
3725
- diag::silence_optional_in_interpolation_segment)
3726
- .highlight (segment->getSourceRange ())
3727
- .fixItInsertAfter (segment->getEndLoc (), " .debugDescription" );
3728
- TC.diagnose (segment->getLoc (), diag::default_optional_to_any)
3729
- .highlight (segment->getSourceRange ())
3730
- .fixItInsertAfter (segment->getEndLoc (), " ?? <#default value#>" );
3731
- TC.diagnose (segment->getLoc (), diag::force_optional_to_any)
3732
- .highlight (segment->getSourceRange ())
3733
- .fixItInsertAfter (segment->getEndLoc (), " !" );
3720
+ // Bail out if we don't have an optional.
3721
+ auto objectTy = segment->getType ()->getOptionalObjectType ();
3722
+ if (!objectTy) {
3723
+ continue ;
3734
3724
}
3725
+ auto segmentTy = OptionalType::get (objectTy);
3726
+
3727
+ TC.diagnose (segment->getStartLoc (),
3728
+ diag::optional_in_string_interpolation_segment)
3729
+ .highlight (segment->getSourceRange ());
3730
+
3731
+ TC.diagnose (segment->getLoc (),
3732
+ diag::silence_optional_in_interpolation_segment_call)
3733
+ .highlight (segment->getSourceRange ())
3734
+ .fixItInsert (segment->getEndLoc (), " .debugDescription" );
3735
+
3736
+ auto opts = PrintOptions::printForDiagnostics ();
3737
+ TC.diagnose (segment->getLoc (),
3738
+ diag::silence_optional_in_interpolation_segment_cast,
3739
+ segmentTy)
3740
+ .highlight (segment->getSourceRange ())
3741
+ .fixItInsert (segment->getEndLoc (),
3742
+ " as " + segmentTy->getString (opts));
3735
3743
}
3736
3744
}
3737
3745
return { true , E };
3738
3746
}
3739
3747
3740
3748
public:
3741
- OptionalToAnyCoercionWalker (TypeChecker &tc) : TC(tc) { }
3749
+ UnintendedOptionalBehaviorWalker (TypeChecker &tc) : TC(tc) { }
3742
3750
};
3743
3751
3744
- OptionalToAnyCoercionWalker Walker (TC);
3752
+ UnintendedOptionalBehaviorWalker Walker (TC);
3745
3753
const_cast <Expr *>(E)->walk (Walker);
3746
3754
}
3747
3755
@@ -3757,7 +3765,7 @@ void swift::performSyntacticExprDiagnostics(TypeChecker &TC, const Expr *E,
3757
3765
diagSyntacticUseRestrictions (TC, E, DC, isExprStmt);
3758
3766
diagRecursivePropertyAccess (TC, E, DC);
3759
3767
diagnoseImplicitSelfUseInClosure (TC, E, DC);
3760
- diagnoseOptionalToAnyCoercion (TC, E, DC);
3768
+ diagnoseUnintendedOptionalBehavior (TC, E, DC);
3761
3769
if (!TC.getLangOpts ().DisableAvailabilityChecking )
3762
3770
diagAvailability (TC, E, const_cast <DeclContext*>(DC));
3763
3771
if (TC.Context .LangOpts .EnableObjCInterop )
0 commit comments