@@ -359,6 +359,40 @@ static Type substGenericFunctionType(GenericFunctionType *genericFnType,
359359 fnType->getResult (), fnType->getExtInfo ());
360360}
361361
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+
362396void InFlightSubstitution::expandPackExpansionShape (Type origShape,
363397 llvm::function_ref<void (Type substComponentShape)> handleComponent) {
364398
@@ -470,16 +504,6 @@ InFlightSubstitution::lookupConformance(CanType dependentType,
470504 return substPackPatterns[index];
471505}
472506
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-
483507namespace {
484508
485509class TypeSubstituter : public TypeTransform <TypeSubstituter> {
@@ -522,6 +546,9 @@ class TypeSubstituter : public TypeTransform<TypeSubstituter> {
522546
523547std::optional<Type>
524548TypeSubstituter::transform (TypeBase *type, TypePosition position) {
549+ if (IFS.isInvariant (type))
550+ return Type (type);
551+
525552 return std::nullopt ;
526553}
527554
0 commit comments