Skip to content

Commit fa8ac95

Browse files
authored
Don't print 'convenience' on protocol extension initializers (swiftlang#18777)
We model them that way in the compiler, but that's not part of the user-level language. rdar://problem/32067077
1 parent ff7667e commit fa8ac95

File tree

4 files changed

+1319
-985
lines changed

4 files changed

+1319
-985
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2707,10 +2707,25 @@ void PrintAST::visitConstructorDecl(ConstructorDecl *decl) {
27072707
if ((decl->getInitKind() == CtorInitializerKind::Convenience ||
27082708
decl->getInitKind() == CtorInitializerKind::ConvenienceFactory) &&
27092709
!decl->getAttrs().hasAttribute<ConvenienceAttr>()) {
2710-
Printer.printKeyword("convenience");
2711-
Printer << " ";
2710+
// Protocol extension initializers are modeled as convenience initializers,
2711+
// but they're not written that way in source. Check if we're actually
2712+
// printing onto a class.
2713+
bool isClassContext;
2714+
if (CurrentType) {
2715+
isClassContext = CurrentType->getClassOrBoundGenericClass() != nullptr;
2716+
} else {
2717+
const DeclContext *dc = decl->getDeclContext();
2718+
isClassContext = dc->getSelfClassDecl() != nullptr;
2719+
}
2720+
if (isClassContext) {
2721+
Printer.printKeyword("convenience");
2722+
Printer << " ";
2723+
} else {
2724+
assert(decl->getDeclContext()->getExtendedProtocolDecl() &&
2725+
"unexpected convenience initializer");
2726+
}
27122727
} else if (decl->getInitKind() == CtorInitializerKind::Factory) {
2713-
Printer << "/*not inherited*/ ";
2728+
Printer << "/*not inherited*/ ";
27142729
}
27152730

27162731
printContextIfNeeded(decl);

test/SourceKit/DocSupport/Inputs/cake1.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,19 @@ public extension P2 where Self : P3 {
2929
public extension Dictionary.Keys {
3030
public func foo() {}
3131
}
32+
33+
public protocol InitProto {
34+
init(x: Int)
35+
}
36+
extension InitProto {
37+
// This initializer is marked as 'CtorInitializerKind::Convenience'.
38+
public init() { self = Self(x: 0) }
39+
}
40+
41+
public struct InitStructImpl : InitProto {
42+
public init(x: Int) {}
43+
}
44+
45+
public class InitClassImpl : InitProto {
46+
public required init(x: Int) {}
47+
}

0 commit comments

Comments
 (0)