Skip to content

Commit f623440

Browse files
committed
[CS] Disfavor solutions that were unable to infer the variable type inside a named pattern
We need this to resolve a test failure in optional.swift.
1 parent a7e0358 commit f623440

File tree

5 files changed

+67
-0
lines changed

5 files changed

+67
-0
lines changed

include/swift/Sema/CSFix.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,10 @@ enum class FixKind : uint8_t {
298298
/// Ignore `ErrorExpr` or `ErrorType` during pre-check.
299299
IgnoreInvalidASTNode,
300300

301+
/// Ignore a named pattern whose type we couldn't infer. This issue should
302+
/// already have been diagnosed elsewhere.
303+
IgnoreInvalidNamedPattern,
304+
301305
/// Resolve type of `nil` by providing a contextual type.
302306
SpecifyContextualTypeForNil,
303307

@@ -2742,6 +2746,31 @@ class IgnoreInvalidASTNode final : public ConstraintFix {
27422746
}
27432747
};
27442748

2749+
class IgnoreInvalidNamedPattern final : public ConstraintFix {
2750+
IgnoreInvalidNamedPattern(ConstraintSystem &cs, NamedPattern *pattern,
2751+
ConstraintLocator *locator)
2752+
: ConstraintFix(cs, FixKind::IgnoreInvalidNamedPattern, locator) {}
2753+
2754+
public:
2755+
std::string getName() const override {
2756+
return "specify type for pattern match";
2757+
}
2758+
2759+
bool diagnose(const Solution &solution, bool asNote = false) const override;
2760+
2761+
bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override {
2762+
return diagnose(*commonFixes.front().first);
2763+
}
2764+
2765+
static IgnoreInvalidNamedPattern *create(ConstraintSystem &cs,
2766+
NamedPattern *pattern,
2767+
ConstraintLocator *locator);
2768+
2769+
static bool classof(ConstraintFix *fix) {
2770+
return fix->getKind() == FixKind::IgnoreInvalidNamedPattern;
2771+
}
2772+
};
2773+
27452774
class SpecifyContextualTypeForNil final : public ConstraintFix {
27462775
SpecifyContextualTypeForNil(ConstraintSystem &cs,
27472776
ConstraintLocator *locator)

include/swift/Sema/ConstraintSystem.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,13 @@ T *getAsStmt(ASTNode node) {
640640
return nullptr;
641641
}
642642

643+
template <typename T = Pattern>
644+
T *getAsPattern(ASTNode node) {
645+
if (auto *P = node.dyn_cast<Pattern *>())
646+
return dyn_cast_or_null<T>(P);
647+
return nullptr;
648+
}
649+
643650
SourceLoc getLoc(ASTNode node);
644651
SourceRange getSourceRange(ASTNode node);
645652

lib/Sema/CSBindings.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1989,6 +1989,20 @@ TypeVariableBinding::fixForHole(ConstraintSystem &cs) const {
19891989
return std::make_pair(fix, /*impact=*/(unsigned)10);
19901990
}
19911991

1992+
if (auto pattern = getAsPattern<NamedPattern>(dstLocator->getAnchor())) {
1993+
if (dstLocator->getPath().size() == 1 &&
1994+
dstLocator->isLastElement<LocatorPathElt::NamedPatternDecl>()) {
1995+
// Not being able to infer the type of a variable in a pattern binding
1996+
// decl is more dramatic than anything that could happen inside the
1997+
// expression because we want to preferrably point the diagnostic to a
1998+
// part of the expression that caused us to be unable to infer the
1999+
// variable's type.
2000+
ConstraintFix *fix =
2001+
IgnoreInvalidNamedPattern::create(cs, pattern, dstLocator);
2002+
return std::make_pair(fix, /*impact=*/(unsigned)100);
2003+
}
2004+
}
2005+
19922006
return None;
19932007
}
19942008

lib/Sema/CSFix.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2004,6 +2004,20 @@ IgnoreResultBuilderWithReturnStmts::create(ConstraintSystem &cs, Type builderTy,
20042004
IgnoreResultBuilderWithReturnStmts(cs, builderTy, locator);
20052005
}
20062006

2007+
bool IgnoreInvalidNamedPattern::diagnose(const Solution &solution,
2008+
bool asNote) const {
2009+
// Not being able to infer the type of a pattern should already have been
2010+
// diagnosed on the pattern's initializer or as a structural issue of the AST.
2011+
return true;
2012+
}
2013+
2014+
IgnoreInvalidNamedPattern *
2015+
IgnoreInvalidNamedPattern::create(ConstraintSystem &cs, NamedPattern *pattern,
2016+
ConstraintLocator *locator) {
2017+
return new (cs.getAllocator())
2018+
IgnoreInvalidNamedPattern(cs, pattern, locator);
2019+
}
2020+
20072021
bool SpecifyBaseTypeForOptionalUnresolvedMember::diagnose(
20082022
const Solution &solution, bool asNote) const {
20092023
MemberMissingExplicitBaseTypeFailure failure(solution, MemberName,

lib/Sema/CSSimplify.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12941,6 +12941,9 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
1294112941
case FixKind::IgnoreInvalidASTNode: {
1294212942
return recordFix(fix, 10) ? SolutionKind::Error : SolutionKind::Solved;
1294312943
}
12944+
case FixKind::IgnoreInvalidNamedPattern: {
12945+
return recordFix(fix, 100) ? SolutionKind::Error : SolutionKind::Solved;
12946+
}
1294412947

1294512948
case FixKind::ExplicitlyConstructRawRepresentable: {
1294612949
// Let's increase impact of this fix for binary operators because

0 commit comments

Comments
 (0)