[CSFix] Generalize a fix for unresolved pattern decl

The fix should support both named (i.e. `test(a)` and "any" patterns
i.e. `test(_)`.
This commit is contained in:
Pavel Yaskevich
2022-07-22 15:33:45 -07:00
parent dee6a31ac9
commit ac89df5c12
4 changed files with 21 additions and 22 deletions

View File

@@ -298,9 +298,9 @@ enum class FixKind : uint8_t {
/// Ignore `ErrorExpr` or `ErrorType` during pre-check. /// Ignore `ErrorExpr` or `ErrorType` during pre-check.
IgnoreInvalidASTNode, IgnoreInvalidASTNode,
/// Ignore a named pattern whose type we couldn't infer. This issue should /// Ignore a named or `_` pattern whose type we couldn't infer.
/// already have been diagnosed elsewhere. /// This issue should already have been diagnosed elsewhere.
IgnoreInvalidNamedPattern, IgnoreUnresolvedPatternVar,
/// Resolve type of `nil` by providing a contextual type. /// Resolve type of `nil` by providing a contextual type.
SpecifyContextualTypeForNil, SpecifyContextualTypeForNil,
@@ -2746,10 +2746,10 @@ public:
} }
}; };
class IgnoreInvalidNamedPattern final : public ConstraintFix { class IgnoreUnresolvedPatternVar final : public ConstraintFix {
IgnoreInvalidNamedPattern(ConstraintSystem &cs, NamedPattern *pattern, IgnoreUnresolvedPatternVar(ConstraintSystem &cs, Pattern *pattern,
ConstraintLocator *locator) ConstraintLocator *locator)
: ConstraintFix(cs, FixKind::IgnoreInvalidNamedPattern, locator) {} : ConstraintFix(cs, FixKind::IgnoreUnresolvedPatternVar, locator) {}
public: public:
std::string getName() const override { std::string getName() const override {
@@ -2762,12 +2762,11 @@ public:
return diagnose(*commonFixes.front().first); return diagnose(*commonFixes.front().first);
} }
static IgnoreInvalidNamedPattern *create(ConstraintSystem &cs, static IgnoreUnresolvedPatternVar *
NamedPattern *pattern, create(ConstraintSystem &cs, Pattern *pattern, ConstraintLocator *locator);
ConstraintLocator *locator);
static bool classof(ConstraintFix *fix) { static bool classof(ConstraintFix *fix) {
return fix->getKind() == FixKind::IgnoreInvalidNamedPattern; return fix->getKind() == FixKind::IgnoreUnresolvedPatternVar;
} }
}; };

View File

@@ -115,7 +115,7 @@ bool BindingSet::isDelayed() const {
// allows us to produce more specific errors because the type variable in // allows us to produce more specific errors because the type variable in
// the expression that introduced the placeholder might be diagnosable using // the expression that introduced the placeholder might be diagnosable using
// fixForHole. // fixForHole.
if (locator->isLastElement<LocatorPathElt::NamedPatternDecl>()) { if (locator->isLastElement<LocatorPathElt::PatternDecl>()) {
return true; return true;
} }
@@ -2061,16 +2061,16 @@ TypeVariableBinding::fixForHole(ConstraintSystem &cs) const {
return std::make_pair(fix, /*impact=*/(unsigned)10); return std::make_pair(fix, /*impact=*/(unsigned)10);
} }
if (auto pattern = getAsPattern<NamedPattern>(dstLocator->getAnchor())) { if (auto pattern = getAsPattern(dstLocator->getAnchor())) {
if (dstLocator->getPath().size() == 1 && if (dstLocator->getPath().size() == 1 &&
dstLocator->isLastElement<LocatorPathElt::NamedPatternDecl>()) { dstLocator->isLastElement<LocatorPathElt::PatternDecl>()) {
// Not being able to infer the type of a variable in a pattern binding // Not being able to infer the type of a variable in a pattern binding
// decl is more dramatic than anything that could happen inside the // decl is more dramatic than anything that could happen inside the
// expression because we want to preferrably point the diagnostic to a // expression because we want to preferrably point the diagnostic to a
// part of the expression that caused us to be unable to infer the // part of the expression that caused us to be unable to infer the
// variable's type. // variable's type.
ConstraintFix *fix = ConstraintFix *fix =
IgnoreInvalidNamedPattern::create(cs, pattern, dstLocator); IgnoreUnresolvedPatternVar::create(cs, pattern, dstLocator);
return std::make_pair(fix, /*impact=*/(unsigned)100); return std::make_pair(fix, /*impact=*/(unsigned)100);
} }
} }

View File

@@ -2004,18 +2004,18 @@ IgnoreResultBuilderWithReturnStmts::create(ConstraintSystem &cs, Type builderTy,
IgnoreResultBuilderWithReturnStmts(cs, builderTy, locator); IgnoreResultBuilderWithReturnStmts(cs, builderTy, locator);
} }
bool IgnoreInvalidNamedPattern::diagnose(const Solution &solution, bool IgnoreUnresolvedPatternVar::diagnose(const Solution &solution,
bool asNote) const { bool asNote) const {
// Not being able to infer the type of a pattern should already have been // Not being able to infer the type of a pattern should already have been
// diagnosed on the pattern's initializer or as a structural issue of the AST. // diagnosed on the pattern's initializer or as a structural issue of the AST.
return true; return true;
} }
IgnoreInvalidNamedPattern * IgnoreUnresolvedPatternVar *
IgnoreInvalidNamedPattern::create(ConstraintSystem &cs, NamedPattern *pattern, IgnoreUnresolvedPatternVar::create(ConstraintSystem &cs, Pattern *pattern,
ConstraintLocator *locator) { ConstraintLocator *locator) {
return new (cs.getAllocator()) return new (cs.getAllocator())
IgnoreInvalidNamedPattern(cs, pattern, locator); IgnoreUnresolvedPatternVar(cs, pattern, locator);
} }
bool SpecifyBaseTypeForOptionalUnresolvedMember::diagnose( bool SpecifyBaseTypeForOptionalUnresolvedMember::diagnose(

View File

@@ -12938,7 +12938,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
case FixKind::IgnoreInvalidASTNode: { case FixKind::IgnoreInvalidASTNode: {
return recordFix(fix, 10) ? SolutionKind::Error : SolutionKind::Solved; return recordFix(fix, 10) ? SolutionKind::Error : SolutionKind::Solved;
} }
case FixKind::IgnoreInvalidNamedPattern: { case FixKind::IgnoreUnresolvedPatternVar: {
return recordFix(fix, 100) ? SolutionKind::Error : SolutionKind::Solved; return recordFix(fix, 100) ? SolutionKind::Error : SolutionKind::Solved;
} }