@@ -112,12 +112,16 @@ case TypeKind::Id:
112
112
case TypeKind::Unresolved:
113
113
case TypeKind::TypeVariable:
114
114
case TypeKind::Placeholder:
115
- case TypeKind::GenericTypeParam:
116
115
case TypeKind::SILToken:
117
116
case TypeKind::Module:
118
117
case TypeKind::BuiltinTuple:
119
118
return t;
120
119
120
+ case TypeKind::GenericTypeParam: {
121
+ auto *param = cast<GenericTypeParamType>(base);
122
+ return asDerived ().transformGenericTypeParam (param, pos);
123
+ }
124
+
121
125
case TypeKind::Enum:
122
126
case TypeKind::Struct:
123
127
case TypeKind::Class:
@@ -164,64 +168,50 @@ case TypeKind::Id:
164
168
case TypeKind::SILBox: {
165
169
bool changed = false ;
166
170
auto boxTy = cast<SILBoxType>(base);
167
- #ifndef NDEBUG
168
- // This interface isn't suitable for updating the substitution map in a
169
- // generic SILBox.
170
- for (Type type : boxTy->getSubstitutions ().getReplacementTypes ()) {
171
- assert (type->isEqual (
172
- doIt (type, TypePosition::Invariant)) &&
173
- " SILBoxType substitutions can't be transformed" );
174
- }
175
- #endif
171
+
176
172
SmallVector<SILField, 4 > newFields;
177
173
auto *l = boxTy->getLayout ();
178
174
for (auto f : l->getFields ()) {
179
175
auto fieldTy = f.getLoweredType ();
180
- auto transformed = doIt (fieldTy, TypePosition::Invariant)
181
- -> getCanonicalType ( );
176
+ auto transformed = asDerived (). transformSILField (
177
+ fieldTy, TypePosition::Invariant );
182
178
changed |= fieldTy != transformed;
183
179
newFields.push_back (SILField (transformed, f.isMutable ()));
184
180
}
181
+
182
+ auto oldSubMap = boxTy->getSubstitutions ();
183
+ auto newSubMap = asDerived ().transformSubMap (oldSubMap);
184
+ if (oldSubMap && !newSubMap)
185
+ return Type ();
186
+ changed |= (oldSubMap != newSubMap);
185
187
if (!changed)
186
188
return t;
187
189
boxTy = SILBoxType::get (ctx,
188
190
SILLayout::get (ctx,
189
191
l->getGenericSignature (),
190
192
newFields,
191
193
l->capturesGenericEnvironment ()),
192
- boxTy-> getSubstitutions () );
194
+ newSubMap );
193
195
return boxTy;
194
196
}
195
197
196
198
case TypeKind::SILFunction: {
197
199
auto fnTy = cast<SILFunctionType>(base);
198
- bool changed = false ;
199
- auto updateSubs = [&](SubstitutionMap &subs) -> bool {
200
- // This interface isn't suitable for doing most transformations on
201
- // a substituted SILFunctionType, but it's too hard to come up with
202
- // an assertion that meaningfully captures what restrictions are in
203
- // place. Generally the restriction that you can't naively substitute
204
- // a SILFunctionType using AST mechanisms will have to be good enough.
205
- SmallVector<Type, 4 > newReplacements;
206
- for (Type type : subs.getReplacementTypes ()) {
207
- auto transformed = doIt (type, TypePosition::Invariant);
208
- newReplacements.push_back (transformed->getCanonicalType ());
209
- if (!type->isEqual (transformed))
210
- changed = true ;
211
- }
212
-
213
- if (changed) {
214
- subs = SubstitutionMap::get (subs.getGenericSignature (),
215
- newReplacements,
216
- subs.getConformances ());
217
- }
218
-
219
- return changed;
220
- };
221
200
222
201
if (fnTy->isPolymorphic ())
223
202
return fnTy;
224
203
204
+ auto updateSubs = [&](SubstitutionMap &subs) -> bool {
205
+ auto newSubs = asDerived ().transformSubMap (subs);
206
+ if (subs && !newSubs)
207
+ return false ;
208
+ if (subs == newSubs)
209
+ return false ;
210
+
211
+ subs = newSubs;
212
+ return true ;
213
+ };
214
+
225
215
if (auto subs = fnTy->getInvocationSubstitutions ()) {
226
216
if (updateSubs (subs)) {
227
217
return fnTy->withInvocationSubstitutions (subs);
@@ -236,6 +226,8 @@ case TypeKind::Id:
236
226
return fnTy;
237
227
}
238
228
229
+ bool changed = false ;
230
+
239
231
SmallVector<SILParameterInfo, 8 > transInterfaceParams;
240
232
for (SILParameterInfo param : fnTy->getParameters ()) {
241
233
if (transformSILParameter (pos.flipped (), param, changed))
@@ -433,23 +425,28 @@ case TypeKind::Id:
433
425
if (!newParentType) return newUnderlyingTy;
434
426
}
435
427
436
- auto subMap = alias->getSubstitutionMap ();
437
- for (Type oldReplacementType : subMap.getReplacementTypes ()) {
438
- Type newReplacementType = doIt (oldReplacementType, TypePosition::Invariant);
439
- if (!newReplacementType)
440
- return newUnderlyingTy;
428
+ if (newParentType && newParentType->isExistentialType ())
429
+ return newUnderlyingTy;
441
430
442
- // If anything changed with the replacement type, we lose the sugar.
443
- // FIXME: This is really unfortunate.
444
- if (newReplacementType.getPointer () != oldReplacementType.getPointer ())
445
- return newUnderlyingTy;
446
- }
431
+ auto oldSubMap = alias->getSubstitutionMap ();
432
+ auto newSubMap = asDerived ().transformSubMap (oldSubMap);
433
+ if (oldSubMap && !newSubMap)
434
+ return Type ();
447
435
448
436
if (oldParentType.getPointer () == newParentType.getPointer () &&
449
- oldUnderlyingTy.getPointer () == newUnderlyingTy.getPointer ())
437
+ oldUnderlyingTy.getPointer () == newUnderlyingTy.getPointer () &&
438
+ oldSubMap == newSubMap)
450
439
return t;
451
440
452
- return TypeAliasType::get (alias->getDecl (), newParentType, subMap,
441
+ // Don't leave local archetypes and type variables behind in sugar
442
+ // if they don't appear in the underlying type, to avoid confusion.
443
+ auto props = newSubMap.getRecursiveProperties ();
444
+ if (props.hasLocalArchetype () && !newUnderlyingTy->hasLocalArchetype ())
445
+ return newUnderlyingTy;
446
+ if (props.hasTypeVariable () && !newUnderlyingTy->hasTypeVariable ())
447
+ return newUnderlyingTy;
448
+
449
+ return TypeAliasType::get (alias->getDecl (), newParentType, newSubMap,
453
450
newUnderlyingTy);
454
451
}
455
452
@@ -593,43 +590,13 @@ case TypeKind::Id:
593
590
}
594
591
595
592
case TypeKind::PackExpansion: {
596
- auto expand = cast<PackExpansionType>(base);
597
-
598
- // Substitution completely replaces this.
599
-
600
- Type transformedPat = doIt (expand->getPatternType (), pos);
601
- if (!transformedPat)
602
- return Type ();
603
-
604
- Type transformedCount = doIt (expand->getCountType (), TypePosition::Shape);
605
- if (!transformedCount)
606
- return Type ();
607
-
608
- if (transformedPat.getPointer () == expand->getPatternType ().getPointer () &&
609
- transformedCount.getPointer () == expand->getCountType ().getPointer ())
610
- return t;
611
-
612
- // // If we transform the count to a pack type, expand the pattern.
613
- // // This is necessary because of how we piece together types in
614
- // // the constraint system.
615
- // if (auto countPack = transformedCount->getAs<PackType>()) {
616
- // return PackExpansionType::expand(transformedPat, countPack);
617
- // }
618
-
619
- return PackExpansionType::get (transformedPat, transformedCount);
593
+ auto *expand = cast<PackExpansionType>(base);
594
+ return asDerived ().transformPackExpansion (expand, pos);
620
595
}
621
596
622
597
case TypeKind::PackElement: {
623
598
auto element = cast<PackElementType>(base);
624
-
625
- Type transformedPack = doIt (element->getPackType (), pos);
626
- if (!transformedPack)
627
- return Type ();
628
-
629
- if (transformedPack.getPointer () == element->getPackType ().getPointer ())
630
- return t;
631
-
632
- return PackElementType::get (transformedPack, element->getLevel ());
599
+ return asDerived ().transformPackElement (element, pos);
633
600
}
634
601
635
602
case TypeKind::Tuple: {
@@ -695,17 +662,7 @@ case TypeKind::Id:
695
662
696
663
case TypeKind::DependentMember: {
697
664
auto dependent = cast<DependentMemberType>(base);
698
- auto dependentBase = doIt (dependent->getBase (), pos);
699
- if (!dependentBase)
700
- return Type ();
701
-
702
- if (dependentBase.getPointer () == dependent->getBase ().getPointer ())
703
- return t;
704
-
705
- if (auto assocType = dependent->getAssocType ())
706
- return DependentMemberType::get (dependentBase, assocType);
707
-
708
- return DependentMemberType::get (dependentBase, dependent->getName ());
665
+ return asDerived ().transformDependentMember (dependent, pos);
709
666
}
710
667
711
668
case TypeKind::GenericFunction:
@@ -1008,8 +965,59 @@ case TypeKind::Id:
1008
965
QueryReplacementTypeArray{sig, newSubs},
1009
966
LookUpConformanceInModule ());
1010
967
}
968
+
969
+ CanType transformSILField (CanType fieldTy, TypePosition pos) {
970
+ return doIt (fieldTy, pos)->getCanonicalType ();
971
+ }
972
+
973
+ Type transformGenericTypeParam (GenericTypeParamType *param, TypePosition pos) {
974
+ return param;
975
+ }
976
+
977
+ Type transformPackExpansion (PackExpansionType *expand, TypePosition pos) {
978
+ // Substitution completely replaces this.
979
+
980
+ Type transformedPat = doIt (expand->getPatternType (), pos);
981
+ if (!transformedPat)
982
+ return Type ();
983
+
984
+ Type transformedCount = doIt (expand->getCountType (), TypePosition::Shape);
985
+ if (!transformedCount)
986
+ return Type ();
987
+
988
+ if (transformedPat.getPointer () == expand->getPatternType ().getPointer () &&
989
+ transformedCount.getPointer () == expand->getCountType ().getPointer ())
990
+ return expand;
991
+
992
+ return PackExpansionType::get (transformedPat, transformedCount);
993
+ }
994
+
995
+ Type transformPackElement (PackElementType *element, TypePosition pos) {
996
+ Type transformedPack = doIt (element->getPackType (), pos);
997
+ if (!transformedPack)
998
+ return Type ();
999
+
1000
+ if (transformedPack.getPointer () == element->getPackType ().getPointer ())
1001
+ return element;
1002
+
1003
+ return PackElementType::get (transformedPack, element->getLevel ());
1004
+ }
1005
+
1006
+ Type transformDependentMember (DependentMemberType *dependent, TypePosition pos) {
1007
+ auto dependentBase = doIt (dependent->getBase (), pos);
1008
+ if (!dependentBase)
1009
+ return Type ();
1010
+
1011
+ if (dependentBase.getPointer () == dependent->getBase ().getPointer ())
1012
+ return dependent;
1013
+
1014
+ if (auto assocType = dependent->getAssocType ())
1015
+ return DependentMemberType::get (dependentBase, assocType);
1016
+
1017
+ return DependentMemberType::get (dependentBase, dependent->getName ());
1018
+ }
1011
1019
};
1012
1020
1013
1021
}
1014
1022
1015
- #endif
1023
+ #endif
0 commit comments