Skip to content

Commit e6826e3

Browse files
authored
Merge pull request swiftlang#38624 from DougGregor/actor-derived-hashable-5.5
Make derived hashValue/hash(into:) nonisolated.
2 parents 9e6ab89 + 694a752 commit e6826e3

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed

lib/Sema/DerivedConformanceEquatableHashable.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,12 @@ deriveHashable_hashInto(
557557
hashDecl->copyFormalAccessFrom(derived.Nominal,
558558
/*sourceIsParentContext=*/true);
559559

560+
// The derived hash(into:) for an actor must be non-isolated.
561+
if (derived.Nominal->isActor() ||
562+
getActorIsolation(derived.Nominal) == ActorIsolation::GlobalActor) {
563+
hashDecl->getAttrs().add(new (C) NonisolatedAttr(/*IsImplicit*/true));
564+
}
565+
560566
derived.addMembersToConformanceContext({hashDecl});
561567

562568
return hashDecl;
@@ -912,6 +918,12 @@ static ValueDecl *deriveHashable_hashValue(DerivedConformance &derived) {
912918
hashValueDecl->copyFormalAccessFrom(derived.Nominal,
913919
/*sourceIsParentContext*/ true);
914920

921+
// The derived hashValue of an actor must be nonisolated.
922+
if (derived.Nominal->isActor() ||
923+
getActorIsolation(derived.Nominal) == ActorIsolation::GlobalActor) {
924+
hashValueDecl->getAttrs().add(new (C) NonisolatedAttr(/*IsImplicit*/true));
925+
}
926+
915927
Pattern *hashValuePat = NamedPattern::createImplicit(C, hashValueDecl);
916928
hashValuePat->setType(intType);
917929
hashValuePat = TypedPattern::createImplicit(C, hashValuePat, intType);
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: %target-typecheck-verify-swift
2+
// REQUIRES: concurrency
3+
4+
@available(SwiftStdlib 5.5, *)
5+
actor A1: Hashable {
6+
nonisolated func hash(into hasher: inout Hasher) { }
7+
static func ==(lhs: A1, rhs: A1) -> Bool { true }
8+
}
9+
10+
@available(SwiftStdlib 5.5, *)
11+
actor A2: Hashable {
12+
nonisolated var hashValue: Int { 0 } // expected-warning{{'Hashable.hashValue' is deprecated as a protocol requirement; conform type 'A2' to 'Hashable' by implementing 'hash(into:)' instead}}
13+
static func ==(lhs: A2, rhs: A2) -> Bool { true }
14+
}
15+
16+
17+
@available(SwiftStdlib 5.5, *)
18+
@MainActor
19+
class C1: Hashable {
20+
nonisolated func hash(into hasher: inout Hasher) { }
21+
nonisolated static func ==(lhs: C1, rhs: C1) -> Bool { true }
22+
}
23+
24+
@available(SwiftStdlib 5.5, *)
25+
@MainActor
26+
class C2: Hashable {
27+
nonisolated var hashValue: Int { 0 } // expected-warning{{'Hashable.hashValue' is deprecated as a protocol requirement; conform type 'C2' to 'Hashable' by implementing 'hash(into:)' instead}}
28+
nonisolated static func ==(lhs: C2, rhs: C2) -> Bool { true }
29+
}
30+

test/decl/protocol/special/Actor.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency
22
// REQUIRES: concurrency
33

4-
// Synthesis of for actores.
4+
// Synthesis of conformances for actors.
55

66
@available(SwiftStdlib 5.5, *)
77
actor A1 {

0 commit comments

Comments
 (0)