@@ -439,19 +439,11 @@ class GenericSignatureBuilder::ExplicitRequirement {
439
439
public:
440
440
ExplicitRequirement (RequirementKind kind,
441
441
const RequirementSource *source,
442
- Type type)
443
- : sourceAndKind(source, kind),
444
- rhs (type ? type->getCanonicalType () : Type()) {}
445
-
446
- ExplicitRequirement (RequirementKind kind,
447
- const RequirementSource *source,
448
- ProtocolDecl *proto)
449
- : sourceAndKind(source, kind), rhs(proto) {}
450
-
451
- ExplicitRequirement (RequirementKind kind,
452
- const RequirementSource *source,
453
- LayoutConstraint layout)
454
- : sourceAndKind(source, kind), rhs(layout) {}
442
+ RequirementRHS rhs)
443
+ : sourceAndKind(source, kind), rhs(rhs) {
444
+ if (auto type = rhs.dyn_cast <Type>())
445
+ this ->rhs = type->getCanonicalType ();
446
+ }
455
447
456
448
// / For a Constraint<T> with an explicit requirement source, we recover the
457
449
// / subject type from the requirement source and the right hand side from the
@@ -468,36 +460,10 @@ class GenericSignatureBuilder::ExplicitRequirement {
468
460
return ExplicitRequirement (kind, constraint.source , constraint.value );
469
461
}
470
462
471
- // / To recover the root explicit requirement from a Constraint<T>, we walk the
472
- // / requirement source up the root, and look at both the root and the next
473
- // / innermost child.
474
- // / Together, these give us the subject type (via the root) and the right hand
475
- // / side of the requirement (from the next innermost child).
476
- // /
477
- // / The requirement kind must be passed in since Constraint<T>'s kind is
478
- // / implicit by virtue of which list it appears under inside its equivalence
479
- // / class, and is not stored inside the constraint.
480
- // /
481
- // / The constraint's actual value is ignored; that's the right hand
482
- // / side of the derived constraint, not the right hand side of the original
483
- // / explicit requirement.
484
- template <typename T>
485
- static ExplicitRequirement fromDerivedConstraint (RequirementKind kind,
486
- Constraint<T> constraint) {
487
- assert (constraint.source ->isDerivedNonRootRequirement ());
488
-
489
- const RequirementSource *root = constraint.source ;
490
- const RequirementSource *child = nullptr ;
491
-
492
- while (root->parent && root->isDerivedRequirement ()) {
493
- child = root;
494
- root = root->parent ;
495
- }
496
-
497
- assert (root != nullptr );
498
- assert (child != nullptr );
499
-
500
- switch (child->kind ) {
463
+ static std::pair<RequirementKind, RequirementRHS>
464
+ getKindAndRHS (const RequirementSource *source,
465
+ ASTContext &ctx) {
466
+ switch (source->kind ) {
501
467
// If we have a protocol requirement source whose parent is the root, then
502
468
// we have an implied constraint coming from a protocol's requirement
503
469
// signature:
@@ -511,8 +477,8 @@ class GenericSignatureBuilder::ExplicitRequirement {
511
477
// Therefore the original constraint was 'T : Sequence'.
512
478
case RequirementSource::ProtocolRequirement:
513
479
case RequirementSource::InferredProtocolRequirement: {
514
- auto *proto = child ->getProtocolDecl ();
515
- return ExplicitRequirement (RequirementKind::Conformance, root , proto);
480
+ auto *proto = source ->getProtocolDecl ();
481
+ return std::make_pair (RequirementKind::Conformance, proto);
516
482
}
517
483
518
484
// If we have a superclass or concrete source whose parent is the root, then
@@ -528,29 +494,28 @@ class GenericSignatureBuilder::ExplicitRequirement {
528
494
// respectively.
529
495
case RequirementSource::Superclass:
530
496
case RequirementSource::Concrete: {
531
- Type conformingType = child ->getStoredType ();
497
+ Type conformingType = source ->getStoredType ();
532
498
if (conformingType) {
533
499
// A concrete requirement source for a self-conforming exitential type
534
500
// stores the original type, and not the conformance, because there is
535
501
// no way to recover the original type from the conformance.
536
502
assert (conformingType->isExistentialType ());
537
503
} else {
538
- auto conformance = child ->getProtocolConformance ();
504
+ auto conformance = source ->getProtocolConformance ();
539
505
if (conformance.isConcrete ())
540
506
conformingType = conformance.getConcrete ()->getType ();
541
507
else {
542
508
// If the conformance was abstract or invalid, we're dealing with
543
509
// invalid code. We have no way to recover the superclass type, so
544
510
// just stick an ErrorType in there.
545
- auto &ctx = constraint.getSubjectDependentType ({ })->getASTContext ();
546
511
conformingType = ErrorType::get (ctx);
547
512
}
548
513
}
549
514
550
- auto kind = (child ->kind == RequirementSource::Superclass
515
+ auto kind = (source ->kind == RequirementSource::Superclass
551
516
? RequirementKind::Superclass
552
517
: RequirementKind::SameType);
553
- return ExplicitRequirement (kind, root , conformingType);
518
+ return std::make_pair (kind, conformingType);
554
519
}
555
520
556
521
// If we have a layout source whose parent is the root, then
@@ -563,19 +528,61 @@ class GenericSignatureBuilder::ExplicitRequirement {
563
528
// by a superclass constraint, ensuring that it supercedes an explicit
564
529
// 'T : AnyObject' constraint).
565
530
case RequirementSource::Layout: {
566
- auto type = child ->getStoredType ();
567
- return ExplicitRequirement (RequirementKind::Superclass, root , type);
531
+ auto type = source ->getStoredType ();
532
+ return std::make_pair (RequirementKind::Superclass, type);
568
533
}
569
534
570
535
default : {
571
- auto &SM = constraint.getSubjectDependentType ({ })->getASTContext ().SourceMgr ;
572
- constraint.source ->dump (llvm::errs (), &SM, 0 );
536
+ source->dump (llvm::errs (), &ctx.SourceMgr , 0 );
573
537
llvm::errs () << " \n " ;
574
- llvm_unreachable (" Unknown root kind" );
538
+ llvm_unreachable (" Unhandled source kind" );
575
539
}
576
540
}
577
541
}
578
542
543
+ static ExplicitRequirement fromRequirementSource (const RequirementSource *source,
544
+ ASTContext &ctx) {
545
+ auto *parent = source->parent ;
546
+
547
+ RequirementKind kind;
548
+ RequirementRHS rhs;
549
+ std::tie (kind, rhs) = getKindAndRHS (source, ctx);
550
+
551
+ return ExplicitRequirement (kind, parent, rhs);
552
+ }
553
+
554
+ // / To recover the root explicit requirement from a Constraint<T>, we walk the
555
+ // / requirement source up the root, and look at both the root and the next
556
+ // / innermost child.
557
+ // / Together, these give us the subject type (via the root) and the right hand
558
+ // / side of the requirement (from the next innermost child).
559
+ // /
560
+ // / The requirement kind must be passed in since Constraint<T>'s kind is
561
+ // / implicit by virtue of which list it appears under inside its equivalence
562
+ // / class, and is not stored inside the constraint.
563
+ // /
564
+ // / The constraint's actual value is ignored; that's the right hand
565
+ // / side of the derived constraint, not the right hand side of the original
566
+ // / explicit requirement.
567
+ template <typename T>
568
+ static ExplicitRequirement fromDerivedConstraint (Constraint<T> constraint,
569
+ ASTContext &ctx) {
570
+ assert (constraint.source ->isDerivedNonRootRequirement ());
571
+
572
+ const RequirementSource *root = constraint.source ;
573
+ const RequirementSource *child = nullptr ;
574
+
575
+ while (root->parent && root->isDerivedRequirement ()) {
576
+ child = root;
577
+ root = root->parent ;
578
+ }
579
+
580
+ assert (child != nullptr );
581
+ assert (root != nullptr );
582
+
583
+ return fromRequirementSource (child, ctx);
584
+ }
585
+
579
586
RequirementKind getKind () const {
580
587
return sourceAndKind.getInt ();
581
588
}
@@ -5818,7 +5825,8 @@ class RedundantRequirementGraph {
5818
5825
addConstraintsFromEquivClass (
5819
5826
RequirementKind kind,
5820
5827
const SmallVectorImpl<Constraint<T>> &exact,
5821
- const SmallVectorImpl<Constraint<T>> &lessSpecific) {
5828
+ const SmallVectorImpl<Constraint<T>> &lessSpecific,
5829
+ ASTContext &ctx) {
5822
5830
// The set of 'redundant explicit requirements', which are known to be less
5823
5831
// specific than some other explicit requirements. An example is a type
5824
5832
// parameter with multiple superclass constraints:
@@ -5848,11 +5856,13 @@ class RedundantRequirementGraph {
5848
5856
5849
5857
for (auto constraint : exact) {
5850
5858
if (constraint.source ->isDerivedNonRootRequirement ()) {
5851
- auto req = ExplicitRequirement::fromDerivedConstraint (kind, constraint);
5859
+ auto req = ExplicitRequirement::fromDerivedConstraint (
5860
+ constraint, ctx);
5852
5861
5853
5862
rootReqs.push_back (req);
5854
5863
} else {
5855
- auto req = ExplicitRequirement::fromExplicitConstraint (kind, constraint);
5864
+ auto req = ExplicitRequirement::fromExplicitConstraint (
5865
+ kind, constraint);
5856
5866
5857
5867
VertexID v = addVertex (req);
5858
5868
#ifndef NDEBUG
@@ -6241,14 +6251,17 @@ void GenericSignatureBuilder::ExplicitRequirement::dump(
6241
6251
break ;
6242
6252
}
6243
6253
6244
- getSource ()->dump (out, SM, 0 );
6245
- out << " : " ;
6254
+ out << getSubjectType () << " : " ;
6246
6255
if (auto type = rhs.dyn_cast <Type>())
6247
6256
out << type;
6248
6257
else if (auto *proto = rhs.dyn_cast <ProtocolDecl *>())
6249
6258
out << proto->getName ();
6250
6259
else
6251
6260
out << rhs.get <LayoutConstraint>();
6261
+
6262
+ out << " (source: " ;
6263
+ getSource ()->dump (out, SM, 0 );
6264
+ out << " )" ;
6252
6265
}
6253
6266
6254
6267
static bool typeImpliesLayoutConstraint (Type t, LayoutConstraint layout) {
@@ -6324,7 +6337,7 @@ void GenericSignatureBuilder::computeRedundantRequirements(
6324
6337
}
6325
6338
6326
6339
graph.addConstraintsFromEquivClass (RequirementKind::Conformance,
6327
- exact, lessSpecific);
6340
+ exact, lessSpecific, Context );
6328
6341
}
6329
6342
6330
6343
Type resolvedConcreteType;
@@ -6376,7 +6389,7 @@ void GenericSignatureBuilder::computeRedundantRequirements(
6376
6389
6377
6390
concreteTypeRequirement =
6378
6391
graph.addConstraintsFromEquivClass (RequirementKind::SameType,
6379
- exact, lessSpecific);
6392
+ exact, lessSpecific, Context );
6380
6393
}
6381
6394
6382
6395
Type resolvedSuperclass;
@@ -6438,7 +6451,7 @@ void GenericSignatureBuilder::computeRedundantRequirements(
6438
6451
6439
6452
superclassRequirement =
6440
6453
graph.addConstraintsFromEquivClass (RequirementKind::Superclass,
6441
- exact, lessSpecific);
6454
+ exact, lessSpecific, Context );
6442
6455
6443
6456
graph.handleConstraintsImpliedByConcrete (RequirementKind::Superclass,
6444
6457
impliedByConcrete,
@@ -6499,7 +6512,7 @@ void GenericSignatureBuilder::computeRedundantRequirements(
6499
6512
6500
6513
layoutRequirement =
6501
6514
graph.addConstraintsFromEquivClass (RequirementKind::Layout,
6502
- exact, lessSpecific);
6515
+ exact, lessSpecific, Context );
6503
6516
6504
6517
graph.handleConstraintsImpliedByConcrete (RequirementKind::Layout,
6505
6518
impliedByConcrete,
@@ -8641,7 +8654,8 @@ GenericSignature GenericSignatureBuilder::computeGenericSignature(
8641
8654
const ProtocolDecl *requirementSignatureSelfProto,
8642
8655
bool rebuildingWithoutRedundantConformances) && {
8643
8656
// Finalize the builder, producing any necessary diagnostics.
8644
- finalize (getGenericParams (), allowConcreteGenericParams,
8657
+ finalize (getGenericParams (),
8658
+ allowConcreteGenericParams,
8645
8659
requirementSignatureSelfProto);
8646
8660
8647
8661
if (rebuildingWithoutRedundantConformances) {
0 commit comments