@@ -5569,6 +5569,17 @@ bool ConstraintSystem::repairFailures(
5569
5569
return true;
5570
5570
};
5571
5571
5572
+ // Propagate a hole from one type to another. This is useful for contextual
5573
+ // types since type resolution forms a top-level ErrorType for types with
5574
+ // nested errors, e.g `S<@error_type>` becomes `@error_type`. As such, when
5575
+ // matching `S<$T0> == $T1` where `$T1` is a hole from a contextual type, we
5576
+ // want to eagerly turn `$T0` into a hole since it's likely that `$T1` would
5577
+ // have provided the contextual info for it.
5578
+ auto tryPropagateHole = [&](Type from, Type to) {
5579
+ if (from->isPlaceholder() && to->hasTypeVariable())
5580
+ recordTypeVariablesAsHoles(to);
5581
+ };
5582
+
5572
5583
if (path.empty()) {
5573
5584
if (!anchor)
5574
5585
return false;
@@ -6342,6 +6353,13 @@ bool ConstraintSystem::repairFailures(
6342
6353
6343
6354
case ConstraintLocator::ClosureBody:
6344
6355
case ConstraintLocator::ClosureResult: {
6356
+ // If either type is a placeholder, consider this fixed, eagerly propagating
6357
+ // a hole from the contextual type.
6358
+ if (lhs->isPlaceholder() || rhs->isPlaceholder()) {
6359
+ tryPropagateHole(rhs, lhs);
6360
+ return true;
6361
+ }
6362
+
6345
6363
if (repairByInsertingExplicitCall(lhs, rhs))
6346
6364
break;
6347
6365
@@ -6361,9 +6379,12 @@ bool ConstraintSystem::repairFailures(
6361
6379
}
6362
6380
6363
6381
case ConstraintLocator::ContextualType: {
6364
- // If either type is a placeholder, consider this fixed
6365
- if (lhs->isPlaceholder() || rhs->isPlaceholder())
6382
+ // If either type is a placeholder, consider this fixed, eagerly propagating
6383
+ // a hole from the contextual type.
6384
+ if (lhs->isPlaceholder() || rhs->isPlaceholder()) {
6385
+ tryPropagateHole(rhs, lhs);
6366
6386
return true;
6387
+ }
6367
6388
6368
6389
// If either side is not yet resolved, it's too early for this fix.
6369
6390
if (lhs->isTypeVariableOrMember() || rhs->isTypeVariableOrMember())
@@ -7002,6 +7023,13 @@ bool ConstraintSystem::repairFailures(
7002
7023
}
7003
7024
7004
7025
case ConstraintLocator::CoercionOperand: {
7026
+ // If either type is a placeholder, consider this fixed, eagerly propagating
7027
+ // a hole from the contextual type.
7028
+ if (lhs->isPlaceholder() || rhs->isPlaceholder()) {
7029
+ tryPropagateHole(rhs, lhs);
7030
+ return true;
7031
+ }
7032
+
7005
7033
auto *coercion = castToExpr<CoerceExpr>(anchor);
7006
7034
7007
7035
// Coercion from T.Type to T.Protocol.
0 commit comments