15
15
// ===----------------------------------------------------------------------===//
16
16
17
17
#include " swift/AST/GenericSignature.h"
18
+ #include " swift/AST/GenericEnvironment.h"
18
19
#include " swift/AST/ASTContext.h"
19
20
#include " swift/AST/Decl.h"
20
21
#include " swift/AST/Module.h"
@@ -68,14 +69,15 @@ ASTContext &GenericSignature::getASTContext(
68
69
return requirements.front ().getFirstType ()->getASTContext ();
69
70
}
70
71
71
- ArchetypeBuilder *GenericSignature::getArchetypeBuilder (ModuleDecl &mod) {
72
- // The archetype builder is associated with the canonical signature.
72
+ GenericEnvironment *
73
+ GenericSignature::getCanonicalGenericEnvironment (ModuleDecl &mod) {
74
+ // The generic environment is associated with the canonical signature.
73
75
if (!isCanonical ())
74
- return getCanonicalSignature ()->getArchetypeBuilder (mod);
76
+ return getCanonicalSignature ()->getCanonicalGenericEnvironment (mod);
75
77
76
78
// Archetype builders are stored on the ASTContext.
77
- return getASTContext ().getOrCreateArchetypeBuilder ( CanGenericSignature ( this ),
78
- &mod);
79
+ return getASTContext ().getCanonicalGenericEnvironment (
80
+ CanGenericSignature ( this ), &mod);
79
81
}
80
82
81
83
bool GenericSignature::isCanonical () const {
@@ -248,70 +250,37 @@ getSubstitutions(ModuleDecl &mod,
248
250
bool GenericSignature::requiresClass (Type type, ModuleDecl &mod) {
249
251
if (!type->isTypeParameter ()) return false ;
250
252
251
- auto &builder = *getArchetypeBuilder (mod);
252
- auto pa = builder.resolveArchetype (type);
253
- if (!pa) return false ;
254
-
255
- pa = pa->getRepresentative ();
256
-
257
- // If this type was mapped to a concrete type, then there is no
258
- // requirement.
259
- if (pa->isConcreteType ()) return false ;
260
-
261
- // If there is a superclass bound, then obviously it must be a class.
262
- if (pa->getSuperclass ()) return true ;
263
-
264
- // If any of the protocols are class-bound, then it must be a class.
265
- for (auto proto : pa->getConformsTo ()) {
266
- if (proto.first ->requiresClass ()) return true ;
267
- }
268
-
253
+ auto genericEnv = getCanonicalGenericEnvironment (mod);
254
+ auto contextTy = genericEnv->mapTypeIntoContext (&mod, type);
255
+ if (auto *archetypeTy = contextTy->getAs <ArchetypeType>())
256
+ return archetypeTy->requiresClass ();
269
257
return false ;
270
258
}
271
259
272
260
// / Determine the superclass bound on the given dependent type.
273
261
Type GenericSignature::getSuperclassBound (Type type, ModuleDecl &mod) {
274
262
if (!type->isTypeParameter ()) return nullptr ;
275
263
276
- auto &builder = *getArchetypeBuilder (mod);
277
- auto pa = builder.resolveArchetype (type);
278
- if (!pa) return nullptr ;
279
-
280
- pa = pa->getRepresentative ();
281
-
282
- // If this type was mapped to a concrete type, then there is no
283
- // requirement.
284
- if (pa->isConcreteType ()) return nullptr ;
264
+ auto genericEnv = getCanonicalGenericEnvironment (mod);
265
+ auto contextTy = genericEnv->mapTypeIntoContext (&mod, type);
266
+ if (auto *archetypeTy = contextTy->getAs <ArchetypeType>())
267
+ return archetypeTy->getSuperclass ();
285
268
286
- // Retrieve the superclass bound.
287
- return pa->getSuperclass ();
269
+ return Type ();
288
270
}
289
271
290
272
// / Determine the set of protocols to which the given dependent type
291
273
// / must conform.
292
- SmallVector <ProtocolDecl *, 2 > GenericSignature::getConformsTo (Type type,
293
- ModuleDecl &mod) {
274
+ ArrayRef <ProtocolDecl *> GenericSignature::getConformsTo (Type type,
275
+ ModuleDecl &mod) {
294
276
if (!type->isTypeParameter ()) return { };
295
277
296
- auto &builder = *getArchetypeBuilder (mod);
297
- auto pa = builder.resolveArchetype (type);
298
- if (!pa) return { };
278
+ auto genericEnv = getCanonicalGenericEnvironment (mod);
279
+ auto contextTy = genericEnv->mapTypeIntoContext (&mod, type);
280
+ if (auto *archetypeTy = contextTy->getAs <ArchetypeType>())
281
+ return archetypeTy->getConformsTo ();
299
282
300
- pa = pa->getRepresentative ();
301
-
302
- // If this type was mapped to a concrete type, then there are no
303
- // requirements.
304
- if (pa->isConcreteType ()) return { };
305
-
306
- // Retrieve the protocols to which this type conforms.
307
- SmallVector<ProtocolDecl *, 2 > result;
308
- for (auto proto : pa->getConformsTo ())
309
- result.push_back (proto.first );
310
-
311
- // Canonicalize the resulting set of protocols.
312
- ProtocolType::canonicalizeProtocols (result);
313
-
314
- return result;
283
+ return { };
315
284
}
316
285
317
286
// / Determine whether the given dependent type is equal to a concrete type.
@@ -325,29 +294,18 @@ bool GenericSignature::isConcreteType(Type type, ModuleDecl &mod) {
325
294
Type GenericSignature::getConcreteType (Type type, ModuleDecl &mod) {
326
295
if (!type->isTypeParameter ()) return Type ();
327
296
328
- auto &builder = *getArchetypeBuilder (mod);
329
- auto pa = builder.resolveArchetype (type);
330
- if (!pa) return Type ();
331
-
332
- pa = pa->getRepresentative ();
333
- if (!pa->isConcreteType ()) return Type ();
297
+ auto genericEnv = getCanonicalGenericEnvironment (mod);
298
+ auto contextTy = genericEnv->mapTypeIntoContext (&mod, type);
299
+ if (contextTy->is <ArchetypeType>())
300
+ return Type ();
334
301
335
- return pa-> getConcreteType () ;
302
+ return contextTy ;
336
303
}
337
304
338
305
Type GenericSignature::getRepresentative (Type type, ModuleDecl &mod) {
339
- assert (type->isTypeParameter ());
340
- auto &builder = *getArchetypeBuilder (mod);
341
- auto pa = builder.resolveArchetype (type);
342
- assert (pa && " not a valid dependent type of this signature?" );
343
- auto rep = pa->getRepresentative ();
344
- if (rep->isConcreteType ()) return rep->getConcreteType ();
345
- if (pa == rep) {
346
- assert (rep->getDependentType (builder, /* allowUnresolved*/ false )
347
- ->getCanonicalType () == type->getCanonicalType ());
348
- return type;
349
- }
350
- return rep->getDependentType (builder, /* allowUnresolved*/ false );
306
+ auto genericEnv = getCanonicalGenericEnvironment (mod);
307
+ auto contextTy = genericEnv->mapTypeIntoContext (&mod, type);
308
+ return genericEnv->mapTypeOutOfContext (&mod, contextTy)->getCanonicalType ();
351
309
}
352
310
353
311
bool GenericSignature::areSameTypeParameterInContext (Type type1, Type type2,
@@ -358,18 +316,10 @@ bool GenericSignature::areSameTypeParameterInContext(Type type1, Type type2,
358
316
if (type1.getPointer () == type2.getPointer ())
359
317
return true ;
360
318
361
- auto &builder = *getArchetypeBuilder (mod);
362
- auto pa1 = builder.resolveArchetype (type1);
363
- assert (pa1 && " not a valid dependent type of this signature?" );
364
- pa1 = pa1->getRepresentative ();
365
- assert (!pa1->isConcreteType ());
366
-
367
- auto pa2 = builder.resolveArchetype (type2);
368
- assert (pa2 && " not a valid dependent type of this signature?" );
369
- pa2 = pa2->getRepresentative ();
370
- assert (!pa2->isConcreteType ());
371
-
372
- return pa1 == pa2;
319
+ auto genericEnv = getCanonicalGenericEnvironment (mod);
320
+ auto first = genericEnv->mapTypeIntoContext (&mod, type1);
321
+ auto second = genericEnv->mapTypeIntoContext (&mod, type2);
322
+ return first->isEqual (second);
373
323
}
374
324
375
325
bool GenericSignature::isCanonicalTypeInContext (Type type, ModuleDecl &mod) {
@@ -383,48 +333,13 @@ bool GenericSignature::isCanonicalTypeInContext(Type type, ModuleDecl &mod) {
383
333
if (!type->hasTypeParameter ())
384
334
return true ;
385
335
386
- auto &builder = *getArchetypeBuilder (mod);
387
-
388
- // Look for non-canonical type parameters.
389
- return !type.findIf ([&](Type component) -> bool {
390
- if (!component->isTypeParameter ()) return false ;
391
-
392
- auto pa = builder.resolveArchetype (component);
393
- if (!pa) return false ;
394
-
395
- auto rep = pa->getArchetypeAnchor ();
396
- return (rep->isConcreteType () || pa != rep);
397
- });
336
+ auto genericEnv = getCanonicalGenericEnvironment (mod);
337
+ auto contextTy = genericEnv->mapTypeIntoContext (&mod, type);
338
+ return type->isEqual (genericEnv->mapTypeOutOfContext (&mod, contextTy));
398
339
}
399
340
400
341
CanType GenericSignature::getCanonicalTypeInContext (Type type, ModuleDecl &mod) {
401
- type = type->getCanonicalType ();
402
-
403
- // All the contextual canonicality rules apply to type parameters, so if the
404
- // type doesn't involve any type parameters, it's already canonical.
405
- if (!type->hasTypeParameter ())
406
- return CanType (type);
407
-
408
- auto &builder = *getArchetypeBuilder (mod);
409
-
410
- // Replace non-canonical type parameters.
411
- type = type.transform ([&](Type component) -> Type {
412
- if (!component->isTypeParameter ()) return component;
413
-
414
- // Resolve the potential archetype. This can be null in nested generic
415
- // types, which we can't immediately canonicalize.
416
- auto pa = builder.resolveArchetype (component);
417
- if (!pa) return component;
418
-
419
- auto rep = pa->getArchetypeAnchor ();
420
- if (rep->isConcreteType ()) {
421
- return getCanonicalTypeInContext (rep->getConcreteType (), mod);
422
- } else {
423
- return rep->getDependentType (builder, /* allowUnresolved*/ false );
424
- }
425
- });
426
-
427
- auto result = type->getCanonicalType ();
428
- assert (isCanonicalTypeInContext (result, mod));
429
- return result;
342
+ auto genericEnv = getCanonicalGenericEnvironment (mod);
343
+ auto contextTy = genericEnv->mapTypeIntoContext (&mod, type);
344
+ return genericEnv->mapTypeOutOfContext (&mod, contextTy)->getCanonicalType ();
430
345
}
0 commit comments