Skip to content

Commit a7bb827

Browse files
committed
[CSDiag] NFC: Remove obsolete diagnoseAmbiguousMultiStatementClosure
1 parent 8bcc192 commit a7bb827

File tree

1 file changed

+0
-158
lines changed

1 file changed

+0
-158
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 0 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -220,11 +220,6 @@ class FailureDiagnosis :public ASTVisitor<FailureDiagnosis, /*exprresult*/bool>{
220220
std::pair<Type, ContextualTypePurpose>
221221
validateContextualType(Type contextualType, ContextualTypePurpose CTP);
222222

223-
/// Check the specified closure to see if it is a multi-statement closure with
224-
/// an uninferred type. If so, diagnose the problem with an error and return
225-
/// true.
226-
bool diagnoseAmbiguousMultiStatementClosure(ClosureExpr *closure);
227-
228223
/// Given a result of name lookup that had no viable results, diagnose the
229224
/// unviable ones.
230225
void diagnoseUnviableLookupResults(MemberLookupResult &lookupResults,
@@ -2694,138 +2689,6 @@ FailureDiagnosis::validateContextualType(Type contextualType,
26942689
return {contextualType, CTP};
26952690
}
26962691

2697-
/// Check the specified closure to see if it is a multi-statement closure with
2698-
/// an uninferred type. If so, diagnose the problem with an error and return
2699-
/// true.
2700-
bool FailureDiagnosis::
2701-
diagnoseAmbiguousMultiStatementClosure(ClosureExpr *closure) {
2702-
if (closure->hasSingleExpressionBody() ||
2703-
closure->hasExplicitResultType())
2704-
return false;
2705-
2706-
auto closureType = CS.getType(closure)->getAs<AnyFunctionType>();
2707-
if (!closureType ||
2708-
!(closureType->getResult()->hasUnresolvedType() ||
2709-
closureType->getResult()->hasTypeVariable()))
2710-
return false;
2711-
2712-
// Okay, we have a multi-statement closure expr that has no inferred result,
2713-
// type, in the context of a larger expression. The user probably expected
2714-
// the compiler to infer the result type of the closure from the body of the
2715-
// closure, which Swift doesn't do for multi-statement closures. Try to be
2716-
// helpful by digging into the body of the closure, looking for a return
2717-
// statement, and inferring the result type from it. If we can figure that
2718-
// out, we can produce a fixit hint.
2719-
class ReturnStmtFinder : public ASTWalker {
2720-
SmallVectorImpl<ReturnStmt*> &returnStmts;
2721-
public:
2722-
ReturnStmtFinder(SmallVectorImpl<ReturnStmt*> &returnStmts)
2723-
: returnStmts(returnStmts) {}
2724-
2725-
// Walk through statements, so we find returns hiding in if/else blocks etc.
2726-
std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override {
2727-
// Keep track of any return statements we find.
2728-
if (auto RS = dyn_cast<ReturnStmt>(S))
2729-
returnStmts.push_back(RS);
2730-
return { true, S };
2731-
}
2732-
2733-
// Don't walk into anything else, since they cannot contain statements
2734-
// that can return from the current closure.
2735-
std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
2736-
return { false, E };
2737-
}
2738-
std::pair<bool, Pattern*> walkToPatternPre(Pattern *P) override {
2739-
return { false, P };
2740-
}
2741-
bool walkToDeclPre(Decl *D) override { return false; }
2742-
bool walkToTypeLocPre(TypeLoc &TL) override { return false; }
2743-
bool walkToTypeReprPre(TypeRepr *T) override { return false; }
2744-
bool walkToParameterListPre(ParameterList *PL) override { return false; }
2745-
};
2746-
2747-
SmallVector<ReturnStmt*, 4> Returns;
2748-
closure->getBody()->walk(ReturnStmtFinder(Returns));
2749-
2750-
// If we found a return statement inside of the closure expression, then go
2751-
// ahead and type check the body to see if we can determine a type.
2752-
for (auto RS : Returns) {
2753-
llvm::SaveAndRestore<DeclContext *> SavedDC(CS.DC, closure);
2754-
2755-
// Otherwise, we're ok to type check the subexpr.
2756-
Type resultType;
2757-
if (RS->hasResult()) {
2758-
auto resultExpr = RS->getResult();
2759-
ConcreteDeclRef decl = nullptr;
2760-
2761-
// If return expression uses closure parameters, which have/are
2762-
// type variables, such means that we won't be able to
2763-
// type-check result correctly and, unfortunately,
2764-
// we are going to leak type variables from the parent
2765-
// constraint system through declaration types.
2766-
bool hasUnresolvedParams = false;
2767-
resultExpr->forEachChildExpr([&](Expr *childExpr) -> Expr *{
2768-
if (auto DRE = dyn_cast<DeclRefExpr>(childExpr)) {
2769-
if (auto param = dyn_cast<ParamDecl>(DRE->getDecl())) {
2770-
auto paramType =
2771-
param->hasInterfaceType() ? param->getType() : Type();
2772-
if (!paramType || paramType->hasTypeVariable()) {
2773-
hasUnresolvedParams = true;
2774-
return nullptr;
2775-
}
2776-
}
2777-
}
2778-
return childExpr;
2779-
});
2780-
2781-
if (hasUnresolvedParams)
2782-
continue;
2783-
2784-
ConstraintSystem::preCheckExpression(resultExpr, CS.DC, &CS);
2785-
2786-
// Obtain type of the result expression without applying solutions,
2787-
// because otherwise this might result in leaking of type variables,
2788-
// since we are not resetting result statement and if expression is
2789-
// successfully type-checked its type cleanup is going to be disabled
2790-
// (we are allowing unresolved types), and as a side-effect it might
2791-
// also be transformed e.g. OverloadedDeclRefExpr -> DeclRefExpr.
2792-
auto type = TypeChecker::getTypeOfExpressionWithoutApplying(
2793-
resultExpr, CS.DC, decl, FreeTypeVariableBinding::UnresolvedType);
2794-
if (type)
2795-
resultType = type->getRValueType();
2796-
}
2797-
2798-
// If we found a type, presuppose it was the intended result and insert a
2799-
// fixit hint.
2800-
if (resultType && !isUnresolvedOrTypeVarType(resultType)) {
2801-
// If there is a location for an 'in' token, then the argument list was
2802-
// specified somehow but no return type was. Insert a "-> ReturnType "
2803-
// before the in token.
2804-
if (closure->getInLoc().isValid()) {
2805-
diagnose(closure->getLoc(), diag::cannot_infer_closure_result_type)
2806-
.fixItInsert(closure->getInLoc(), diag::insert_closure_return_type,
2807-
resultType, /*argListSpecified*/ false);
2808-
return true;
2809-
}
2810-
2811-
// Otherwise, the closure must take zero arguments. We know this
2812-
// because the if one or more argument is specified, a multi-statement
2813-
// closure *must* name them, or explicitly ignore them with "_ in".
2814-
//
2815-
// As such, we insert " () -> ReturnType in " right after the '{' that
2816-
// starts the closure body.
2817-
diagnose(closure->getLoc(), diag::cannot_infer_closure_result_type)
2818-
.fixItInsertAfter(closure->getBody()->getLBraceLoc(),
2819-
diag::insert_closure_return_type, resultType,
2820-
/*argListSpecified*/ true);
2821-
return true;
2822-
}
2823-
}
2824-
2825-
diagnose(closure->getLoc(), diag::cannot_infer_closure_result_type);
2826-
return true;
2827-
}
2828-
28292692
/// Emit an ambiguity diagnostic about the specified expression.
28302693
void FailureDiagnosis::diagnoseAmbiguity(Expr *E) {
28312694
if (auto *assignment = dyn_cast<AssignExpr>(E)) {
@@ -2855,11 +2718,6 @@ void FailureDiagnosis::diagnoseAmbiguity(Expr *E) {
28552718
// Unresolved/Anonymous ClosureExprs are common enough that we should give
28562719
// them tailored diagnostics.
28572720
if (auto CE = dyn_cast<ClosureExpr>(E->getValueProvidingExpr())) {
2858-
// If this is a multi-statement closure with no explicit result type, emit
2859-
// a note to clue the developer in.
2860-
if (diagnoseAmbiguousMultiStatementClosure(CE))
2861-
return;
2862-
28632721
diagnose(E->getLoc(), diag::cannot_infer_closure_type)
28642722
.highlight(E->getSourceRange());
28652723
return;
@@ -2901,22 +2759,6 @@ void FailureDiagnosis::diagnoseAmbiguity(Expr *E) {
29012759
return;
29022760
}
29032761

2904-
// A very common cause of this diagnostic is a situation where a closure expr
2905-
// has no inferred type, due to being a multiline closure. Check to see if
2906-
// this is the case and (if so), speculatively diagnose that as the problem.
2907-
bool didDiagnose = false;
2908-
E->forEachChildExpr([&](Expr *subExpr) -> Expr*{
2909-
auto closure = dyn_cast<ClosureExpr>(subExpr);
2910-
if (!didDiagnose && closure)
2911-
didDiagnose = diagnoseAmbiguousMultiStatementClosure(closure);
2912-
2913-
return subExpr;
2914-
});
2915-
2916-
if (didDiagnose) return;
2917-
2918-
2919-
29202762
// Attempt to re-type-check the entire expression, allowing ambiguity, but
29212763
// ignoring a contextual type.
29222764
if (expr == E) {

0 commit comments

Comments
 (0)