@@ -250,10 +250,6 @@ class FailureDiagnosis :public ASTVisitor<FailureDiagnosis, /*exprresult*/bool>{
250
250
251
251
bool diagnoseTrailingClosureErrors (ApplyExpr *expr);
252
252
253
- bool
254
- diagnoseClosureExpr (ClosureExpr *closureExpr, Type contextualType,
255
- llvm::function_ref<bool (Type, Type)> resultTypeProcessor);
256
-
257
253
bool diagnoseSubscriptErrors (SubscriptExpr *SE, bool performingSet);
258
254
259
255
bool visitExpr (Expr *E);
@@ -272,8 +268,6 @@ class FailureDiagnosis :public ASTVisitor<FailureDiagnosis, /*exprresult*/bool>{
272
268
bool visitCoerceExpr (CoerceExpr *CE);
273
269
bool visitIfExpr (IfExpr *IE);
274
270
bool visitRebindSelfInConstructorExpr (RebindSelfInConstructorExpr *E);
275
- bool visitCaptureListExpr (CaptureListExpr *CLE);
276
- bool visitClosureExpr (ClosureExpr *CE);
277
271
};
278
272
} // end anonymous namespace
279
273
@@ -1720,7 +1714,6 @@ bool FailureDiagnosis::diagnoseTrailingClosureErrors(ApplyExpr *callExpr) {
1720
1714
if (!callExpr->hasTrailingClosure ())
1721
1715
return false ;
1722
1716
1723
- auto *DC = CS.DC ;
1724
1717
auto *fnExpr = callExpr->getFn ();
1725
1718
auto *argExpr = callExpr->getArg ();
1726
1719
@@ -1819,63 +1812,6 @@ bool FailureDiagnosis::diagnoseTrailingClosureErrors(ApplyExpr *callExpr) {
1819
1812
return true ;
1820
1813
}
1821
1814
}
1822
-
1823
- auto processor = [&](Type resultType, Type expectedResultType) -> bool {
1824
- if (resultType && expectedResultType) {
1825
- if (!resultType->isEqual (expectedResultType)) {
1826
- auto &DE = CS.getASTContext ().Diags ;
1827
- DE.diagnose (closureExpr->getEndLoc (),
1828
- diag::cannot_convert_closure_result, resultType,
1829
- expectedResultType);
1830
- return true ;
1831
- }
1832
-
1833
- // Looks like both actual and expected result types match,
1834
- // there is nothing we can diagnose in this case.
1835
- return false ;
1836
- }
1837
-
1838
- // If we got a result type, let's re-typecheck the function using it,
1839
- // maybe we can find a problem where contextually we expect one type
1840
- // but trailing closure produces completely different one.
1841
- auto fnType = paramType->getAs <AnyFunctionType>();
1842
- if (!fnType)
1843
- return false ;
1844
-
1845
- class ClosureCalleeListener : public ExprTypeCheckListener {
1846
- FunctionType *InputType;
1847
- Type ResultType;
1848
-
1849
- public:
1850
- explicit ClosureCalleeListener (FunctionType *inputType, Type resultType)
1851
- : InputType(inputType), ResultType(resultType) {}
1852
-
1853
- bool builtConstraints (ConstraintSystem &cs, Expr *expr) override {
1854
- if (!ResultType)
1855
- return false ;
1856
-
1857
- AnyFunctionType::Param Input (InputType);
1858
- auto expectedType = FunctionType::get ({Input}, ResultType);
1859
- cs.addConstraint (ConstraintKind::Conversion, cs.getType (expr),
1860
- expectedType, cs.getConstraintLocator (expr),
1861
- /* isFavored*/ true );
1862
- return false ;
1863
- }
1864
- };
1865
-
1866
- auto expectedArgType = FunctionType::get (fnType->getParams (), resultType,
1867
- fnType->getExtInfo ());
1868
-
1869
- llvm::SaveAndRestore<DeclContext *> SavedDC (CS.DC , DC);
1870
- ClosureCalleeListener listener (expectedArgType, CS.getContextualType ());
1871
- return !typeCheckChildIndependently (callExpr->getFn (), Type (),
1872
- CTP_CalleeResult, TCC_ForceRecheck,
1873
- &listener);
1874
- };
1875
-
1876
- // Let's see if there are any structural problems with closure itself.
1877
- if (diagnoseClosureExpr (closureExpr, paramType, processor))
1878
- return true ;
1879
1815
}
1880
1816
1881
1817
return false ;
@@ -2516,191 +2452,6 @@ visitRebindSelfInConstructorExpr(RebindSelfInConstructorExpr *E) {
2516
2452
return false ;
2517
2453
}
2518
2454
2519
- bool FailureDiagnosis::visitCaptureListExpr (CaptureListExpr *CLE) {
2520
- // Always walk into the closure of a capture list expression.
2521
- return visitClosureExpr (CLE->getClosureBody ());
2522
- }
2523
-
2524
- static bool isInvalidClosureResultType (Type resultType) {
2525
- return !resultType || resultType->hasUnresolvedType () ||
2526
- resultType->hasTypeVariable () || resultType->hasArchetype ();
2527
- }
2528
-
2529
- bool FailureDiagnosis::visitClosureExpr (ClosureExpr *CE) {
2530
- return diagnoseClosureExpr (
2531
- CE, CS.getContextualType (),
2532
- [&](Type resultType, Type expectedResultType) -> bool {
2533
- if (isInvalidClosureResultType (expectedResultType))
2534
- return false ;
2535
-
2536
- // Following situations are possible:
2537
- // * No result type - possible structurable problem in the body;
2538
- // * Function result type - possible use of function without calling it,
2539
- // which is properly diagnosed by actual type-check call.
2540
- if (resultType && !resultType->getRValueType ()->is <AnyFunctionType>()) {
2541
- if (!resultType->isEqual (expectedResultType)) {
2542
- diagnose (CE->getEndLoc (), diag::cannot_convert_closure_result,
2543
- resultType, expectedResultType);
2544
- return true ;
2545
- }
2546
- }
2547
- return false ;
2548
- });
2549
- }
2550
-
2551
- bool FailureDiagnosis::diagnoseClosureExpr (
2552
- ClosureExpr *CE, Type contextualType,
2553
- llvm::function_ref<bool (Type, Type)> resultTypeProcessor) {
2554
- // Look through IUO because it doesn't influence
2555
- // neither parameter nor return type diagnostics itself,
2556
- // but if we have function type inside, that might
2557
- // signficantly improve diagnostic quality.
2558
- // FIXME: We need to rework this with IUOs out of the type system.
2559
- // if (contextualType) {
2560
- // if (auto IUO =
2561
- // CS.lookThroughImplicitlyUnwrappedOptionalType(contextualType))
2562
- // contextualType = IUO;
2563
- // }
2564
-
2565
- Type expectedResultType;
2566
-
2567
- // If we have a contextual type available for this closure, apply it to the
2568
- // ParamDecls in our parameter list. This ensures that any uses of them get
2569
- // appropriate types.
2570
- if (contextualType && contextualType->is <FunctionType>()) {
2571
- auto fnType = contextualType->getAs <FunctionType>();
2572
- auto *params = CE->getParameters ();
2573
- auto inferredArgs = fnType->getParams ();
2574
-
2575
- // It is very common for a contextual type to disagree with the argument
2576
- // list built into the closure expr. This can be because the closure expr
2577
- // had an explicitly specified pattern, a la:
2578
- // { a,b in ... }
2579
- // or could be because the closure has an implicitly generated one:
2580
- // { $0 + $1 }
2581
- // in either case, we want to produce nice and clear diagnostics.
2582
- unsigned actualArgCount = params->size ();
2583
- unsigned inferredArgCount = inferredArgs.size ();
2584
-
2585
- if (actualArgCount != inferredArgCount) {
2586
- if (inferredArgCount == 1 && actualArgCount > 1 ) {
2587
- auto *argTupleTy = inferredArgs.front ().getOldType ()->getAs <TupleType>();
2588
- // Let's see if inferred argument is actually a tuple inside of Paren.
2589
- if (argTupleTy) {
2590
- // Looks like the number of closure parameters matches number
2591
- // of inferred arguments, which means we can we can emit an
2592
- // error about an attempt to make use of tuple splat or tuple
2593
- // destructuring and provide a proper fix-it.
2594
- if (argTupleTy->getNumElements () == actualArgCount) {
2595
- ClosureParamDestructuringFailure failure (
2596
- CS, fnType, CS.getConstraintLocator (CE));
2597
- return failure.diagnoseAsError ();
2598
- }
2599
- }
2600
- }
2601
-
2602
- // Extraneous arguments.
2603
- if (inferredArgCount < actualArgCount) {
2604
- auto diag = diagnose (
2605
- params->getStartLoc (), diag::closure_argument_list_tuple, fnType,
2606
- inferredArgCount, actualArgCount, (actualArgCount == 1 ));
2607
-
2608
- bool onlyAnonymousParams =
2609
- std::all_of (params->begin (), params->end (),
2610
- [](ParamDecl *param) { return !param->hasName (); });
2611
-
2612
- // If closure expects no parameters but N was given,
2613
- // and all of them are anonymous let's suggest removing them.
2614
- if (inferredArgCount == 0 && onlyAnonymousParams) {
2615
- auto inLoc = CE->getInLoc ();
2616
- auto &sourceMgr = CS.getASTContext ().SourceMgr ;
2617
-
2618
- if (inLoc.isValid ())
2619
- diag.fixItRemoveChars (params->getStartLoc (),
2620
- Lexer::getLocForEndOfToken (sourceMgr, inLoc));
2621
- }
2622
- return true ;
2623
- }
2624
-
2625
- // Missing arguments are already diagnosed via new diagnostic framework.
2626
- return false ;
2627
- }
2628
-
2629
- // Coerce parameter types here only if there are no unresolved
2630
- TypeChecker::coerceParameterListToType (params, CE, fnType);
2631
- expectedResultType = fnType->getResult ();
2632
- }
2633
-
2634
- // Defend against type variables from our constraint system leaking into
2635
- // recursive constraints systems formed when checking the body of the
2636
- // closure. These typevars come into them when the body does name
2637
- // lookups against the parameter decls.
2638
- //
2639
- // Handle this by rewriting the arguments to UnresolvedType().
2640
- for (auto VD : *CE->getParameters ()) {
2641
- if (VD->hasInterfaceType () && (VD->getType ()->hasTypeVariable () ||
2642
- VD->getType ()->hasError ())) {
2643
- VD->setInterfaceType (CS.getASTContext ().TheUnresolvedType );
2644
- }
2645
- }
2646
-
2647
- // If this is a complex leaf closure, there is nothing more we can do.
2648
- if (!CE->hasSingleExpressionBody ())
2649
- return false ;
2650
-
2651
- if (isInvalidClosureResultType (expectedResultType))
2652
- expectedResultType = Type ();
2653
-
2654
- // When we're type checking a single-expression closure, we need to reset the
2655
- // DeclContext to this closure for the recursive type checking. Otherwise,
2656
- // if there is a closure in the subexpression, we can violate invariants.
2657
- {
2658
- llvm::SaveAndRestore<DeclContext *> SavedDC (CS.DC , CE);
2659
-
2660
- // Explicitly disallow to produce solutions with unresolved type variables,
2661
- // because there is no auxiliary logic which would handle that and it's
2662
- // better to allow failure diagnosis to run directly on the closure body.
2663
- // Note that presence of contextual type implicitly forbids such solutions,
2664
- // but it's not always reset.
2665
-
2666
- if (expectedResultType && !CE->hasExplicitResultType ()) {
2667
- auto closure = CE->getSingleExpressionBody ();
2668
- ConcreteDeclRef decl = nullptr ;
2669
- // Let's try to compute result type without mutating AST and
2670
- // using expected (contextual) result type, that's going to help
2671
- // diagnose situations where contextual type expected one result
2672
- // type but actual closure produces a different one without explicitly
2673
- // declaring it (e.g. by using anonymous parameters).
2674
- auto type = TypeChecker::getTypeOfExpressionWithoutApplying (
2675
- closure, CS.DC , decl, FreeTypeVariableBinding::Disallow);
2676
-
2677
- if (type && resultTypeProcessor (type, expectedResultType))
2678
- return true ;
2679
- }
2680
-
2681
- // If the closure had an expected result type, use it.
2682
- if (CE->hasExplicitResultType ())
2683
- expectedResultType = CE->getExplicitResultTypeLoc ().getType ();
2684
-
2685
- // If we couldn't diagnose anything related to the contextual result type
2686
- // let's run proper type-check with expected type and try to verify it.
2687
-
2688
- auto CTP = expectedResultType ? CTP_ClosureResult : CTP_Unused;
2689
- auto *bodyExpr = typeCheckChildIndependently (CE->getSingleExpressionBody (),
2690
- expectedResultType, CTP,
2691
- TCCOptions (), nullptr , false );
2692
-
2693
- if (!bodyExpr)
2694
- return true ;
2695
-
2696
- if (resultTypeProcessor (CS.getType (bodyExpr), expectedResultType))
2697
- return true ;
2698
- }
2699
-
2700
- // Otherwise, we can't produce a specific diagnostic.
2701
- return false ;
2702
- }
2703
-
2704
2455
bool FailureDiagnosis::visitArrayExpr (ArrayExpr *E) {
2705
2456
// If we had a contextual type, then it either conforms to
2706
2457
// ExpressibleByArrayLiteral or it is an invalid contextual type.
0 commit comments