The compiler behaves a bit strange here, maybe I'm missing something?
Consider an inner generic type, with a constraint on the type:
struct MyInnerType<T: Error> {
let t: T
}
I don't have to worry about this constraint here, presumably the compiler figures that you won't be able to construct a value with the wrong T anyway. This makes sense.
struct MyOuterType1 {
func test<T>(_ value: MyInnerType<T>) { }
}
This is perhaps a bit less obvious, but it works in practice because you need to constrain it manually:
struct MyOuterType1b {
func test<T>() -> MyInnerType<T> { fatalError() }
}
This also works because the entire outer type is constrained w.r.t T
struct MyOuterType2<T: Error> {
func test() -> MyInnerType<T> { fatalError() }
}
This rightly fails, because the outer type could have anything as T
, and it is "in control" of T
struct MyOuterType3<T> {
// T does not conform to Error
func test() -> MyInnerType<T> { fatalError() }
}
So why does this work? T
is constrained, but not to Error
.
struct MyOuterType4<T> {
func test() -> MyInnerType<T> where T: Collection { fatalError() }
}
That function looks like it's available for any T
that is a Collection
, but in reality T
will have to be both a Collection
and an Error
:
enum MyEnum { case one }
enum MyError: Error { case one }
extension Array: Error where Element: Error { }
func ttt() {
// Collection and Error -> OK
MyOuterType4<[MyError]>().test()
// Only Collection -> Referencing instance method 'test()' on 'Array' requires that 'Double' conform to 'Error'
MyOuterType4<[Double]>().test()
// Only Error -> Instance method 'test()' requires that 'MyError' conform to 'Collection'
MyOuterType4<MyError>().test()
// Neither -> Compiler shows both of the errors
MyOuterType4<MyEnum>().test()
}
When the constraint is on the type though, it has to be the correct one:
struct MyOuterType4<T: Collection> {
// Type 'T' does not conform to protocol 'Error'
func test(_ value: MyInnerType<T>) { }
}
This is not necessarily a bug, but I wonder if there's an explanation for the behaviour?