Skip to content

Commit 96ee57b

Browse files
Merge pull request #70623 from AnthonyLatsis/init-sema
Move unqualified `init` diagnosis from Parse to Sema
2 parents 517d187 + ff2a5e0 commit 96ee57b

22 files changed

+299
-118
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,8 +413,6 @@ ERROR(subscript_without_get,none,
413413
"subscript declarations must have a getter", ())
414414

415415
// initializer
416-
ERROR(invalid_nested_init,none,
417-
"missing '%select{super.|self.}0' at initializer invocation", (bool))
418416
ERROR(initializer_decl_wrong_scope,none,
419417
"initializers may only be declared within a type", ())
420418
ERROR(expected_lparen_initializer,PointsToFirstBadToken,

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4284,6 +4284,11 @@ ERROR(no_member_of_module,none,
42844284

42854285
ERROR(super_with_no_base_class,none,
42864286
"'super' members cannot be referenced in a root class", ())
4287+
ERROR(unqualified_init,none,
4288+
"initializer expression requires explicit access"
4289+
"%select{|; did you mean to prepend it with|; did you mean to prepend "
4290+
"it with}0%select{| 'self.'?| 'super.'?}0",
4291+
(unsigned))
42874292

42884293
ERROR(bad_init_ref_base, none,
42894294
"'init' can only refer to the initializers of "

include/swift/AST/Identifier.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,8 @@ class DeclBaseName {
323323

324324
bool isSubscript() const { return getKind() == Kind::Subscript; }
325325

326+
bool isConstructor() const { return getKind() == Kind::Constructor; }
327+
326328
/// Return the identifier backing the name. Assumes that the name is not
327329
/// special.
328330
Identifier getIdentifier() const {

include/swift/Parse/Parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1799,7 +1799,7 @@ class Parser {
17991799
SourceLoc &rightAngleLoc, ArgumentList *&argList, bool isExprBasic,
18001800
const Diagnostic &diag);
18011801

1802-
ParserResult<Expr> parseExprIdentifier();
1802+
ParserResult<Expr> parseExprIdentifier(bool allowKeyword);
18031803
Expr *parseExprEditorPlaceholder(Token PlaceholderTok,
18041804
Identifier PlaceholderId);
18051805

lib/AST/Decl.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5691,7 +5691,7 @@ void NominalTypeDecl::synthesizeSemanticMembersIfNeeded(DeclName member) {
56915691
auto baseName = member.getBaseName();
56925692
auto &Context = getASTContext();
56935693
llvm::Optional<ImplicitMemberAction> action = llvm::None;
5694-
if (baseName == DeclBaseName::createConstructor())
5694+
if (baseName.isConstructor())
56955695
action.emplace(ImplicitMemberAction::ResolveImplicitInit);
56965696

56975697
if (member.isSimpleName() && !baseName.isSpecial()) {
@@ -5701,19 +5701,20 @@ void NominalTypeDecl::synthesizeSemanticMembersIfNeeded(DeclName member) {
57015701
} else {
57025702
auto argumentNames = member.getArgumentNames();
57035703
if (member.isSimpleName() || argumentNames.size() == 1) {
5704-
if (baseName == DeclBaseName::createConstructor()) {
5704+
if (baseName.isConstructor()) {
57055705
if ((member.isSimpleName() || argumentNames.front() == Context.Id_from)) {
57065706
action.emplace(ImplicitMemberAction::ResolveDecodable);
57075707
} else if (argumentNames.front() == Context.Id_system) {
57085708
action.emplace(ImplicitMemberAction::ResolveDistributedActorSystem);
57095709
}
57105710
} else if (!baseName.isSpecial() &&
5711-
baseName.getIdentifier() == Context.Id_encode &&
5712-
(member.isSimpleName() || argumentNames.front() == Context.Id_to)) {
5711+
baseName.getIdentifier() == Context.Id_encode &&
5712+
(member.isSimpleName() ||
5713+
argumentNames.front() == Context.Id_to)) {
57135714
action.emplace(ImplicitMemberAction::ResolveEncodable);
57145715
}
57155716
} else if (member.isSimpleName() || argumentNames.size() == 2) {
5716-
if (baseName == DeclBaseName::createConstructor()) {
5717+
if (baseName.isConstructor()) {
57175718
if (argumentNames[0] == Context.Id_resolve &&
57185719
argumentNames[1] == Context.Id_using) {
57195720
action.emplace(ImplicitMemberAction::ResolveDistributedActor);
@@ -10370,7 +10371,7 @@ ConstructorDecl::ConstructorDecl(DeclName Name, SourceLoc ConstructorLoc,
1037010371
Bits.ConstructorDecl.HasStubImplementation = 0;
1037110372
Bits.ConstructorDecl.Failable = Failable;
1037210373

10373-
assert(Name.getBaseName() == DeclBaseName::createConstructor());
10374+
assert(Name.getBaseName().isConstructor());
1037410375
}
1037510376

1037610377
ConstructorDecl *ConstructorDecl::createImported(

lib/AST/NameLookup.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ bool swift::removeOverriddenDecls(SmallVectorImpl<ValueDecl*> &decls) {
344344
// C.init overrides B.init overrides A.init, but only C.init and
345345
// A.init are in the chain. Make sure we still remove A.init from the
346346
// set in this case.
347-
if (decl->getBaseName() == DeclBaseName::createConstructor()) {
347+
if (decl->getBaseName().isConstructor()) {
348348
/// FIXME: Avoid the possibility of an infinite loop by fixing the root
349349
/// cause instead (incomplete circularity detection).
350350
assert(decl != overrides && "Circular class inheritance?");
@@ -2494,7 +2494,7 @@ QualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
24942494
// current class permits inheritance. Even then, only find complete
24952495
// object initializers.
24962496
bool visitSuperclass = true;
2497-
if (member.getBaseName() == DeclBaseName::createConstructor()) {
2497+
if (member.getBaseName().isConstructor()) {
24982498
if (classDecl->inheritsSuperclassInitializers())
24992499
onlyCompleteObjectInits = true;
25002500
else

lib/ClangImporter/ClangImporter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6275,7 +6275,7 @@ ClangImporter::Implementation::loadNamedMembers(
62756275
}
62766276
}
62776277

6278-
if (N == DeclBaseName::createConstructor()) {
6278+
if (N.isConstructor()) {
62796279
if (auto *classDecl = dyn_cast<ClassDecl>(D)) {
62806280
SmallVector<Decl *, 4> ctors;
62816281
importInheritedConstructors(cast<clang::ObjCInterfaceDecl>(CD),

lib/ClangImporter/ImportDecl.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,8 +1137,7 @@ namespace {
11371137
}
11381138

11391139
bool isFactoryInit(ImportedName &name) {
1140-
return name &&
1141-
name.getDeclName().getBaseName() == DeclBaseName::createConstructor() &&
1140+
return name && name.getDeclName().getBaseName().isConstructor() &&
11421141
(name.getInitKind() == CtorInitializerKind::Factory ||
11431142
name.getInitKind() == CtorInitializerKind::ConvenienceFactory);
11441143
}
@@ -3501,7 +3500,7 @@ namespace {
35013500
isa<clang::CXXMethodDecl>(decl) && Impl.importSymbolicCXXDecls;
35023501
if (!dc->isModuleScopeContext() && !isa<clang::CXXMethodDecl>(decl)) {
35033502
// Handle initializers.
3504-
if (name.getBaseName() == DeclBaseName::createConstructor()) {
3503+
if (name.getBaseName().isConstructor()) {
35053504
assert(!accessorInfo);
35063505
return importGlobalAsInitializer(decl, name, dc,
35073506
importedName.getInitKind(),

lib/Parse/ParseExpr.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,8 +1755,9 @@ ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) {
17551755

17561756
LLVM_FALLTHROUGH;
17571757
}
1758+
case tok::kw_init:
17581759
case tok::kw_Self: // Self
1759-
return parseExprIdentifier();
1760+
return parseExprIdentifier(/*allowKeyword=*/true);
17601761

17611762
case tok::kw_Any: { // Any
17621763
auto TyR = parseAnyType();
@@ -2390,17 +2391,20 @@ ParserStatus Parser::parseFreestandingMacroExpansion(
23902391

23912392
/// expr-identifier:
23922393
/// unqualified-decl-name generic-args?
2393-
ParserResult<Expr> Parser::parseExprIdentifier() {
2394+
ParserResult<Expr> Parser::parseExprIdentifier(bool allowKeyword) {
23942395
ParserStatus status;
2395-
assert(Tok.isAny(tok::identifier, tok::kw_self, tok::kw_Self));
2396+
assert(Tok.isAny(tok::identifier, tok::kw_self, tok::kw_Self) ||
2397+
(allowKeyword && Tok.isKeyword()));
23962398
Token IdentTok = Tok;
23972399

2400+
auto declNameFlags = DeclNameFlag::AllowCompoundNames |
2401+
DeclNameFlag::AllowLowercaseAndUppercaseSelf;
2402+
if (allowKeyword) {
2403+
declNameFlags |= DeclNameFlag::AllowKeywords;
2404+
}
23982405
// Parse the unqualified-decl-name.
23992406
DeclNameLoc loc;
2400-
DeclNameRef name =
2401-
parseDeclNameRef(loc, diag::expected_expr,
2402-
DeclNameFlag::AllowCompoundNames |
2403-
DeclNameFlag::AllowLowercaseAndUppercaseSelf);
2407+
DeclNameRef name = parseDeclNameRef(loc, diag::expected_expr, declNameFlags);
24042408

24052409
SmallVector<TypeRepr*, 8> args;
24062410
SourceLoc LAngleLoc, RAngleLoc;
@@ -2701,7 +2705,7 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
27012705
// the expression to capture.
27022706
if (!Tok.is(tok::code_complete)) {
27032707
name = Context.getIdentifier(Tok.getText());
2704-
auto initializerResult = parseExprIdentifier();
2708+
auto initializerResult = parseExprIdentifier(/*allowKeyword=*/false);
27052709
status |= initializerResult;
27062710
initializer = initializerResult.get();
27072711
} else {

lib/Parse/ParsePattern.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -799,11 +799,11 @@ Parser::parseFunctionSignature(DeclBaseName SimpleName,
799799
SmallVector<Identifier, 4> NamePieces;
800800
ParserStatus Status;
801801

802-
ParameterContextKind paramContext = SimpleName.isOperator()
803-
? ParameterContextKind::Operator
804-
: (SimpleName == DeclBaseName::createConstructor()
805-
? ParameterContextKind::Initializer
806-
: ParameterContextKind::Function);
802+
ParameterContextKind paramContext =
803+
SimpleName.isOperator()
804+
? ParameterContextKind::Operator
805+
: (SimpleName.isConstructor() ? ParameterContextKind::Initializer
806+
: ParameterContextKind::Function);
807807
Status |= parseFunctionArguments(NamePieces, bodyParams, paramContext,
808808
defaultArgs);
809809
FullName = DeclName(Context, SimpleName, NamePieces);

0 commit comments

Comments
 (0)