@@ -1234,28 +1234,29 @@ InitKindRequest::evaluate(Evaluator &evaluator, ConstructorDecl *decl) const {
1234
1234
1235
1235
// Convenience inits are only allowed on classes and in extensions thereof.
1236
1236
if (decl->getAttrs ().hasAttribute <ConvenienceAttr>()) {
1237
- if (auto extType = decl->getDeclContext ()->getDeclaredInterfaceType ()) {
1238
- auto extClass = extType-> getClassOrBoundGenericClass ( );
1237
+ if (auto nominal = decl->getDeclContext ()->getSelfNominalTypeDecl ()) {
1238
+ auto classDecl = dyn_cast<ClassDecl>(nominal );
1239
1239
1240
1240
// Forbid convenience inits on Foreign CF types, as Swift does not yet
1241
1241
// support user-defined factory inits.
1242
- if (extClass &&
1243
- extClass ->getForeignClassKind () == ClassDecl::ForeignKind::CFType) {
1242
+ if (classDecl &&
1243
+ classDecl ->getForeignClassKind () == ClassDecl::ForeignKind::CFType) {
1244
1244
diags.diagnose (decl->getLoc (), diag::cfclass_convenience_init);
1245
1245
}
1246
1246
1247
- if (!extClass && !extType-> hasError () ) {
1247
+ if (!classDecl ) {
1248
1248
auto ConvenienceLoc =
1249
1249
decl->getAttrs ().getAttribute <ConvenienceAttr>()->getLocation ();
1250
1250
1251
1251
// Produce a tailored diagnostic for structs and enums.
1252
- bool isStruct = extType-> getStructOrBoundGenericStruct ( ) != nullptr ;
1253
- if (isStruct || extType-> getEnumOrBoundGenericEnum ( )) {
1252
+ bool isStruct = dyn_cast<StructDecl>(nominal ) != nullptr ;
1253
+ if (isStruct || dyn_cast<EnumDecl>(nominal )) {
1254
1254
diags.diagnose (decl->getLoc (), diag::enumstruct_convenience_init,
1255
1255
isStruct ? " structs" : " enums" )
1256
1256
.fixItRemove (ConvenienceLoc);
1257
1257
} else {
1258
- diags.diagnose (decl->getLoc (), diag::nonclass_convenience_init, extType)
1258
+ diags.diagnose (decl->getLoc (), diag::nonclass_convenience_init,
1259
+ nominal->getName ())
1259
1260
.fixItRemove (ConvenienceLoc);
1260
1261
}
1261
1262
return CtorInitializerKind::Designated;
@@ -1264,7 +1265,7 @@ InitKindRequest::evaluate(Evaluator &evaluator, ConstructorDecl *decl) const {
1264
1265
1265
1266
return CtorInitializerKind::Convenience;
1266
1267
1267
- } else if (auto extType = decl->getDeclContext ()->getDeclaredInterfaceType ()) {
1268
+ } else if (auto nominal = decl->getDeclContext ()->getSelfNominalTypeDecl ()) {
1268
1269
// A designated init for a class must be written within the class itself.
1269
1270
//
1270
1271
// This is because designated initializers of classes get a vtable entry,
@@ -1273,10 +1274,11 @@ InitKindRequest::evaluate(Evaluator &evaluator, ConstructorDecl *decl) const {
1273
1274
// If we implement the ability for extensions defined in the same module
1274
1275
// (or the same file) to add vtable entries, we can re-evaluate this
1275
1276
// restriction.
1276
- if (extType-> getClassOrBoundGenericClass ( ) &&
1277
+ if (dyn_cast<ClassDecl>(nominal ) &&
1277
1278
!decl->isSynthesized () && isa<ExtensionDecl>(decl->getDeclContext ()) &&
1278
1279
!(decl->getAttrs ().hasAttribute <DynamicReplacementAttr>())) {
1279
- diags.diagnose (decl->getLoc (), diag::designated_init_in_extension, extType)
1280
+ diags.diagnose (decl->getLoc (), diag::designated_init_in_extension,
1281
+ nominal->getName ())
1280
1282
.fixItInsert (decl->getLoc (), " convenience " );
1281
1283
return CtorInitializerKind::Convenience;
1282
1284
}
0 commit comments