|
41 | 41 | using namespace swift;
|
42 | 42 | using namespace constraints;
|
43 | 43 |
|
| 44 | +static bool hasFixFor(const Solution &solution, ConstraintLocator *locator) { |
| 45 | + return llvm::any_of(solution.Fixes, [&locator](const ConstraintFix *fix) { |
| 46 | + return fix->getLocator() == locator; |
| 47 | + }); |
| 48 | +} |
| 49 | + |
44 | 50 | FailureDiagnostic::~FailureDiagnostic() {}
|
45 | 51 |
|
46 | 52 | bool FailureDiagnostic::diagnose(bool asNote) {
|
@@ -6127,6 +6133,53 @@ bool MissingContextualBaseInMemberRefFailure::diagnoseAsError() {
|
6127 | 6133 |
|
6128 | 6134 | bool UnableToInferClosureParameterType::diagnoseAsError() {
|
6129 | 6135 | auto *closure = castToExpr<ClosureExpr>(getRawAnchor());
|
| 6136 | + |
| 6137 | + // Let's check whether this closure is an argument to |
| 6138 | + // a call which couldn't be properly resolved e.g. |
| 6139 | + // missing member or invalid contextual reference and |
| 6140 | + // if so let's not diagnose this problem because main |
| 6141 | + // issue here is inability to establish context for |
| 6142 | + // closure inference. |
| 6143 | + // |
| 6144 | + // TODO(diagnostics): Once we gain an ability to determine |
| 6145 | + // originating source of type holes this check could be |
| 6146 | + // significantly simplified. |
| 6147 | + { |
| 6148 | + auto &solution = getSolution(); |
| 6149 | + |
| 6150 | + // If there is a contextual mismatch associated with this |
| 6151 | + // closure, let's not diagnose any parameter type issues. |
| 6152 | + if (hasFixFor(solution, getConstraintLocator( |
| 6153 | + closure, LocatorPathElt::ContextualType()))) |
| 6154 | + return false; |
| 6155 | + |
| 6156 | + if (auto *parentExpr = findParentExpr(closure)) { |
| 6157 | + while (parentExpr && |
| 6158 | + (isa<TupleExpr>(parentExpr) || isa<ParenExpr>(parentExpr))) { |
| 6159 | + parentExpr = findParentExpr(parentExpr); |
| 6160 | + } |
| 6161 | + |
| 6162 | + if (parentExpr) { |
| 6163 | + // Missing or invalid member reference in call. |
| 6164 | + if (auto *AE = dyn_cast<ApplyExpr>(parentExpr)) { |
| 6165 | + if (getType(AE->getFn())->isHole()) |
| 6166 | + return false; |
| 6167 | + } |
| 6168 | + |
| 6169 | + // Any fix anchored on parent expression makes it unnecessary |
| 6170 | + // to diagnose unability to infer parameter type because it's |
| 6171 | + // an indication that proper context couldn't be established to |
| 6172 | + // resolve the closure. |
| 6173 | + ASTNode parentNode(parentExpr); |
| 6174 | + if (llvm::any_of(solution.Fixes, |
| 6175 | + [&parentNode](const ConstraintFix *fix) -> bool { |
| 6176 | + return fix->getAnchor() == parentNode; |
| 6177 | + })) |
| 6178 | + return false; |
| 6179 | + } |
| 6180 | + } |
| 6181 | + } |
| 6182 | + |
6130 | 6183 | auto paramIdx = getLocator()
|
6131 | 6184 | ->castLastElementTo<LocatorPathElt::TupleElement>()
|
6132 | 6185 | .getIndex();
|
|
0 commit comments