@@ -549,16 +549,16 @@ bool MemberAccessOnOptionalBaseFailure::diagnoseAsError() {
549
549
resultIsOptional, SourceRange ());
550
550
}
551
551
552
- // Suggest a default value via ?? <default value>
553
- static void offerDefaultValueUnwrapFixit (TypeChecker &TC, DeclContext *DC, Expr *expr, Expr *rootExpr) {
554
- auto diag =
555
- TC.diagnose (expr->getLoc (), diag::unwrap_with_default_value);
552
+ void MissingOptionalUnwrapFailure::offerDefaultValueUnwrapFixIt (
553
+ DeclContext *DC, Expr *expr) const {
554
+ auto diag = emitDiagnostic (expr->getLoc (), diag::unwrap_with_default_value);
556
555
556
+ auto &TC = getTypeChecker ();
557
557
// Figure out what we need to parenthesize.
558
558
bool needsParensInside =
559
- exprNeedsParensBeforeAddingNilCoalescing (TC, DC, expr);
559
+ exprNeedsParensBeforeAddingNilCoalescing (TC, DC, expr);
560
560
bool needsParensOutside =
561
- exprNeedsParensAfterAddingNilCoalescing (TC, DC, expr, rootExpr );
561
+ exprNeedsParensAfterAddingNilCoalescing (TC, DC, expr, getParentExpr () );
562
562
563
563
llvm::SmallString<2 > insertBefore;
564
564
llvm::SmallString<32 > insertAfter;
@@ -580,8 +580,8 @@ static void offerDefaultValueUnwrapFixit(TypeChecker &TC, DeclContext *DC, Expr
580
580
}
581
581
582
582
// Suggest a force-unwrap.
583
- static void offerForceUnwrapFixit (ConstraintSystem &CS, Expr *expr) {
584
- auto diag = CS. TC . diagnose (expr->getLoc (), diag::unwrap_with_force_value);
583
+ void MissingOptionalUnwrapFailure::offerForceUnwrapFixIt ( Expr *expr) const {
584
+ auto diag = emitDiagnostic (expr->getLoc (), diag::unwrap_with_force_value);
585
585
586
586
// If expr is optional as the result of an optional chain and this last
587
587
// dot isn't a member returning optional, then offer to force the last
@@ -590,7 +590,7 @@ static void offerForceUnwrapFixit(ConstraintSystem &CS, Expr *expr) {
590
590
if (auto dotExpr =
591
591
dyn_cast<UnresolvedDotExpr>(optionalChain->getSubExpr ())) {
592
592
auto bind = dyn_cast<BindOptionalExpr>(dotExpr->getBase ());
593
- if (bind && !CS. getType (dotExpr)->getOptionalObjectType ()) {
593
+ if (bind && !getType (dotExpr)->getOptionalObjectType ()) {
594
594
diag.fixItReplace (SourceRange (bind->getLoc ()), " !" );
595
595
return ;
596
596
}
@@ -601,7 +601,7 @@ static void offerForceUnwrapFixit(ConstraintSystem &CS, Expr *expr) {
601
601
diag.fixItInsertAfter (expr->getEndLoc (), " !" );
602
602
} else {
603
603
diag.fixItInsert (expr->getStartLoc (), " (" )
604
- .fixItInsertAfter (expr->getEndLoc (), " )!" );
604
+ .fixItInsertAfter (expr->getEndLoc (), " )!" );
605
605
}
606
606
}
607
607
@@ -622,8 +622,38 @@ class VarDeclMultipleReferencesChecker : public ASTWalker {
622
622
int referencesCount () { return count; }
623
623
};
624
624
625
- static bool diagnoseUnwrap (ConstraintSystem &CS, Expr *expr, Expr *rootExpr, Type baseType,
626
- Type unwrappedType) {
625
+ bool MissingOptionalUnwrapFailure::diagnoseAsError () {
626
+ if (hasComplexLocator ())
627
+ return false ;
628
+
629
+ auto *anchor = getAnchor ();
630
+
631
+ if (auto assignExpr = dyn_cast<AssignExpr>(anchor))
632
+ anchor = assignExpr->getSrc ();
633
+
634
+ auto *unwrappedExpr = anchor->getValueProvidingExpr ();
635
+
636
+ if (auto *tryExpr = dyn_cast<OptionalTryExpr>(unwrappedExpr)) {
637
+ bool isSwift5OrGreater = getASTContext ().isSwiftVersionAtLeast (5 );
638
+ auto subExprType = getType (tryExpr->getSubExpr ());
639
+ bool subExpressionIsOptional = (bool )subExprType->getOptionalObjectType ();
640
+
641
+ if (isSwift5OrGreater && subExpressionIsOptional) {
642
+ // Using 'try!' won't change the type for a 'try?' with an optional
643
+ // sub-expr under Swift 5+, so just report that a missing unwrap can't be
644
+ // handled here.
645
+ return false ;
646
+ }
647
+
648
+ emitDiagnostic (tryExpr->getTryLoc (), diag::missing_unwrap_optional_try,
649
+ getType (anchor)->getRValueType ())
650
+ .fixItReplace ({tryExpr->getTryLoc (), tryExpr->getQuestionLoc ()},
651
+ " try!" );
652
+ return true ;
653
+ }
654
+
655
+ auto baseType = getBaseType ();
656
+ auto unwrappedType = getUnwrappedType ();
627
657
628
658
assert (!baseType->hasTypeVariable () &&
629
659
" Base type must not be a type variable" );
@@ -633,15 +663,14 @@ static bool diagnoseUnwrap(ConstraintSystem &CS, Expr *expr, Expr *rootExpr, Typ
633
663
if (!baseType->getOptionalObjectType ())
634
664
return false ;
635
665
636
- CS. TC . diagnose (expr ->getLoc (), diag::optional_not_unwrapped, baseType ,
637
- unwrappedType);
666
+ emitDiagnostic (unwrappedExpr ->getLoc (), diag::optional_not_unwrapped,
667
+ baseType, unwrappedType);
638
668
639
669
// If the expression we're unwrapping is the only reference to a
640
670
// local variable whose type isn't explicit in the source, then
641
671
// offer unwrapping fixits on the initializer as well.
642
- if (auto declRef = dyn_cast<DeclRefExpr>(expr )) {
672
+ if (auto declRef = dyn_cast<DeclRefExpr>(unwrappedExpr )) {
643
673
if (auto varDecl = dyn_cast<VarDecl>(declRef->getDecl ())) {
644
-
645
674
bool singleUse = false ;
646
675
AbstractFunctionDecl *AFD = nullptr ;
647
676
if (auto contextDecl = varDecl->getDeclContext ()->getAsDecl ()) {
@@ -658,69 +687,37 @@ static bool diagnoseUnwrap(ConstraintSystem &CS, Expr *expr, Expr *rootExpr, Typ
658
687
659
688
Expr *initializer = varDecl->getParentInitializer ();
660
689
if (auto declRefExpr = dyn_cast<DeclRefExpr>(initializer)) {
661
- if (declRefExpr->getDecl ()->getAttrs ().hasAttribute <ImplicitlyUnwrappedOptionalAttr>()) {
662
- CS.TC .diagnose (declRefExpr->getLoc (), diag::unwrap_iuo_initializer,
690
+ if (declRefExpr->getDecl ()
691
+ ->getAttrs ()
692
+ .hasAttribute <ImplicitlyUnwrappedOptionalAttr>()) {
693
+ emitDiagnostic (declRefExpr->getLoc (), diag::unwrap_iuo_initializer,
663
694
baseType);
664
695
}
665
696
}
666
697
667
698
auto fnTy = AFD->getInterfaceType ()->castTo <AnyFunctionType>();
668
- bool voidReturn = fnTy->getResult ()->isEqual (TupleType::getEmpty (CS.DC ->getASTContext ()));
699
+ bool voidReturn =
700
+ fnTy->getResult ()->isEqual (TupleType::getEmpty (getASTContext ()));
669
701
670
- auto diag = CS. TC . diagnose (varDecl->getLoc (), diag::unwrap_with_guard);
702
+ auto diag = emitDiagnostic (varDecl->getLoc (), diag::unwrap_with_guard);
671
703
diag.fixItInsert (binding->getStartLoc (), " guard " );
672
704
if (voidReturn) {
673
705
diag.fixItInsertAfter (binding->getEndLoc (), " else { return }" );
674
706
} else {
675
707
diag.fixItInsertAfter (binding->getEndLoc (), " else { return <"
676
- " #default value#" " > }" );
708
+ " #default value#"
709
+ " > }" );
677
710
}
678
711
diag.flush ();
679
712
680
- offerDefaultValueUnwrapFixit (CS.TC , varDecl->getDeclContext (),
681
- initializer, rootExpr);
682
- offerForceUnwrapFixit (CS, initializer);
713
+ offerDefaultValueUnwrapFixIt (varDecl->getDeclContext (), initializer);
714
+ offerForceUnwrapFixIt (initializer);
683
715
}
684
716
}
685
717
}
686
718
687
- offerDefaultValueUnwrapFixit (CS.TC , CS.DC , expr, rootExpr);
688
- offerForceUnwrapFixit (CS, expr);
689
- return true ;
690
- }
691
-
692
- bool MissingOptionalUnwrapFailure::diagnoseAsError () {
693
- if (hasComplexLocator ())
694
- return false ;
695
-
696
- auto *anchor = getAnchor ();
697
- auto *rootExpr = getParentExpr ();
698
-
699
- if (auto assignExpr = dyn_cast<AssignExpr>(anchor))
700
- anchor = assignExpr->getSrc ();
701
-
702
- auto *unwrapped = anchor->getValueProvidingExpr ();
703
- auto type = getType (anchor)->getRValueType ();
704
-
705
- auto *tryExpr = dyn_cast<OptionalTryExpr>(unwrapped);
706
- if (!tryExpr) {
707
- return diagnoseUnwrap (getConstraintSystem (), unwrapped, rootExpr, getBaseType (),
708
- getUnwrappedType ());
709
- }
710
-
711
- bool isSwift5OrGreater = getTypeChecker ().getLangOpts ().isSwiftVersionAtLeast (5 );
712
- auto subExprType = getType (tryExpr->getSubExpr ());
713
- bool subExpressionIsOptional = (bool )subExprType->getOptionalObjectType ();
714
-
715
-
716
- if (isSwift5OrGreater && subExpressionIsOptional) {
717
- // Using 'try!' won't change the type for a 'try?' with an optional sub-expr
718
- // under Swift 5+, so just report that a missing unwrap can't be handled here.
719
- return false ;
720
- }
721
-
722
- emitDiagnostic (tryExpr->getTryLoc (), diag::missing_unwrap_optional_try, type)
723
- .fixItReplace ({tryExpr->getTryLoc (), tryExpr->getQuestionLoc ()}, " try!" );
719
+ offerDefaultValueUnwrapFixIt (getDC (), unwrappedExpr);
720
+ offerForceUnwrapFixIt (unwrappedExpr);
724
721
return true ;
725
722
}
726
723
0 commit comments