@@ -955,30 +955,28 @@ StructuralRequirementsRequest::evaluate(Evaluator &evaluator,
955
955
// DependentMemberType X, and the right hand side is the
956
956
// underlying type of the typealias.
957
957
if (auto *typeAliasDecl = dyn_cast<TypeAliasDecl>(decl)) {
958
- if (!typeAliasDecl->isGeneric ()) {
959
- // Ignore the typealias if we have an associated type with the same name
960
- // in the same protocol. This is invalid anyway, but it's just here to
961
- // ensure that we produce the same requirement signature on some tests
962
- // with -requirement-machine-protocol-signatures=verify.
963
- if (assocTypes.contains (typeAliasDecl->getName ()))
964
- continue ;
958
+ if (typeAliasDecl->isGeneric ())
959
+ continue ;
965
960
966
- // The structural type of a typealias will always be a TypeAliasType,
967
- // so unwrap it to avoid a requirement that prints as 'Self.T == Self.T'
968
- // in diagnostics.
969
- auto underlyingType = typeAliasDecl-> getStructuralType ();
970
- if (auto *aliasType = dyn_cast<TypeAliasType>(underlyingType. getPointer ()))
971
- underlyingType = aliasType-> getSinglyDesugaredType () ;
961
+ // Ignore the typealias if we have an associated type with the same name
962
+ // in the same protocol. This is invalid anyway, but it's just here to
963
+ // ensure that we produce the same requirement signature on some tests
964
+ // with -requirement-machine-protocol-signatures=verify.
965
+ if (assocTypes. contains (typeAliasDecl-> getName ()))
966
+ continue ;
972
967
973
- if (underlyingType->is <UnboundGenericType>())
974
- continue ;
968
+ // The structural type of a typealias will always be a TypeAliasType,
969
+ // so unwrap it to avoid a requirement that prints as 'Self.T == Self.T'
970
+ // in diagnostics.
971
+ auto underlyingType = typeAliasDecl->getStructuralType ();
972
+ if (underlyingType->is <UnboundGenericType>())
973
+ continue ;
975
974
976
- auto subjectType = DependentMemberType::get (
977
- selfTy, typeAliasDecl->getName ());
978
- Requirement req (RequirementKind::SameType, subjectType,
979
- underlyingType);
980
- result.push_back ({req, typeAliasDecl->getLoc ()});
981
- }
975
+ auto subjectType = DependentMemberType::get (
976
+ selfTy, typeAliasDecl->getName ());
977
+ Requirement req (RequirementKind::SameType, subjectType,
978
+ underlyingType);
979
+ result.push_back ({req, typeAliasDecl->getLoc ()});
982
980
}
983
981
}
984
982
@@ -1037,21 +1035,28 @@ TypeAliasRequirementsRequest::evaluate(Evaluator &evaluator,
1037
1035
return typeDecl->getDeclaredInterfaceType ();
1038
1036
};
1039
1037
1038
+ auto isSuitableType = [&](TypeDecl *req) -> bool {
1039
+ // Ignore generic types.
1040
+ if (auto genReq = dyn_cast<GenericTypeDecl>(req))
1041
+ if (genReq->isGeneric ())
1042
+ return false ;
1043
+
1044
+ // Ignore typealiases with UnboundGenericType, since they
1045
+ // are like generic typealiases.
1046
+ if (auto *typeAlias = dyn_cast<TypeAliasDecl>(req))
1047
+ if (getStructuralType (typeAlias)->is <UnboundGenericType>())
1048
+ return false ;
1049
+
1050
+ return true ;
1051
+ };
1052
+
1040
1053
// Collect all typealiases from inherited protocols recursively.
1041
1054
llvm::MapVector<Identifier, TinyPtrVector<TypeDecl *>> inheritedTypeDecls;
1042
1055
for (auto *inheritedProto : ctx.getRewriteContext ().getInheritedProtocols (proto)) {
1043
1056
for (auto req : inheritedProto->getMembers ()) {
1044
1057
if (auto *typeReq = dyn_cast<TypeDecl>(req)) {
1045
- // Ignore generic types.
1046
- if (auto genReq = dyn_cast<GenericTypeDecl>(req))
1047
- if (genReq->getGenericParams ())
1048
- continue ;
1049
-
1050
- // Ignore typealiases with UnboundGenericType, since they
1051
- // are like generic typealiases.
1052
- if (auto *typeAlias = dyn_cast<TypeAliasDecl>(req))
1053
- if (getStructuralType (typeAlias)->is <UnboundGenericType>())
1054
- continue ;
1058
+ if (!isSuitableType (typeReq))
1059
+ continue ;
1055
1060
1056
1061
inheritedTypeDecls[typeReq->getName ()].push_back (typeReq);
1057
1062
}
@@ -1061,10 +1066,13 @@ TypeAliasRequirementsRequest::evaluate(Evaluator &evaluator,
1061
1066
// An inferred same-type requirement between the two type declarations
1062
1067
// within this protocol or a protocol it inherits.
1063
1068
auto recordInheritedTypeRequirement = [&](TypeDecl *first, TypeDecl *second) {
1064
- desugarRequirement (Requirement (RequirementKind::SameType,
1065
- getStructuralType (first),
1066
- getStructuralType (second)),
1067
- SourceLoc (), result, ignoredInverses, errors);
1069
+ auto firstType = getStructuralType (first);
1070
+ auto secondType = getStructuralType (second);
1071
+ assert (!firstType->is <UnboundGenericType>());
1072
+ assert (!secondType->is <UnboundGenericType>());
1073
+
1074
+ desugarRequirement (Requirement (RequirementKind::SameType, firstType, secondType),
1075
+ SourceLoc (), result, ignoredInverses, errors);
1068
1076
};
1069
1077
1070
1078
// Local function to find the insertion point for the protocol's "where"
@@ -1190,25 +1198,31 @@ TypeAliasRequirementsRequest::evaluate(Evaluator &evaluator,
1190
1198
const auto name = inherited.first ;
1191
1199
for (auto found : proto->lookupDirect (name)) {
1192
1200
// We only want concrete type declarations.
1193
- auto type = dyn_cast<TypeDecl>(found);
1194
- if (!type || isa<AssociatedTypeDecl>(type )) continue ;
1201
+ auto typeReq = dyn_cast<TypeDecl>(found);
1202
+ if (!typeReq || isa<AssociatedTypeDecl>(typeReq )) continue ;
1195
1203
1196
1204
// Ignore nominal types. They're always invalid declarations.
1197
- if (isa<NominalTypeDecl>(type))
1205
+ if (isa<NominalTypeDecl>(typeReq))
1206
+ continue ;
1207
+
1208
+ // Ignore generic type aliases.
1209
+ if (!isSuitableType (typeReq))
1198
1210
continue ;
1199
1211
1200
1212
// ... from the same module as the protocol.
1201
- if (type ->getModuleContext () != proto->getModuleContext ()) continue ;
1213
+ if (typeReq ->getModuleContext () != proto->getModuleContext ()) continue ;
1202
1214
1203
1215
// Ignore types defined in constrained extensions; their equivalence
1204
1216
// to the associated type would have to be conditional, which we cannot
1205
1217
// model.
1206
- if (auto ext = dyn_cast<ExtensionDecl>(type ->getDeclContext ())) {
1218
+ if (auto ext = dyn_cast<ExtensionDecl>(typeReq ->getDeclContext ())) {
1207
1219
// FIXME: isConstrainedExtension() can cause request cycles because it
1208
1220
// computes a generic signature. getTrailingWhereClause() should be good
1209
1221
// enough for protocol extensions, which cannot specify constraints in
1210
1222
// any other way right now (eg, via requirement inference or by
1211
1223
// extending a bound generic type).
1224
+ //
1225
+ // FIXME: Protocol extensions with noncopyable generics can!
1212
1226
if (ext->getTrailingWhereClause ()) continue ;
1213
1227
}
1214
1228
@@ -1221,19 +1235,19 @@ TypeAliasRequirementsRequest::evaluate(Evaluator &evaluator,
1221
1235
dyn_cast<AssociatedTypeDecl>(inheritedType)) {
1222
1236
// Infer a same-type requirement between the typealias' underlying
1223
1237
// type and the inherited associated type.
1224
- recordInheritedTypeRequirement (inheritedAssocTypeDecl, type );
1238
+ recordInheritedTypeRequirement (inheritedAssocTypeDecl, typeReq );
1225
1239
1226
1240
// Warn that one should use where clauses for this.
1227
1241
if (shouldWarnAboutRedeclaration) {
1228
1242
auto inheritedFromProto = inheritedAssocTypeDecl->getProtocol ();
1229
1243
auto fixItWhere = getProtocolWhereLoc ();
1230
- ctx.Diags .diagnose (type ,
1244
+ ctx.Diags .diagnose (typeReq ,
1231
1245
diag::typealias_override_associated_type,
1232
1246
name,
1233
1247
inheritedFromProto->getDeclaredInterfaceType ())
1234
1248
.fixItInsertAfter (fixItWhere.Loc ,
1235
- getConcreteTypeReq (type , fixItWhere.Item ))
1236
- .fixItRemove (type ->getSourceRange ());
1249
+ getConcreteTypeReq (typeReq , fixItWhere.Item ))
1250
+ .fixItRemove (typeReq ->getSourceRange ());
1237
1251
ctx.Diags .diagnose (inheritedAssocTypeDecl, diag::decl_declared_here,
1238
1252
inheritedAssocTypeDecl);
1239
1253
@@ -1244,7 +1258,7 @@ TypeAliasRequirementsRequest::evaluate(Evaluator &evaluator,
1244
1258
}
1245
1259
1246
1260
// Two typealiases that should be the same.
1247
- recordInheritedTypeRequirement (inheritedType, type );
1261
+ recordInheritedTypeRequirement (inheritedType, typeReq );
1248
1262
}
1249
1263
1250
1264
// We can remove this entry.
0 commit comments