diff --git a/lib/Sema/CSFix.cpp b/lib/Sema/CSFix.cpp index 92b7331da02..802a2414d11 100644 --- a/lib/Sema/CSFix.cpp +++ b/lib/Sema/CSFix.cpp @@ -235,3 +235,12 @@ InsertExplicitCall *InsertExplicitCall::create(ConstraintSystem &cs, ConstraintLocator *locator) { return new (cs.getAllocator()) InsertExplicitCall(cs, locator); } + +bool UseSubscriptOperator::diagnose(Expr *root, bool asNote) const { + return false; +} + +UseSubscriptOperator *UseSubscriptOperator::create(ConstraintSystem &cs, + ConstraintLocator *locator) { + return new (cs.getAllocator()) UseSubscriptOperator(cs, locator); +} diff --git a/lib/Sema/CSFix.h b/lib/Sema/CSFix.h index c969ab6f2a7..1a43dcb1d0c 100644 --- a/lib/Sema/CSFix.h +++ b/lib/Sema/CSFix.h @@ -96,6 +96,9 @@ enum class FixKind : uint8_t { /// Add explicit `()` at the end of function or member to call it. InsertCall, + + /// Instead of spelling out `subscript` directly, use subscript operator. + UseSubscriptOperator, }; class ConstraintFix { @@ -447,6 +450,21 @@ public: ConstraintLocator *locator); }; +class UseSubscriptOperator final : public ConstraintFix { +public: + UseSubscriptOperator(ConstraintSystem &cs, ConstraintLocator *locator) + : ConstraintFix(cs, FixKind::UseSubscriptOperator, locator) {} + + std::string getName() const override { + return "replace '.subscript(...)' with subscript operator"; + } + + bool diagnose(Expr *root, bool asNote = false) const override; + + static UseSubscriptOperator *create(ConstraintSystem &cs, + ConstraintLocator *locator); +}; + } // end namespace constraints } // end namespace swift diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 8a3cdfb37f8..f30d8060f55 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -3765,10 +3765,6 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint( // function takes no arguments, otherwise it // would make sense to report this a missing member. if (funcType->getNumParams() == 0) { - auto *fix = InsertExplicitCall::create(*this, locator); - if (recordFix(fix)) - return SolutionKind::Error; - auto result = simplifyMemberConstraint( kind, funcType->getResult(), member, memberTy, useDC, functionRefKind, outerAlternatives, flags, locatorB); @@ -3777,9 +3773,24 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint( // let's return, otherwise let's fall-through and report // this problem as a missing member. if (result == SolutionKind::Solved) - return result; + return recordFix(InsertExplicitCall::create(*this, locator)) + ? SolutionKind::Error + : SolutionKind::Solved; } } + + // Instead of using subscript operator spelled out `subscript` directly. + if (member.getBaseName() == getTokenText(tok::kw_subscript)) { + auto result = simplifyMemberConstraint( + kind, baseTy, DeclBaseName::createSubscript(), memberTy, useDC, + functionRefKind, {}, flags, locatorB); + + // Looks like it was indeed meant to be a subscript operator. + if (result == SolutionKind::Solved) + return recordFix(UseSubscriptOperator::create(*this, locator)) + ? SolutionKind::Error + : SolutionKind::Solved; + } } return SolutionKind::Error; } @@ -5442,6 +5453,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint( return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved; } + case FixKind::UseSubscriptOperator: case FixKind::InsertCall: case FixKind::ExplicitlyEscaping: case FixKind::CoerceToCheckedCast: