Why can’t i open this existential?

i’ve got a protocol HTML.OutputStreamable with a requirement +=(_:_:)

public
protocol _HTMLOutputStreamable
{
    static
    func += (html:inout HTML.ContentEncoder, self:Self)
}

today, i tried to use it to encode a list from [any HTML.OutputStreamable]:

html[.ol]
{
    for entry:any HTML.OutputStreamable in self.entries
    {
        $0[.li]
        {
            $0[.dl] { $0 += entry }
        }
    }
}

each closure in the DSL receives an inout HTML.ContentEncoder in $0. and i really thought implicitly-opened existentials would help me out here. but sadly i get the infamous

error: type 'any HTML.OutputStreamable' (aka 'any _HTMLOutputStreamable') 
cannot conform to '_HTMLOutputStreamable'

why?

It's a static requirement, so you need to open the existential manually by passing it to a generic function.

protocol Foo {
    static func += (lhs: Self, rhs: Int)
}

func test(_ items: [any Foo]) {    
    for item in items {
        item += 42 // error: type 'any Foo' cannot conform to 'Foo'
    }
}

func test2(_ items: [any Foo]) {    
    func add(_ x: some Foo, _ y: Int) {
        x += y
    }
    for item in items {
        add(item, 42) // works
    }
}
1 Like