19
19
#include " swift/AST/ASTContext.h"
20
20
#include " swift/AST/ExistentialLayout.h"
21
21
#include " swift/AST/ProtocolConformance.h"
22
+ #include " swift/AST/TypeTransform.h"
22
23
#include " swift/Basic/Assertions.h"
23
24
#include " swift/Basic/Defer.h"
24
25
@@ -262,33 +263,49 @@ GenericEnvironment::GenericEnvironment(GenericSignature signature,
262
263
assert (i == openedPacksBuffer.size ());
263
264
}
264
265
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);
272
272
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
+ }
278
287
}
279
288
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);
287
292
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" );
290
298
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
+ }
292
309
}
293
310
294
311
Type
@@ -337,9 +354,6 @@ Type TypeBase::mapTypeOutOfContext() {
337
354
SubstFlags::SubstitutePrimaryArchetypes);
338
355
}
339
356
340
- class GenericEnvironment ::NestedTypeStorage
341
- : public llvm::DenseMap<CanType, Type> { };
342
-
343
357
auto GenericEnvironment::getOrCreateNestedTypeStorage () -> NestedTypeStorage & {
344
358
if (nestedTypeStorage)
345
359
return *nestedTypeStorage;
@@ -355,35 +369,41 @@ auto GenericEnvironment::getOrCreateNestedTypeStorage() -> NestedTypeStorage & {
355
369
356
370
Type
357
371
GenericEnvironment::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
+
358
378
auto genericSig = getGenericSignature ();
359
- auto requirements = genericSig->getLocalRequirements (depType);
360
379
361
- if (requirements. concreteType )
362
- return mapTypeIntoContext (requirements. concreteType );
380
+ // Reduce it.
381
+ auto reducedType = genericSig. getReducedType (canType );
363
382
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
+ }
365
390
366
391
auto &ctx = genericSig->getASTContext ();
367
392
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
+ }
385
401
}
386
402
403
+ // Otherwise, we're going to create a new archetype. Look up its
404
+ // requirements.
405
+ auto requirements = genericSig->getLocalRequirements (reducedType);
406
+
387
407
// Substitute into the superclass.
388
408
Type superclass = requirements.superclass ;
389
409
if (superclass && superclass->hasTypeParameter ()) {
@@ -394,16 +414,18 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
394
414
395
415
Type result;
396
416
397
- auto rootGP = requirements.anchor ->getRootGenericParam ();
417
+ auto sugaredType = genericSig->getSugaredType (reducedType);
418
+
419
+ auto rootGP = reducedType->getRootGenericParam ();
398
420
switch (getKind ()) {
399
421
case Kind::Primary:
400
422
if (rootGP->isParameterPack ()) {
401
- result = PackArchetypeType::get (ctx, this , requirements. anchor ,
423
+ result = PackArchetypeType::get (ctx, this , sugaredType ,
402
424
requirements.packShape ,
403
425
requirements.protos , superclass,
404
426
requirements.layout );
405
427
} else {
406
- result = PrimaryArchetypeType::getNew (ctx, this , requirements. anchor ,
428
+ result = PrimaryArchetypeType::getNew (ctx, this , sugaredType ,
407
429
requirements.protos , superclass,
408
430
requirements.layout );
409
431
}
@@ -415,19 +437,19 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
415
437
// represents an opaque declaration, then apply the outer substitutions.
416
438
// It would be incorrect to build an opaque type archetype here.
417
439
if (rootGP->getDepth () < genericSig->getMaxDepth ()) {
418
- result = maybeApplyOuterContextSubstitutions (requirements. anchor );
440
+ result = maybeApplyOuterContextSubstitutions (reducedType );
419
441
break ;
420
442
}
421
443
422
- result = OpaqueTypeArchetypeType::getNew (this , requirements. anchor ,
444
+ result = OpaqueTypeArchetypeType::getNew (this , sugaredType ,
423
445
requirements.protos , superclass,
424
446
requirements.layout );
425
447
break ;
426
448
}
427
449
428
450
case Kind::OpenedExistential: {
429
451
if (rootGP->getDepth () < genericSig->getMaxDepth ()) {
430
- result = maybeApplyOuterContextSubstitutions (requirements. anchor );
452
+ result = maybeApplyOuterContextSubstitutions (reducedType );
431
453
break ;
432
454
}
433
455
@@ -439,16 +461,16 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
439
461
// For compatibility, continue using the existential layout's version when
440
462
// the interface type is a generic parameter. We should align these at
441
463
// some point.
442
- if (depType-> is <GenericTypeParamType>()) {
464
+ if (isa <GenericTypeParamType>(reducedType )) {
443
465
auto layout = getOpenedExistentialType ()->getExistentialLayout ();
444
466
SmallVector<ProtocolDecl *, 2 > protos;
445
467
for (auto proto : layout.getProtocols ())
446
468
protos.push_back (proto);
447
469
448
- result = OpenedArchetypeType::getNew (this , requirements. anchor , protos,
470
+ result = OpenedArchetypeType::getNew (this , sugaredType , protos,
449
471
superclass, requirements.layout );
450
472
} else {
451
- result = OpenedArchetypeType::getNew (this , requirements. anchor ,
473
+ result = OpenedArchetypeType::getNew (this , sugaredType ,
452
474
requirements.protos , superclass,
453
475
requirements.layout );
454
476
}
@@ -458,71 +480,87 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
458
480
459
481
case Kind::OpenedElement: {
460
482
if (rootGP->getDepth () < genericSig->getMaxDepth ()) {
461
- result = maybeApplyOuterContextSubstitutions (requirements. anchor );
483
+ result = maybeApplyOuterContextSubstitutions (reducedType );
462
484
break ;
463
485
}
464
486
465
- result = ElementArchetypeType::getNew (this , requirements. anchor ,
487
+ result = ElementArchetypeType::getNew (this , sugaredType ,
466
488
requirements.protos , superclass,
467
489
requirements.layout );
468
490
break ;
469
491
}
470
492
}
471
493
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) ;
476
498
477
499
return result;
478
500
}
479
501
480
502
Type 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>();
486
504
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 );
491
509
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 () ;
497
515
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;
499
519
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;
505
536
}
506
537
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
+
508
553
}
509
554
510
555
Type GenericEnvironment::mapTypeIntoContext (Type type) const {
511
556
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);
518
559
}
519
560
520
561
Type 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);
526
564
}
527
565
528
566
namespace {
0 commit comments