@@ -403,7 +403,7 @@ Type PropertyMap::getTypeForTerm(const MutableTerm &term,
403
403
// / Concrete type terms are written in terms of generic parameter types that
404
404
// / have a depth of 0, and an index into an array of substitution terms.
405
405
// /
406
- // / See RewriteSystemBuilder::getConcreteSubstitutionSchema ().
406
+ // / See RewriteSystemBuilder::getSubstitutionSchemaFromType ().
407
407
unsigned RewriteContext::getGenericParamIndex (Type type) {
408
408
auto *paramTy = type->castTo <GenericTypeParamType>();
409
409
assert (paramTy->getDepth () == 0 );
@@ -429,6 +429,7 @@ RewriteContext::getRelativeTermForType(CanType typeWitness,
429
429
// Get the substitution S corresponding to τ_0_n.
430
430
unsigned index = getGenericParamIndex (typeWitness->getRootGenericParam ());
431
431
result = MutableTerm (substitutions[index]);
432
+ assert (result.back ().getKind () != Symbol::Kind::Shape);
432
433
433
434
// If the substitution is a term consisting of a single protocol symbol
434
435
// [P], save P for later.
@@ -471,7 +472,7 @@ RewriteContext::getRelativeTermForType(CanType typeWitness,
471
472
}
472
473
473
474
// / Reverses the transformation performed by
474
- // / RewriteSystemBuilder::getConcreteSubstitutionSchema ().
475
+ // / RewriteSystemBuilder::getSubstitutionSchemaFromType ().
475
476
Type PropertyMap::getTypeFromSubstitutionSchema (
476
477
Type schema, ArrayRef<Term> substitutions,
477
478
ArrayRef<GenericTypeParamType *> genericParams,
@@ -481,11 +482,38 @@ Type PropertyMap::getTypeFromSubstitutionSchema(
481
482
if (!schema->hasTypeParameter ())
482
483
return schema;
483
484
484
- return schema.transformRec ([&](Type t) -> llvm::Optional<Type> {
485
+ return schema.transformWithPosition (
486
+ TypePosition::Invariant,
487
+ [&](Type t, TypePosition pos) -> llvm::Optional<Type> {
485
488
if (t->is <GenericTypeParamType>()) {
486
489
auto index = RewriteContext::getGenericParamIndex (t);
487
490
auto substitution = substitutions[index];
488
491
492
+ bool isShapePosition = (pos == TypePosition::Shape);
493
+ bool isShapeTerm = (substitution.back () == Symbol::forShape (Context));
494
+ if (isShapePosition != isShapeTerm) {
495
+ llvm::errs () << " Shape vs. type mixup\n\n " ;
496
+ schema.dump (llvm::errs ());
497
+ llvm::errs () << " Substitutions:\n " ;
498
+ for (auto otherSubst : substitutions) {
499
+ llvm::errs () << " - " ;
500
+ otherSubst.dump (llvm::errs ());
501
+ llvm::errs () << " \n " ;
502
+ }
503
+ llvm::errs () << " \n " ;
504
+ dump (llvm::errs ());
505
+
506
+ abort ();
507
+ }
508
+
509
+ // Undo the thing where the count type of a PackExpansionType
510
+ // becomes a shape term.
511
+ if (isShapeTerm) {
512
+ MutableTerm mutTerm (substitution.begin (),
513
+ substitution.end () - 1 );
514
+ substitution = Term::get (mutTerm, Context);
515
+ }
516
+
489
517
// Prepend the prefix of the lookup key to the substitution.
490
518
if (prefix.empty ()) {
491
519
// Skip creation of a new MutableTerm in the case where the
@@ -535,17 +563,31 @@ RewriteContext::getRelativeSubstitutionSchemaFromType(
535
563
if (!concreteType->hasTypeParameter ())
536
564
return concreteType;
537
565
538
- return CanType (concreteType.transformRec ([&](Type t) -> llvm::Optional<Type> {
566
+ return CanType (concreteType.transformWithPosition (
567
+ TypePosition::Invariant,
568
+ [&](Type t, TypePosition pos) -> llvm::Optional<Type> {
569
+
539
570
if (!t->isTypeParameter ())
540
571
return llvm::None;
541
572
542
573
auto term = getRelativeTermForType (CanType (t), substitutions);
543
574
544
- unsigned newIndex = result.size ();
575
+ // PackExpansionType(pattern=T, count=U) becomes
576
+ // PackExpansionType(pattern=τ_0_0, count=τ_0_1) with
577
+ //
578
+ // τ_0_0 := T
579
+ // τ_0_1 := U.[shape]
580
+ if (pos == TypePosition::Shape) {
581
+ assert (false );
582
+ term.add (Symbol::forShape (*this ));
583
+ }
584
+
585
+ unsigned index = result.size ();
586
+
545
587
result.push_back (Term::get (term, *this ));
546
588
547
589
return CanGenericTypeParamType::get (/* isParameterPack=*/ false ,
548
- /* depth=*/ 0 , newIndex ,
590
+ /* depth=*/ 0 , index ,
549
591
Context);
550
592
}));
551
593
}
@@ -566,12 +608,26 @@ RewriteContext::getSubstitutionSchemaFromType(CanType concreteType,
566
608
if (!concreteType->hasTypeParameter ())
567
609
return concreteType;
568
610
569
- return CanType (concreteType.transformRec ([&](Type t) -> llvm::Optional<Type> {
611
+ return CanType (concreteType.transformWithPosition (
612
+ TypePosition::Invariant,
613
+ [&](Type t, TypePosition pos)
614
+ -> llvm::Optional<Type> {
615
+
570
616
if (!t->isTypeParameter ())
571
617
return llvm::None;
572
618
619
+ // PackExpansionType(pattern=T, count=U) becomes
620
+ // PackExpansionType(pattern=τ_0_0, count=τ_0_1) with
621
+ //
622
+ // τ_0_0 := T
623
+ // τ_0_1 := U.[shape]
624
+ MutableTerm term = getMutableTermForType (CanType (t), proto);
625
+ if (pos == TypePosition::Shape)
626
+ term.add (Symbol::forShape (*this ));
627
+
573
628
unsigned index = result.size ();
574
- result.push_back (getTermForType (CanType (t), proto));
629
+
630
+ result.push_back (Term::get (term, *this ));
575
631
576
632
return CanGenericTypeParamType::get (/* isParameterPack=*/ false ,
577
633
/* depth=*/ 0 , index,
0 commit comments