@@ -971,30 +971,28 @@ StructuralRequirementsRequest::evaluate(Evaluator &evaluator,
971
971
// DependentMemberType X, and the right hand side is the
972
972
// underlying type of the typealias.
973
973
if (auto *typeAliasDecl = dyn_cast<TypeAliasDecl>(decl)) {
974
- if (!typeAliasDecl->isGeneric ()) {
975
- // Ignore the typealias if we have an associated type with the same name
976
- // in the same protocol. This is invalid anyway, but it's just here to
977
- // ensure that we produce the same requirement signature on some tests
978
- // with -requirement-machine-protocol-signatures=verify.
979
- if (assocTypes.contains (typeAliasDecl->getName ()))
980
- continue ;
974
+ if (typeAliasDecl->isGeneric ())
975
+ continue ;
981
976
982
- // The structural type of a typealias will always be a TypeAliasType,
983
- // so unwrap it to avoid a requirement that prints as 'Self.T == Self.T'
984
- // in diagnostics.
985
- auto underlyingType = typeAliasDecl-> getStructuralType ();
986
- if (auto *aliasType = dyn_cast<TypeAliasType>(underlyingType. getPointer ()))
987
- underlyingType = aliasType-> getSinglyDesugaredType () ;
977
+ // Ignore the typealias if we have an associated type with the same name
978
+ // in the same protocol. This is invalid anyway, but it's just here to
979
+ // ensure that we produce the same requirement signature on some tests
980
+ // with -requirement-machine-protocol-signatures=verify.
981
+ if (assocTypes. contains (typeAliasDecl-> getName ()))
982
+ continue ;
988
983
989
- if (underlyingType->is <UnboundGenericType>())
990
- continue ;
984
+ // The structural type of a typealias will always be a TypeAliasType,
985
+ // so unwrap it to avoid a requirement that prints as 'Self.T == Self.T'
986
+ // in diagnostics.
987
+ auto underlyingType = typeAliasDecl->getStructuralType ();
988
+ if (underlyingType->is <UnboundGenericType>())
989
+ continue ;
991
990
992
- auto subjectType = DependentMemberType::get (
993
- selfTy, typeAliasDecl->getName ());
994
- Requirement req (RequirementKind::SameType, subjectType,
995
- underlyingType);
996
- result.push_back ({req, typeAliasDecl->getLoc ()});
997
- }
991
+ auto subjectType = DependentMemberType::get (
992
+ selfTy, typeAliasDecl->getName ());
993
+ Requirement req (RequirementKind::SameType, subjectType,
994
+ underlyingType);
995
+ result.push_back ({req, typeAliasDecl->getLoc ()});
998
996
}
999
997
}
1000
998
@@ -1053,21 +1051,28 @@ TypeAliasRequirementsRequest::evaluate(Evaluator &evaluator,
1053
1051
return typeDecl->getDeclaredInterfaceType ();
1054
1052
};
1055
1053
1054
+ auto isSuitableType = [&](TypeDecl *req) -> bool {
1055
+ // Ignore generic types.
1056
+ if (auto genReq = dyn_cast<GenericTypeDecl>(req))
1057
+ if (genReq->isGeneric ())
1058
+ return false ;
1059
+
1060
+ // Ignore typealiases with UnboundGenericType, since they
1061
+ // are like generic typealiases.
1062
+ if (auto *typeAlias = dyn_cast<TypeAliasDecl>(req))
1063
+ if (getStructuralType (typeAlias)->is <UnboundGenericType>())
1064
+ return false ;
1065
+
1066
+ return true ;
1067
+ };
1068
+
1056
1069
// Collect all typealiases from inherited protocols recursively.
1057
1070
llvm::MapVector<Identifier, TinyPtrVector<TypeDecl *>> inheritedTypeDecls;
1058
1071
for (auto *inheritedProto : ctx.getRewriteContext ().getInheritedProtocols (proto)) {
1059
1072
for (auto req : inheritedProto->getMembers ()) {
1060
1073
if (auto *typeReq = dyn_cast<TypeDecl>(req)) {
1061
- // Ignore generic types.
1062
- if (auto genReq = dyn_cast<GenericTypeDecl>(req))
1063
- if (genReq->getGenericParams ())
1064
- continue ;
1065
-
1066
- // Ignore typealiases with UnboundGenericType, since they
1067
- // are like generic typealiases.
1068
- if (auto *typeAlias = dyn_cast<TypeAliasDecl>(req))
1069
- if (getStructuralType (typeAlias)->is <UnboundGenericType>())
1070
- continue ;
1074
+ if (!isSuitableType (typeReq))
1075
+ continue ;
1071
1076
1072
1077
inheritedTypeDecls[typeReq->getName ()].push_back (typeReq);
1073
1078
}
@@ -1077,10 +1082,13 @@ TypeAliasRequirementsRequest::evaluate(Evaluator &evaluator,
1077
1082
// An inferred same-type requirement between the two type declarations
1078
1083
// within this protocol or a protocol it inherits.
1079
1084
auto recordInheritedTypeRequirement = [&](TypeDecl *first, TypeDecl *second) {
1080
- desugarRequirement (Requirement (RequirementKind::SameType,
1081
- getStructuralType (first),
1082
- getStructuralType (second)),
1083
- SourceLoc (), result, ignoredInverses, errors);
1085
+ auto firstType = getStructuralType (first);
1086
+ auto secondType = getStructuralType (second);
1087
+ assert (!firstType->is <UnboundGenericType>());
1088
+ assert (!secondType->is <UnboundGenericType>());
1089
+
1090
+ desugarRequirement (Requirement (RequirementKind::SameType, firstType, secondType),
1091
+ SourceLoc (), result, ignoredInverses, errors);
1084
1092
};
1085
1093
1086
1094
// Local function to find the insertion point for the protocol's "where"
@@ -1206,25 +1214,31 @@ TypeAliasRequirementsRequest::evaluate(Evaluator &evaluator,
1206
1214
const auto name = inherited.first ;
1207
1215
for (auto found : proto->lookupDirect (name)) {
1208
1216
// We only want concrete type declarations.
1209
- auto type = dyn_cast<TypeDecl>(found);
1210
- if (!type || isa<AssociatedTypeDecl>(type )) continue ;
1217
+ auto typeReq = dyn_cast<TypeDecl>(found);
1218
+ if (!typeReq || isa<AssociatedTypeDecl>(typeReq )) continue ;
1211
1219
1212
1220
// Ignore nominal types. They're always invalid declarations.
1213
- if (isa<NominalTypeDecl>(type))
1221
+ if (isa<NominalTypeDecl>(typeReq))
1222
+ continue ;
1223
+
1224
+ // Ignore generic type aliases.
1225
+ if (!isSuitableType (typeReq))
1214
1226
continue ;
1215
1227
1216
1228
// ... from the same module as the protocol.
1217
- if (type ->getModuleContext () != proto->getModuleContext ()) continue ;
1229
+ if (typeReq ->getModuleContext () != proto->getModuleContext ()) continue ;
1218
1230
1219
1231
// Ignore types defined in constrained extensions; their equivalence
1220
1232
// to the associated type would have to be conditional, which we cannot
1221
1233
// model.
1222
- if (auto ext = dyn_cast<ExtensionDecl>(type ->getDeclContext ())) {
1234
+ if (auto ext = dyn_cast<ExtensionDecl>(typeReq ->getDeclContext ())) {
1223
1235
// FIXME: isConstrainedExtension() can cause request cycles because it
1224
1236
// computes a generic signature. getTrailingWhereClause() should be good
1225
1237
// enough for protocol extensions, which cannot specify constraints in
1226
1238
// any other way right now (eg, via requirement inference or by
1227
1239
// extending a bound generic type).
1240
+ //
1241
+ // FIXME: Protocol extensions with noncopyable generics can!
1228
1242
if (ext->getTrailingWhereClause ()) continue ;
1229
1243
}
1230
1244
@@ -1237,19 +1251,19 @@ TypeAliasRequirementsRequest::evaluate(Evaluator &evaluator,
1237
1251
dyn_cast<AssociatedTypeDecl>(inheritedType)) {
1238
1252
// Infer a same-type requirement between the typealias' underlying
1239
1253
// type and the inherited associated type.
1240
- recordInheritedTypeRequirement (inheritedAssocTypeDecl, type );
1254
+ recordInheritedTypeRequirement (inheritedAssocTypeDecl, typeReq );
1241
1255
1242
1256
// Warn that one should use where clauses for this.
1243
1257
if (shouldWarnAboutRedeclaration) {
1244
1258
auto inheritedFromProto = inheritedAssocTypeDecl->getProtocol ();
1245
1259
auto fixItWhere = getProtocolWhereLoc ();
1246
- ctx.Diags .diagnose (type ,
1260
+ ctx.Diags .diagnose (typeReq ,
1247
1261
diag::typealias_override_associated_type,
1248
1262
name,
1249
1263
inheritedFromProto->getDeclaredInterfaceType ())
1250
1264
.fixItInsertAfter (fixItWhere.Loc ,
1251
- getConcreteTypeReq (type , fixItWhere.Item ))
1252
- .fixItRemove (type ->getSourceRange ());
1265
+ getConcreteTypeReq (typeReq , fixItWhere.Item ))
1266
+ .fixItRemove (typeReq ->getSourceRange ());
1253
1267
ctx.Diags .diagnose (inheritedAssocTypeDecl, diag::decl_declared_here,
1254
1268
inheritedAssocTypeDecl);
1255
1269
@@ -1260,7 +1274,7 @@ TypeAliasRequirementsRequest::evaluate(Evaluator &evaluator,
1260
1274
}
1261
1275
1262
1276
// Two typealiases that should be the same.
1263
- recordInheritedTypeRequirement (inheritedType, type );
1277
+ recordInheritedTypeRequirement (inheritedType, typeReq );
1264
1278
}
1265
1279
1266
1280
// We can remove this entry.
0 commit comments