@@ -5569,6 +5569,17 @@ bool ConstraintSystem::repairFailures(
55695569 return true;
55705570 };
55715571
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+
55725583 if (path.empty()) {
55735584 if (!anchor)
55745585 return false;
@@ -6342,6 +6353,13 @@ bool ConstraintSystem::repairFailures(
63426353
63436354 case ConstraintLocator::ClosureBody:
63446355 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+
63456363 if (repairByInsertingExplicitCall(lhs, rhs))
63466364 break;
63476365
@@ -6361,9 +6379,12 @@ bool ConstraintSystem::repairFailures(
63616379 }
63626380
63636381 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);
63666386 return true;
6387+ }
63676388
63686389 // If either side is not yet resolved, it's too early for this fix.
63696390 if (lhs->isTypeVariableOrMember() || rhs->isTypeVariableOrMember())
@@ -7002,6 +7023,13 @@ bool ConstraintSystem::repairFailures(
70027023 }
70037024
70047025 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+
70057033 auto *coercion = castToExpr<CoerceExpr>(anchor);
70067034
70077035 // Coercion from T.Type to T.Protocol.
0 commit comments