Skip to content

Commit 4373c61

Browse files
committed
[Sema] fix conditional Copyable checking
1 parent e75c451 commit 4373c61

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

lib/Sema/TypeCheckInvertible.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,8 @@ bool checkCopyableConformance(ProtocolConformance *conformance) {
216216
};
217217

218218
// This nominal cannot be Copyable if it contains noncopyable storage.
219-
return !HasNoncopyable(nom, nom, /*diagnose=*/true).visit();
219+
return !HasNoncopyable(nom, conformance->getDeclContext(),
220+
/*diagnose=*/true).visit();
220221
}
221222

222223
/// Visit the instance storage of the given nominal type as seen through

test/Generics/inverse_copyable_generics.swift

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,41 @@ class ClassContainment<T: ~Copyable> {
5959
checkCopyable(t) // expected-error {{noncopyable type 'T' cannot be substituted for copyable generic parameter 'T' in 'checkCopyable'}}
6060
}
6161
}
62+
63+
64+
/// ----------------
65+
66+
enum Maybe<Wrapped: ~Copyable>: ~Copyable {
67+
case just(Wrapped)
68+
case none
69+
}
70+
extension Maybe: Copyable where Wrapped: Copyable {}
71+
72+
struct RequireCopyable<T> {}
73+
// expected-note@-1{{requirement specified as 'NC' : 'Copyable'}}
74+
// expected-note@-2{{requirement from conditional conformance of 'Maybe<NC>' to 'Copyable'}}
75+
// expected-note@-3{{requirement specified as 'Wrapped' : 'Copyable'}}
76+
// expected-note@-4{{requirement from conditional conformance of 'Maybe<Wrapped>' to 'Copyable'}}
77+
78+
struct NC: ~Copyable {}
79+
80+
typealias ok1 = RequireCopyable<Int>
81+
typealias ok2 = RequireCopyable<Maybe<Int>>
82+
83+
typealias err1 = RequireCopyable<Maybe<NC>>
84+
// expected-error@-1{{type 'NC' does not conform to protocol 'Copyable'}}
85+
// expected-error@-2{{'RequireCopyable' requires that 'NC' conform to 'Copyable'}}
86+
87+
typealias err2 = RequireCopyable<NC>
88+
// expected-error@-1{{type 'NC' does not conform to protocol 'Copyable'}}
89+
90+
// plain extension doesn't treat Self as Copyable
91+
extension Maybe {
92+
func check1(_ t: RequireCopyable<Self>) {}
93+
// expected-error@-1 {{type 'Wrapped' does not conform to protocol 'Copyable'}}
94+
// expected-error@-2 {{'RequireCopyable' requires that 'Wrapped' conform to 'Copyable'}}
95+
}
96+
97+
extension Maybe where Self: Copyable {
98+
func check2(_ t: RequireCopyable<Self>) {}
99+
}

0 commit comments

Comments
 (0)