@@ -220,11 +220,6 @@ class FailureDiagnosis :public ASTVisitor<FailureDiagnosis, /*exprresult*/bool>{
220
220
std::pair<Type, ContextualTypePurpose>
221
221
validateContextualType(Type contextualType, ContextualTypePurpose CTP);
222
222
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
-
228
223
/// Given a result of name lookup that had no viable results, diagnose the
229
224
/// unviable ones.
230
225
void diagnoseUnviableLookupResults(MemberLookupResult &lookupResults,
@@ -2694,138 +2689,6 @@ FailureDiagnosis::validateContextualType(Type contextualType,
2694
2689
return {contextualType, CTP};
2695
2690
}
2696
2691
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
-
2829
2692
/// Emit an ambiguity diagnostic about the specified expression.
2830
2693
void FailureDiagnosis::diagnoseAmbiguity(Expr *E) {
2831
2694
if (auto *assignment = dyn_cast<AssignExpr>(E)) {
@@ -2855,11 +2718,6 @@ void FailureDiagnosis::diagnoseAmbiguity(Expr *E) {
2855
2718
// Unresolved/Anonymous ClosureExprs are common enough that we should give
2856
2719
// them tailored diagnostics.
2857
2720
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
-
2863
2721
diagnose(E->getLoc(), diag::cannot_infer_closure_type)
2864
2722
.highlight(E->getSourceRange());
2865
2723
return;
@@ -2901,22 +2759,6 @@ void FailureDiagnosis::diagnoseAmbiguity(Expr *E) {
2901
2759
return;
2902
2760
}
2903
2761
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
-
2920
2762
// Attempt to re-type-check the entire expression, allowing ambiguity, but
2921
2763
// ignoring a contextual type.
2922
2764
if (expr == E) {
0 commit comments