Skip to content

Commit 38a6cfa

Browse files
committed
[CSDiagnostic] Convert force optional unwrap diagnostic into a contextual one
Record both sides of conversion where a form of force unwrap is necessary to be able to produce tailored diagnostics such as for an attempt to use optional type as a boolean.
1 parent bdeaced commit 38a6cfa

File tree

2 files changed

+31
-29
lines changed

2 files changed

+31
-29
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,11 @@ bool MissingOptionalUnwrapFailure::diagnoseAsError() {
12161216
if (hasComplexLocator())
12171217
return false;
12181218

1219+
if (!getUnwrappedType()->isBool()) {
1220+
if (diagnoseConversionToBool())
1221+
return true;
1222+
}
1223+
12191224
auto *anchor = getAnchor();
12201225

12211226
// If this is an unresolved member expr e.g. `.foo` its

lib/Sema/CSDiagnostics.h

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -631,35 +631,6 @@ class MemberAccessOnOptionalBaseFailure final : public FailureDiagnostic {
631631
bool diagnoseAsError() override;
632632
};
633633

634-
/// Diagnose failures related to use of the unwrapped optional types,
635-
/// which require some type of force-unwrap e.g. "!" or "try!".
636-
class MissingOptionalUnwrapFailure final : public FailureDiagnostic {
637-
Type BaseType;
638-
Type UnwrappedType;
639-
640-
public:
641-
MissingOptionalUnwrapFailure(ConstraintSystem &cs, Type baseType,
642-
Type unwrappedType, ConstraintLocator *locator)
643-
: FailureDiagnostic(cs, locator), BaseType(baseType),
644-
UnwrappedType(unwrappedType) {}
645-
646-
bool diagnoseAsError() override;
647-
648-
private:
649-
Type getBaseType() const {
650-
return resolveType(BaseType, /*reconstituteSugar=*/true);
651-
}
652-
653-
Type getUnwrappedType() const {
654-
return resolveType(UnwrappedType, /*reconstituteSugar=*/true);
655-
}
656-
657-
/// Suggest a default value via `?? <default value>`
658-
void offerDefaultValueUnwrapFixIt(DeclContext *DC, Expr *expr) const;
659-
/// Suggest a force optional unwrap via `!`
660-
void offerForceUnwrapFixIt(Expr *expr) const;
661-
};
662-
663634
/// Diagnose errors associated with rvalues in positions
664635
/// where an lvalue is required, such as inout arguments.
665636
class RValueTreatedAsLValueFailure final : public FailureDiagnostic {
@@ -852,6 +823,32 @@ class ContextualFailure : public FailureDiagnostic {
852823
getDiagnosticFor(ContextualTypePurpose context, bool forProtocol);
853824
};
854825

826+
/// Diagnose failures related to use of the unwrapped optional types,
827+
/// which require some type of force-unwrap e.g. "!" or "try!".
828+
class MissingOptionalUnwrapFailure final : public ContextualFailure {
829+
public:
830+
MissingOptionalUnwrapFailure(ConstraintSystem &cs, Type fromType, Type toType,
831+
ConstraintLocator *locator)
832+
: ContextualFailure(cs, fromType, toType, locator) {}
833+
834+
bool diagnoseAsError() override;
835+
836+
private:
837+
Type getBaseType() const {
838+
return resolveType(getFromType(), /*reconstituteSugar=*/true);
839+
}
840+
841+
Type getUnwrappedType() const {
842+
return resolveType(getBaseType()->getOptionalObjectType(),
843+
/*reconstituteSugar=*/true);
844+
}
845+
846+
/// Suggest a default value via `?? <default value>`
847+
void offerDefaultValueUnwrapFixIt(DeclContext *DC, Expr *expr) const;
848+
/// Suggest a force optional unwrap via `!`
849+
void offerForceUnwrapFixIt(Expr *expr) const;
850+
};
851+
855852
/// Diagnostics for mismatched generic arguments e.g
856853
/// ```swift
857854
/// struct F<G> {}

0 commit comments

Comments
 (0)