Why can't I cast `Woo<Any>` to `Woo<Int>` concrete type? But `Array<Any>` to `Array<Int>` is OK?

Your use case doesn't actually require the associated type, but it's nice to have the option.

protocol JamesRandiProtocol<Boo> {
  associatedtype Boo
  var boo: Boo { get }

extension Woo: JamesRandiProtocol { }

(Woo(boo: 3) as Any) as! Woo<Int>
(Woo(boo: 3) as any JamesRandiProtocol<Int>) as! Woo<Int>
(Woo(boo: 3) as any JamesRandiProtocol) as! Woo<Int>

To reiterate what's been said or suggested elsewhere, we need this:

(Woo(boo: 3) as any Woo) as! Woo<Int>