Skip to content

Commit a0d4dd7

Browse files
committed
move-only types can't witness associatedtype requirements
1 parent 6004793 commit a0d4dd7

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4596,6 +4596,14 @@ swift::checkTypeWitness(Type type, AssociatedTypeDecl *assocType,
45964596
proto->isComputingRequirementSignature())
45974597
return ErrorType::get(ctx);
45984598

4599+
// No move-only type can witness an associatedtype requirement.
4600+
if (type->isPureMoveOnly()) {
4601+
// describe the failure reason as it not conforming to Copyable
4602+
auto *copyable = ctx.getProtocol(KnownProtocolKind::Copyable);
4603+
assert(copyable && "missing _Copyable from stdlib!");
4604+
return CheckTypeWitnessResult(copyable->getDeclaredInterfaceType());
4605+
}
4606+
45994607
const auto depTy = DependentMemberType::get(proto->getSelfInterfaceType(),
46004608
assocType);
46014609

test/Constraints/moveonly_constraints.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,27 @@ func checkStdlibTypes(_ mo: MO) {
162162
_ = [MO]() // expected-error {{move-only type 'MO' cannot be used with generics yet}}
163163

164164
let s: String = "hello \(mo)" // expected-error {{move-only type 'MO' cannot be used with generics yet}}
165+
}
166+
167+
// ensure that associated types can't be witnessed by move-only types
168+
169+
protocol HasType<Ty> {
170+
associatedtype Ty // expected-note 3{{protocol requires nested type 'Ty'; do you want to add it?}}
171+
}
172+
173+
class SomeGuy: HasType { // expected-error {{type 'SomeGuy' does not conform to protocol 'HasType'}}
174+
typealias Ty = MO // expected-note {{possibly intended match 'SomeGuy.Ty' (aka 'MO') does not conform to '_Copyable'}}
175+
}
176+
177+
struct AnotherGuy: HasType { // expected-error {{type 'AnotherGuy' does not conform to protocol 'HasType'}}
178+
@_moveOnly struct Ty {} // expected-note {{possibly intended match 'AnotherGuy.Ty' does not conform to '_Copyable'}}
179+
}
180+
181+
protocol Gives: HasType {
182+
func give() -> Ty
183+
}
184+
185+
struct GenerousGuy: Gives { // expected-error {{type 'GenerousGuy' does not conform to protocol 'HasType'}}
186+
typealias Ty = MO // expected-note {{possibly intended match 'GenerousGuy.Ty' (aka 'MO') does not conform to '_Copyable'}}
187+
func give() -> Ty {}
165188
}

0 commit comments

Comments
 (0)