Skip to content

Commit ffc6f20

Browse files
committed
[move-only] Allow for nominal non-class move only types to have destructors.
In the process of doing this I also moved the logic of checking if a type can have a destructor to the type checker from the parser.
1 parent b3c1339 commit ffc6f20

File tree

4 files changed

+42
-27
lines changed

4 files changed

+42
-27
lines changed

include/swift/Parse/Parser.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -976,13 +976,12 @@ class Parser {
976976
PD_AllowTopLevel = 1 << 1,
977977
PD_HasContainerType = 1 << 2,
978978
PD_DisallowInit = 1 << 3,
979-
PD_AllowDestructor = 1 << 4,
980-
PD_AllowEnumElement = 1 << 5,
981-
PD_InProtocol = 1 << 6,
982-
PD_InClass = 1 << 7,
983-
PD_InExtension = 1 << 8,
984-
PD_InStruct = 1 << 9,
985-
PD_InEnum = 1 << 10,
979+
PD_AllowEnumElement = 1 << 4,
980+
PD_InProtocol = 1 << 5,
981+
PD_InClass = 1 << 6,
982+
PD_InExtension = 1 << 7,
983+
PD_InStruct = 1 << 8,
984+
PD_InEnum = 1 << 9,
986985
};
987986

988987
/// Options that control the parsing of declarations.

lib/AST/ASTVerifier.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3142,8 +3142,9 @@ class Verifier : public ASTWalker {
31423142
PrettyStackTraceDecl debugStack("verifying DestructorDecl", DD);
31433143

31443144
auto *ND = DD->getDeclContext()->getSelfNominalTypeDecl();
3145-
if (!isa<ClassDecl>(ND) && !DD->isInvalid()) {
3146-
Out << "DestructorDecls outside classes should be marked invalid";
3145+
if (!isa<ClassDecl>(ND) && !ND->isMoveOnly() && !DD->isInvalid()) {
3146+
Out << "DestructorDecls outside classes/move only types should be "
3147+
"marked invalid\n";
31473148
abort();
31483149
}
31493150
verifyCheckedBase(DD);

lib/Parse/ParseDecl.cpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,36 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17-
#include "swift/Parse/Parser.h"
18-
#include "swift/Parse/CodeCompletionCallbacks.h"
19-
#include "swift/Parse/ParsedSyntaxRecorder.h"
20-
#include "swift/Parse/ParseSILSupport.h"
21-
#include "swift/Parse/SyntaxParsingContext.h"
22-
#include "swift/Syntax/SyntaxKind.h"
23-
#include "swift/Subsystems.h"
24-
#include "swift/Strings.h"
2517
#include "swift/AST/ASTWalker.h"
2618
#include "swift/AST/Attr.h"
27-
#include "swift/AST/GenericParamList.h"
28-
#include "swift/AST/LazyResolver.h"
2919
#include "swift/AST/DebuggerClient.h"
20+
#include "swift/AST/Decl.h"
3021
#include "swift/AST/DiagnosticsParse.h"
22+
#include "swift/AST/GenericParamList.h"
3123
#include "swift/AST/Initializer.h"
24+
#include "swift/AST/LazyResolver.h"
3225
#include "swift/AST/Module.h"
3326
#include "swift/AST/ParameterList.h"
3427
#include "swift/AST/ParseRequests.h"
3528
#include "swift/AST/SourceFile.h"
3629
#include "swift/Basic/Defer.h"
3730
#include "swift/Basic/Statistic.h"
3831
#include "swift/Basic/StringExtras.h"
32+
#include "swift/Parse/CodeCompletionCallbacks.h"
33+
#include "swift/Parse/ParseSILSupport.h"
34+
#include "swift/Parse/ParsedSyntaxRecorder.h"
35+
#include "swift/Parse/Parser.h"
36+
#include "swift/Parse/SyntaxParsingContext.h"
37+
#include "swift/Strings.h"
38+
#include "swift/Subsystems.h"
39+
#include "swift/Syntax/SyntaxKind.h"
40+
#include "llvm/ADT/PointerUnion.h"
41+
#include "llvm/ADT/StringSwitch.h"
42+
#include "llvm/ADT/Twine.h"
3943
#include "llvm/Support/Compiler.h"
4044
#include "llvm/Support/MemoryBuffer.h"
4145
#include "llvm/Support/Path.h"
4246
#include "llvm/Support/SaveAndRestore.h"
43-
#include "llvm/ADT/PointerUnion.h"
44-
#include "llvm/ADT/StringSwitch.h"
45-
#include "llvm/ADT/Twine.h"
4647
#include <algorithm>
4748

4849
using namespace swift;
@@ -5111,9 +5112,7 @@ static Parser::ParseDeclOptions getMemberParseDeclOptions(
51115112
Parser::PD_InProtocol);
51125113

51135114
case DeclKind::Class:
5114-
return ParseDeclOptions(
5115-
Parser::PD_HasContainerType | Parser::PD_AllowDestructor |
5116-
Parser::PD_InClass);
5115+
return ParseDeclOptions(Parser::PD_HasContainerType | Parser::PD_InClass);
51175116

51185117
case DeclKind::Struct:
51195118
return ParseDeclOptions(Parser::PD_HasContainerType | Parser::PD_InStruct);
@@ -8748,8 +8747,13 @@ parseDeclDeinit(ParseDeclOptions Flags, DeclAttributes &Attributes) {
87488747

87498748
DD->getAttrs() = Attributes;
87508749

8751-
// Reject 'destructor' functions outside of classes
8752-
if (!(Flags & PD_AllowDestructor)) {
8750+
// Reject 'destructor' functions outside of structs, enums, and classes.
8751+
//
8752+
// Later in the type checker, we validate that structs/enums only do this if
8753+
// they are move only.
8754+
auto *nom = dyn_cast<NominalTypeDecl>(CurDeclContext);
8755+
if (!nom ||
8756+
(!isa<StructDecl>(nom) && !isa<EnumDecl>(nom) && !isa<ClassDecl>(nom))) {
87538757
diagnose(DestructorLoc, diag::destructor_decl_outside_class);
87548758

87558759
// Tell the type checker not to touch this destructor.

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#include "swift/AST/ASTWalker.h"
3232
#include "swift/AST/AccessNotes.h"
3333
#include "swift/AST/AccessScope.h"
34+
#include "swift/AST/Decl.h"
35+
#include "swift/AST/DeclContext.h"
3436
#include "swift/AST/ExistentialLayout.h"
3537
#include "swift/AST/Expr.h"
3638
#include "swift/AST/ForeignErrorConvention.h"
@@ -3349,6 +3351,15 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
33493351
}
33503352

33513353
void visitDestructorDecl(DestructorDecl *DD) {
3354+
// Only check again for destructor decl outside of a class if our dstructor
3355+
// is not marked as invalid.
3356+
if (!DD->isInvalid()) {
3357+
auto *nom = dyn_cast<NominalTypeDecl>(DD->getDeclContext());
3358+
if (!nom || (!isa<ClassDecl>(nom) && !nom->isMoveOnly())) {
3359+
DD->diagnose(diag::destructor_decl_outside_class);
3360+
}
3361+
}
3362+
33523363
TypeChecker::checkDeclAttributes(DD);
33533364

33543365
if (DD->getDeclContext()->isLocalContext()) {

0 commit comments

Comments
 (0)