Files
swift-mirror/test/Generics/unbound.swift
Slava Pestov 39b697898a Sema: Fix for unbound generic type handling
Previously we prohibited unbound generics in the underlying
type of a typealias, but due to an oversight the check was
not performed when resolving a nested type.

So this worked:

struct Outer { struct Inner<T> {} }
typealias OuterInner = Outer.Inner
let _: OuterInner<Int> = Outer.Inner<Int>()

However it was easy to cause a crash this way by stating an
unbound generic type where one was not expected. Also,
unqualified types in a typealias did not get this treatment,
so the following did not work:

typealias MyOptional = Optional

Formalize the old behavior by allowing unbound generic types
in the underlying type of a typealias, while otherwise
prohibiting unbound references to nested types.
2017-04-23 00:02:29 -07:00

76 lines
2.5 KiB
Swift

// RUN: %target-typecheck-verify-swift
// Verify the use of unbound generic types. They are permitted in
// certain places where type inference can fill in the generic
// arguments, and banned everywhere else.
// --------------------------------------------------
// Places where generic arguments are always required
// --------------------------------------------------
struct Foo<T> { // expected-note 3{{generic type 'Foo' declared here}}
struct Wibble { }
}
class Dict<K, V> { } // expected-note{{generic type 'Dict' declared here}} expected-note{{generic type 'Dict' declared here}} expected-note{{generic type 'Dict' declared here}}
// The underlying type of a typealias can only have unbound generic arguments
// at the top level.
typealias F = Foo // OK
typealias FW = Foo.Wibble // expected-error{{reference to generic type 'Foo' requires arguments in <...>}}
typealias FFW = () -> Foo // expected-error{{reference to generic type 'Foo' requires arguments in <...>}}
typealias OFW = Optional<() -> Foo> // expected-error{{reference to generic type 'Foo' requires arguments in <...>}}
// Cannot inherit from a generic type without arguments.
class MyDict : Dict { } // expected-error{{reference to generic type 'Dict' requires arguments in <...>}}
// Cannot create variables of a generic type without arguments.
// FIXME: <rdar://problem/14238814> would allow it for local variables
// only
var x : Dict // expected-error{{reference to generic type 'Dict' requires arguments in <...>}}
// Cannot create parameters of generic type without arguments.
func f(x: Dict) {} // expected-error{{reference to generic type 'Dict' requires arguments in <...>}}
class GC<T, U> {
init() {}
func f() -> GC {
let gc = GC()
return gc
}
}
extension GC {
func g() -> GC {
let gc = GC()
return gc
}
}
class SomeClassWithInvalidMethod {
func method<T>() { // expected-error {{generic parameter 'T' is not used in function signature}}
self.method()
}
}
// <rdar://problem/20792596> QoI: Cannot invoke with argument list (T), expected an argument list of (T)
protocol r20792596P {}
// expected-note @+1 {{in call to function 'foor20792596'}}
func foor20792596<T: r20792596P>(x: T) -> T {
return x
}
func callfoor20792596<T>(x: T) -> T {
return foor20792596(x) // expected-error {{generic parameter 'T' could not be inferred}}
}
// <rdar://problem/31181895> parameter "not used in function signature" when part of a superclass constraint
struct X1<T> {
func bar<U>() where T: X2<U> {}
}
class X2<T> {}