@@ -181,9 +181,8 @@ class TypeMatcher {
181181
182182 bool visitReferenceStorageType (CanReferenceStorageType firstStorage,
183183 Type secondType, Type sugaredFirstType) {
184- auto _secondStorage = secondType->getCanonicalType ();
185- if (firstStorage->getKind () == _secondStorage->getKind ()) {
186- auto secondStorage = cast<ReferenceStorageType>(_secondStorage);
184+ if (firstStorage->getKind () == secondType->getDesugaredType ()->getKind ()) {
185+ auto secondStorage = secondType->castTo <ReferenceStorageType>();
187186 return this ->visit (firstStorage.getReferentType (),
188187 secondStorage->getReferentType (),
189188 sugaredFirstType->castTo <ReferenceStorageType>()
@@ -195,9 +194,8 @@ class TypeMatcher {
195194
196195 bool visitNominalType (CanNominalType firstNominal,
197196 Type secondType, Type sugaredFirstType) {
198- auto _secondNominal = secondType->getCanonicalType ();
199- if (firstNominal->getKind () == _secondNominal->getKind ()) {
200- auto secondNominal = cast<NominalType>(_secondNominal);
197+ if (firstNominal->getKind () == secondType->getDesugaredType ()->getKind ()) {
198+ auto secondNominal = secondType->castTo <NominalType>();
201199 if (firstNominal->getDecl () != secondNominal->getDecl ())
202200 return mismatch (firstNominal.getPointer (), secondNominal,
203201 sugaredFirstType);
@@ -216,9 +214,8 @@ class TypeMatcher {
216214
217215 bool visitAnyMetatypeType (CanAnyMetatypeType firstMeta,
218216 Type secondType, Type sugaredFirstType) {
219- auto _secondMeta = secondType->getCanonicalType ();
220- if (firstMeta->getKind () == _secondMeta->getKind ()) {
221- auto secondMeta = cast<AnyMetatypeType>(_secondMeta);
217+ if (firstMeta->getKind () == secondType->getDesugaredType ()->getKind ()) {
218+ auto secondMeta = secondType->castTo <AnyMetatypeType>();
222219 return this ->visit (firstMeta.getInstanceType (),
223220 secondMeta->getInstanceType (),
224221 sugaredFirstType->castTo <AnyMetatypeType>()
@@ -229,7 +226,41 @@ class TypeMatcher {
229226 }
230227
231228 TRIVIAL_CASE (ModuleType)
232- TRIVIAL_CASE (ArchetypeType)
229+
230+ bool visitArchetypeType (CanArchetypeType firstArchetype,
231+ Type secondType,
232+ Type sugaredFirstType) {
233+ if (auto firstOpaqueArchetype = dyn_cast<OpaqueTypeArchetypeType>(firstArchetype)) {
234+ if (auto secondOpaqueArchetype = secondType->getAs <OpaqueTypeArchetypeType>()) {
235+ if (firstOpaqueArchetype->getDecl () == secondOpaqueArchetype->getDecl ()) {
236+ auto firstSubMap = firstOpaqueArchetype->getSubstitutions ();
237+ auto secondSubMap = secondOpaqueArchetype->getSubstitutions ();
238+ assert (firstSubMap.getReplacementTypes ().size () ==
239+ secondSubMap.getReplacementTypes ().size ());
240+
241+ for (unsigned i : indices (firstSubMap.getReplacementTypes ())) {
242+ auto firstSubstType = firstSubMap.getReplacementTypes ()[i];
243+ auto secondSubstType = secondSubMap.getReplacementTypes ()[i];
244+
245+ if (!this ->visit (firstSubstType->getCanonicalType (),
246+ secondSubstType, firstSubstType))
247+ return false ;
248+ }
249+
250+ return true ;
251+ }
252+ }
253+ }
254+
255+ // FIXME: Once OpenedArchetypeType stores substitutions, do something
256+ // similar to the above.
257+
258+ if (firstArchetype->isEqual (secondType))
259+ return true ;
260+
261+
262+ return mismatch (firstArchetype.getPointer (), secondType, sugaredFirstType);
263+ }
233264
234265 bool visitDynamicSelfType (CanDynamicSelfType firstDynamicSelf,
235266 Type secondType,
0 commit comments