@@ -157,8 +157,10 @@ namespace {
157
157
class ConcreteContraction {
158
158
bool Debug;
159
159
160
- llvm::SmallDenseMap<GenericParamKey, Type> ConcreteTypes;
161
- llvm::SmallDenseMap<GenericParamKey, Type> Superclasses;
160
+ llvm::SmallDenseMap<GenericParamKey,
161
+ llvm::SmallDenseSet<Type, 1 >> ConcreteTypes;
162
+ llvm::SmallDenseMap<GenericParamKey,
163
+ llvm::SmallDenseSet<Type, 1 >> Superclasses;
162
164
llvm::SmallDenseMap<GenericParamKey,
163
165
llvm::SmallVector<ProtocolDecl *, 1 >> Conformances;
164
166
@@ -296,20 +298,22 @@ Type ConcreteContraction::substTypeParameter(
296
298
Type concreteType;
297
299
{
298
300
auto found = ConcreteTypes.find (key);
299
- if (found != ConcreteTypes.end ())
300
- concreteType = found->second ;
301
+ if (found != ConcreteTypes.end () && found-> second . size () == 1 )
302
+ concreteType = * found->second . begin () ;
301
303
}
302
304
303
305
Type superclass;
304
306
{
305
307
auto found = Superclasses.find (key);
306
- if (found != Superclasses.end ())
307
- superclass = found->second ;
308
+ if (found != Superclasses.end () && found-> second . size () == 1 )
309
+ superclass = * found->second . begin () ;
308
310
}
309
311
310
312
if (!concreteType && !superclass)
311
313
return type;
312
314
315
+ // If we have both, prefer the concrete type requirement since it is more
316
+ // specific.
313
317
if (!concreteType) {
314
318
assert (superclass);
315
319
@@ -434,35 +438,15 @@ bool ConcreteContraction::performConcreteContraction(
434
438
if (constraintType->isTypeParameter ())
435
439
break ;
436
440
437
- auto entry = std::make_pair (GenericParamKey (genericParam),
438
- constraintType);
439
- bool inserted = ConcreteTypes.insert (entry).second ;
440
- if (!inserted) {
441
- if (Debug) {
442
- llvm::dbgs () << " @ Concrete contraction cannot proceed: "
443
- << " duplicate concrete type requirements\n " ;
444
- }
445
- return false ;
446
- }
447
-
441
+ ConcreteTypes[GenericParamKey (genericParam)].insert (constraintType);
448
442
break ;
449
443
}
450
444
case RequirementKind::Superclass: {
451
445
auto constraintType = req.req .getSecondType ();
452
446
assert (!constraintType->isTypeParameter () &&
453
447
" You forgot to call desugarRequirement()" );
454
448
455
- auto entry = std::make_pair (GenericParamKey (genericParam),
456
- constraintType);
457
- bool inserted = Superclasses.insert (entry).second ;
458
- if (!inserted) {
459
- if (Debug) {
460
- llvm::dbgs () << " @ Concrete contraction cannot proceed: "
461
- << " duplicate superclass requirements\n " ;
462
- }
463
- return false ;
464
- }
465
-
449
+ Superclasses[GenericParamKey (genericParam)].insert (constraintType);
466
450
break ;
467
451
}
468
452
case RequirementKind::Conformance: {
@@ -484,10 +468,10 @@ bool ConcreteContraction::performConcreteContraction(
484
468
for (const auto &pair : Conformances) {
485
469
auto subjectType = pair.first ;
486
470
auto found = Superclasses.find (subjectType);
487
- if (found == Superclasses.end ())
471
+ if (found == Superclasses.end () || found-> second . size () != 1 )
488
472
continue ;
489
473
490
- auto superclassTy = found->second ;
474
+ auto superclassTy = * found->second . begin () ;
491
475
492
476
for (const auto *proto : pair.second ) {
493
477
if (auto otherSuperclassTy = proto->getSuperclass ()) {
@@ -511,35 +495,27 @@ bool ConcreteContraction::performConcreteContraction(
511
495
if (ConcreteTypes.empty () && Superclasses.empty ())
512
496
return false ;
513
497
514
- // If a generic parameter is subject to both a concrete type and superclass
515
- // requirement, bail out because we're not smart enough to figure out what's
516
- // going on.
517
- for (auto pair : ConcreteTypes) {
518
- auto subjectType = pair.first ;
519
-
520
- if (Superclasses.find (subjectType) != Superclasses.end ()) {
521
- if (Debug) {
522
- llvm::dbgs () << " @ Concrete contraction cannot proceed; "
523
- << " τ_" << subjectType.Depth << " _" << subjectType.Index
524
- << " has both a concrete type and superclass requirement" ;
525
- }
526
- return false ;
527
- }
528
- }
529
-
530
498
if (Debug) {
531
499
llvm::dbgs () << " @ Concrete types: @\n " ;
532
500
for (auto pair : ConcreteTypes) {
533
501
llvm::dbgs () << " - τ_" << pair.first .Depth
534
- << " _" << pair.first .Index << " == "
535
- << pair.second << " \n " ;
502
+ << " _" << pair.first .Index ;
503
+ if (pair.second .size () == 1 ) {
504
+ llvm::dbgs () << " == " << *pair.second .begin () << " \n " ;
505
+ } else {
506
+ llvm::dbgs () << " has duplicate concrete type requirements\n " ;
507
+ }
536
508
}
537
509
538
510
llvm::dbgs () << " @ Superclasses: @\n " ;
539
511
for (auto pair : Superclasses) {
540
512
llvm::dbgs () << " - τ_" << pair.first .Depth
541
- << " _" << pair.first .Index << " : "
542
- << pair.second << " \n " ;
513
+ << " _" << pair.first .Index ;
514
+ if (pair.second .size () == 1 ) {
515
+ llvm::dbgs () << " : " << *pair.second .begin () << " \n " ;
516
+ } else {
517
+ llvm::dbgs () << " has duplicate superclass requirements\n " ;
518
+ }
543
519
}
544
520
}
545
521
0 commit comments