Files
swift-mirror/test/Generics/inheritance.swift
Slava Pestov 3aacf5d805 ArchetypeBuilder: Allow generic signature superclass constraints to contain type parameters
There was a diagnostic to catch these, but it wasn't triggered
reliably, and it sounds like users were already relying on this
feature working in the few cases where it did.

So instead, just map an archetype's superclass into context
when building the archetype.

Recursion is still not allowed and is diagnosed, for example
<T, U where T : C<U>, U : C<T>>.

Note that compiler_crashers_fixed/00022-no-stacktrace.swift no
longer produces a diagnostic in Sema, despite the fact that the
code is invalid. It does diagnose in IRGen when we map the
type into context. Diagnosing in Sema requires fixing the
declaration checker to correctly handle recursion through a
generic signature. Right now, if recursion is detected, we bail
out, but do not always diagnose. Alternatively, we could
prohibit unbound generic types from appearing in generic
signatures.

This is a more principled fix for rdar://problem/24590570.
2016-02-11 23:23:26 -08:00

77 lines
1.7 KiB
Swift

// RUN: %target-parse-verify-swift
class A {
func foo() { }
}
class B : A {
func bar() { }
}
class Other { }
func acceptA(a: A) { }
func f0<T : A>(obji: T, _ ai: A, _ bi: B) {
var obj = obji, a = ai, b = bi
// Method access
obj.foo()
obj.bar() // expected-error{{value of type 'T' has no member 'bar'}}
// Calls
acceptA(obj)
// Derived-to-base conversion for assignment
a = obj
// Invalid assignments
obj = a // expected-error{{'A' is not convertible to 'T'}}
obj = b // expected-error{{'B' is not convertible to 'T'}}
// Downcast that is actually a coercion
a = (obj as? A)! // expected-warning{{conditional cast from 'T' to 'A' always succeeds}}
a = obj as A
// Downcasts
b = obj as! B
}
func call_f0(a: A, b: B, other: Other) {
f0(a, a, b)
f0(b, a, b)
f0(other, a, b) // expected-error{{cannot convert value of type 'Other' to expected argument type 'A'}}
}
class X<T> {
func f() -> T {}
}
class Y<T> : X<[T]> {
}
func testGenericInherit() {
let yi : Y<Int>
_ = yi.f() as [Int]
}
struct SS<T> : T { } // expected-error{{inheritance from non-protocol type 'T'}}
enum SE<T> : T { case X } // expected-error{{raw type 'T' is not convertible from any literal}}
// expected-error@-1{{type 'SE<T>' does not conform to protocol 'RawRepresentable'}}
// Also need Equatable for init?(RawValue)
enum SE2<T : IntegerLiteralConvertible>
: T // expected-error{{RawRepresentable 'init' cannot be synthesized because raw type 'T' is not Equatable}}
{ case X }
// ... but not if init?(RawValue) is directly implemented some other way.
enum SE3<T : IntegerLiteralConvertible> : T {
case X
init?(rawValue: T) {
self = SE3.X
}
}
enum SE4<T : protocol<IntegerLiteralConvertible,Equatable> > : T { case X }