@@ -6330,15 +6330,14 @@ visitRebindSelfInConstructorExpr(RebindSelfInConstructorExpr *E) {
63306330
63316331
63326332bool FailureDiagnosis::visitClosureExpr (ClosureExpr *CE) {
6333+ auto contextualType = CS->getContextualType ();
63336334 Type expectedResultType;
6334-
6335+
63356336 // If we have a contextual type available for this closure, apply it to the
63366337 // ParamDecls in our parameter list. This ensures that any uses of them get
63376338 // appropriate types.
6338- if (CS->getContextualType () &&
6339- CS->getContextualType ()->is <AnyFunctionType>()) {
6340-
6341- auto fnType = CS->getContextualType ()->castTo <AnyFunctionType>();
6339+ if (contextualType && contextualType->is <AnyFunctionType>()) {
6340+ auto fnType = contextualType->getAs <AnyFunctionType>();
63426341 auto *params = CE->getParameters ();
63436342 Type inferredArgType = fnType->getInput ();
63446343
@@ -6393,12 +6392,24 @@ bool FailureDiagnosis::visitClosureExpr(ClosureExpr *CE) {
63936392 return true ;
63946393 }
63956394
6395+ // Coerce parameter types here only if there are no unresolved
63966396 if (CS->TC .coerceParameterListToType (params, CE, fnType))
63976397 return true ;
63986398
6399+ for (auto param : *params) {
6400+ auto paramType = param->getType ();
6401+ // If this is unresolved 'inout' parameter, it's better to drop
6402+ // 'inout' from type but keep 'mutability' classifier because that
6403+ // might help to diagnose actual problem e.g. type inference and
6404+ // doesn't give us much information anyway.
6405+ if (paramType->is <InOutType>() && paramType->hasUnresolvedType ()) {
6406+ param->setType (CS->getASTContext ().TheUnresolvedType );
6407+ param->setInterfaceType (param->getType ());
6408+ }
6409+ }
6410+
63996411 expectedResultType = fnType->getResult ();
64006412 } else {
6401-
64026413 // Defend against type variables from our constraint system leaking into
64036414 // recursive constraints systems formed when checking the body of the
64046415 // closure. These typevars come into them when the body does name
@@ -6417,36 +6428,67 @@ bool FailureDiagnosis::visitClosureExpr(ClosureExpr *CE) {
64176428 if (!CE->hasSingleExpressionBody ())
64186429 return false ;
64196430
6420- // If the closure had an expected result type, use it.
6421- if (CE->hasExplicitResultType ())
6422- expectedResultType = CE->getExplicitResultTypeLoc ().getType ();
6423-
64246431 // When we're type checking a single-expression closure, we need to reset the
64256432 // DeclContext to this closure for the recursive type checking. Otherwise,
64266433 // if there is a closure in the subexpression, we can violate invariants.
64276434 {
64286435 llvm::SaveAndRestore<DeclContext*> SavedDC (CS->DC , CE);
6429-
6430- auto CTP = expectedResultType ? CTP_ClosureResult : CTP_Unused;
64316436
64326437 // Explicitly disallow to produce solutions with unresolved type variables,
64336438 // because there is no auxiliary logic which would handle that and it's
64346439 // better to allow failure diagnosis to run directly on the closure body.
64356440 // Note that presence of contextual type implicitly forbids such solutions,
64366441 // but it's not always reset.
6442+
6443+ if (expectedResultType && !CE->hasExplicitResultType ()) {
6444+ ExprCleaner cleaner (CE);
6445+
6446+ auto closure = CE->getSingleExpressionBody ();
6447+ ConcreteDeclRef decl = nullptr ;
6448+ // Let's try to compute result type without mutating AST and
6449+ // using expected (contextual) result type, that's going to help
6450+ // diagnose situations where contextual type expected one result
6451+ // type but actual closure produces a different one without explicitly
6452+ // declaring it (e.g. by using anonymous parameters).
6453+ auto type = CS->TC .getTypeOfExpressionWithoutApplying (
6454+ closure, CS->DC , decl, FreeTypeVariableBinding::Disallow);
6455+
6456+ Type resultType = type.hasValue () ? *type : Type ();
6457+
6458+ // Following situations are possible:
6459+ // * No result type - possible structurable problem in the body;
6460+ // * Function result type - possible use of function without calling it,
6461+ // which is properly diagnosed by actual type-check call.
6462+ if (resultType && !resultType->getRValueType ()->is <AnyFunctionType>()) {
6463+ if (!resultType->isEqual (expectedResultType)) {
6464+ diagnose (closure->getEndLoc (), diag::cannot_convert_closure_result,
6465+ resultType, expectedResultType);
6466+ return true ;
6467+ }
6468+ }
6469+ }
6470+
6471+ // If the closure had an expected result type, use it.
6472+ if (CE->hasExplicitResultType ())
6473+ expectedResultType = CE->getExplicitResultTypeLoc ().getType ();
6474+
6475+ // If we couldn't diagnose anything related to the contextual result type
6476+ // let's run proper type-check with expected type and try to verify it.
6477+
6478+ auto CTP = expectedResultType ? CTP_ClosureResult : CTP_Unused;
64376479 if (!typeCheckChildIndependently (CE->getSingleExpressionBody (),
64386480 expectedResultType, CTP, TCCOptions (),
64396481 nullptr , false ))
64406482 return true ;
64416483 }
6442-
6484+
64436485 // If the body of the closure looked ok, then look for a contextual type
64446486 // error. This is necessary because FailureDiagnosis::diagnoseExprFailure
64456487 // doesn't do this for closures.
6446- if (CS-> getContextualType () &&
6447- !CS-> getContextualType ()-> isEqual (CE-> getType ())) {
6448-
6449- auto fnType = CS-> getContextualType ()-> getAs <AnyFunctionType>() ;
6488+ if (contextualType) {
6489+ auto fnType = contextualType-> getAs <AnyFunctionType>();
6490+ if (!fnType || fnType-> isEqual (CE-> getType ()))
6491+ return false ;
64506492
64516493 // If the closure had an explicitly written return type incompatible with
64526494 // the contextual type, diagnose that.
0 commit comments