SE-0341: Opaque Parameter Declarations

I brought this up in the pitch thread for SE-0328 and there were some comments in the replies about this being potentially confusing. I agree that it’s probably best to rule out opaque types in contravariant positions for now.

If anything, the argument for it to work this way is probably clearer for contravariant positions in function arguments than it is in return types, due to the way type inference works

  1. Function arguments:
protocol P { 
  func foo() -> Int
}
struct TheP : P {
  func foo() -> Int {
    return 1
  } 
}
// equivalent to func actOnP(closure: (A) -> Int) -> <A: P> Int
func actOnP(closure: (some P) -> Int) -> Int {
   return closure(TheP())
}

actOnP { p in p.foo() } // 1
  1. Function return
protocol Q {
  func bar(i: Int) -> Int
}
struct TheQ : Q {
  func bar(i: Int) -> Int {
    return i
  }
}
// equivalent to func takeAQ<B : Q>() -> (B) -> Int
func takeAQ() -> (some Q) -> Int {
  return { q in q.bar(1) }
}
// so far so good... now how to use `takeAQ`?
let a = takeAQ() // Error? haven't specified the type of 'some Q'
// Need to use inference from use site
func actOnQ(f: (TheQ) -> Int) -> Int {
 return f(TheQ())
}
actOnQ(f: takeAQ())
1 Like