@@ -2077,8 +2077,11 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2,
2077
2077
// will also fail (because type can't satisfy it), and it's
2078
2078
// more interesting for diagnostics.
2079
2079
auto req = last->getAs <LocatorPathElt::AnyRequirement>();
2080
- if (type1->isHole () || (req &&
2081
- req->getRequirementKind () == RequirementKind::Superclass))
2080
+ if (!req)
2081
+ return getTypeMatchFailure (locator);
2082
+
2083
+ if (type1->isHole () ||
2084
+ req->getRequirementKind () == RequirementKind::Superclass)
2082
2085
return getTypeMatchSuccess ();
2083
2086
2084
2087
auto *fix = fixRequirementFailure (*this , type1, type2, locator);
@@ -2171,6 +2174,11 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2,
2171
2174
if (last->is <LocatorPathElt::FunctionResult>())
2172
2175
return getTypeMatchFailure (locator);
2173
2176
2177
+ // If instance types didn't line up correctly, let's produce a
2178
+ // diagnostic which mentions them together with their metatypes.
2179
+ if (last->is <LocatorPathElt::InstanceType>())
2180
+ return getTypeMatchFailure (locator);
2181
+
2174
2182
} else { // There are no elements in the path
2175
2183
auto *anchor = locator.getAnchor ();
2176
2184
if (!(anchor &&
@@ -2814,6 +2822,14 @@ bool ConstraintSystem::repairFailures(
2814
2822
return false ;
2815
2823
2816
2824
if (auto *coercion = dyn_cast<CoerceExpr>(anchor)) {
2825
+ // Coercion from T.Type to T.Protocol.
2826
+ if (hasConversionOrRestriction (
2827
+ ConversionRestrictionKind::MetatypeToExistentialMetatype))
2828
+ return false ;
2829
+
2830
+ if (hasConversionOrRestriction (ConversionRestrictionKind::Superclass))
2831
+ return false ;
2832
+
2817
2833
// Let's check whether the sub-expression is an optional type which
2818
2834
// is possible to unwrap (either by force or `??`) to satisfy the cast,
2819
2835
// otherwise we'd have to fallback to force downcast.
@@ -2839,10 +2855,11 @@ bool ConstraintSystem::repairFailures(
2839
2855
2840
2856
if (hasConversionOrRestriction (ConversionRestrictionKind::Existential))
2841
2857
return false ;
2842
-
2858
+
2843
2859
auto *fix = ContextualMismatch::create (*this , lhs, rhs,
2844
2860
getConstraintLocator (locator));
2845
2861
conversionsOrFixes.push_back (fix);
2862
+ return true ;
2846
2863
}
2847
2864
2848
2865
// This could be:
@@ -3486,15 +3503,17 @@ bool ConstraintSystem::repairFailures(
3486
3503
// If there is a deep equality, superclass restriction
3487
3504
// already recorded, let's not add bother ignoring
3488
3505
// contextual type, because actual fix is going to
3489
- // be perform once restriction is applied.
3490
- if (llvm::any_of (conversionsOrFixes,
3491
- [](const RestrictionOrFix &entry) -> bool {
3492
- return entry.IsRestriction &&
3493
- (entry.getRestriction () ==
3494
- ConversionRestrictionKind::Superclass ||
3495
- entry.getRestriction () ==
3496
- ConversionRestrictionKind::DeepEquality);
3497
- }))
3506
+ // be performed once restriction is applied.
3507
+ if (hasConversionOrRestriction (ConversionRestrictionKind::Superclass))
3508
+ break ;
3509
+
3510
+ if (hasConversionOrRestriction (
3511
+ ConversionRestrictionKind::MetatypeToExistentialMetatype))
3512
+ break ;
3513
+
3514
+ if (hasConversionOrRestriction (ConversionRestrictionKind::DeepEquality) &&
3515
+ !hasConversionOrRestriction (
3516
+ ConversionRestrictionKind::OptionalToOptional))
3498
3517
break ;
3499
3518
3500
3519
conversionsOrFixes.push_back (IgnoreContextualType::create (
@@ -8232,15 +8251,42 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
8232
8251
return recordFix (fix) ? SolutionKind::Error : SolutionKind::Solved;
8233
8252
};
8234
8253
8254
+ auto fixContextualFailure = [&](Type fromType, Type toType,
8255
+ ConstraintLocatorBuilder locator) -> bool {
8256
+ auto *loc = getConstraintLocator (locator);
8257
+ if (loc->isForAssignment () || loc->isForCoercion () ||
8258
+ loc->isForContextualType ()) {
8259
+ if (restriction == ConversionRestrictionKind::Superclass) {
8260
+ if (auto *fix =
8261
+ CoerceToCheckedCast::attempt (*this , fromType, toType, loc))
8262
+ return !recordFix (fix);
8263
+ }
8264
+
8265
+ auto *fix = ContextualMismatch::create (*this , fromType, toType, loc);
8266
+ return !recordFix (fix);
8267
+ }
8268
+
8269
+ return false ;
8270
+ };
8271
+
8235
8272
switch (restriction) {
8236
8273
// for $< in { <, <c, <oc }:
8237
8274
// T_i $< U_i ===> (T_i...) $< (U_i...)
8238
8275
case ConversionRestrictionKind::DeepEquality:
8239
8276
return matchDeepEqualityTypes (type1, type2, locator);
8240
8277
8241
- case ConversionRestrictionKind::Superclass:
8278
+ case ConversionRestrictionKind::Superclass: {
8242
8279
addContextualScore ();
8243
- return matchSuperclassTypes (type1, type2, subflags, locator);
8280
+
8281
+ auto result = matchSuperclassTypes (type1, type2, subflags, locator);
8282
+
8283
+ if (!(shouldAttemptFixes () && result.isFailure ()))
8284
+ return result;
8285
+
8286
+ return fixContextualFailure (type1, type2, locator)
8287
+ ? getTypeMatchSuccess ()
8288
+ : getTypeMatchFailure (locator);
8289
+ }
8244
8290
8245
8291
// for $< in { <, <c, <oc }:
8246
8292
// T $< U, U : P_i ===> T $< protocol<P_i...>
@@ -8255,15 +8301,23 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
8255
8301
// P : Q ===> T.Protocol $< Q.Type
8256
8302
// for P protocol, Q protocol,
8257
8303
// P $< Q ===> P.Type $< Q.Type
8258
- case ConversionRestrictionKind::MetatypeToExistentialMetatype:
8304
+ case ConversionRestrictionKind::MetatypeToExistentialMetatype: {
8259
8305
addContextualScore ();
8260
8306
8261
- return matchExistentialTypes (
8262
- type1->castTo <MetatypeType>()->getInstanceType (),
8263
- type2->castTo <ExistentialMetatypeType>()->getInstanceType (),
8264
- ConstraintKind::ConformsTo,
8265
- subflags,
8266
- locator.withPathElement (ConstraintLocator::InstanceType));
8307
+ auto instanceTy1 = type1->getMetatypeInstanceType ();
8308
+ auto instanceTy2 = type2->getMetatypeInstanceType ();
8309
+
8310
+ auto result = matchExistentialTypes (
8311
+ instanceTy1, instanceTy2, ConstraintKind::ConformsTo, subflags,
8312
+ locator.withPathElement (ConstraintLocator::InstanceType));
8313
+
8314
+ if (!(shouldAttemptFixes () && result.isFailure ()))
8315
+ return result;
8316
+
8317
+ return fixContextualFailure (type1, type2, locator)
8318
+ ? getTypeMatchSuccess ()
8319
+ : getTypeMatchFailure (locator);
8320
+ }
8267
8321
8268
8322
// for $< in { <, <c, <oc }:
8269
8323
// for P protocol, C class, D class,
@@ -8278,13 +8332,16 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
8278
8332
if (!superclass1)
8279
8333
return SolutionKind::Error;
8280
8334
8281
- return matchTypes (
8282
- superclass1 ,
8283
- instance2,
8284
- ConstraintKind::Subtype,
8285
- subflags,
8286
- locator. withPathElement (ConstraintLocator::InstanceType)) ;
8335
+ auto result =
8336
+ matchTypes (superclass1, instance2, ConstraintKind::Subtype, subflags ,
8337
+ locator. withPathElement (ConstraintLocator::InstanceType));
8338
+
8339
+ if (!( shouldAttemptFixes () && result. isFailure ()))
8340
+ return result ;
8287
8341
8342
+ return fixContextualFailure (type1, type2, locator)
8343
+ ? getTypeMatchSuccess ()
8344
+ : getTypeMatchFailure (locator);
8288
8345
}
8289
8346
// for $< in { <, <c, <oc }:
8290
8347
// T $< U ===> T $< U?
0 commit comments