@@ -2316,13 +2316,9 @@ bool TypeBase::isTriviallyRepresentableIn(ForeignLanguage language,
2316
2316
llvm_unreachable (" Unhandled ForeignRepresentableKind in switch." );
2317
2317
}
2318
2318
2319
- // / Is t1 not just a subtype of t2, but one such that its values are
2320
- // / trivially convertible to values of the other?
2321
- static bool canOverride (CanType t1, CanType t2,
2322
- OverrideMatchMode matchMode,
2323
- bool isParameter,
2324
- bool insideOptional,
2325
- LazyResolver *resolver) {
2319
+ static bool matches (CanType t1, CanType t2, TypeMatchOptions matchMode,
2320
+ bool isParameter, bool insideOptional,
2321
+ LazyResolver *resolver) {
2326
2322
if (t1 == t2) return true ;
2327
2323
2328
2324
// First try unwrapping optionals.
@@ -2332,26 +2328,24 @@ static bool canOverride(CanType t1, CanType t2,
2332
2328
if (auto obj2 = t2.getAnyOptionalObjectType ()) {
2333
2329
// Optional-to-optional.
2334
2330
if (auto obj1 = t1.getAnyOptionalObjectType ()) {
2335
- // Allow T? and T! to freely override one another.
2336
- return canOverride (obj1, obj2, matchMode,
2337
- /* isParameter=*/ false ,
2338
- /* insideOptional=*/ true ,
2339
- resolver);
2331
+ // Allow T? and T! to freely match one another.
2332
+ return matches (obj1, obj2, matchMode, /* isParameter=*/ false ,
2333
+ /* insideOptional=*/ true , resolver);
2340
2334
}
2341
2335
2342
2336
// Value-to-optional.
2343
- return canOverride (t1, obj2, matchMode,
2344
- /* isParameter=*/ false ,
2345
- /* insideOptional=*/ true ,
2346
- resolver);
2337
+ if (matchMode.contains (TypeMatchFlags::AllowOverride) ||
2338
+ matchMode.contains (TypeMatchFlags::AllowTopLevelOptionalMismatch)) {
2339
+ return matches (t1, obj2, matchMode, /* isParameter=*/ false ,
2340
+ /* insideOptional=*/ true , resolver);
2341
+ }
2347
2342
2348
- } else if (matchMode == OverrideMatchMode::AllowTopLevelOptionalMismatch) {
2343
+ } else if (matchMode.contains (
2344
+ TypeMatchFlags::AllowTopLevelOptionalMismatch)) {
2349
2345
// Optional-to-value, normally disallowed.
2350
2346
if (auto obj1 = t1.getAnyOptionalObjectType ()) {
2351
- return canOverride (obj1, t2, matchMode,
2352
- /* isParameter=*/ false ,
2353
- /* insideOptional=*/ true ,
2354
- resolver);
2347
+ return matches (obj1, t2, matchMode, /* isParameter=*/ false ,
2348
+ /* insideOptional=*/ true , resolver);
2355
2349
}
2356
2350
}
2357
2351
}
@@ -2362,54 +2356,49 @@ static bool canOverride(CanType t1, CanType t2,
2362
2356
// certain that the LHS isn't also a singleton tuple.
2363
2357
auto tuple1 = dyn_cast<TupleType>(t1);
2364
2358
if (!tuple1 || tuple1->getNumElements () != tuple2->getNumElements ()) {
2365
- if (tuple2->getNumElements () == 1 )
2366
- return canOverride (t1, tuple2.getElementType (0 ),
2367
- matchMode,
2368
- isParameter,
2369
- /* insideOptional=*/ false ,
2370
- resolver);
2359
+ if (tuple2->getNumElements () == 1 ) {
2360
+ return matches (t1, tuple2.getElementType (0 ), matchMode, isParameter,
2361
+ /* insideOptional=*/ false , resolver);
2362
+ }
2371
2363
return false ;
2372
2364
}
2373
2365
2374
2366
for (auto i : indices (tuple1.getElementTypes ())) {
2375
- if (!canOverride (tuple1.getElementType (i),
2376
- tuple2.getElementType (i),
2377
- matchMode,
2378
- isParameter,
2379
- /* insideOptional=*/ false ,
2380
- resolver))
2367
+ if (!matches (tuple1.getElementType (i), tuple2.getElementType (i),
2368
+ matchMode, isParameter, /* insideOptional=*/ false , resolver)){
2381
2369
return false ;
2370
+ }
2382
2371
}
2383
2372
return true ;
2384
2373
}
2385
2374
2386
- // Function-to-function. (Polymorphic functions?)
2375
+ // Function-to-function.
2376
+ // FIXME: This completely leaves out generic functions.
2387
2377
if (auto fn2 = dyn_cast<FunctionType>(t2)) {
2388
2378
auto fn1 = dyn_cast<FunctionType>(t1);
2389
2379
if (!fn1)
2390
2380
return false ;
2391
2381
2392
- // Allow the base type to be throwing even if the overriding type isn't
2382
+ // When checking overrides, allow the base type to be throwing even if the
2383
+ // overriding type isn't.
2393
2384
auto ext1 = fn1->getExtInfo ();
2394
2385
auto ext2 = fn2->getExtInfo ();
2395
- if (ext2.throws ()) ext1 = ext1.withThrows (true );
2386
+ if (matchMode.contains (TypeMatchFlags::AllowOverride)) {
2387
+ if (ext2.throws ()) {
2388
+ ext1 = ext1.withThrows (true );
2389
+ }
2390
+ }
2396
2391
if (ext1 != ext2)
2397
2392
return false ;
2398
2393
2399
2394
// Inputs are contravariant, results are covariant.
2400
- return (canOverride (fn2.getInput (), fn1.getInput (),
2401
- matchMode,
2402
- /* isParameter=*/ true ,
2403
- /* insideOptional=*/ false ,
2404
- resolver) &&
2405
- canOverride (fn1.getResult (), fn2.getResult (),
2406
- matchMode,
2407
- /* isParameter=*/ false ,
2408
- /* insideOptional=*/ false ,
2409
- resolver));
2410
- }
2411
-
2412
- if (matchMode == OverrideMatchMode::AllowNonOptionalForIUOParam &&
2395
+ return (matches (fn2.getInput (), fn1.getInput (), matchMode,
2396
+ /* isParameter=*/ true , /* insideOptional=*/ false , resolver) &&
2397
+ matches (fn1.getResult (), fn2.getResult (), matchMode,
2398
+ /* isParameter=*/ false , /* insideOptional=*/ false , resolver));
2399
+ }
2400
+
2401
+ if (matchMode.contains (TypeMatchFlags::AllowNonOptionalForIUOParam) &&
2413
2402
isParameter && !insideOptional) {
2414
2403
// Allow T to override T! in certain cases.
2415
2404
if (auto obj1 = t1->getImplicitlyUnwrappedOptionalObjectType ()) {
@@ -2419,16 +2408,17 @@ static bool canOverride(CanType t1, CanType t2,
2419
2408
}
2420
2409
2421
2410
// Class-to-class.
2422
- return t2->isExactSuperclassOf (t1);
2411
+ if (matchMode.contains (TypeMatchFlags::AllowOverride))
2412
+ if (t2->isExactSuperclassOf (t1))
2413
+ return true ;
2414
+
2415
+ return false ;
2423
2416
}
2424
2417
2425
- bool TypeBase::canOverride (Type other, OverrideMatchMode matchMode,
2426
- LazyResolver *resolver) {
2427
- return ::canOverride (getCanonicalType (), other->getCanonicalType (),
2428
- matchMode,
2429
- /* isParameter=*/ false ,
2430
- /* insideOptional=*/ false ,
2431
- resolver);
2418
+ bool TypeBase::matches (Type other, TypeMatchOptions matchMode,
2419
+ LazyResolver *resolver) {
2420
+ return ::matches (getCanonicalType (), other->getCanonicalType (), matchMode,
2421
+ /* isParameter=*/ false , /* insideOptional=*/ false , resolver);
2432
2422
}
2433
2423
2434
2424
// / getNamedElementId - If this tuple has a field with the specified name,
0 commit comments