Skip to content

Commit cb4a248

Browse files
committed
Sema: Diagnose non-required class initializer calls on protocols with superclass contraint
1 parent 66e6a6a commit cb4a248

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

lib/Sema/CSApply.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,9 @@ static bool isNonFinalClass(Type type) {
320320
if (auto super = archetype->getSuperclass())
321321
return isNonFinalClass(super);
322322

323+
if (type->isExistentialType())
324+
return true;
325+
323326
return false;
324327
}
325328

test/decl/protocol/protocol_with_superclass.swift

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,68 @@ func usesProtoRefinesProtoWithClass2<T : ProtoRefinesProtoWithClass>(_ t: T) {
196196
let _: Generic<String> = t
197197
// expected-error@-1 {{cannot convert value of type 'T' to specified type 'Generic<String>'}}
198198
}
199+
200+
class ClassWithInits<T> {
201+
init(notRequiredInit: ()) {}
202+
// expected-note@-1 6{{selected non-required initializer 'init(notRequiredInit:)'}}
203+
204+
required init(requiredInit: ()) {}
205+
}
206+
207+
protocol ProtocolWithClassInits : ClassWithInits<Int> {}
208+
209+
func useProtocolWithClassInits1() {
210+
_ = ProtocolWithClassInits(notRequiredInit: ())
211+
// expected-error@-1 {{member 'init' cannot be used on type 'ProtocolWithClassInits'}}
212+
213+
_ = ProtocolWithClassInits(requiredInit: ())
214+
// expected-error@-1 {{member 'init' cannot be used on type 'ProtocolWithClassInits'}}
215+
}
216+
217+
func useProtocolWithClassInits2(_ t: ProtocolWithClassInits.Type) {
218+
_ = t.init(notRequiredInit: ())
219+
// expected-error@-1 {{constructing an object of class type 'ProtocolWithClassInits' with a metatype value must use a 'required' initializer}}
220+
221+
let _: ProtocolWithClassInits = t.init(requiredInit: ())
222+
}
223+
224+
func useProtocolWithClassInits3<T : ProtocolWithClassInits>(_ t: T.Type) {
225+
_ = T(notRequiredInit: ())
226+
// expected-error@-1 {{constructing an object of class type 'T' with a metatype value must use a 'required' initializer}}
227+
228+
let _: T = T(requiredInit: ())
229+
230+
_ = t.init(notRequiredInit: ())
231+
// expected-error@-1 {{constructing an object of class type 'T' with a metatype value must use a 'required' initializer}}
232+
233+
let _: T = t.init(requiredInit: ())
234+
}
235+
236+
protocol ProtocolRefinesClassInits : ProtocolWithClassInits {}
237+
238+
func useProtocolRefinesClassInits1() {
239+
_ = ProtocolRefinesClassInits(notRequiredInit: ())
240+
// expected-error@-1 {{member 'init' cannot be used on type 'ProtocolRefinesClassInits'}}
241+
242+
_ = ProtocolRefinesClassInits(requiredInit: ())
243+
// expected-error@-1 {{member 'init' cannot be used on type 'ProtocolRefinesClassInits'}}
244+
}
245+
246+
func useProtocolRefinesClassInits2(_ t: ProtocolRefinesClassInits.Type) {
247+
_ = t.init(notRequiredInit: ())
248+
// expected-error@-1 {{constructing an object of class type 'ProtocolRefinesClassInits' with a metatype value must use a 'required' initializer}}
249+
250+
let _: ProtocolRefinesClassInits = t.init(requiredInit: ())
251+
}
252+
253+
func useProtocolRefinesClassInits3<T : ProtocolRefinesClassInits>(_ t: T.Type) {
254+
_ = T(notRequiredInit: ())
255+
// expected-error@-1 {{constructing an object of class type 'T' with a metatype value must use a 'required' initializer}}
256+
257+
let _: T = T(requiredInit: ())
258+
259+
_ = t.init(notRequiredInit: ())
260+
// expected-error@-1 {{constructing an object of class type 'T' with a metatype value must use a 'required' initializer}}
261+
262+
let _: T = t.init(requiredInit: ())
263+
}

0 commit comments

Comments
 (0)