@@ -359,6 +359,40 @@ static Type substGenericFunctionType(GenericFunctionType *genericFnType,
359
359
fnType->getResult (), fnType->getExtInfo ());
360
360
}
361
361
362
+ InFlightSubstitution::InFlightSubstitution (TypeSubstitutionFn substType,
363
+ LookupConformanceFn lookupConformance,
364
+ SubstOptions options)
365
+ : Options(options),
366
+ BaselineSubstType(substType),
367
+ BaselineLookupConformance(lookupConformance) {
368
+ // FIXME: Don't substitute type parameters if one of the special flags is set.
369
+ Props |= RecursiveTypeProperties::HasTypeParameter;
370
+
371
+ // If none of the special flags are set, we substitute type parameters and
372
+ // primary archetypes only.
373
+ if (!Options.contains (SubstFlags::SubstitutePrimaryArchetypes) &&
374
+ !Options.contains (SubstFlags::SubstituteLocalArchetypes) &&
375
+ !Options.contains (SubstFlags::SubstituteOpaqueArchetypes)) {
376
+ Props |= RecursiveTypeProperties::HasPrimaryArchetype;
377
+ }
378
+
379
+ if (Options.contains (SubstFlags::SubstitutePrimaryArchetypes))
380
+ Props |= RecursiveTypeProperties::HasPrimaryArchetype;
381
+
382
+ if (Options.contains (SubstFlags::SubstituteLocalArchetypes)) {
383
+ Props |= RecursiveTypeProperties::HasOpenedExistential;
384
+ Props |= RecursiveTypeProperties::HasElementArchetype;
385
+ }
386
+
387
+ if (Options.contains (SubstFlags::SubstituteOpaqueArchetypes))
388
+ Props |= RecursiveTypeProperties::HasOpaqueArchetype;
389
+ }
390
+
391
+ bool InFlightSubstitution::isInvariant (Type derivedType) const {
392
+ // If none of the bits are set, the type won't be changed by substitution.
393
+ return !(derivedType->getRecursiveProperties ().getBits () & Props.getBits ());
394
+ }
395
+
362
396
void InFlightSubstitution::expandPackExpansionShape (Type origShape,
363
397
llvm::function_ref<void (Type substComponentShape)> handleComponent) {
364
398
@@ -470,16 +504,6 @@ InFlightSubstitution::lookupConformance(CanType dependentType,
470
504
return substPackPatterns[index];
471
505
}
472
506
473
- bool InFlightSubstitution::isInvariant (Type derivedType) const {
474
- if (derivedType->hasPrimaryArchetype () || derivedType->hasTypeParameter ())
475
- return false ;
476
- if (shouldSubstituteLocalArchetypes () && derivedType->hasLocalArchetype ())
477
- return false ;
478
- if (shouldSubstituteOpaqueArchetypes () && derivedType->hasOpaqueArchetype ())
479
- return false ;
480
- return true ;
481
- }
482
-
483
507
namespace {
484
508
485
509
class TypeSubstituter : public TypeTransform <TypeSubstituter> {
@@ -522,6 +546,9 @@ class TypeSubstituter : public TypeTransform<TypeSubstituter> {
522
546
523
547
std::optional<Type>
524
548
TypeSubstituter::transform (TypeBase *type, TypePosition position) {
549
+ if (IFS.isInvariant (type))
550
+ return Type (type);
551
+
525
552
return std::nullopt;
526
553
}
527
554
0 commit comments