Skip to content

Commit 7c3e480

Browse files
authored
Merge pull request #65896 from kavon/discard-generic-noncopyable
allow `discard` in generic noncopyable type
2 parents 121b372 + 20b060b commit 7c3e480

File tree

5 files changed

+23
-4
lines changed

5 files changed

+23
-4
lines changed

lib/AST/Type.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ bool TypeBase::isMarkerExistential() {
189189
}
190190

191191
bool TypeBase::isPureMoveOnly() {
192-
if (auto *nom = getNominalOrBoundGenericNominal())
192+
if (auto *nom = getAnyNominal())
193193
return nom->isMoveOnly();
194194

195195
// if any components of the tuple are move-only, then the tuple is move-only.

lib/Sema/TypeCheckDecl.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -912,8 +912,9 @@ IsFinalRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
912912
}
913913

914914
bool IsMoveOnlyRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
915-
// For now only do this for nominal type decls.
916-
if (isa<NominalTypeDecl>(decl)) {
915+
// TODO: isPureMoveOnly and isMoveOnly and other checks are all spread out
916+
// and need to be merged together.
917+
if (isa<ClassDecl>(decl) || isa<StructDecl>(decl) || isa<EnumDecl>(decl)) {
917918
if (decl->getAttrs().hasAttribute<MoveOnlyAttr>()) {
918919
if (!decl->getASTContext().supportsMoveOnlyTypes())
919920
decl->diagnose(diag::moveOnly_requires_lexical_lifetimes);

lib/Sema/TypeCheckStmt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1262,7 +1262,7 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
12621262
// check the kind of type this discard statement appears within.
12631263
if (!diagnosed) {
12641264
auto *nominalDecl = fn->getDeclContext()->getSelfNominalTypeDecl();
1265-
Type nominalType = nominalDecl->getDeclaredType();
1265+
Type nominalType = nominalDecl->getDeclaredTypeInContext();
12661266

12671267
// must be noncopyable
12681268
if (!nominalType->isPureMoveOnly()) {

test/Sema/discard.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,9 @@ enum NoDeinitEnum: ~Copyable {
161161
discard self // expected-error {{'discard' has no effect for type 'NoDeinitEnum' unless it has a deinitializer}}{{5-18=}}
162162
}
163163
}
164+
165+
struct HasGenericNotStored<T>: ~Copyable {
166+
consuming func discard() { discard self }
167+
func identity(_ t: T) -> T { return t }
168+
deinit{}
169+
}

test/Sema/discard_trivially_destroyed.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,15 @@ struct AllOK: ~Copyable {
9898
consuming func doDiscard() { discard self }
9999
deinit {}
100100
}
101+
102+
struct HasGenericStored<T>: ~Copyable {
103+
let t: T // expected-note {{type 'T' cannot be trivially destroyed}}
104+
consuming func discard() { discard self } // expected-error {{can only 'discard' type 'HasGenericStored<T>' if it contains trivially-destroyed stored properties at this time}}
105+
deinit{}
106+
}
107+
108+
struct HasAny: ~Copyable {
109+
var t: Any // expected-note {{type 'Any' cannot be trivially destroyed}}
110+
consuming func discard() { discard self } // expected-error {{can only 'discard' type 'HasAny' if it contains trivially-destroyed stored properties at this time}}
111+
deinit{}
112+
}

0 commit comments

Comments
 (0)