@@ -344,6 +344,43 @@ static bool isSupportedDisjunction(Constraint *disjunction) {
344344 });
345345}
346346
347+ // / Determine whether the given overload choice constitutes a
348+ // / valid choice that would be attempted during normal solving
349+ // / without any score increases.
350+ static ValueDecl *isViableOverloadChoice (ConstraintSystem &cs,
351+ Constraint *constraint,
352+ ConstraintLocator *locator) {
353+ if (constraint->isDisabled ())
354+ return nullptr ;
355+
356+ if (constraint->getKind () != ConstraintKind::BindOverload)
357+ return nullptr ;
358+
359+ auto choice = constraint->getOverloadChoice ();
360+ auto *decl = choice.getDeclOrNull ();
361+ if (!decl)
362+ return nullptr ;
363+
364+ // Ignore declarations that come from implicitly imported modules
365+ // when `MemberImportVisibility` feature is enabled otherwise
366+ // we might end up favoring an overload that would be diagnosed
367+ // as unavailable later.
368+ if (cs.getASTContext ().LangOpts .hasFeature (Feature::MemberImportVisibility)) {
369+ if (auto *useDC = constraint->getOverloadUseDC ()) {
370+ if (!useDC->isDeclImported (decl))
371+ return nullptr ;
372+ }
373+ }
374+
375+ // If disjunction choice is unavailable or disfavored we cannot
376+ // do anything with it.
377+ if (decl->getAttrs ().hasAttribute <DisfavoredOverloadAttr>() ||
378+ cs.isDeclUnavailable (decl, locator))
379+ return nullptr ;
380+
381+ return decl;
382+ }
383+
347384// / Given the type variable that represents a result type of a
348385// / function call, check whether that call is to an initializer
349386// / and based on that deduce possible type for the result.
@@ -389,16 +426,30 @@ inferTypeFromInitializerResultType(ConstraintSystem &cs,
389426 if (initRef == disjunctions.end ())
390427 return {};
391428
392- bool hasFailable =
393- llvm::any_of ((*initRef)->getNestedConstraints (), [](Constraint *choice) {
394- if (choice->isDisabled ())
395- return false ;
396- auto *decl =
397- dyn_cast_or_null<ConstructorDecl>(getOverloadChoiceDecl (choice));
398- return decl && decl->isFailable ();
399- });
429+ unsigned numFailable = 0 ;
430+ unsigned total = 0 ;
431+ for (auto *choice : (*initRef)->getNestedConstraints ()) {
432+ auto *decl = isViableOverloadChoice (cs, choice, ctorLocator);
433+ if (!decl || !isa<ConstructorDecl>(decl))
434+ continue ;
400435
401- return {instanceTy, hasFailable};
436+ auto *ctor = cast<ConstructorDecl>(decl);
437+ if (ctor->isFailable ())
438+ ++numFailable;
439+
440+ ++total;
441+ }
442+
443+ if (numFailable > 0 ) {
444+ // If all of the active choices are failable, produce an optional
445+ // type only.
446+ if (numFailable == total)
447+ return {instanceTy->wrapInOptionalType (), /* hasFailable=*/ false };
448+ // Otherwise there are two options.
449+ return {instanceTy, /* hasFailable*/ true };
450+ }
451+
452+ return {instanceTy, /* hasFailable=*/ false };
402453}
403454
404455// / If the given expression represents a chain of operators that only have
@@ -502,38 +553,14 @@ void forEachDisjunctionChoice(
502553 llvm::function_ref<void (Constraint *, ValueDecl *decl, FunctionType *)>
503554 callback) {
504555 for (auto constraint : disjunction->getNestedConstraints ()) {
505- if (constraint->isDisabled ())
506- continue ;
507-
508- if (constraint->getKind () != ConstraintKind::BindOverload)
509- continue ;
510-
511- auto choice = constraint->getOverloadChoice ();
512- auto *decl = choice.getDeclOrNull ();
556+ auto *decl =
557+ isViableOverloadChoice (cs, constraint, disjunction->getLocator ());
513558 if (!decl)
514559 continue ;
515560
516- // Ignore declarations that come from implicitly imported modules
517- // when `MemberImportVisibility` feature is enabled otherwise
518- // we might end up favoring an overload that would be diagnosed
519- // as unavailable later.
520- if (cs.getASTContext ().LangOpts .hasFeature (
521- Feature::MemberImportVisibility)) {
522- if (auto *useDC = constraint->getDeclContext ()) {
523- if (!useDC->isDeclImported (decl))
524- continue ;
525- }
526- }
527-
528- // If disjunction choice is unavailable or disfavored we cannot
529- // do anything with it.
530- if (decl->getAttrs ().hasAttribute <DisfavoredOverloadAttr>() ||
531- cs.isDeclUnavailable (decl, disjunction->getLocator ()))
532- continue ;
533-
534- Type overloadType =
535- cs.getEffectiveOverloadType (disjunction->getLocator (), choice,
536- /* allowMembers=*/ true , cs.DC );
561+ Type overloadType = cs.getEffectiveOverloadType (
562+ disjunction->getLocator (), constraint->getOverloadChoice (),
563+ /* allowMembers=*/ true , constraint->getOverloadUseDC ());
537564
538565 if (!overloadType || !overloadType->is <FunctionType>())
539566 continue ;
0 commit comments