@@ -2316,8 +2316,16 @@ bool TypeBase::isTriviallyRepresentableIn(ForeignLanguage language,
2316
2316
llvm_unreachable (" Unhandled ForeignRepresentableKind in switch." );
2317
2317
}
2318
2318
2319
+ namespace {
2320
+ enum class ParameterPosition {
2321
+ NotParameter,
2322
+ Parameter,
2323
+ ParameterTupleElement
2324
+ };
2325
+ } // end anonymous namespace
2326
+
2319
2327
static bool matches (CanType t1, CanType t2, TypeMatchOptions matchMode,
2320
- bool isParameter , bool insideOptional,
2328
+ ParameterPosition paramPosition , bool insideOptional,
2321
2329
LazyResolver *resolver) {
2322
2330
if (t1 == t2) return true ;
2323
2331
@@ -2329,22 +2337,22 @@ static bool matches(CanType t1, CanType t2, TypeMatchOptions matchMode,
2329
2337
// Optional-to-optional.
2330
2338
if (auto obj1 = t1.getAnyOptionalObjectType ()) {
2331
2339
// Allow T? and T! to freely match one another.
2332
- return matches (obj1, obj2, matchMode, /* isParameter= */ false ,
2340
+ return matches (obj1, obj2, matchMode, ParameterPosition::NotParameter ,
2333
2341
/* insideOptional=*/ true , resolver);
2334
2342
}
2335
2343
2336
2344
// Value-to-optional.
2337
2345
if (matchMode.contains (TypeMatchFlags::AllowOverride) ||
2338
2346
matchMode.contains (TypeMatchFlags::AllowTopLevelOptionalMismatch)) {
2339
- return matches (t1, obj2, matchMode, /* isParameter= */ false ,
2347
+ return matches (t1, obj2, matchMode, ParameterPosition::NotParameter ,
2340
2348
/* insideOptional=*/ true , resolver);
2341
2349
}
2342
2350
2343
2351
} else if (matchMode.contains (
2344
2352
TypeMatchFlags::AllowTopLevelOptionalMismatch)) {
2345
2353
// Optional-to-value, normally disallowed.
2346
2354
if (auto obj1 = t1.getAnyOptionalObjectType ()) {
2347
- return matches (obj1, t2, matchMode, /* isParameter= */ false ,
2355
+ return matches (obj1, t2, matchMode, ParameterPosition::NotParameter ,
2348
2356
/* insideOptional=*/ true , resolver);
2349
2357
}
2350
2358
}
@@ -2354,18 +2362,30 @@ static bool matches(CanType t1, CanType t2, TypeMatchOptions matchMode,
2354
2362
if (auto tuple2 = dyn_cast<TupleType>(t2)) {
2355
2363
// We only ever look into singleton tuples on the RHS if we're
2356
2364
// certain that the LHS isn't also a singleton tuple.
2365
+ ParameterPosition elementPosition;
2366
+ switch (paramPosition) {
2367
+ case ParameterPosition::NotParameter:
2368
+ case ParameterPosition::ParameterTupleElement:
2369
+ elementPosition = ParameterPosition::NotParameter;
2370
+ break ;
2371
+ case ParameterPosition::Parameter:
2372
+ elementPosition = ParameterPosition::ParameterTupleElement;
2373
+ break ;
2374
+ }
2375
+
2357
2376
auto tuple1 = dyn_cast<TupleType>(t1);
2358
2377
if (!tuple1 || tuple1->getNumElements () != tuple2->getNumElements ()) {
2359
2378
if (tuple2->getNumElements () == 1 ) {
2360
- return matches (t1, tuple2.getElementType (0 ), matchMode, isParameter ,
2379
+ return matches (t1, tuple2.getElementType (0 ), matchMode, elementPosition ,
2361
2380
/* insideOptional=*/ false , resolver);
2362
2381
}
2363
2382
return false ;
2364
2383
}
2365
2384
2366
2385
for (auto i : indices (tuple1.getElementTypes ())) {
2367
2386
if (!matches (tuple1.getElementType (i), tuple2.getElementType (i),
2368
- matchMode, isParameter, /* insideOptional=*/ false , resolver)){
2387
+ matchMode, elementPosition, /* insideOptional=*/ false ,
2388
+ resolver)){
2369
2389
return false ;
2370
2390
}
2371
2391
}
@@ -2393,13 +2413,17 @@ static bool matches(CanType t1, CanType t2, TypeMatchOptions matchMode,
2393
2413
2394
2414
// Inputs are contravariant, results are covariant.
2395
2415
return (matches (fn2.getInput (), fn1.getInput (), matchMode,
2396
- /* isParameter=*/ true , /* insideOptional=*/ false , resolver) &&
2416
+ ParameterPosition::Parameter, /* insideOptional=*/ false ,
2417
+ resolver) &&
2397
2418
matches (fn1.getResult (), fn2.getResult (), matchMode,
2398
- /* isParameter=*/ false , /* insideOptional=*/ false , resolver));
2419
+ ParameterPosition::NotParameter, /* insideOptional=*/ false ,
2420
+ resolver));
2399
2421
}
2400
2422
2401
2423
if (matchMode.contains (TypeMatchFlags::AllowNonOptionalForIUOParam) &&
2402
- isParameter && !insideOptional) {
2424
+ (paramPosition == ParameterPosition::Parameter ||
2425
+ paramPosition == ParameterPosition::ParameterTupleElement) &&
2426
+ !insideOptional) {
2403
2427
// Allow T to override T! in certain cases.
2404
2428
if (auto obj1 = t1->getImplicitlyUnwrappedOptionalObjectType ()) {
2405
2429
t1 = obj1->getCanonicalType ();
@@ -2412,13 +2436,18 @@ static bool matches(CanType t1, CanType t2, TypeMatchOptions matchMode,
2412
2436
if (t2->isExactSuperclassOf (t1))
2413
2437
return true ;
2414
2438
2439
+ if (matchMode.contains (TypeMatchFlags::AllowABICompatible))
2440
+ if (isABICompatibleEvenAddingOptional (t1, t2))
2441
+ return true ;
2442
+
2415
2443
return false ;
2416
2444
}
2417
2445
2418
2446
bool TypeBase::matches (Type other, TypeMatchOptions matchMode,
2419
2447
LazyResolver *resolver) {
2420
2448
return ::matches (getCanonicalType (), other->getCanonicalType (), matchMode,
2421
- /* isParameter=*/ false , /* insideOptional=*/ false , resolver);
2449
+ ParameterPosition::NotParameter, /* insideOptional=*/ false ,
2450
+ resolver);
2422
2451
}
2423
2452
2424
2453
// / getNamedElementId - If this tuple has a field with the specified name,
0 commit comments