Skip to content

Commit 9d00f42

Browse files
committed
Sema: compute InitKindRequest::evaluate in a more performant way.
Use `getSelfNominalTypeDecl` rather than `getDeclaredInterfaceType` in `InitKindRequest::evaluate`, since it's cheaper to perform.
1 parent 53b6d7e commit 9d00f42

File tree

2 files changed

+15
-13
lines changed

2 files changed

+15
-13
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2813,13 +2813,13 @@ NOTE(convenience_init_here,none,
28132813
ERROR(designated_init_in_extension,none,
28142814
"designated initializer cannot be declared in an extension of %0; "
28152815
"did you mean this to be a convenience initializer?",
2816-
(Type))
2816+
(DeclName))
28172817
ERROR(enumstruct_convenience_init,none,
28182818
"delegating initializers in %0 are not marked with 'convenience'",
28192819
(StringRef))
28202820
ERROR(nonclass_convenience_init,none,
28212821
"convenience initializer not allowed in non-class type %0",
2822-
(Type))
2822+
(DeclName))
28232823
ERROR(cfclass_convenience_init,none,
28242824
"convenience initializers are not supported in extensions of CF types",
28252825
())

lib/Sema/TypeCheckDecl.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,28 +1234,29 @@ InitKindRequest::evaluate(Evaluator &evaluator, ConstructorDecl *decl) const {
12341234

12351235
// Convenience inits are only allowed on classes and in extensions thereof.
12361236
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);
12391239

12401240
// Forbid convenience inits on Foreign CF types, as Swift does not yet
12411241
// support user-defined factory inits.
1242-
if (extClass &&
1243-
extClass->getForeignClassKind() == ClassDecl::ForeignKind::CFType) {
1242+
if (classDecl &&
1243+
classDecl->getForeignClassKind() == ClassDecl::ForeignKind::CFType) {
12441244
diags.diagnose(decl->getLoc(), diag::cfclass_convenience_init);
12451245
}
12461246

1247-
if (!extClass && !extType->hasError()) {
1247+
if (!classDecl) {
12481248
auto ConvenienceLoc =
12491249
decl->getAttrs().getAttribute<ConvenienceAttr>()->getLocation();
12501250

12511251
// 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)) {
12541254
diags.diagnose(decl->getLoc(), diag::enumstruct_convenience_init,
12551255
isStruct ? "structs" : "enums")
12561256
.fixItRemove(ConvenienceLoc);
12571257
} else {
1258-
diags.diagnose(decl->getLoc(), diag::nonclass_convenience_init, extType)
1258+
diags.diagnose(decl->getLoc(), diag::nonclass_convenience_init,
1259+
nominal->getName())
12591260
.fixItRemove(ConvenienceLoc);
12601261
}
12611262
return CtorInitializerKind::Designated;
@@ -1264,7 +1265,7 @@ InitKindRequest::evaluate(Evaluator &evaluator, ConstructorDecl *decl) const {
12641265

12651266
return CtorInitializerKind::Convenience;
12661267

1267-
} else if (auto extType = decl->getDeclContext()->getDeclaredInterfaceType()) {
1268+
} else if (auto nominal = decl->getDeclContext()->getSelfNominalTypeDecl()) {
12681269
// A designated init for a class must be written within the class itself.
12691270
//
12701271
// This is because designated initializers of classes get a vtable entry,
@@ -1273,10 +1274,11 @@ InitKindRequest::evaluate(Evaluator &evaluator, ConstructorDecl *decl) const {
12731274
// If we implement the ability for extensions defined in the same module
12741275
// (or the same file) to add vtable entries, we can re-evaluate this
12751276
// restriction.
1276-
if (extType->getClassOrBoundGenericClass() &&
1277+
if (dyn_cast<ClassDecl>(nominal) &&
12771278
!decl->isSynthesized() && isa<ExtensionDecl>(decl->getDeclContext()) &&
12781279
!(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())
12801282
.fixItInsert(decl->getLoc(), "convenience ");
12811283
return CtorInitializerKind::Convenience;
12821284
}

0 commit comments

Comments
 (0)