mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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.
77 lines
1.7 KiB
Swift
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 }
|