Opaque Result Types Bug?

#1
func test() -> some Collection { // Function declares an opaque return type, but has no return statements in its body from which to infer an underlying type
    fatalError() // Cannot convert return expression of type 'Never' to return type 'some Collection'
}

Is this a bug?

#2

No. From the evolution proposal:

3 Likes
#3

Thanks.

(Tino) #4

Still, I think it‘s quite ugly that the feature creates such a special case :-(

(Adrian Zubarev) #5

Never as bottom type should help here. Then one day you would write fatalError() as Array<Int>.

(Chéyo Jiménez) #6

return Never doesn't work?

(Adrian Zubarev) #7

The point is that it does not make sense even when we had the bottom type. The type is opaque only for the user but not for the compiler and in case you want to type check two collections of the same expected type you clearly don‘t want one of them to be Never. That‘s why you likely would upcast Never to a concrete collection of your choice. This mimics (where there is no type erasure):

func foo() -> [Int] {
  fatalError()
}

// the compiler knows that this return type hides `[Int]`
// it‘s not interesting that it actually is `Never` which will 
// cause termination of the program
func bar() -> some Collection {
  return fatalError() as [Int]
} 
(Chéyo Jiménez) #8
func foo() -> [Int] {
  fatalError()
}
// this should work if it doesn’t why not?
func bar() -> some Collection {
  return foo()
} 

(Adrian Zubarev) #9

As far as I know this would work yes, but the thread was opened because you cannot use fatalError yet in bar just like in foo. For that you‘d need the ability to upcast Never to a type of your choice.