Skip to content

Commit 9924719

Browse files
[CSFix] Creating fix for diagnose missing unwrap of optional base type on key path application
1 parent f4f44d2 commit 9924719

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

lib/Sema/CSFix.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,3 +1508,36 @@ bool SpecifyKeyPathRootType::diagnose(const Solution &solution,
15081508

15091509
return failure.diagnose(asNote);
15101510
}
1511+
1512+
bool UnwrapOptionalBaseKeyPathApplication::diagnose(const Solution &solution,
1513+
bool asNote) const {
1514+
MissingOptionalUnwrapKeyPathFailure failure(solution, getFromType(),
1515+
getToType(), getLocator());
1516+
return failure.diagnose(asNote);
1517+
}
1518+
1519+
UnwrapOptionalBaseKeyPathApplication *
1520+
UnwrapOptionalBaseKeyPathApplication::attempt(ConstraintSystem &cs, Type baseTy,
1521+
Type rootTy,
1522+
ConstraintLocator *locator) {
1523+
if(baseTy->hasTypeVariable() || rootTy->hasTypeVariable())
1524+
return nullptr;
1525+
1526+
if (!isExpr<SubscriptExpr>(locator->getAnchor()))
1527+
return nullptr;
1528+
1529+
// Only diagnose this if base is an optional type and we only have a
1530+
// single level of optionality so we can safely suggest unwrapping.
1531+
auto nonOptionalTy = baseTy->getOptionalObjectType();
1532+
if (!nonOptionalTy || nonOptionalTy->getOptionalObjectType())
1533+
return nullptr;
1534+
1535+
auto result =
1536+
cs.matchTypes(nonOptionalTy, rootTy, ConstraintKind::Subtype,
1537+
ConstraintSystem::TypeMatchFlags::TMF_ApplyingFix, locator);
1538+
if (result.isFailure())
1539+
return nullptr;
1540+
1541+
return new (cs.getAllocator())
1542+
UnwrapOptionalBaseKeyPathApplication(cs, baseTy, rootTy, locator);
1543+
}

lib/Sema/CSFix.h

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,9 @@ enum class FixKind : uint8_t {
268268

269269
/// Specify key path root type when it cannot be infered from context.
270270
SpecifyKeyPathRootType,
271-
271+
272+
/// Unwrap optional base on key path application.
273+
UnwrapOptionalBaseKeyPathApplication,
272274
};
273275

274276
class ConstraintFix {
@@ -1918,6 +1920,32 @@ class SpecifyKeyPathRootType final : public ConstraintFix {
19181920
ConstraintLocator *locator);
19191921
};
19201922

1923+
/// Diagnose missing unwrap of optional base type on key path application.
1924+
///
1925+
/// \code
1926+
/// func f(_ bar: Bar? , keyPath: KeyPath<Bar, Int>) {
1927+
/// bar[keyPath: keyPath]
1928+
/// }
1929+
/// \endcode
1930+
class UnwrapOptionalBaseKeyPathApplication final : public ContextualMismatch {
1931+
protected:
1932+
UnwrapOptionalBaseKeyPathApplication(ConstraintSystem &cs, Type lhs, Type rhs,
1933+
ConstraintLocator *locator)
1934+
: ContextualMismatch(cs, FixKind::UnwrapOptionalBaseKeyPathApplication,
1935+
lhs, rhs, locator) {}
1936+
1937+
public:
1938+
std::string getName() const override {
1939+
return "force unwrap base on key path application";
1940+
}
1941+
1942+
bool diagnose(const Solution &solution, bool asNote = false) const override;
1943+
1944+
static UnwrapOptionalBaseKeyPathApplication *
1945+
attempt(ConstraintSystem &cs, Type baseTy, Type rootTy,
1946+
ConstraintLocator *locator);
1947+
};
1948+
19211949
} // end namespace constraints
19221950
} // end namespace swift
19231951

0 commit comments

Comments
 (0)