@@ -344,6 +344,43 @@ static bool isSupportedDisjunction(Constraint *disjunction) {
344
344
});
345
345
}
346
346
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
+
347
384
// / Given the type variable that represents a result type of a
348
385
// / function call, check whether that call is to an initializer
349
386
// / and based on that deduce possible type for the result.
@@ -389,16 +426,30 @@ inferTypeFromInitializerResultType(ConstraintSystem &cs,
389
426
if (initRef == disjunctions.end ())
390
427
return {};
391
428
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 ;
400
435
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 };
402
453
}
403
454
404
455
// / If the given expression represents a chain of operators that only have
@@ -502,38 +553,14 @@ void forEachDisjunctionChoice(
502
553
llvm::function_ref<void (Constraint *, ValueDecl *decl, FunctionType *)>
503
554
callback) {
504
555
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 ());
513
558
if (!decl)
514
559
continue ;
515
560
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 ());
537
564
538
565
if (!overloadType || !overloadType->is <FunctionType>())
539
566
continue ;
0 commit comments