@@ -450,7 +450,9 @@ Pattern *ModuleFile::maybeReadPattern() {
450
450
}
451
451
}
452
452
453
- ProtocolConformanceRef ModuleFile::readConformance (llvm::BitstreamCursor &Cursor){
453
+ ProtocolConformanceRef ModuleFile::readConformance (
454
+ llvm::BitstreamCursor &Cursor,
455
+ GenericEnvironment *genericEnv) {
454
456
using namespace decls_block ;
455
457
456
458
SmallVector<uint64_t , 16 > scratch;
@@ -475,6 +477,10 @@ ProtocolConformanceRef ModuleFile::readConformance(llvm::BitstreamCursor &Cursor
475
477
476
478
ASTContext &ctx = getContext ();
477
479
Type conformingType = getType (conformingTypeID);
480
+ if (genericEnv) {
481
+ conformingType = genericEnv->mapTypeIntoContext (getAssociatedModule (),
482
+ conformingType);
483
+ }
478
484
479
485
PrettyStackTraceType trace (getAssociatedModule ()->getASTContext (),
480
486
" reading specialized conformance for" ,
@@ -483,12 +489,13 @@ ProtocolConformanceRef ModuleFile::readConformance(llvm::BitstreamCursor &Cursor
483
489
// Read the substitutions.
484
490
SmallVector<Substitution, 4 > substitutions;
485
491
while (numSubstitutions--) {
486
- auto sub = maybeReadSubstitution (Cursor);
492
+ auto sub = maybeReadSubstitution (Cursor, genericEnv );
487
493
assert (sub.hasValue () && " Missing substitution?" );
488
494
substitutions.push_back (*sub);
489
495
}
490
496
491
- ProtocolConformanceRef genericConformance = readConformance (Cursor);
497
+ ProtocolConformanceRef genericConformance =
498
+ readConformance (Cursor, genericEnv);
492
499
PrettyStackTraceDecl traceTo (" ... to" , genericConformance.getRequirement ());
493
500
494
501
assert (genericConformance.isConcrete () && " Abstract generic conformance?" );
@@ -505,11 +512,17 @@ ProtocolConformanceRef ModuleFile::readConformance(llvm::BitstreamCursor &Cursor
505
512
506
513
ASTContext &ctx = getContext ();
507
514
Type conformingType = getType (conformingTypeID);
515
+ if (genericEnv) {
516
+ conformingType = genericEnv->mapTypeIntoContext (getAssociatedModule (),
517
+ conformingType);
518
+ }
519
+
508
520
PrettyStackTraceType trace (getAssociatedModule ()->getASTContext (),
509
521
" reading inherited conformance for" ,
510
522
conformingType);
511
523
512
- ProtocolConformanceRef inheritedConformance = readConformance (Cursor);
524
+ ProtocolConformanceRef inheritedConformance =
525
+ readConformance (Cursor, genericEnv);
513
526
PrettyStackTraceDecl traceTo (" ... to" ,
514
527
inheritedConformance.getRequirement ());
515
528
@@ -541,8 +554,7 @@ ProtocolConformanceRef ModuleFile::readConformance(llvm::BitstreamCursor &Cursor
541
554
auto module = getModule (moduleID);
542
555
543
556
SmallVector<ProtocolConformance *, 2 > conformances;
544
- nominal->lookupConformance (module , proto,
545
- conformances);
557
+ nominal->lookupConformance (module , proto, conformances);
546
558
PrettyStackTraceModuleFile traceMsg (
547
559
" If you're seeing a crash here, check that your SDK and dependencies "
548
560
" are at least as new as the versions used to build" , this );
@@ -641,7 +653,8 @@ NormalProtocolConformance *ModuleFile::readNormalConformance(
641
653
}
642
654
643
655
Optional<Substitution>
644
- ModuleFile::maybeReadSubstitution (llvm::BitstreamCursor &cursor) {
656
+ ModuleFile::maybeReadSubstitution (llvm::BitstreamCursor &cursor,
657
+ GenericEnvironment *genericEnv) {
645
658
BCOffsetRAII lastRecordOffset (cursor);
646
659
647
660
auto entry = cursor.advance (AF_DontPopBlockAtEnd);
@@ -661,6 +674,10 @@ ModuleFile::maybeReadSubstitution(llvm::BitstreamCursor &cursor) {
661
674
numConformances);
662
675
663
676
auto replacementTy = getType (replacementID);
677
+ if (genericEnv) {
678
+ replacementTy = genericEnv->mapTypeIntoContext (getAssociatedModule (),
679
+ replacementTy);
680
+ }
664
681
665
682
SmallVector<ProtocolConformanceRef, 4 > conformanceBuf;
666
683
while (numConformances--) {
@@ -4206,17 +4223,85 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
4206
4223
ASTContext &ctx = getContext ();
4207
4224
ArrayRef<uint64_t >::iterator rawIDIter = rawIDs.begin ();
4208
4225
4209
- WitnessMap witnesses;
4210
4226
while (valueCount--) {
4211
- auto first = cast<ValueDecl>(getDecl (*rawIDIter++));
4212
- auto second = cast_or_null<ValueDecl>(getDecl (*rawIDIter++));
4213
- assert (second || first->getAttrs ().hasAttribute <OptionalAttr>() ||
4214
- first->getAttrs ().isUnavailable (ctx));
4215
- (void ) ctx;
4216
- if (second)
4217
- witnesses.insert (std::make_pair (first, second));
4218
- else
4219
- witnesses.insert (std::make_pair (first, Witness ()));
4227
+ auto req = cast<ValueDecl>(getDecl (*rawIDIter++));
4228
+ auto witness = cast_or_null<ValueDecl>(getDecl (*rawIDIter++));
4229
+ assert (witness ||
4230
+ req->getAttrs ().hasAttribute <OptionalAttr>() ||
4231
+ req->getAttrs ().isUnavailable (ctx));
4232
+ if (!witness) {
4233
+ conformance->setWitness (req, Witness ());
4234
+ continue ;
4235
+ }
4236
+
4237
+ // Generic signature and environment.
4238
+ GenericSignature *syntheticSig = nullptr ;
4239
+ GenericEnvironment *syntheticEnv = nullptr ;
4240
+ if (unsigned numGenericParams = *rawIDIter++) {
4241
+ // Generic parameters.
4242
+ SmallVector<GenericTypeParamType *, 2 > genericParams;
4243
+ while (numGenericParams--) {
4244
+ genericParams.push_back (
4245
+ getType (*rawIDIter++)->castTo <GenericTypeParamType>());
4246
+ }
4247
+
4248
+ // Generic requirements.
4249
+ SmallVector<Requirement, 4 > requirements;
4250
+ readGenericRequirements (requirements);
4251
+
4252
+ // Form the generic signature for the synthetic environment.
4253
+ syntheticSig = GenericSignature::get (genericParams, requirements);
4254
+
4255
+ // Create an archetype builder, which will help us create the
4256
+ // synthetic environment.
4257
+ ArchetypeBuilder builder (*getAssociatedModule (), ctx.Diags );
4258
+ builder.addGenericSignature (syntheticSig, nullptr );
4259
+ builder.finalize (SourceLoc ());
4260
+ syntheticEnv = builder.getGenericEnvironment ();
4261
+ }
4262
+
4263
+ // Requirement -> synthetic map.
4264
+ SubstitutionMap reqToSyntheticMap;
4265
+ bool hasReqToSyntheticMap = false ;
4266
+ if (unsigned numEntries = *rawIDIter++) {
4267
+ hasReqToSyntheticMap = true ;
4268
+ while (numEntries--) {
4269
+ auto first = getType (*rawIDIter++);
4270
+ auto second = getType (*rawIDIter++);
4271
+ reqToSyntheticMap.addSubstitution (first->getCanonicalType (), second);
4272
+
4273
+ if (unsigned numConformances = *rawIDIter++) {
4274
+ SmallVector<ProtocolConformanceRef, 2 > conformances;
4275
+ while (numConformances--) {
4276
+ conformances.push_back (readConformance (DeclTypeCursor));
4277
+ }
4278
+ reqToSyntheticMap.addConformances (first->getCanonicalType (),
4279
+ ctx.AllocateCopy (conformances));
4280
+ }
4281
+ }
4282
+ }
4283
+
4284
+ // Witness substitutions.
4285
+ SmallVector<Substitution, 4 > witnessSubstitutions;
4286
+ if (unsigned numWitnessSubstitutions = *rawIDIter++) {
4287
+ while (numWitnessSubstitutions--) {
4288
+ auto sub = maybeReadSubstitution (DeclTypeCursor, syntheticEnv);
4289
+ witnessSubstitutions.push_back (*sub);
4290
+ }
4291
+ }
4292
+
4293
+ // Handle simple witnesses.
4294
+ if (witnessSubstitutions.empty () && !syntheticSig && !syntheticEnv &&
4295
+ !hasReqToSyntheticMap) {
4296
+ conformance->setWitness (req, Witness (witness));
4297
+ continue ;
4298
+ }
4299
+
4300
+ // Set the witness.
4301
+ conformance->setWitness (req,
4302
+ Witness (witness, witnessSubstitutions,
4303
+ syntheticSig, syntheticEnv,
4304
+ reqToSyntheticMap));
4220
4305
}
4221
4306
assert (rawIDIter <= rawIDs.end () && " read too much" );
4222
4307
@@ -4232,16 +4317,12 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
4232
4317
}
4233
4318
assert (rawIDIter <= rawIDs.end () && " read too much" );
4234
4319
4320
+
4235
4321
// Set type witnesses.
4236
4322
for (auto typeWitness : typeWitnesses) {
4237
4323
conformance->setTypeWitness (typeWitness.first , typeWitness.second .first ,
4238
4324
typeWitness.second .second );
4239
4325
}
4240
-
4241
- // Set witnesses.
4242
- for (auto witness : witnesses) {
4243
- conformance->setWitness (witness.first , witness.second );
4244
- }
4245
4326
}
4246
4327
4247
4328
static Optional<ForeignErrorConvention::Kind>
0 commit comments