Teach TypeMember constraints to suggest force unwrapping optionals, the same way

value member constraints do.

This fixes:
<rdar://problem/21662365> QoI: diagnostic for for-each over an optional sequence isn't great

before we'd produce:
t.swift:3:10: error: '[Int]?' does not have a member named 'Generator'
for x in array {
         ^

now we produce:

t.swift:3:10: error: value of optional type '[Int]?' not unwrapped; did you mean to use '!' or '?'?
for x in array {
         ^



Swift SVN r29902
This commit is contained in:
Chris Lattner
2015-07-02 23:25:08 +00:00
parent 35e55940ca
commit 612a41278a
4 changed files with 36 additions and 0 deletions

View File

@@ -2981,6 +2981,25 @@ ConstraintSystem::simplifyMemberConstraint(const Constraint &constraint) {
auto lookup = TC.lookupMemberType(DC, baseObjTy, name.getBaseName(),
lookupOptions);
if (!lookup) {
// If the base type was an optional, try to look through it.
if (shouldAttemptFixes() && baseObjTy->getOptionalObjectType()) {
// Note the fix.
increaseScore(SK_Fix);
if (worseThanBestSolution())
return SolutionKind::Error;
Fixes.push_back({FixKind::ForceOptional, constraint.getLocator()});
// Look through one level of optional.
addConstraint(Constraint::create(*this, ConstraintKind::TypeMember,
baseObjTy->getOptionalObjectType(),
constraint.getSecondType(),
constraint.getMember(),
constraint.getLocator()));
return SolutionKind::Solved;
}
// FIXME: Customize diagnostic to mention types.
recordFailure(constraint.getLocator(), Failure::DoesNotHaveMember,
baseObjTy, name);