1919#include " swift/AST/ASTContext.h"
2020#include " swift/AST/ExistentialLayout.h"
2121#include " swift/AST/ProtocolConformance.h"
22+ #include " swift/AST/TypeTransform.h"
2223#include " swift/Basic/Assertions.h"
2324#include " swift/Basic/Defer.h"
2425
@@ -262,33 +263,49 @@ GenericEnvironment::GenericEnvironment(GenericSignature signature,
262263 assert (i == openedPacksBuffer.size ());
263264}
264265
265- void GenericEnvironment::addMapping (GenericParamKey key,
266- Type contextType) {
267- // Find the index into the parallel arrays of generic parameters and
268- // context types.
269- auto genericParams = getGenericParams ();
270- unsigned index = key.findIndexIn (genericParams);
271- assert (genericParams[index] == key && " Bad generic parameter" );
266+ class GenericEnvironment ::NestedTypeStorage
267+ : public llvm::DenseMap<CanType, Type> { };
268+
269+ void GenericEnvironment::addMapping (CanType depType, Type contextType) {
270+ if (auto genericParam = dyn_cast<GenericTypeParamType>(depType)) {
271+ GenericParamKey key (genericParam);
272272
273- // Add the mapping from the generic parameter to the context type.
274- assert (getContextTypes ()[index].isNull () ||
275- getContextTypes ()[index]->is <ErrorType>() &&
276- " Already recoded this mapping" );
277- getContextTypes ()[index] = contextType;
273+ // Find the index into the parallel arrays of generic parameters and
274+ // context types.
275+ auto genericParams = getGenericParams ();
276+ unsigned index = key.findIndexIn (genericParams);
277+ assert (genericParams[index] == key && " Bad generic parameter" );
278+
279+ // Add the mapping from the generic parameter to the context type.
280+ assert (getContextTypes ()[index].isNull () ||
281+ getContextTypes ()[index]->is <ErrorType>() &&
282+ " Already recoded this mapping" );
283+ getContextTypes ()[index] = contextType;
284+ } else {
285+ getOrCreateNestedTypeStorage ()[depType] = contextType;
286+ }
278287}
279288
280- std::optional<Type>
281- GenericEnvironment::getMappingIfPresent (GenericParamKey key) const {
282- // Find the index into the parallel arrays of generic parameters and
283- // context types.
284- auto genericParams = getGenericParams ();
285- unsigned index = key.findIndexIn (genericParams);
286- assert (genericParams[index] == key && " Bad generic parameter" );
289+ Type GenericEnvironment::getMappingIfPresent (CanType depType) const {
290+ if (auto genericParam = dyn_cast<GenericTypeParamType>(depType)) {
291+ GenericParamKey key (genericParam);
287292
288- if (auto type = getContextTypes ()[index])
289- return type;
293+ // Find the index into the parallel arrays of generic parameters and
294+ // context types.
295+ auto genericParams = getGenericParams ();
296+ unsigned index = key.findIndexIn (genericParams);
297+ assert (genericParams[index] == key && " Bad generic parameter" );
290298
291- return std::nullopt ;
299+ return getContextTypes ()[index];
300+ } else {
301+ auto &storage = const_cast <GenericEnvironment *>(this )
302+ ->getOrCreateNestedTypeStorage ();
303+ auto found = storage.find (depType);
304+ if (found != storage.end ())
305+ return found->second ;
306+
307+ return Type ();
308+ }
292309}
293310
294311Type
@@ -337,9 +354,6 @@ Type TypeBase::mapTypeOutOfContext() {
337354 SubstFlags::SubstitutePrimaryArchetypes);
338355}
339356
340- class GenericEnvironment ::NestedTypeStorage
341- : public llvm::DenseMap<CanType, Type> { };
342-
343357auto GenericEnvironment::getOrCreateNestedTypeStorage () -> NestedTypeStorage & {
344358 if (nestedTypeStorage)
345359 return *nestedTypeStorage;
@@ -355,35 +369,41 @@ auto GenericEnvironment::getOrCreateNestedTypeStorage() -> NestedTypeStorage & {
355369
356370Type
357371GenericEnvironment::getOrCreateArchetypeFromInterfaceType (Type depType) {
372+ auto canType = depType->getCanonicalType ();
373+
374+ // Have we seen this exact type parameter before?
375+ if (auto type = getMappingIfPresent (canType))
376+ return type;
377+
358378 auto genericSig = getGenericSignature ();
359- auto requirements = genericSig->getLocalRequirements (depType);
360379
361- if (requirements. concreteType )
362- return mapTypeIntoContext (requirements. concreteType );
380+ // Reduce it.
381+ auto reducedType = genericSig. getReducedType (canType );
363382
364- assert (requirements.anchor && " No anchor or concrete type?" );
383+ // If this type parameter is equivalent to a concrete type,
384+ // map the concrete type into context and cache the result.
385+ if (!reducedType->isTypeParameter ()) {
386+ auto result = mapTypeIntoContext (reducedType);
387+ addMapping (canType, result);
388+ return result;
389+ }
365390
366391 auto &ctx = genericSig->getASTContext ();
367392
368- // First, write an ErrorType to the location where this type is cached,
369- // to catch re-entrant lookups that might arise from an invalid generic
370- // signature (eg, <X where X == Array<X>>).
371- CanDependentMemberType nestedType;
372- GenericTypeParamType *genericParam = nullptr ;
373- if (auto depMemTy = requirements.anchor ->getAs <DependentMemberType>()) {
374- nestedType = cast<DependentMemberType>(depMemTy->getCanonicalType ());
375- auto &entry = getOrCreateNestedTypeStorage ()[nestedType];
376- if (entry)
377- return entry;
378-
379- entry = ErrorType::get (ctx);
380- } else {
381- genericParam = requirements.anchor ->castTo <GenericTypeParamType>();
382- if (auto type = getMappingIfPresent (genericParam))
383- return *type;
384- addMapping (genericParam, ErrorType::get (ctx));
393+ // If the original type parameter was not reduced, see if we have an
394+ // archetype for the reduced type parameter.
395+ if (canType != reducedType) {
396+ if (auto type = getMappingIfPresent (reducedType)) {
397+ // Cache the result.
398+ addMapping (canType, type);
399+ return type;
400+ }
385401 }
386402
403+ // Otherwise, we're going to create a new archetype. Look up its
404+ // requirements.
405+ auto requirements = genericSig->getLocalRequirements (reducedType);
406+
387407 // Substitute into the superclass.
388408 Type superclass = requirements.superclass ;
389409 if (superclass && superclass->hasTypeParameter ()) {
@@ -394,16 +414,18 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
394414
395415 Type result;
396416
397- auto rootGP = requirements.anchor ->getRootGenericParam ();
417+ auto sugaredType = genericSig->getSugaredType (reducedType);
418+
419+ auto rootGP = reducedType->getRootGenericParam ();
398420 switch (getKind ()) {
399421 case Kind::Primary:
400422 if (rootGP->isParameterPack ()) {
401- result = PackArchetypeType::get (ctx, this , requirements. anchor ,
423+ result = PackArchetypeType::get (ctx, this , sugaredType ,
402424 requirements.packShape ,
403425 requirements.protos , superclass,
404426 requirements.layout );
405427 } else {
406- result = PrimaryArchetypeType::getNew (ctx, this , requirements. anchor ,
428+ result = PrimaryArchetypeType::getNew (ctx, this , sugaredType ,
407429 requirements.protos , superclass,
408430 requirements.layout );
409431 }
@@ -415,19 +437,19 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
415437 // represents an opaque declaration, then apply the outer substitutions.
416438 // It would be incorrect to build an opaque type archetype here.
417439 if (rootGP->getDepth () < genericSig->getMaxDepth ()) {
418- result = maybeApplyOuterContextSubstitutions (requirements. anchor );
440+ result = maybeApplyOuterContextSubstitutions (reducedType );
419441 break ;
420442 }
421443
422- result = OpaqueTypeArchetypeType::getNew (this , requirements. anchor ,
444+ result = OpaqueTypeArchetypeType::getNew (this , sugaredType ,
423445 requirements.protos , superclass,
424446 requirements.layout );
425447 break ;
426448 }
427449
428450 case Kind::OpenedExistential: {
429451 if (rootGP->getDepth () < genericSig->getMaxDepth ()) {
430- result = maybeApplyOuterContextSubstitutions (requirements. anchor );
452+ result = maybeApplyOuterContextSubstitutions (reducedType );
431453 break ;
432454 }
433455
@@ -439,16 +461,16 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
439461 // For compatibility, continue using the existential layout's version when
440462 // the interface type is a generic parameter. We should align these at
441463 // some point.
442- if (depType-> is <GenericTypeParamType>()) {
464+ if (isa <GenericTypeParamType>(reducedType )) {
443465 auto layout = getOpenedExistentialType ()->getExistentialLayout ();
444466 SmallVector<ProtocolDecl *, 2 > protos;
445467 for (auto proto : layout.getProtocols ())
446468 protos.push_back (proto);
447469
448- result = OpenedArchetypeType::getNew (this , requirements. anchor , protos,
470+ result = OpenedArchetypeType::getNew (this , sugaredType , protos,
449471 superclass, requirements.layout );
450472 } else {
451- result = OpenedArchetypeType::getNew (this , requirements. anchor ,
473+ result = OpenedArchetypeType::getNew (this , sugaredType ,
452474 requirements.protos , superclass,
453475 requirements.layout );
454476 }
@@ -458,71 +480,87 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
458480
459481 case Kind::OpenedElement: {
460482 if (rootGP->getDepth () < genericSig->getMaxDepth ()) {
461- result = maybeApplyOuterContextSubstitutions (requirements. anchor );
483+ result = maybeApplyOuterContextSubstitutions (reducedType );
462484 break ;
463485 }
464486
465- result = ElementArchetypeType::getNew (this , requirements. anchor ,
487+ result = ElementArchetypeType::getNew (this , sugaredType ,
466488 requirements.protos , superclass,
467489 requirements.layout );
468490 break ;
469491 }
470492 }
471493
472- if (genericParam)
473- addMapping (genericParam , result);
474- else
475- getOrCreateNestedTypeStorage ()[nestedType] = result;
494+ // Cache the result.
495+ addMapping (canType , result);
496+ if (canType != reducedType)
497+ addMapping (reducedType, result) ;
476498
477499 return result;
478500}
479501
480502Type QueryInterfaceTypeSubstitutions::operator ()(SubstitutableType *type) const {
481- if (auto gp = type->getAs <GenericTypeParamType>()) {
482- // Find the index into the parallel arrays of generic parameters and
483- // context types.
484- auto genericParams = self->getGenericParams ();
485- GenericParamKey key (gp);
503+ auto gp = type->castTo <GenericTypeParamType>();
486504
487- // Make sure that this generic parameter is from this environment.
488- unsigned index = key. findIndexIn (genericParams);
489- if (index == genericParams. size () || genericParams[index] != key)
490- return Type ( );
505+ // Find the index into the parallel arrays of generic parameters and
506+ // context types.
507+ auto genericParams = self-> getGenericParams ();
508+ GenericParamKey key (gp );
491509
492- // If the context type isn't already known, lazily create it.
493- auto mutableSelf = const_cast <GenericEnvironment *>(self);
494- Type &contextType = mutableSelf-> getContextTypes ()[index] ;
495- if (contextType )
496- return contextType ;
510+ // Make sure that this generic parameter is from this environment and
511+ // return substitution failure if not.
512+ unsigned index = key. findIndexIn (genericParams) ;
513+ if (index == genericParams. size () )
514+ return Type () ;
497515
498- auto result = mutableSelf->getOrCreateArchetypeFromInterfaceType (type);
516+ // If the context type isn't already known, lazily create it.
517+ if (auto contextType = self->getContextTypes ()[index])
518+ return contextType;
499519
500- assert (!contextType ||
501- contextType->isEqual (result) ||
502- contextType->is <ErrorType>());
503- contextType = result;
504- return result;
520+ return const_cast <GenericEnvironment *>(self)
521+ ->getOrCreateArchetypeFromInterfaceType (gp);
522+ }
523+
524+ namespace {
525+
526+ struct MapTypeIntoContext : TypeTransform<MapTypeIntoContext> {
527+ GenericEnvironment *env;
528+
529+ explicit MapTypeIntoContext (GenericEnvironment *env) : env(env) {}
530+
531+ std::optional<Type> transform (TypeBase *type, TypePosition pos) {
532+ if (!type->hasTypeParameter ())
533+ return Type (type);
534+
535+ return std::nullopt ;
505536 }
506537
507- return Type ();
538+ Type transformGenericTypeParamType (GenericTypeParamType *param,
539+ TypePosition pos) {
540+ return env->getOrCreateArchetypeFromInterfaceType (param);
541+ }
542+
543+ Type transformDependentMemberType (DependentMemberType *dependent,
544+ TypePosition pos) {
545+ return env->getOrCreateArchetypeFromInterfaceType (dependent);
546+ }
547+
548+ CanType transformSILField (CanType fieldTy, TypePosition pos) {
549+ return fieldTy;
550+ }
551+ };
552+
508553}
509554
510555Type GenericEnvironment::mapTypeIntoContext (Type type) const {
511556 assert (!type->hasPrimaryArchetype () && " already have a contextual type" );
512-
513- Type result = type.subst (QueryInterfaceTypeSubstitutions (this ),
514- LookUpConformanceInModule (),
515- SubstFlags::PreservePackExpansionLevel);
516- ASSERT (getKind () != Kind::Primary || !result->hasTypeParameter ());
517- return result;
557+ return MapTypeIntoContext (const_cast <GenericEnvironment *>(this ))
558+ .doIt (type, TypePosition::Invariant);
518559}
519560
520561Type GenericEnvironment::mapTypeIntoContext (GenericTypeParamType *type) const {
521- auto self = const_cast <GenericEnvironment *>(this );
522- Type result = QueryInterfaceTypeSubstitutions (self)(type);
523- if (!result)
524- return ErrorType::get (type);
525- return result;
562+ return const_cast <GenericEnvironment *>(this )
563+ ->getOrCreateArchetypeFromInterfaceType (type);
526564}
527565
528566namespace {
0 commit comments