@@ -823,24 +823,13 @@ static PotentialBindings getPotentialBindings(ConstraintSystem &cs,
823
823
// Relational constraints: break out to look for types above/below.
824
824
break ;
825
825
826
- case ConstraintKind::DynamicTypeOf: {
827
- auto otherTy = constraint->getSecondType ();
828
- if (constraint->getSecondType ()->isEqual (typeVar))
829
- otherTy = constraint->getFirstType ();
830
-
831
- auto simplified = cs.simplifyType (otherTy);
832
- if (simplified->hasTypeVariable ())
833
- result.InvolvesTypeVariables = true ;
834
- continue ;
835
- }
836
-
837
826
case ConstraintKind::BridgingConversion:
838
827
case ConstraintKind::CheckedCast:
828
+ case ConstraintKind::DynamicTypeOf:
839
829
case ConstraintKind::EscapableFunctionOf:
840
830
case ConstraintKind::OpenedExistentialOf:
841
831
case ConstraintKind::KeyPath:
842
832
case ConstraintKind::KeyPathApplication:
843
- // FIXME: check for other type variables?
844
833
// Constraints from which we can't do anything.
845
834
continue ;
846
835
@@ -1038,17 +1027,6 @@ static PotentialBindings getPotentialBindings(ConstraintSystem &cs,
1038
1027
continue ;
1039
1028
}
1040
1029
1041
- // If the other side of an argument conversion is also a type
1042
- // variable, we shouldn't allow that to block us from attempting
1043
- // bindings if it is the only constraint involving other type
1044
- // variables. Doing this allows us to attempt a binding much
1045
- // earlier in solving which can result in backing out of
1046
- // solutions that cannot work due to conformance constraints.
1047
- if (constraint->getKind () ==
1048
- ConstraintKind::OperatorArgumentTupleConversion ||
1049
- constraint->getKind () == ConstraintKind::OperatorArgumentConversion)
1050
- continue ;
1051
-
1052
1030
result.InvolvesTypeVariables = true ;
1053
1031
continue ;
1054
1032
}
@@ -2411,81 +2389,6 @@ determineBestBindings(ConstraintSystem &CS) {
2411
2389
return std::make_pair (bestBindings, bestTypeVar);
2412
2390
}
2413
2391
2414
- Constraint *getApplicableFunctionConstraint (ConstraintSystem &CS,
2415
- Constraint *disjunction) {
2416
- auto *nested = disjunction->getNestedConstraints ().front ();
2417
- auto *firstTy = nested->getFirstType ()->castTo <TypeVariableType>();
2418
-
2419
- // FIXME: Is there something else we should be doing when a member
2420
- // of a disjunction is already bound because it's in an
2421
- // equivalence class?
2422
- if (CS.getFixedType (firstTy))
2423
- return nullptr ;
2424
-
2425
- Constraint *found = nullptr ;
2426
- for (auto *constraint : CS.getConstraintGraph ()[firstTy].getConstraints ()) {
2427
- if (constraint->getKind () != ConstraintKind::ApplicableFunction)
2428
- continue ;
2429
-
2430
- // Unapplied function reference, e.g. a.map(String.init)
2431
- if (!constraint->getSecondType ()->isEqual (firstTy))
2432
- return nullptr ;
2433
-
2434
- found = constraint;
2435
- break ;
2436
- }
2437
-
2438
- if (!found)
2439
- return nullptr ;
2440
-
2441
- #if !defined(NDEBUG)
2442
- for (auto *constraint : CS.getConstraintGraph ()[firstTy].getConstraints ()) {
2443
- if (constraint == found)
2444
- continue ;
2445
-
2446
- assert (constraint->getKind () != ConstraintKind::ApplicableFunction &&
2447
- " Type variable is involved in more than one applicable!" );
2448
- }
2449
- #endif
2450
-
2451
- return found;
2452
- }
2453
-
2454
- static unsigned countUnboundTypes (ConstraintSystem &CS,
2455
- Constraint *disjunction) {
2456
- auto *nested = disjunction->getNestedConstraints ().front ();
2457
- assert (nested->getKind () == ConstraintKind::BindOverload &&
2458
- " Expected bind overload constraint!" );
2459
-
2460
- auto firstTy = nested->getFirstType ();
2461
-
2462
- if (!firstTy->is <FunctionType>()) {
2463
- // If the disjunction is of the form "$T1 bound to..." we should have
2464
- // an associated applicable function constraint.
2465
- auto *applicableFn = getApplicableFunctionConstraint (CS, disjunction);
2466
-
2467
- // If we have an unapplied function, we should be able to leave
2468
- // that disjunction for last without any downside.
2469
- if (!applicableFn)
2470
- return 100 ;
2471
-
2472
- firstTy = applicableFn->getFirstType ();
2473
- }
2474
-
2475
- auto *fnTy = firstTy->getAs <FunctionType>();
2476
- assert (fnTy && " Expected function type!" );
2477
- auto simplifiedTy = CS.simplifyType (fnTy->getInput ());
2478
-
2479
- SmallPtrSet<TypeVariableType *, 4 > typeVars;
2480
- findInferableTypeVars (simplifiedTy, typeVars);
2481
- unsigned count = 0 ;
2482
- for (auto *tv : typeVars)
2483
- if (!CS.getFixedType (tv))
2484
- ++count;
2485
-
2486
- return count;
2487
- }
2488
-
2489
2392
bool ConstraintSystem::solveSimplified (
2490
2393
SmallVectorImpl<Solution> &solutions,
2491
2394
FreeTypeVariableBinding allowFreeTypeVariables) {
@@ -2542,78 +2445,29 @@ bool ConstraintSystem::solveSimplified(
2542
2445
return false ;
2543
2446
}
2544
2447
2545
- // Select a disjunction based on a few factors, prioritizing
2546
- // coercions and initializer disjunctions, followed by bind overload
2547
- // disjunctions with with fewest unbound argument types.
2548
- Optional<Constraint *> selection;
2549
- Optional<unsigned > lowestUnbound;
2550
- Optional<unsigned > lowestActive;
2551
-
2552
- for (auto candidate : disjunctions) {
2553
- unsigned countActive = candidate->countActiveNestedConstraints ();
2554
- // Skip disjunctions with no active constraints.
2555
- if (!countActive)
2556
- continue ;
2557
-
2558
- // If this is the first disjunction with an active constraint,
2559
- // consider this our selection until we find a better one.
2560
- if (!selection)
2561
- selection = candidate;
2562
-
2563
- if (auto loc = candidate->getLocator ()) {
2564
- // If we have a coercion disjunction remaining, select that as
2565
- // they tend to constraint type variables maximally and give us
2566
- // information about potential bindings.
2567
- if (auto anchor = loc->getAnchor ()) {
2568
- if (isa<CoerceExpr>(anchor)) {
2569
- selection = candidate;
2448
+ // Pick the smallest disjunction.
2449
+ // FIXME: This heuristic isn't great, but it helped somewhat for
2450
+ // overload sets.
2451
+ auto disjunction = disjunctions[0 ];
2452
+ auto bestSize = disjunction->countActiveNestedConstraints ();
2453
+ if (bestSize > 2 ) {
2454
+ for (auto contender : llvm::makeArrayRef (disjunctions).slice (1 )) {
2455
+ unsigned newSize = contender->countActiveNestedConstraints ();
2456
+ if (newSize < bestSize) {
2457
+ bestSize = newSize;
2458
+ disjunction = contender;
2459
+
2460
+ if (bestSize == 2 )
2570
2461
break ;
2571
- }
2572
- }
2573
-
2574
- // Initializers also provide a lot of information in the form of
2575
- // the result type and tend to split the system into independent
2576
- // pieces.
2577
- auto path = loc->getPath ();
2578
- if (!path.empty () &&
2579
- path.back ().getKind () ==
2580
- ConstraintLocator::PathElementKind::ConstructorMember) {
2581
- selection = candidate;
2582
- break ;
2583
2462
}
2584
2463
}
2585
-
2586
- // Attempt to find a bind overload disjunction before considering
2587
- // this one.
2588
- assert (!candidate->getNestedConstraints ().empty () &&
2589
- " Expected non-empty disjunction!" );
2590
- if (candidate->getNestedConstraints ().front ()->getKind () !=
2591
- ConstraintKind::BindOverload)
2592
- continue ;
2593
-
2594
- // Otherwise, attempt to count the number of unbound types used
2595
- // for bind overload disjunctions.
2596
- unsigned countUnbound = countUnboundTypes (*this , candidate);
2597
-
2598
- // If the number of unbound arguments is smaller than previous
2599
- // candidate, or if we had no previous candidate, this is our
2600
- // newest best option.
2601
- if (!lowestUnbound || countUnbound < lowestUnbound.getValue () ||
2602
- (countUnbound == lowestUnbound.getValue () &&
2603
- countActive < lowestActive.getValue ())) {
2604
- selection = candidate;
2605
- lowestUnbound = countUnbound;
2606
- lowestActive = countActive;
2607
- }
2608
2464
}
2609
2465
2610
2466
// If there are no active constraints in the disjunction, there is
2611
2467
// no solution.
2612
- if (!selection )
2468
+ if (bestSize == 0 )
2613
2469
return true ;
2614
2470
2615
- auto *disjunction = selection.getValue ();
2616
-
2617
2471
// Remove this disjunction constraint from the list.
2618
2472
auto afterDisjunction = InactiveConstraints.erase (disjunction);
2619
2473
CG.removeConstraint (disjunction);
0 commit comments